From 9045d4d9b9fe67012420804ca0816173d27da18f Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Wed, 1 Jun 2011 10:39:28 -0400 Subject: [PATCH 117/150] - count CRLs correctly, handle signerInfo-less signedData --- src/plugins/preauth/pkinit/pkinit_crypto_nss.c | 114 +++++++++++++----------- 1 files changed, 61 insertions(+), 53 deletions(-) diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_nss.c b/src/plugins/preauth/pkinit/pkinit_crypto_nss.c index 7f9b975..855f80e 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) 2006,2007,2010 Red Hat, Inc. + * Copyright (c) 2006,2007,2010,2011 Red Hat, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without @@ -2602,8 +2602,8 @@ crypto_load_files(krb5_context context, n_crls = i; /* Allocate a bigger list. */ crls = PORT_ArenaZAlloc(id_cryptoctx->pool, - sizeof(crls[0]) * (i + 2)); - for (j = 0; j < i; j++) { + sizeof(crls[0]) * (n_crls + 2)); + for (j = 0; j < n_crls; j++) { crls[j] = id_cryptoctx->id_crls[j]; } if (crl != NULL) { @@ -3173,7 +3173,7 @@ crypto_cert_select_default(krb5_context context, __FUNCTION__, node->cert->subjectName); code = cert_retrieve_cert_sans(context, node->cert, &sans, NULL, NULL); - if (sans != NULL) { + if ((code == 0) && (sans != NULL)) { for (i = 0; sans[i] != NULL; i++) { c = krb5_princ_component(context, sans[i], 0); @@ -4455,6 +4455,7 @@ crypto_signeddata_common_verify(krb5_context context, CERTCertificate *cert; SECOidTag encapsulated_tag; SECStatus status; + int n_signers; *is_signed = 0; @@ -4466,54 +4467,60 @@ crypto_signeddata_common_verify(krb5_context context, return EINVAL; } sdata = NSS_CMSContentInfo_GetContent(cinfo); - if ((sdata == NULL) || - (NSS_CMSSignedData_SignerInfoCount(sdata) != 1)) { - if (sdata != NULL) { - pkiDebug("%s: wrong number of signers (%d, not 1)\n", - __FUNCTION__, - NSS_CMSSignedData_SignerInfoCount(sdata)); - } else { - pkiDebug("%s: no signers? decoding error? content-info " - "was NULL\n", __FUNCTION__); - } - return ENOENT; - } - if (NSS_CMSSignedData_ImportCerts(sdata, certdb, - usage, PR_FALSE) != SECSuccess) { - pkiDebug("%s: error importing signer certs\n", __FUNCTION__); - return ENOENT; - } - signer = NSS_CMSSignedData_GetSignerInfo(sdata, 0); - if (signer == NULL) { - pkiDebug("%s: no signers?\n", __FUNCTION__); + if (sdata == NULL) { + pkiDebug("%s: decoding error? content-info was NULL\n", + __FUNCTION__); return ENOENT; } - /* Verify the signer's certificate. */ - if (!NSS_CMSSignedData_HasDigests(sdata)) { - pkiDebug("%s: no digests?\n", __FUNCTION__); + n_signers = NSS_CMSSignedData_SignerInfoCount(sdata); + if (n_signers > 1) { + pkiDebug("%s: wrong number of signers (%d, not 0 or 1)\n", + __FUNCTION__, n_signers); return ENOENT; } - status = NSS_CMSSignedData_VerifySignerInfo(sdata, 0, certdb, - usage); - if (status != SECSuccess) { - pkiDebug("%s: signer verify failed: %s\n", __FUNCTION__, - PR_ErrorToString(status == SECFailure ? - PORT_GetError() : status, - PR_LANGUAGE_I_DEFAULT)); - switch (cms_msg_type) { - case CMS_SIGN_DRAFT9: - case CMS_SIGN_CLIENT: - return KRB5KDC_ERR_CLIENT_NOT_TRUSTED; - break; - case CMS_SIGN_SERVER: - case CMS_ENVEL_SERVER: - return KRB5KDC_ERR_KDC_NOT_TRUSTED; - break; - default: - return ENOMEM; + if (n_signers < 1) { + signer = NULL; + } else { + /* Import the bundle's certs and locate the signerInfo. */ + if (NSS_CMSSignedData_ImportCerts(sdata, certdb, usage, + PR_FALSE) != SECSuccess) { + pkiDebug("%s: error importing signer certs\n", + __FUNCTION__); + return ENOENT; + } + signer = NSS_CMSSignedData_GetSignerInfo(sdata, 0); + if (signer == NULL) { + pkiDebug("%s: no signers?\n", __FUNCTION__); + return ENOENT; + } + /* Verify the signer's certificate. */ + if (!NSS_CMSSignedData_HasDigests(sdata)) { + pkiDebug("%s: no digests?\n", __FUNCTION__); + return ENOENT; + } + status = NSS_CMSSignedData_VerifySignerInfo(sdata, 0, certdb, + usage); + if (status != SECSuccess) { + pkiDebug("%s: signer verify failed: %s\n", __FUNCTION__, + PR_ErrorToString(status == SECFailure ? + PORT_GetError() : status, + PR_LANGUAGE_I_DEFAULT)); + switch (cms_msg_type) { + case CMS_SIGN_DRAFT9: + case CMS_SIGN_CLIENT: + return KRB5KDC_ERR_CLIENT_NOT_TRUSTED; + break; + case CMS_SIGN_SERVER: + case CMS_ENVEL_SERVER: + return KRB5KDC_ERR_KDC_NOT_TRUSTED; + break; + default: + return ENOMEM; + } } + pkiDebug("%s: signer verify passed\n", __FUNCTION__); + *is_signed = 1; } - pkiDebug("%s: signer verify passed\n", __FUNCTION__); /* Pull out the payload. */ ecinfo = NSS_CMSSignedData_GetContentInfo(sdata); if (ecinfo == NULL) { @@ -4532,14 +4539,15 @@ crypto_signeddata_common_verify(krb5_context context, pkiDebug("%s: warning: encapsulated content appears empty\n", __FUNCTION__); } - /* Save the peer cert -- we'll need it later. */ - pkiDebug("%s: saving peer certificate\n", __FUNCTION__); - if (req_cryptoctx->peer_cert != NULL) { - CERT_DestroyCertificate(req_cryptoctx->peer_cert); + if (signer != NULL) { + /* Save the peer cert -- we'll need it later. */ + pkiDebug("%s: saving peer certificate\n", __FUNCTION__); + if (req_cryptoctx->peer_cert != NULL) { + CERT_DestroyCertificate(req_cryptoctx->peer_cert); + } + cert = NSS_CMSSignerInfo_GetSigningCertificate(signer, certdb); + req_cryptoctx->peer_cert = CERT_DupCertificate(cert); } - cert = NSS_CMSSignerInfo_GetSigningCertificate(signer, certdb); - req_cryptoctx->peer_cert = CERT_DupCertificate(cert); - *is_signed = 1; return 0; } -- 1.7.6.4