From 9a876b2551319a6a522a9a7ef3f8dd5f15052025 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Mon, 27 Sep 2010 19:06:00 -0400 Subject: [PATCH 002/150] - also check the algorithm identifier of the client's key --- src/plugins/preauth/pkinit/pkinit_crypto_nss.c | 29 ++++++++++++++++++----- 1 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_nss.c b/src/plugins/preauth/pkinit/pkinit_crypto_nss.c index b7c6716..6e0e92b 100644 --- a/src/plugins/preauth/pkinit/pkinit_crypto_nss.c +++ b/src/plugins/preauth/pkinit/pkinit_crypto_nss.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Red Hat, Inc. + * Copyright (c) 2006,2007,2010 Red Hat, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without @@ -353,9 +353,11 @@ secitem_from_dh_pubval(PLArenaPool *pool, } /* Create DH parameters to be sent to the KDC. On success, dh_params should - * contain an encoded DomainParameters structure (per RFC3279), and dh_pubkey - * should contain the public value we're prepared to send to the KDC, encoded - * first as an integer and then wrapped up in a bit string. */ + * contain an encoded DomainParameters structure (per RFC3280, the "parameters" + * in an AlgorithmIdentifier), and dh_pubkey should contain the public value + * we're prepared to send to the KDC, encoded first as an integer and then + * wrapped up in a bit string (per RFC3280, the "subjectPublicKey" field of a + * SubjectPublicKeyInfo). */ krb5_error_code client_create_dh(krb5_context context, pkinit_plg_crypto_context plg_cryptoctx, @@ -487,7 +489,7 @@ client_process_dh(krb5_context context, } /* Rebuild the KDC's public key using our parameters and the supplied - * public value. */ + * public value (subjectPublicKey). */ pub = SECKEY_ConvertToPublicKey(req_cryptoctx->client_seckey); if (pub == NULL) { PORT_FreeArena(pool, PR_TRUE); @@ -501,7 +503,8 @@ client_process_dh(krb5_context context, return ENOMEM; } - /* Generate the shared value. */ + /* Generate the shared value using our private key and the KDC's + * public key. */ slot = PK11_GetBestSlot(CKM_DH_PKCS_KEY_PAIR_GEN, NULL); if (slot == NULL) { SECKEY_DestroyPublicKey(pub); @@ -595,6 +598,7 @@ server_process_dh(krb5_context context, { PLArenaPool *pool; CERTSubjectPublicKeyInfo *spki; + SECOidData *oid; SECKEYPrivateKey *priv; SECKEYPublicKey *pub, pub2; SECKEYDHParams dh_params; @@ -616,6 +620,16 @@ server_process_dh(krb5_context context, PORT_FreeArena(pool, PR_TRUE); return ENOMEM; } + + /* 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. */ if (SEC_ASN1DecodeItem(pool, ¶ms, domain_parameters_template, &spki->algorithm.parameters) != SECSuccess) { @@ -662,7 +676,8 @@ server_process_dh(krb5_context context, return ENOMEM; } - /* Generate the shared value. */ + /* Generate the shared value using our private key and the client's + * public key. */ sym = PK11_PubDerive(priv, &pub2, PR_FALSE, NULL, NULL, CKM_DH_PKCS_DERIVE, -- 1.7.6.4