libcli/auth: rewrite schannel sign/seal code to be more generic
authorStefan Metzmacher <metze@samba.org>
Wed, 16 Sep 2009 00:03:46 +0000 (02:03 +0200)
committerStefan Metzmacher <metze@samba.org>
Wed, 16 Sep 2009 10:29:06 +0000 (12:29 +0200)
This prepares support for HMAC-SHA256/AES.

metze

libcli/auth/schannel_proto.h
libcli/auth/schannel_sign.c
source3/rpc_client/cli_pipe.c
source3/rpc_server/srv_pipe.c
source4/auth/gensec/schannel.c

index d31707d5c2bb20a1d462098c99be531865416a06..eee71995765c513ad3ce81aee75e417ada248bff 100644 (file)
 #ifndef _LIBCLI_AUTH_SCHANNEL_PROTO_H__
 #define _LIBCLI_AUTH_SCHANNEL_PROTO_H__
 
 #ifndef _LIBCLI_AUTH_SCHANNEL_PROTO_H__
 #define _LIBCLI_AUTH_SCHANNEL_PROTO_H__
 
-NTSTATUS schannel_unseal_packet(struct schannel_state *state,
+NTSTATUS netsec_incoming_packet(struct schannel_state *state,
                                TALLOC_CTX *mem_ctx,
                                TALLOC_CTX *mem_ctx,
+                               bool do_unseal,
                                uint8_t *data, size_t length,
                                const DATA_BLOB *sig);
                                uint8_t *data, size_t length,
                                const DATA_BLOB *sig);
-NTSTATUS schannel_check_packet(struct schannel_state *state,
-                              TALLOC_CTX *mem_ctx,
-                              const uint8_t *data, size_t length,
-                              const DATA_BLOB *sig);
-NTSTATUS schannel_seal_packet(struct schannel_state *state,
-                             TALLOC_CTX *mem_ctx,
-                             uint8_t *data, size_t length,
-                             DATA_BLOB *sig);
-NTSTATUS schannel_sign_packet(struct schannel_state *state,
-                             TALLOC_CTX *mem_ctx,
-                             const uint8_t *data, size_t length,
-                             DATA_BLOB *sig);
+NTSTATUS netsec_outgoing_packet(struct schannel_state *state,
+                               TALLOC_CTX *mem_ctx,
+                               bool do_seal,
+                               uint8_t *data, size_t length,
+                               DATA_BLOB *sig);
+
 #endif
 #endif
index e60b4107bbbf310a1c993cb359e96fc730794739..0672f671970588f5a176ff4735d1b340b726c364 100644 (file)
 #include "../libcli/auth/schannel.h"
 #include "../lib/crypto/crypto.h"
 
 #include "../libcli/auth/schannel.h"
 #include "../lib/crypto/crypto.h"
 
-#define NETSEC_SIGN_SIGNATURE { 0x77, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 }
-#define NETSEC_SEAL_SIGNATURE { 0x77, 0x00, 0x7a, 0x00, 0xff, 0xff, 0x00, 0x00 }
+static void netsec_offset_and_sizes(struct schannel_state *state,
+                                   bool do_seal,
+                                   uint32_t *_min_sig_size,
+                                   uint32_t *_used_sig_size,
+                                   uint32_t *_checksum_length,
+                                   uint32_t *_confounder_ofs)
+{
+       uint32_t min_sig_size = 24;
+       uint32_t used_sig_size = 32;
+       uint32_t checksum_length = 8;
+       uint32_t confounder_ofs = 24;
+
+       if (do_seal) {
+               min_sig_size += 8;
+       }
+
+       if (_min_sig_size) {
+               *_min_sig_size = min_sig_size;
+       }
+
+       if (_used_sig_size) {
+               *_used_sig_size = used_sig_size;
+       }
+
+       if (_checksum_length) {
+               *_checksum_length = checksum_length;
+       }
+
+       if (_confounder_ofs) {
+               *_confounder_ofs = confounder_ofs;
+       }
+}
 
 /*******************************************************************
  Encode or Decode the sequence number (which is symmetric)
  ********************************************************************/
 
 /*******************************************************************
  Encode or Decode the sequence number (which is symmetric)
  ********************************************************************/
