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 */
24SECStatus
25NSS_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
87done:
88  return rv;
89}
90
91