1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-07 00:58:40 +03:00

r13539: Add 128 bit creds processing client and server. Thanks to Andrew Bartlett's

Samba4 code.
Jeremy.
(This used to be commit a2fb436fc5dd536cfe860be93f55f9cb58139a0e)
This commit is contained in:
Jeremy Allison 2006-02-17 04:22:32 +00:00 committed by Gerald (Jerry) Carter
parent c7aad1deea
commit 39a572e010
4 changed files with 98 additions and 24 deletions

View File

@ -28,14 +28,14 @@
/*********************************************************************** /***********************************************************************
the rfc 2104 version of hmac_md5 initialisation. the rfc 2104 version of hmac_md5 initialisation.
***********************************************************************/ ***********************************************************************/
void hmac_md5_init_rfc2104(uchar* key, int key_len, HMACMD5Context *ctx)
void hmac_md5_init_rfc2104(const unsigned char *key, int key_len, HMACMD5Context *ctx)
{ {
int i; int i;
/* if key is longer than 64 bytes reset it to key=MD5(key) */ /* if key is longer than 64 bytes reset it to key=MD5(key) */
if (key_len > 64) if (key_len > 64) {
{ unsigned char tk[16];
uchar tk[16];
struct MD5Context tctx; struct MD5Context tctx;
MD5Init(&tctx); MD5Init(&tctx);
@ -53,8 +53,7 @@ void hmac_md5_init_rfc2104(uchar* key, int key_len, HMACMD5Context *ctx)
memcpy( ctx->k_opad, key, key_len); memcpy( ctx->k_opad, key, key_len);
/* XOR key with ipad and opad values */ /* XOR key with ipad and opad values */
for (i=0; i<64; i++) for (i=0; i<64; i++) {
{
ctx->k_ipad[i] ^= 0x36; ctx->k_ipad[i] ^= 0x36;
ctx->k_opad[i] ^= 0x5c; ctx->k_opad[i] ^= 0x5c;
} }
@ -66,14 +65,14 @@ void hmac_md5_init_rfc2104(uchar* key, int key_len, HMACMD5Context *ctx)
/*********************************************************************** /***********************************************************************
the microsoft version of hmac_md5 initialisation. the microsoft version of hmac_md5 initialisation.
***********************************************************************/ ***********************************************************************/
void hmac_md5_init_limK_to_64(const uchar* key, int key_len,
void hmac_md5_init_limK_to_64(const unsigned char* key, int key_len,
HMACMD5Context *ctx) HMACMD5Context *ctx)
{ {
int i; int i;
/* if key is longer than 64 bytes truncate it */ /* if key is longer than 64 bytes truncate it */
if (key_len > 64) if (key_len > 64) {
{
key_len = 64; key_len = 64;
} }
@ -96,7 +95,8 @@ void hmac_md5_init_limK_to_64(const uchar* key, int key_len,
/*********************************************************************** /***********************************************************************
update hmac_md5 "inner" buffer update hmac_md5 "inner" buffer
***********************************************************************/ ***********************************************************************/
void hmac_md5_update(const uchar* text, int text_len, HMACMD5Context *ctx)
void hmac_md5_update(const unsigned char *text, int text_len, HMACMD5Context *ctx)
{ {
MD5Update(&ctx->ctx, text, text_len); /* then text of datagram */ MD5Update(&ctx->ctx, text, text_len); /* then text of datagram */
} }
@ -104,7 +104,7 @@ void hmac_md5_update(const uchar* text, int text_len, HMACMD5Context *ctx)
/*********************************************************************** /***********************************************************************
finish off hmac_md5 "inner" buffer and generate outer one. finish off hmac_md5 "inner" buffer and generate outer one.
***********************************************************************/ ***********************************************************************/
void hmac_md5_final(uchar *digest, HMACMD5Context *ctx) void hmac_md5_final(unsigned char *digest, HMACMD5Context *ctx)
{ {
struct MD5Context ctx_o; struct MD5Context ctx_o;
@ -121,7 +121,8 @@ void hmac_md5_final(uchar *digest, HMACMD5Context *ctx)
single function to calculate an HMAC MD5 digest from data. single function to calculate an HMAC MD5 digest from data.
use the microsoft hmacmd5 init method because the key is 16 bytes. use the microsoft hmacmd5 init method because the key is 16 bytes.
************************************************************/ ************************************************************/
void hmac_md5( uchar key[16], uchar* data, int data_len, uchar* digest)
void hmac_md5( unsigned char key[16], unsigned char *data, int data_len, unsigned char *digest)
{ {
HMACMD5Context ctx; HMACMD5Context ctx;
hmac_md5_init_limK_to_64(key, 16, &ctx); hmac_md5_init_limK_to_64(key, 16, &ctx);

View File

@ -25,7 +25,7 @@
Represent a credential as a string. Represent a credential as a string.
****************************************************************************/ ****************************************************************************/
char *credstr(const uchar *cred) char *credstr(const unsigned char *cred)
{ {
static fstring buf; static fstring buf;
slprintf(buf, sizeof(buf) - 1, "%02X%02X%02X%02X%02X%02X%02X%02X", slprintf(buf, sizeof(buf) - 1, "%02X%02X%02X%02X%02X%02X%02X%02X",
@ -34,6 +34,58 @@ char *credstr(const uchar *cred)
return buf; return buf;
} }
/****************************************************************************
Setup the session key and the client and server creds in dc.
ADS-style 128 bit session keys.
Used by both client and server creds setup.
****************************************************************************/
static void creds_init_128(struct dcinfo *dc,
const DOM_CHAL *clnt_chal_in,
const DOM_CHAL *srv_chal_in,
const char mach_pw[16])
{
unsigned char zero[4], tmp[16];
HMACMD5Context ctx;
struct MD5Context md5;
/* Just in case this isn't already there */
memcpy(dc->mach_pw, mach_pw, 16);
ZERO_STRUCT(dc->sess_key);
memset(zero, 0, sizeof(zero));
hmac_md5_init_rfc2104(mach_pw, 16, &ctx);
MD5Init(&md5);
MD5Update(&md5, zero, sizeof(zero));
MD5Update(&md5, clnt_chal_in->data, 8);
MD5Update(&md5, srv_chal_in->data, 8);
MD5Final(tmp, &md5);
hmac_md5_update(tmp, sizeof(tmp), &ctx);
hmac_md5_final(dc->sess_key, &ctx);
/* debug output */
DEBUG(5,("creds_init_128\n"));
DEBUG(5,("\tclnt_chal_in: %s\n", credstr(clnt_chal_in->data)));
DEBUG(5,("\tsrv_chal_in : %s\n", credstr(srv_chal_in->data)));
dump_data_pw("\tsession_key ", (const unsigned char *)dc->sess_key, 16);
/* Generate the next client and server creds. */
des_crypt112(dc->clnt_chal.data, /* output */
clnt_chal_in->data, /* input */
dc->sess_key, /* input */
1);
des_crypt112(dc->srv_chal.data, /* output */
srv_chal_in->data, /* input */
dc->sess_key, /* input */
1);
/* Seed is the client chal. */
memcpy(dc->seed_chal.data, dc->clnt_chal.data, 8);
}
/**************************************************************************** /****************************************************************************
Setup the session key and the client and server creds in dc. Setup the session key and the client and server creds in dc.
@ -63,10 +115,10 @@ static void creds_init_64(struct dcinfo *dc,
/* debug output */ /* debug output */
DEBUG(5,("creds_init_64\n")); DEBUG(5,("creds_init_64\n"));
DEBUG(5,(" clnt_chal_in: %s\n", credstr(clnt_chal_in->data))); DEBUG(5,("\tclnt_chal_in: %s\n", credstr(clnt_chal_in->data)));
DEBUG(5,(" srv_chal_in : %s\n", credstr(srv_chal_in->data))); DEBUG(5,("\tsrv_chal_in : %s\n", credstr(srv_chal_in->data)));
DEBUG(5,(" clnt+srv : %s\n", credstr(sum2))); DEBUG(5,("\tclnt+srv : %s\n", credstr(sum2)));
DEBUG(5,(" sess_key_out : %s\n", credstr(dc->sess_key))); DEBUG(5,("\tsess_key_out : %s\n", credstr(dc->sess_key)));
/* Generate the next client and server creds. */ /* Generate the next client and server creds. */
@ -120,21 +172,30 @@ static void creds_step(struct dcinfo *dc)
Create a server credential struct. Create a server credential struct.
****************************************************************************/ ****************************************************************************/
void creds_server_init(struct dcinfo *dc, void creds_server_init(uint32 neg_flags,
struct dcinfo *dc,
DOM_CHAL *clnt_chal, DOM_CHAL *clnt_chal,
DOM_CHAL *srv_chal, DOM_CHAL *srv_chal,
const char mach_pw[16], const char mach_pw[16],
DOM_CHAL *init_chal_out) DOM_CHAL *init_chal_out)
{ {
DEBUG(10,("creds_server_init: neg_flags : %x\n", (unsigned int)neg_flags));
DEBUG(10,("creds_server_init: client chal : %s\n", credstr(clnt_chal->data) )); DEBUG(10,("creds_server_init: client chal : %s\n", credstr(clnt_chal->data) ));
DEBUG(10,("creds_server_init: server chal : %s\n", credstr(srv_chal->data) )); DEBUG(10,("creds_server_init: server chal : %s\n", credstr(srv_chal->data) ));
dump_data_pw("creds_server_init: machine pass", (const unsigned char *)mach_pw, 16); dump_data_pw("creds_server_init: machine pass", (const unsigned char *)mach_pw, 16);
/* Generate the session key and the next client and server creds. */ /* Generate the session key and the next client and server creds. */
creds_init_64(dc, if (neg_flags & NETLOGON_NEG_128BIT) {
creds_init_128(dc,
clnt_chal, clnt_chal,
srv_chal, srv_chal,
mach_pw); mach_pw);
} else {
creds_init_64(dc,
clnt_chal,
srv_chal,
mach_pw);
}
dump_data_pw("creds_server_init: session key", dc->sess_key, 16); dump_data_pw("creds_server_init: session key", dc->sess_key, 16);
@ -213,7 +274,8 @@ BOOL creds_server_step(struct dcinfo *dc, const DOM_CRED *received_cred, DOM_CRE
Create a client credential struct. Create a client credential struct.
****************************************************************************/ ****************************************************************************/
void creds_client_init(struct dcinfo *dc, void creds_client_init(uint32 neg_flags,
struct dcinfo *dc,
DOM_CHAL *clnt_chal, DOM_CHAL *clnt_chal,
DOM_CHAL *srv_chal, DOM_CHAL *srv_chal,
const unsigned char mach_pw[16], const unsigned char mach_pw[16],
@ -221,15 +283,23 @@ void creds_client_init(struct dcinfo *dc,
{ {
dc->sequence = time(NULL); dc->sequence = time(NULL);
DEBUG(10,("creds_client_init: neg_flags : %x\n", (unsigned int)neg_flags));
DEBUG(10,("creds_client_init: client chal : %s\n", credstr(clnt_chal->data) )); DEBUG(10,("creds_client_init: client chal : %s\n", credstr(clnt_chal->data) ));
DEBUG(10,("creds_client_init: server chal : %s\n", credstr(srv_chal->data) )); DEBUG(10,("creds_client_init: server chal : %s\n", credstr(srv_chal->data) ));
dump_data_pw("creds_client_init: machine pass", (const unsigned char *)mach_pw, 16); dump_data_pw("creds_client_init: machine pass", (const unsigned char *)mach_pw, 16);
/* Generate the session key and the next client and server creds. */ /* Generate the session key and the next client and server creds. */
creds_init_64(dc, if (neg_flags & NETLOGON_NEG_128BIT) {
creds_init_128(dc,
clnt_chal,
srv_chal,
mach_pw);
} else {
creds_init_64(dc,
clnt_chal, clnt_chal,
srv_chal, srv_chal,
mach_pw); mach_pw);
}
dump_data_pw("creds_client_init: session key", dc->sess_key, 16); dump_data_pw("creds_client_init: session key", dc->sess_key, 16);

View File

@ -301,7 +301,8 @@ NTSTATUS rpccli_netlogon_setup_creds(struct rpc_pipe_client *cli,
} }
/* Calculate the session key and client credentials */ /* Calculate the session key and client credentials */
creds_client_init(dc, creds_client_init(*neg_flags_inout,
dc,
&clnt_chal_send, &clnt_chal_send,
&srv_chal_recv, &srv_chal_recv,
machine_pwd, machine_pwd,

View File

@ -338,7 +338,8 @@ NTSTATUS _net_auth(pipes_struct *p, NET_Q_AUTH *q_u, NET_R_AUTH *r_u)
} }
/* From the client / server challenges and md4 password, generate sess key */ /* From the client / server challenges and md4 password, generate sess key */
creds_server_init(p->dc, creds_server_init(0, /* No neg flags. */
p->dc,
&p->dc->clnt_chal, /* Stored client chal. */ &p->dc->clnt_chal, /* Stored client chal. */
&p->dc->srv_chal, /* Stored server chal. */ &p->dc->srv_chal, /* Stored server chal. */
(const char *)p->dc->mach_pw, (const char *)p->dc->mach_pw,
@ -415,7 +416,8 @@ NTSTATUS _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u)
} }
/* From the client / server challenges and md4 password, generate sess key */ /* From the client / server challenges and md4 password, generate sess key */
creds_server_init(p->dc, creds_server_init(q_u->clnt_flgs.neg_flags,
p->dc,
&p->dc->clnt_chal, /* Stored client chal. */ &p->dc->clnt_chal, /* Stored client chal. */
&p->dc->srv_chal, /* Stored server chal. */ &p->dc->srv_chal, /* Stored server chal. */
(const char *)p->dc->mach_pw, (const char *)p->dc->mach_pw,