-static void netsec_deal_with_seq_num(struct schannel_state *state,
-                                    const uint8_t packet_digest[8],
-                                    uint8_t seq_num[8])
+static void netsec_do_seq_num(struct schannel_state *state,
+                             const uint8_t *checksum,
+                             uint32_t checksum_length,
+                             uint8_t seq_num[8])
 {
        static const uint8_t zeros[4];
        uint8_t sequence_key[16];
        uint8_t digest1[16];
 
        hmac_md5(state->creds->session_key, zeros, sizeof(zeros), digest1);
 {
        static const uint8_t zeros[4];
        uint8_t sequence_key[16];
        uint8_t digest1[16];
 
        hmac_md5(state->creds->session_key, zeros, sizeof(zeros), digest1);
-       hmac_md5(digest1, packet_digest, 8, sequence_key);
+       hmac_md5(digest1, checksum, checksum_length, sequence_key);
        arcfour_crypt(seq_num, sequence_key, 8);
 
        state->seq_num++;
 }
 
        arcfour_crypt(seq_num, sequence_key, 8);
 
        state->seq_num++;
 }
 
-
-/*******************************************************************
- Calculate the key with which to encode the data payload
- ********************************************************************/
-static void netsec_get_sealing_key(const uint8_t session_key[16],
-                                  const uint8_t seq_num[8],
-                                  uint8_t sealing_key[16])
+static void netsec_do_seal(struct schannel_state *state,
+                          const uint8_t seq_num[8],
+                          uint8_t confounder[8],
+                          uint8_t *data, uint32_t length)
 {
 {
+       uint8_t sealing_key[16];
        static const uint8_t zeros[4];
        uint8_t digest2[16];
        uint8_t sess_kf0[16];
        int i;
 
        for (i = 0; i < 16; i++) {
        static const uint8_t zeros[4];
        uint8_t digest2[16];
        uint8_t sess_kf0[16];
        int i;
 
        for (i = 0; i < 16; i++) {
-               sess_kf0[i] = session_key[i] ^ 0xf0;
+               sess_kf0[i] = state->creds->session_key[i] ^ 0xf0;
        }
 
        hmac_md5(sess_kf0, zeros, 4, digest2);
        hmac_md5(digest2, seq_num, 8, sealing_key);
        }
 
        hmac_md5(sess_kf0, zeros, 4, digest2);
        hmac_md5(digest2, seq_num, 8, sealing_key);
-}
 
 
+       arcfour_crypt(confounder, sealing_key, 8);
+       arcfour_crypt(data, sealing_key, length);
+}
 
 /*******************************************************************
  Create a digest over the entire packet (including the data), and
  MD5 it with the session key.
  ********************************************************************/
 
 /*******************************************************************
  Create a digest over the entire packet (including the data), and
  MD5 it with the session key.
  ********************************************************************/
