From 7f15d2918bad3c96d5b4eb7bd649373ecfbd2714 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Tue, 19 Oct 2010 21:49:53 -0400 Subject: [PATCH 056/150] - fix client dh processing - fix octetstring2key - client with dh seems to work now! --- src/plugins/preauth/pkinit/pkinit_crypto_nss.c | 59 ++++++++++++++++++----- 1 files changed, 46 insertions(+), 13 deletions(-) diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_nss.c b/src/plugins/preauth/pkinit/pkinit_crypto_nss.c index d9b77a2..b9e6a08 100644 --- a/src/plugins/preauth/pkinit/pkinit_crypto_nss.c +++ b/src/plugins/preauth/pkinit/pkinit_crypto_nss.c @@ -1184,7 +1184,7 @@ client_process_dh(krb5_context context, { PLArenaPool *pool; PK11SlotInfo *slot; - SECKEYPublicKey pub; + SECKEYPublicKey *pub, pub2; PK11SymKey *sym; SECItem *bits; @@ -1195,9 +1195,15 @@ client_process_dh(krb5_context context, /* Rebuild the KDC's public key using our parameters and the supplied * public value (subjectPublicKey). */ - pub = *(req_cryptoctx->client_dh_pubkey); + pub = SECKEY_CopyPublicKey(req_cryptoctx->client_dh_pubkey); + if (pub == NULL) { + PORT_FreeArena(pool, PR_TRUE); + return ENOMEM; + } + pub2 = *pub; if (secitem_from_dh_pubval(pool, dh_pubkey, dh_pubkey_len, - &pub.u.dh.publicValue) != 0) { + &pub2.u.dh.publicValue) != 0) { + SECKEY_DestroyPublicKey(pub); PORT_FreeArena(pool, PR_TRUE); return ENOMEM; } @@ -1207,10 +1213,11 @@ client_process_dh(krb5_context context, slot = PK11_GetBestSlot(CKM_DH_PKCS_KEY_PAIR_GEN, crypto_pwcb_prep(id_cryptoctx, context)); if (slot == NULL) { + SECKEY_DestroyPublicKey(pub); PORT_FreeArena(pool, PR_TRUE); return ENOMEM; } - sym = PK11_PubDerive(req_cryptoctx->client_dh_privkey, &pub, PR_FALSE, + sym = PK11_PubDerive(req_cryptoctx->client_dh_privkey, &pub2, PR_FALSE, NULL, NULL, CKM_DH_PKCS_DERIVE, CKM_TLS_MASTER_KEY_DERIVE_DH, @@ -1219,6 +1226,7 @@ client_process_dh(krb5_context context, crypto_pwcb_prep(id_cryptoctx, context)); if (sym == NULL) { PK11_FreeSlot(slot); + SECKEY_DestroyPublicKey(pub); PORT_FreeArena(pool, PR_TRUE); return ENOMEM; } @@ -1229,12 +1237,14 @@ client_process_dh(krb5_context context, (secitem_to_buf_len(bits, dh_session_key, dh_session_key_len) != 0)) { PK11_FreeSymKey(sym); PK11_FreeSlot(slot); + SECKEY_DestroyPublicKey(pub); PORT_FreeArena(pool, PR_TRUE); return ENOMEM; } PK11_FreeSymKey(sym); PK11_FreeSlot(slot); + SECKEY_DestroyPublicKey(pub); PORT_FreeArena(pool, PR_TRUE); return 0; } @@ -2534,20 +2544,27 @@ pkinit_identity_set_prompter(pkinit_identity_crypto_context id_cryptoctx, krb5_error_code pkinit_octetstring2key(krb5_context context, krb5_enctype etype, - unsigned char *key, - unsigned int key_len, + unsigned char *dh_key, + unsigned int dh_key_len, krb5_keyblock *krb5key) { PK11Context *ctx; - unsigned int left, length; - unsigned char c, buf[160 / 8]; /* the longest digest we support */ - char rnd_buf[key_len]; + unsigned int left, length, rnd_len; + unsigned char c, buf[512]; /* the longest digest we support */ + char rnd_buf[dh_key_len]; + size_t kbyte, klength; krb5_data rnd_data; krb5_error_code result; SECOidTag hash_alg = SEC_OID_SHA1; + result = krb5_c_keylengths(context, etype, &kbyte, &klength); + if (result != 0) { + return result; + } + c = 0; - left = key_len; + rnd_len = kbyte; + left = rnd_len; while (left > 0) { ctx = PK11_CreateDigestContext(hash_alg); if (ctx == NULL) { @@ -2556,22 +2573,26 @@ pkinit_octetstring2key(krb5_context context, return ENOMEM; } if (PK11_DigestBegin(ctx) != SECSuccess) { + PK11_DestroyContext(ctx, PR_TRUE); memset(buf, 0, sizeof(buf)); memset(rnd_buf, 0, sizeof(rnd_buf)); return ENOMEM; } if (PK11_DigestOp(ctx, &c, 1) != SECSuccess) { + PK11_DestroyContext(ctx, PR_TRUE); memset(buf, 0, sizeof(buf)); memset(rnd_buf, 0, sizeof(rnd_buf)); return ENOMEM; } - if (PK11_DigestOp(ctx, key, key_len) != SECSuccess) { + if (PK11_DigestOp(ctx, dh_key, dh_key_len) != SECSuccess) { + PK11_DestroyContext(ctx, PR_TRUE); memset(buf, 0, sizeof(buf)); memset(rnd_buf, 0, sizeof(rnd_buf)); return ENOMEM; } if (PK11_DigestFinal(ctx, buf, &length, sizeof(buf)) != SECSuccess) { + PK11_DestroyContext(ctx, PR_TRUE); memset(buf, 0, sizeof(buf)); memset(rnd_buf, 0, sizeof(rnd_buf)); return ENOMEM; @@ -2580,16 +2601,28 @@ pkinit_octetstring2key(krb5_context context, if (left < length) { length = left; } - memcpy(rnd_buf + key_len - left, buf, length); + memcpy(rnd_buf + rnd_len - left, buf, length); left -= length; c++; } + krb5_free_keyblock_contents(context, krb5key); + + krb5key->contents = malloc(klength); + if (krb5key->contents == NULL) { + krb5key->length = 0; + return ENOMEM; + } + krb5key->length = klength; + krb5key->enctype = etype; + rnd_data.data = rnd_buf; - rnd_data.length = key_len; + rnd_data.length = rnd_len; result = krb5_c_random_to_key(context, etype, &rnd_data, krb5key); + memset(buf, 0, sizeof(buf)); memset(rnd_buf, 0, sizeof(rnd_buf)); + return result; } -- 1.7.6.4