1 /* 2 * NSS utility functions 3 * 4 * This Source Code Form is subject to the terms of the Mozilla Public 5 * License, v. 2.0. If a copy of the MPL was not distributed with this 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 7 8 #include <stdio.h> 9 #include <string.h> 10 #include "prerror.h" 11 #include "secitem.h" 12 #include "prnetdb.h" 13 #include "cert.h" 14 #include "nspr.h" 15 #include "secder.h" 16 #include "key.h" 17 #include "nss.h" 18 19 /* 20 * Look to see if any of the signers in the cert chain for "cert" are found 21 * in the list of caNames. 22 * Returns SECSuccess if so, SECFailure if not. 23 */ 24 SECStatus 25 NSS_CmpCertChainWCANames(CERTCertificate *cert, CERTDistNames *caNames) 26 { 27 SECItem * caname; 28 CERTCertificate * curcert; 29 CERTCertificate * oldcert; 30 PRInt32 contentlen; 31 int j; 32 int headerlen; 33 int depth; 34 SECStatus rv; 35 SECItem issuerName; 36 SECItem compatIssuerName; 37 38 if (!cert || !caNames || !caNames->nnames || !caNames->names || 39 !caNames->names->data) 40 return SECFailure; 41 depth=0; 42 curcert = CERT_DupCertificate(cert); 43 44 while( curcert ) { 45 issuerName = curcert->derIssuer; 46 47 /* compute an alternate issuer name for compatibility with 2.0 48 * enterprise server, which send the CA names without 49 * the outer layer of DER header 50 */ 51 rv = DER_Lengths(&issuerName, &headerlen, (PRUint32 *)&contentlen); 52 if ( rv == SECSuccess ) { 53 compatIssuerName.data = &issuerName.data[headerlen]; 54 compatIssuerName.len = issuerName.len - headerlen; 55 } else { 56 compatIssuerName.data = NULL; 57 compatIssuerName.len = 0; 58 } 59 60 for (j = 0; j < caNames->nnames; j++) { 61 caname = &caNames->names[j]; 62 if (SECITEM_CompareItem(&issuerName, caname) == SECEqual) { 63 rv = SECSuccess; 64 CERT_DestroyCertificate(curcert); 65 goto done; 66 } else if (SECITEM_CompareItem(&compatIssuerName, caname) == SECEqual) { 67 rv = SECSuccess; 68 CERT_DestroyCertificate(curcert); 69 goto done; 70 } 71 } 72 if ( ( depth <= 20 ) && 73 ( SECITEM_CompareItem(&curcert->derIssuer, &curcert->derSubject) 74 != SECEqual ) ) { 75 oldcert = curcert; 76 curcert = CERT_FindCertByName(curcert->dbhandle, 77 &curcert->derIssuer); 78 CERT_DestroyCertificate(oldcert); 79 depth++; 80 } else { 81 CERT_DestroyCertificate(curcert); 82 curcert = NULL; 83 } 84 } 85 rv = SECFailure; 86 87 done: 88 return rv; 89 } 90 91