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