-static void schannel_digest(const uint8_t sess_key[16],
-                           const uint8_t netsec_sig[8],
-                           const uint8_t *confounder,
-                           const uint8_t *data, size_t data_len,
-                           uint8_t digest_final[16])
+static void netsec_do_sign(struct schannel_state *state,
+                          const uint8_t *confounder,
+                          const uint8_t *data, size_t data_len,
+                          uint8_t header[8],
+                          uint8_t *checksum)
 {
        uint8_t packet_digest[16];
        static const uint8_t zeros[4];
 {
        uint8_t packet_digest[16];
        static const uint8_t zeros[4];
@@ -83,187 +114,155 @@ static void schannel_digest(const uint8_t sess_key[16],
 
        MD5Init(&ctx);
        MD5Update(&ctx, zeros, 4);
 
        MD5Init(&ctx);
        MD5Update(&ctx, zeros, 4);
-       MD5Update(&ctx, netsec_sig, 8);
        if (confounder) {
        if (confounder) {
+               SSVAL(header, 0, NL_SIGN_HMAC_MD5);
+               SSVAL(header, 2, NL_SEAL_RC4);
+               SSVAL(header, 4, 0xFFFF);
+               SSVAL(header, 6, 0x0000);
+
+               MD5Update(&ctx, header, 8);
                MD5Update(&ctx, confounder, 8);
                MD5Update(&ctx, confounder, 8);
+       } else {
+               SSVAL(header, 0, NL_SIGN_HMAC_MD5);
+               SSVAL(header, 2, NL_SEAL_NONE);
+               SSVAL(header, 4, 0xFFFF);
+               SSVAL(header, 6, 0x0000);
+
+               MD5Update(&ctx, header, 8);
        }
        MD5Update(&ctx, data, data_len);
        MD5Final(packet_digest, &ctx);
 
        }
        MD5Update(&ctx, data, data_len);
        MD5Final(packet_digest, &ctx);
 
-       hmac_md5(sess_key, packet_digest, sizeof(packet_digest), digest_final);
+       hmac_md5(state->creds->session_key,
+                packet_digest, sizeof(packet_digest),
+                checksum);
 }
 
 }
 
-
-/*
-  unseal a packet
-*/
-NTSTATUS schannel_unseal_packet(struct schannel_state *state,
+NTSTATUS netsec_incoming_packet(struct schannel_state *state,
                                TALLOC_CTX *mem_ctx,
                                TALLOC_CTX *mem_ctx,
+                               bool do_unseal,
                                uint8_t *data, size_t length,
                                const DATA_BLOB *sig)
 {
                                uint8_t *data, size_t length,
                                const DATA_BLOB *sig)
 {
-       uint8_t digest_final[16];
-       uint8_t confounder[8];
+       uint32_t min_sig_size = 0;
+       uint8_t header[8];
+       uint8_t checksum[32];
+       uint32_t checksum_length = sizeof(checksum_length);
+       uint8_t _confounder[8];
+       uint8_t *confounder = NULL;
+       uint32_t confounder_ofs = 0;
        uint8_t seq_num[8];
        uint8_t seq_num[8];
-       uint8_t sealing_key[16];
-       static const uint8_t netsec_sig[8] = NETSEC_SEAL_SIGNATURE;
+       int ret;
+
+       netsec_offset_and_sizes(state,
+                               do_unseal,
+                               &min_sig_size,
+                               NULL,
+                               &checksum_length,
+                               &confounder_ofs);
 
 
-       if (sig->length != 32) {
+       if (sig->length < min_sig_size) {
                return NT_STATUS_ACCESS_DENIED;
        }
 
                return NT_STATUS_ACCESS_DENIED;
        }
 
-       memcpy(confounder, sig->data+24, 8);
+       if (do_unseal) {
+               confounder = _confounder;
+               memcpy(confounder, sig->data+confounder_ofs, 8);
+       } else {
+               confounder = NULL;
+       }
 
        RSIVAL(seq_num, 0, state->seq_num);
        SIVAL(seq_num, 4, state->initiator?0:0x80);
 
 
        RSIVAL(seq_num, 0, state->seq_num);
        SIVAL(seq_num, 4, state->initiator?0:0x80);
 
-       netsec_get_sealing_key(state->creds->session_key, seq_num, sealing_key);
-       arcfour_crypt(confounder, sealing_key, 8);
-       arcfour_crypt(data, sealing_key, length);
-
-       schannel_digest(state->creds->session_key,
-                       netsec_sig, confounder,
-                       data, length, digest_final);
-
-       if (memcmp(digest_final, sig->data+16, 8) != 0) {
-               dump_data_pw("calc digest:", digest_final, 8);
-               dump_data_pw("wire digest:", sig->data+16, 8);
-               return NT_STATUS_ACCESS_DENIED;
+       if (do_unseal) {
+               netsec_do_seal(state, seq_num,
+                              confounder,
+                              data, length);
        }
 
        }
 
-       netsec_deal_with_seq_num(state, digest_final, seq_num);
-
-       if (memcmp(seq_num, sig->data+8, 8) != 0) {
-               dump_data_pw("calc seq num:", seq_num, 8);
-               dump_data_pw("wire seq num:", sig->data+8, 8);
-               return NT_STATUS_ACCESS_DENIED;
-       }
-
-       return NT_STATUS_OK;
-}
-
-/*
-  check the signature on a packet
-*/
-NTSTATUS schannel_check_packet(struct schannel_state *state,
-                              TALLOC_CTX *mem_ctx,
-                              const uint8_t *data, size_t length,
-                              const DATA_BLOB *sig)
-{
-       uint8_t digest_final[16];
-       uint8_t seq_num[8];
-       static const uint8_t netsec_sig[8] = NETSEC_SIGN_SIGNATURE;
+       netsec_do_sign(state, confounder,
+                      data, length,
+                      header, checksum);
 
 
-       /* w2k sends just 24 bytes and skip the confounder */
-       if (sig->length != 32 && sig->length != 24) {
+       ret = memcmp(checksum, sig->data+16, checksum_length);
+       if (ret != 0) {
+               dump_data_pw("calc digest:", checksum, checksum_length);
+               dump_data_pw("wire digest:", sig->data+16, checksum_length);
                return NT_STATUS_ACCESS_DENIED;
        }
 
                return NT_STATUS_ACCESS_DENIED;
        }
 
-       RSIVAL(seq_num, 0, state->seq_num);
-       SIVAL(seq_num, 4, state->initiator?0:0x80);
-
-       dump_data_pw("seq_num:\n", seq_num, 8);
-       dump_data_pw("sess_key:\n", state->creds->session_key, 16);
+       netsec_do_seq_num(state, checksum, checksum_length, seq_num);
 
 
-       schannel_digest(state->creds->session_key,
-                       netsec_sig, NULL,
-                       data, length, digest_final);
-
-       netsec_deal_with_seq_num(state, digest_final, seq_num);
-
-       if (memcmp(seq_num, sig->data+8, 8) != 0) {
+       ret = memcmp(seq_num, sig->data+8, 8);
+       if (ret != 0) {
                dump_data_pw("calc seq num:", seq_num, 8);
                dump_data_pw("wire seq num:", sig->data+8, 8);
                return NT_STATUS_ACCESS_DENIED;
        }
 
                dump_data_pw("calc seq num:", seq_num, 8);
                dump_data_pw("wire seq num:", sig->data+8, 8);
                return NT_STATUS_ACCESS_DENIED;
        }
 
-       if (memcmp(digest_final, sig->data+16, 8) != 0) {
-               dump_data_pw("calc digest:", digest_final, 8);
-               dump_data_pw("wire digest:", sig->data+16, 8);
-               return NT_STATUS_ACCESS_DENIED;
-       }
-
        return NT_STATUS_OK;
 }
 
        return NT_STATUS_OK;
 }
 
-
-/*
-  seal a packet
-*/
-NTSTATUS schannel_seal_packet(struct schannel_state *state,
-                             TALLOC_CTX *mem_ctx,
-                             uint8_t *data, size_t length,
-                             DATA_BLOB *sig)
+NTSTATUS netsec_outgoing_packet(struct schannel_state *state,
+                               TALLOC_CTX *mem_ctx,
+                               bool do_seal,
+                               uint8_t *data, size_t length,
+                               DATA_BLOB *sig)
 {
 {
-       uint8_t digest_final[16];
-       uint8_t confounder[8];
+       uint32_t min_sig_size = 0;
+       uint32_t used_sig_size = 0;
+       uint8_t header[8];
+       uint8_t checksum[32];
+       uint32_t checksum_length = sizeof(checksum_length);
+       uint8_t _confounder[8];
+       uint8_t *confounder = NULL;
+       uint32_t confounder_ofs = 0;
        uint8_t seq_num[8];
        uint8_t seq_num[8];
-       uint8_t sealing_key[16];
-       static const uint8_t netsec_sig[8] = NETSEC_SEAL_SIGNATURE;
 
 
-       generate_random_buffer(confounder, 8);
+       netsec_offset_and_sizes(state,
+                               do_seal,
+                               &min_sig_size,
+                               &used_sig_size,
+                               &checksum_length,
+                               &confounder_ofs);
 
        RSIVAL(seq_num, 0, state->seq_num);
        SIVAL(seq_num, 4, state->initiator?0x80:0);
 
 
        RSIVAL(seq_num, 0, state->seq_num);
        SIVAL(seq_num, 4, state->initiator?0x80:0);
 
-       schannel_digest(state->creds->session_key,
-                       netsec_sig, confounder,
-                       data, length, digest_final);
-
-       netsec_get_sealing_key(state->creds->session_key, seq_num, sealing_key);
-       arcfour_crypt(confounder, sealing_key, 8);
-       arcfour_crypt(data, sealing_key, length);
-
-       netsec_deal_with_seq_num(state, digest_final, seq_num);
-
-       (*sig) = data_blob_talloc(mem_ctx, NULL, 32);
-
-       memcpy(sig->data, netsec_sig, 8);
-       memcpy(sig->data+8, seq_num, 8);
-       memcpy(sig->data+16, digest_final, 8);
-       memcpy(sig->data+24, confounder, 8);
-
-       dump_data_pw("signature:", sig->data+ 0, 8);
-       dump_data_pw("seq_num  :", sig->data+ 8, 8);
-       dump_data_pw("digest   :", sig->data+16, 8);
-       dump_data_pw("confound :", sig->data+24, 8);
-
-       return NT_STATUS_OK;
-}
-
-
-/*
-  sign a packet
-*/
-NTSTATUS schannel_sign_packet(struct schannel_state *state,
-                             TALLOC_CTX *mem_ctx,
-                             const uint8_t *data, size_t length,
-                             DATA_BLOB *sig)
-{
-       uint8_t digest_final[16];
-       uint8_t seq_num[8];
-       static const uint8_t netsec_sig[8] = NETSEC_SIGN_SIGNATURE;
+       if (do_seal) {
+               confounder = _confounder;
+               generate_random_buffer(confounder, 8);
+       } else {
+               confounder = NULL;
+       }
 
 
-       RSIVAL(seq_num, 0, state->seq_num);
-       SIVAL(seq_num, 4, state->initiator?0x80:0);
+       netsec_do_sign(state, confounder,
+                      data, length,
+                      header, checksum);
 
 
-       schannel_digest(state->creds->session_key,
-                       netsec_sig, NULL,
-                       data, length, digest_final);
+       if (do_seal) {
+               netsec_do_seal(state, seq_num,
+                              confounder,
+                              data, length);
+       }
 
 
-       netsec_deal_with_seq_num(state, digest_final, seq_num);
+       netsec_do_seq_num(state, checksum, checksum_length, seq_num);
 
 
-       (*sig) = data_blob_talloc(mem_ctx, NULL, 32);
+       (*sig) = data_blob_talloc_zero(mem_ctx, used_sig_size);
 
 
-       memcpy(sig->data, netsec_sig, 8);
+       memcpy(sig->data, header, 8);
        memcpy(sig->data+8, seq_num, 8);
        memcpy(sig->data+8, seq_num, 8);
-       memcpy(sig->data+16, digest_final, 8);
-       memset(sig->data+24, 0, 8);
+       memcpy(sig->data+16, checksum, checksum_length);
+
+       if (confounder) {
+               memcpy(sig->data+confounder_ofs, confounder, 8);
+       }
 
        dump_data_pw("signature:", sig->data+ 0, 8);
        dump_data_pw("seq_num  :", sig->data+ 8, 8);
 
        dump_data_pw("signature:", sig->data+ 0, 8);
        dump_data_pw("seq_num  :", sig->data+ 8, 8);
-       dump_data_pw("digest   :", sig->data+16, 8);
-       dump_data_pw("confound :", sig->data+24, 8);
+       dump_data_pw("digest   :", sig->data+16, checksum_length);
+       dump_data_pw("confound :", sig->data+confounder_ofs, 8);
 
        return NT_STATUS_OK;
 }
 
        return NT_STATUS_OK;
 }
index 393c7260d9944722b0bf62aebacb7f908078d819..186696fbbcf259220e01107f27611d91d5499e7f 100644 (file)
@@ -676,6 +676,7 @@ static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *p
        uint32 save_offset = prs_offset(current_pdu);
        struct schannel_state *schannel_auth =
                cli->auth->a_u.schannel_auth;
        uint32 save_offset = prs_offset(current_pdu);
        struct schannel_state *schannel_auth =
                cli->auth->a_u.schannel_auth;
+       uint8_t *data;
        uint32 data_len;
        DATA_BLOB blob;
        NTSTATUS status;
        uint32 data_len;
        DATA_BLOB blob;
        NTSTATUS status;
@@ -727,20 +728,24 @@ static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *p
                dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
        }
 
                dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
        }
 
