From 6d766fc13b6dc728ccc9992768c53abd316e7fcd Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Wed, 29 Sep 2010 14:05:16 -0400 Subject: [PATCH 021/150] implement pkinit_check_kdc_pkid --- src/plugins/preauth/pkinit/pkinit_crypto_nss.c | 45 ++++++++++++++++++++++- 1 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_nss.c b/src/plugins/preauth/pkinit/pkinit_crypto_nss.c index ec67911..d82cb4d 100644 --- a/src/plugins/preauth/pkinit/pkinit_crypto_nss.c +++ b/src/plugins/preauth/pkinit/pkinit_crypto_nss.c @@ -1334,7 +1334,8 @@ crypto_cert_select(krb5_context context, pkinit_cert_matching_data *data) return 0; } -/* Try to select the "default" cert. */ +/* Try to select the "default" cert, which for now is the only cert, if we only + * have one. */ krb5_error_code crypto_cert_select_default(krb5_context context, pkinit_plg_crypto_context plg_cryptoctx, @@ -1351,6 +1352,9 @@ crypto_cert_select_default(krb5_context context, if (result != 0) { return result; } + if (count != 1) { + return ENOENT; + } if (id_cryptoctx->id_cert != NULL) { CERT_DestroyCertificate(id_cryptoctx->id_cert); } @@ -1435,6 +1439,7 @@ pkinit_process_td_trusted_certifiers(krb5_context context, return ENOSYS; } +/* Check if the encoded issuer/serial matches our (the KDC's) certificate. */ krb5_error_code pkinit_check_kdc_pkid(krb5_context context, pkinit_plg_crypto_context plg_cryptoctx, @@ -1444,7 +1449,43 @@ pkinit_check_kdc_pkid(krb5_context context, unsigned int pkid_len, int *valid_kdcPkId) { - return ENOSYS; + PLArenaPool *pool; + CERTCertificate *cert; + SECItem pkid; + struct issuer_and_serial_number isn; + + pool = PORT_NewArena(sizeof(double)); + if (pool == NULL) { + return ENOMEM; + } + + /* Verify that we have selected a certificate for our (the KDC's) own + * use. */ + if (id_cryptoctx->id_cert == NULL) { + return ENOENT; + } + cert = id_cryptoctx->id_cert; + + /* Decode the pair. */ + pkid.data = pkid_buf; + pkid.len = pkid_len; + memset(&isn, 0, sizeof(isn)); + if (SEC_ASN1DecodeItem(pool, &isn, issuer_and_serial_number_template, + &pkid) != SECSuccess) { + PORT_FreeArena(pool, PR_TRUE); + return ENOMEM; + } + + /* Compare the issuer and serial number. */ + *valid_kdcPkId = SECITEM_ItemsAreEqual(&isn.issuer, + &cert->derIssuer) && + SECITEM_ItemsAreEqual(&isn.serial, + &cert->serialNumber); + + /* Clean up. */ + PORT_FreeArena(pool, PR_TRUE); + + return 0; } krb5_error_code -- 1.7.6.4