From 343b9d4930e2ffda4781c9212d94273477e95b78 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Wed, 20 Oct 2010 20:23:00 -0400 Subject: [PATCH 060/150] - cache the client's domain parameters in server_check_dh - rework server_process_dh to use cached client parameters and the client's public value, which is what it actually gets --- src/plugins/preauth/pkinit/pkinit_crypto_nss.c | 147 +++++++++-------------- 1 files changed, 58 insertions(+), 89 deletions(-) diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_nss.c b/src/plugins/preauth/pkinit/pkinit_crypto_nss.c index 7c75cd9..8280af9 100644 --- a/src/plugins/preauth/pkinit/pkinit_crypto_nss.c +++ b/src/plugins/preauth/pkinit/pkinit_crypto_nss.c @@ -68,46 +68,6 @@ static krb5_error_code cert_retrieve_cert_sans(krb5_context context, static int cert_load_default_identity(krb5_context context, pkinit_identity_crypto_context id); -/* Plugin and request state. */ -struct _pkinit_plg_crypto_context { - PLArenaPool *pool; - NSSInitContext *ncontext; -}; - -struct _pkinit_req_crypto_context { - PLArenaPool *pool; - SECKEYPrivateKey *client_dh_privkey; /* used by clients */ - SECKEYPublicKey *client_dh_pubkey; /* used by clients */ - CERTCertificate *peer_cert; /* the other party */ -}; - -struct _pkinit_identity_crypto_context { - PLArenaPool *pool; - PRBool loaded; - PK11SlotList *slots; - PK11SlotInfo *slot; - CERTCertList *id_certs, *ca_certs, *other_certs; - SECKEYPrivateKeyList *id_keys; - CERTCertificate *id_cert; - struct { - krb5_context context; - krb5_prompter_fct prompter; - void *prompter_data; - } pwcb_args; -}; - -struct _pkinit_cert_info { /* aka _pkinit_cert_handle */ - PLArenaPool *pool; - struct _pkinit_identity_crypto_context *id_cryptoctx; - CERTCertificate *cert; -}; - -struct _pkinit_cert_iter_info { /* aka _pkinit_cert_iter_handle */ - PLArenaPool *pool; - struct _pkinit_identity_crypto_context *id_cryptoctx; - CERTCertListNode *node; -}; - /* Protocol elements. */ /* DH parameters: draft-ietf-cat-kerberos-pk-init-08.txt, 3.1.2.2. */ @@ -246,6 +206,47 @@ issuer_and_serial_number_template[] = { { 0, 0, NULL, 0}, }; +/* Plugin and request state. */ +struct _pkinit_plg_crypto_context { + PLArenaPool *pool; + NSSInitContext *ncontext; +}; + +struct _pkinit_req_crypto_context { + PLArenaPool *pool; + SECKEYPrivateKey *client_dh_privkey; /* used by clients */ + SECKEYPublicKey *client_dh_pubkey; /* used by clients */ + struct domain_parameters client_dh_params; /* used by KDCs */ + CERTCertificate *peer_cert; /* the other party */ +}; + +struct _pkinit_identity_crypto_context { + PLArenaPool *pool; + PRBool loaded; + PK11SlotList *slots; + PK11SlotInfo *slot; + CERTCertList *id_certs, *ca_certs, *other_certs; + SECKEYPrivateKeyList *id_keys; + CERTCertificate *id_cert; + struct { + krb5_context context; + krb5_prompter_fct prompter; + void *prompter_data; + } pwcb_args; +}; + +struct _pkinit_cert_info { /* aka _pkinit_cert_handle */ + PLArenaPool *pool; + struct _pkinit_identity_crypto_context *id_cryptoctx; + CERTCertificate *cert; +}; + +struct _pkinit_cert_iter_info { /* aka _pkinit_cert_iter_handle */ + PLArenaPool *pool; + struct _pkinit_identity_crypto_context *id_cryptoctx; + CERTCertListNode *node; +}; + /* KerberosString: RFC 4120, 5.2.1. */ static const SEC_ASN1Template kerberos_string_template[] = { @@ -1308,7 +1309,6 @@ server_check_dh(krb5_context context, int minbits) { PLArenaPool *pool; - struct domain_parameters params; SECItem item; pool = PORT_NewArena(sizeof(double)); @@ -1318,14 +1318,17 @@ server_check_dh(krb5_context context, item.data = dh_params->data; item.len = dh_params->length; - memset(¶ms, 0, sizeof(params)); - if (SEC_ASN1DecodeItem(pool, ¶ms, domain_parameters_template, + memset(&req_cryptoctx->client_dh_params, 0, + sizeof(req_cryptoctx->client_dh_params)); + if (SEC_ASN1DecodeItem(req_cryptoctx->pool, + &req_cryptoctx->client_dh_params, + domain_parameters_template, &item) != SECSuccess) { PORT_FreeArena(pool, PR_TRUE); return ENOMEM; } - if (get_integer_bits(¶ms.p) < minbits) { + if (get_integer_bits(&req_cryptoctx->client_dh_params.p) < minbits) { PORT_FreeArena(pool, PR_TRUE); return KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED; } @@ -1352,14 +1355,11 @@ server_process_dh(krb5_context context, unsigned int *server_key_len) { PLArenaPool *pool; - CERTSubjectPublicKeyInfo *spki; - SECOidData *oid; SECKEYPrivateKey *priv; SECKEYPublicKey *pub, pub2; SECKEYDHParams dh_params; PK11SymKey *sym; - struct domain_parameters params; - SECItem item, *bits; + SECItem pubval, *bits; PK11SlotInfo *slot; pool = PORT_NewArena(sizeof(double)); @@ -1367,44 +1367,20 @@ server_process_dh(krb5_context context, return ENOMEM; } - /* Decode the client's public key. */ - item.data = received_pubkey; - item.len = received_pub_len; - spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&item); - if (spki == NULL) { - PORT_FreeArena(pool, PR_TRUE); - return ENOMEM; - } + /* Store the client's public value. */ + pubval.data = received_pubkey; + pubval.len = received_pub_len; - /* Make sure the key's identified as a DH key. */ - oid = SECOID_FindOID(&spki->algorithm.algorithm); - if (oid->offset != SEC_OID_X942_DIFFIE_HELMAN_KEY) { - SECKEY_DestroySubjectPublicKeyInfo(spki); - PORT_FreeArena(pool, PR_TRUE); - return ENOMEM; - } - - /* Decode the domain parameters. */ - memset(¶ms, 0, sizeof(params)); - if (SEC_ASN1DecodeItem(pool, ¶ms, - domain_parameters_template, - &spki->algorithm.parameters) != SECSuccess) { - SECKEY_DestroySubjectPublicKeyInfo(spki); - PORT_FreeArena(pool, PR_TRUE); - return ENOMEM; - } - - /* Set up DH parameters the using client-supplied domain parameters. */ + /* Set up DH parameters the using client's domain parameters. */ memset(&dh_params, 0, sizeof(dh_params)); dh_params.arena = pool; - dh_params.prime = params.p; - dh_params.base = params.g; + dh_params.prime = req_cryptoctx->client_dh_params.p; + dh_params.base = req_cryptoctx->client_dh_params.g; - /* Generate a public value and a private key. */ + /* Generate a public value and a private key using the parameters. */ slot = PK11_GetBestSlot(CKM_DH_PKCS_KEY_PAIR_GEN, crypto_pwcb_prep(id_cryptoctx, context)); if (slot == NULL) { - SECKEY_DestroySubjectPublicKeyInfo(spki); PORT_FreeArena(pool, PR_TRUE); return ENOMEM; } @@ -1414,22 +1390,18 @@ server_process_dh(krb5_context context, crypto_pwcb_prep(id_cryptoctx, context)); if (priv == NULL) { PK11_FreeSlot(slot); - SECKEY_DestroySubjectPublicKeyInfo(spki); PORT_FreeArena(pool, PR_TRUE); return ENOMEM; } - /* Rebuild the client's public key using the client's parameters and + /* Build the client's public key using the client's parameters and * public value. */ pub2 = *pub; - if (secitem_from_dh_pubval(pool, - spki->subjectPublicKey.data, - spki->subjectPublicKey.len, - &pub2.u.dh.publicValue) != 0) { + if (SEC_ASN1DecodeItem(pool, &pub2.u.dh.publicValue, + SEC_IntegerTemplate, &pubval) != SECSuccess) { SECKEY_DestroyPrivateKey(priv); SECKEY_DestroyPublicKey(pub); PK11_FreeSlot(slot); - SECKEY_DestroySubjectPublicKeyInfo(spki); PORT_FreeArena(pool, PR_TRUE); return ENOMEM; } @@ -1447,7 +1419,6 @@ server_process_dh(krb5_context context, SECKEY_DestroyPrivateKey(priv); SECKEY_DestroyPublicKey(pub); PK11_FreeSlot(slot); - SECKEY_DestroySubjectPublicKeyInfo(spki); PORT_FreeArena(pool, PR_TRUE); return ENOMEM; } @@ -1467,7 +1438,6 @@ server_process_dh(krb5_context context, SECKEY_DestroyPrivateKey(priv); SECKEY_DestroyPublicKey(pub); PK11_FreeSlot(slot); - SECKEY_DestroySubjectPublicKeyInfo(spki); PORT_FreeArena(pool, PR_TRUE); return ENOMEM; } @@ -1476,7 +1446,6 @@ server_process_dh(krb5_context context, SECKEY_DestroyPrivateKey(priv); SECKEY_DestroyPublicKey(pub); PK11_FreeSlot(slot); - SECKEY_DestroySubjectPublicKeyInfo(spki); PORT_FreeArena(pool, PR_TRUE); return 0; } -- 1.7.6.4