Home | History | Annotate | Download | only in ssl
      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