+       data = (uint8_t *)prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN;
+
        switch (cli->auth->auth_level) {
        case DCERPC_AUTH_LEVEL_PRIVACY:
        switch (cli->auth->auth_level) {
        case DCERPC_AUTH_LEVEL_PRIVACY:
-               status = schannel_unseal_packet(schannel_auth,
+               status = netsec_incoming_packet(schannel_auth,
                                                talloc_tos(),
                                                talloc_tos(),
-                                               (uint8_t *)prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN,
+                                               true,
+                                               data,
                                                data_len,
                                                &blob);
                break;
        case DCERPC_AUTH_LEVEL_INTEGRITY:
                                                data_len,
                                                &blob);
                break;
        case DCERPC_AUTH_LEVEL_INTEGRITY:
-               status = schannel_check_packet(schannel_auth,
-                                              talloc_tos(),
-                                              (uint8_t *)prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN,
-                                              data_len,
-                                              &blob);
+               status = netsec_incoming_packet(schannel_auth,
+                                               talloc_tos(),
+                                               false,
+                                               data,
+                                               data_len,
+                                               &blob);
                break;
        default:
                status = NT_STATUS_INTERNAL_ERROR;
                break;
        default:
                status = NT_STATUS_INTERNAL_ERROR;
@@ -1948,18 +1953,20 @@ static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
 
        switch (cli->auth->auth_level) {
        case DCERPC_AUTH_LEVEL_PRIVACY:
 
        switch (cli->auth->auth_level) {
        case DCERPC_AUTH_LEVEL_PRIVACY:
-               status = schannel_seal_packet(sas,
-                                             talloc_tos(),
-                                             (uint8_t *)data_p,
-                                             data_and_pad_len,
-                                             &blob);
+               status = netsec_outgoing_packet(sas,
+                                               talloc_tos(),
+                                               true,
+                                               (uint8_t *)data_p,
+                                               data_and_pad_len,
+                                               &blob);
                break;
        case DCERPC_AUTH_LEVEL_INTEGRITY:
                break;
        case DCERPC_AUTH_LEVEL_INTEGRITY:
-               status = schannel_sign_packet(sas,
-                                             talloc_tos(),
-                                             (uint8_t *)data_p,
-                                             data_and_pad_len,
-                                             &blob);
+               status = netsec_outgoing_packet(sas,
+                                               talloc_tos(),
+                                               false,
+                                               (uint8_t *)data_p,
+                                               data_and_pad_len,
+                                               &blob);
                break;
        default:
                status = NT_STATUS_INTERNAL_ERROR;
                break;
        default:
                status = NT_STATUS_INTERNAL_ERROR;
index 1bd170f90135d2c2b5ffaaf035d9d388686051ee..627dac0f8212e314e338b10f0c363a8388d261d0 100644 (file)
@@ -411,6 +411,7 @@ static bool create_next_pdu_schannel(pipes_struct *p)
                 */
                RPC_HDR_AUTH auth_info;
                DATA_BLOB blob;
                 */
                RPC_HDR_AUTH auth_info;
                DATA_BLOB blob;
+               uint8_t *data;
 
                /* Check it's the type of reply we were expecting to decode */
 
 
                /* Check it's the type of reply we were expecting to decode */
 
@@ -427,20 +428,24 @@ static bool create_next_pdu_schannel(pipes_struct *p)
                        return False;
                }
 
                        return False;
                }
 
+               data = (uint8_t *)prs_data_p(&p->out_data.frag) + data_pos;
+
                switch (p->auth.auth_level) {
                case DCERPC_AUTH_LEVEL_PRIVACY:
                switch (p->auth.auth_level) {
                case DCERPC_AUTH_LEVEL_PRIVACY:
-                       status = schannel_seal_packet(p->auth.a_u.schannel_auth,
-                                                     talloc_tos(),
-                                                     (uint8_t *)prs_data_p(&p->out_data.frag) + data_pos,
-                                                     data_len + ss_padding_len,
-                                                     &blob);
+                       status = netsec_outgoing_packet(p->auth.a_u.schannel_auth,
+                                                       talloc_tos(),
+                                                       true,
+                                                       data,
+                                                       data_len + ss_padding_len,
+                                                       &blob);
                        break;
                case DCERPC_AUTH_LEVEL_INTEGRITY:
                        break;
                case DCERPC_AUTH_LEVEL_INTEGRITY:
-                       status = schannel_sign_packet(p->auth.a_u.schannel_auth,
-                                                     talloc_tos(),
-                                                     (uint8_t *)prs_data_p(&p->out_data.frag) + data_pos,
-                                                     data_len + ss_padding_len,
-                                                     &blob);
+                       status = netsec_outgoing_packet(p->auth.a_u.schannel_auth,
+                                                       talloc_tos(),
+                                                       false,
+                                                       data,
+                                                       data_len + ss_padding_len,
+                                                       &blob);
                        break;
                default:
                        status = NT_STATUS_INTERNAL_ERROR;
                        break;
                default:
                        status = NT_STATUS_INTERNAL_ERROR;
@@ -2162,6 +2167,7 @@ bool api_pipe_schannel_process(pipes_struct *p, prs_struct *rpc_in, uint32 *p_ss
        RPC_HDR_AUTH auth_info;
        DATA_BLOB blob;
        NTSTATUS status;
        RPC_HDR_AUTH auth_info;
        DATA_BLOB blob;
        NTSTATUS status;
+       uint8_t *data;
 
        auth_len = p->hdr.auth_len;
 
 
        auth_len = p->hdr.auth_len;
 
@@ -2215,20 +2221,24 @@ bool api_pipe_schannel_process(pipes_struct *p, prs_struct *rpc_in, uint32 *p_ss
                dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
        }
 
                dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
        }
 
+       data = (uint8_t *)prs_data_p(rpc_in)+RPC_HDR_REQ_LEN;
+
        switch (auth_info.auth_level) {
        case DCERPC_AUTH_LEVEL_PRIVACY:
        switch (auth_info.auth_level) {
        case DCERPC_AUTH_LEVEL_PRIVACY:
-               status = schannel_unseal_packet(p->auth.a_u.schannel_auth,
+               status = netsec_incoming_packet(p->auth.a_u.schannel_auth,
                                                talloc_tos(),
                                                talloc_tos(),
-                                               (uint8_t *)prs_data_p(rpc_in)+RPC_HDR_REQ_LEN,
+                                               true,
+                                               data,
                                                data_len,
                                                &blob);
                break;
        case DCERPC_AUTH_LEVEL_INTEGRITY:
                                                data_len,
                                                &blob);
                break;
        case DCERPC_AUTH_LEVEL_INTEGRITY:
-               status = schannel_check_packet(p->auth.a_u.schannel_auth,
-                                              talloc_tos(),
-                                              (uint8_t *)prs_data_p(rpc_in)+RPC_HDR_REQ_LEN,
-                                              data_len,
-                                              &blob);
+               status = netsec_incoming_packet(p->auth.a_u.schannel_auth,
+                                               talloc_tos(),
+                                               false,
+                                               data,
+                                               data_len,
+                                               &blob);
                break;
        default:
                status = NT_STATUS_INTERNAL_ERROR;
                break;
        default:
                status = NT_STATUS_INTERNAL_ERROR;
index 3efaf9bccaeae08fbda6d9bad864c25e13ea53d6..0233f5e57c36d0495c336ac72aa0c684db855010 100644 (file)
@@ -282,48 +282,71 @@ static bool schannel_have_feature(struct gensec_security *gensec_security,
        return false;
 }
 
        return false;
 }
 
-static NTSTATUS schannel_seal_packet_wrap(struct gensec_security *gensec_security,
-                                         TALLOC_CTX *mem_ctx,
-                                         uint8_t *data, size_t length,
-                                         const uint8_t *whole_pdu, size_t pdu_length,
-                                         DATA_BLOB *sig)
+/*
+  unseal a packet
+*/
+static NTSTATUS schannel_unseal_packet(struct gensec_security *gensec_security,
+                                      TALLOC_CTX *mem_ctx,
+                                      uint8_t *data, size_t length,
+                                      const uint8_t *whole_pdu, size_t pdu_length,
+                                      const DATA_BLOB *sig)
 {
 {
-       struct schannel_state *state = talloc_get_type(gensec_security->private_data, struct schannel_state);
+       struct schannel_state *state =
+               talloc_get_type(gensec_security->private_data,
+                               struct schannel_state);
 
 
-       return schannel_seal_packet(state, mem_ctx, data, length, sig);
+       return netsec_incoming_packet(state, mem_ctx, true,
+                                     data, length, sig);
 }
 
 }
 
-static NTSTATUS schannel_sign_packet_wrap(struct gensec_security *gensec_security,
-                                         TALLOC_CTX *mem_ctx,
-                                         const uint8_t *data, size_t length,
-                                         const uint8_t *whole_pdu, size_t pdu_length,
-                                         DATA_BLOB *sig)
+/*
+  check the signature on a packet
+*/
+static NTSTATUS schannel_check_packet(struct gensec_security *gensec_security,
+                                     TALLOC_CTX *mem_ctx,
+                                     const uint8_t *data, size_t length,
+                                     const uint8_t *whole_pdu, size_t pdu_length,
+                                     const DATA_BLOB *sig)
 {
 {
-       struct schannel_state *state = talloc_get_type(gensec_security->private_data, struct schannel_state);
+       struct schannel_state *state =
+               talloc_get_type(gensec_security->private_data,
+                               struct schannel_state);
 
 
-       return schannel_sign_packet(state, mem_ctx, data, length, sig);
+       return netsec_incoming_packet(state, mem_ctx, false,
+                                     data, length, sig);
 }
 }
-
-static NTSTATUS schannel_check_packet_wrap(struct gensec_security *gensec_security,
-                                          TALLOC_CTX *mem_ctx,
-                                          const uint8_t *data, size_t length,
-                                          const uint8_t *whole_pdu, size_t pdu_length,
-                                          const DATA_BLOB *sig)
+/*
+  seal a packet
+*/
+static NTSTATUS schannel_seal_packet(struct gensec_security *gensec_security,
+                                    TALLOC_CTX *mem_ctx,
+                                    uint8_t *data, size_t length,
+                                    const uint8_t *whole_pdu, size_t pdu_length,
+                                    DATA_BLOB *sig)
 {
 {
-       struct schannel_state *state = talloc_get_type(gensec_security->private_data, struct schannel_state);
+       struct schannel_state *state =
+               talloc_get_type(gensec_security->private_data,
+                               struct schannel_state);
 
 
-       return schannel_check_packet(state, mem_ctx, data, length, sig);
+       return netsec_outgoing_packet(state, mem_ctx, true,
+                                     data, length, sig);
 }
 
 }
 
-static NTSTATUS schannel_unseal_packet_wrap(struct gensec_security *gensec_security,
-                                           TALLOC_CTX *mem_ctx,
-                                           uint8_t *data, size_t length,
-                                           const uint8_t *whole_pdu, size_t pdu_length,
-                                           const DATA_BLOB *sig)
+/*
+  sign a packet
+*/
+static NTSTATUS schannel_sign_packet(struct gensec_security *gensec_security,
+                                    TALLOC_CTX *mem_ctx,
+                                    const uint8_t *data, size_t length,
+                                    const uint8_t *whole_pdu, size_t pdu_length,
+                                    DATA_BLOB *sig)
 {
 {
-       struct schannel_state *state = talloc_get_type(gensec_security->private_data, struct schannel_state);
+       struct schannel_state *state =
+               talloc_get_type(gensec_security->private_data,
+                               struct schannel_state);
 
 
-       return schannel_unseal_packet(state, mem_ctx, data, length, sig);
+       return netsec_outgoing_packet(state, mem_ctx, false,
+                                     data, length, sig);
 }
 
 static const struct gensec_security_ops gensec_schannel_security_ops = {
 }
 
 static const struct gensec_security_ops gensec_schannel_security_ops = {
@@ -332,10 +355,10 @@ static const struct gensec_security_ops gensec_schannel_security_ops = {
        .client_start   = schannel_client_start,
        .server_start   = schannel_server_start,
        .update         = schannel_update,
        .client_start   = schannel_client_start,
        .server_start   = schannel_server_start,
        .update         = schannel_update,
-       .seal_packet    = schannel_seal_packet_wrap,
-       .sign_packet    = schannel_sign_packet_wrap,
-       .check_packet   = schannel_check_packet_wrap,
-       .unseal_packet  = schannel_unseal_packet_wrap,
+       .seal_packet    = schannel_seal_packet,
+       .sign_packet    = schannel_sign_packet,
+       .check_packet   = schannel_check_packet,
+       .unseal_packet  = schannel_unseal_packet,
        .session_key    = schannel_session_key,
        .session_info   = schannel_session_info,
        .sig_size       = schannel_sig_size,
        .session_key    = schannel_session_key,
        .session_info   = schannel_session_info,
        .sig_size       = schannel_sig_size,