/* * NSS utility functions * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* $Id: cmpcert.c,v 1.7 2012/04/25 14:50:12 gerv%gerv.net Exp $ */ #include #include #include "prerror.h" #include "secitem.h" #include "prnetdb.h" #include "cert.h" #include "nspr.h" #include "secder.h" #include "key.h" #include "nss.h" /* * Look to see if any of the signers in the cert chain for "cert" are found * in the list of caNames. * Returns SECSuccess if so, SECFailure if not. */ SECStatus NSS_CmpCertChainWCANames(CERTCertificate *cert, CERTDistNames *caNames) { SECItem * caname; CERTCertificate * curcert; CERTCertificate * oldcert; PRInt32 contentlen; int j; int headerlen; int depth; SECStatus rv; SECItem issuerName; SECItem compatIssuerName; if (!cert || !caNames || !caNames->nnames || !caNames->names || !caNames->names->data) return SECFailure; depth=0; curcert = CERT_DupCertificate(cert); while( curcert ) { issuerName = curcert->derIssuer; /* compute an alternate issuer name for compatibility with 2.0 * enterprise server, which send the CA names without * the outer layer of DER header */ rv = DER_Lengths(&issuerName, &headerlen, (PRUint32 *)&contentlen); if ( rv == SECSuccess ) { compatIssuerName.data = &issuerName.data[headerlen]; compatIssuerName.len = issuerName.len - headerlen; } else { compatIssuerName.data = NULL; compatIssuerName.len = 0; } for (j = 0; j < caNames->nnames; j++) { caname = &caNames->names[j]; if (SECITEM_CompareItem(&issuerName, caname) == SECEqual) { rv = SECSuccess; CERT_DestroyCertificate(curcert); goto done; } else if (SECITEM_CompareItem(&compatIssuerName, caname) == SECEqual) { rv = SECSuccess; CERT_DestroyCertificate(curcert); goto done; } } if ( ( depth <= 20 ) && ( SECITEM_CompareItem(&curcert->derIssuer, &curcert->derSubject) != SECEqual ) ) { oldcert = curcert; curcert = CERT_FindCertByName(curcert->dbhandle, &curcert->derIssuer); CERT_DestroyCertificate(oldcert); depth++; } else { CERT_DestroyCertificate(curcert); curcert = NULL; } } rv = SECFailure; done: return rv; }