certdb.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:55k
源码类别:

CA认证

开发平台:

WINDOWS

  1. /*
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is the Netscape security libraries.
  13.  * 
  14.  * The Initial Developer of the Original Code is Netscape
  15.  * Communications Corporation.  Portions created by Netscape are 
  16.  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
  17.  * Rights Reserved.
  18.  * 
  19.  * Contributor(s):
  20.  * 
  21.  * Alternatively, the contents of this file may be used under the
  22.  * terms of the GNU General Public License Version 2 or later (the
  23.  * "GPL"), in which case the provisions of the GPL are applicable 
  24.  * instead of those above.  If you wish to allow use of your 
  25.  * version of this file only under the terms of the GPL and not to
  26.  * allow others to use your version of this file under the MPL,
  27.  * indicate your decision by deleting the provisions above and
  28.  * replace them with the notice and other provisions required by
  29.  * the GPL.  If you do not delete the provisions above, a recipient
  30.  * may use your version of this file under either the MPL or the
  31.  * GPL.
  32.  */
  33. /*
  34.  * Certificate handling code
  35.  *
  36.  * $Id: certdb.c,v 1.3 2000/09/06 22:10:06 relyea%netscape.com Exp $
  37.  */
  38. #include "prlock.h"
  39. #include "prmon.h"
  40. #include "prtime.h"
  41. #include "cert.h"
  42. #include "secder.h"
  43. #include "secoid.h"
  44. #include "secasn1.h"
  45. #include "blapi.h" /* for SHA1_HashBuf */
  46. #include "genname.h"
  47. #include "keyhi.h"
  48. #include "secitem.h"
  49. #include "mcom_db.h"
  50. #include "certdb.h"
  51. #include "prprf.h"
  52. #include "sechash.h"
  53. #include "prlong.h"
  54. #include "certxutl.h"
  55. #include "portreg.h"
  56. #include "secerr.h"
  57. #include "sslerr.h"
  58. #include "nsslocks.h"
  59. #include "cdbhdl.h"
  60. /*
  61.  * Certificate database handling code
  62.  */
  63. const SEC_ASN1Template CERT_CertExtensionTemplate[] = {
  64.     { SEC_ASN1_SEQUENCE,
  65.   0, NULL, sizeof(CERTCertExtension) },
  66.     { SEC_ASN1_OBJECT_ID,
  67.   offsetof(CERTCertExtension,id) },
  68.     { SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN, /* XXX DER_DEFAULT */
  69.   offsetof(CERTCertExtension,critical) },
  70.     { SEC_ASN1_OCTET_STRING,
  71.   offsetof(CERTCertExtension,value) },
  72.     { 0, }
  73. };
  74. const SEC_ASN1Template CERT_SequenceOfCertExtensionTemplate[] = {
  75.     { SEC_ASN1_SEQUENCE_OF, 0, CERT_CertExtensionTemplate }
  76. };
  77. const SEC_ASN1Template CERT_CertificateTemplate[] = {
  78.     { SEC_ASN1_SEQUENCE,
  79.       0, NULL, sizeof(CERTCertificate) },
  80.     { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | 
  81.   SEC_ASN1_CONTEXT_SPECIFIC | 0,  /* XXX DER_DEFAULT */ 
  82.   offsetof(CERTCertificate,version),
  83.   SEC_IntegerTemplate },
  84.     { SEC_ASN1_INTEGER,
  85.   offsetof(CERTCertificate,serialNumber) },
  86.     { SEC_ASN1_INLINE,
  87.   offsetof(CERTCertificate,signature),
  88.   SECOID_AlgorithmIDTemplate },
  89.     { SEC_ASN1_SAVE, 
  90.   offsetof(CERTCertificate,derIssuer) },
  91.     { SEC_ASN1_INLINE,
  92.   offsetof(CERTCertificate,issuer),
  93.   CERT_NameTemplate },
  94.     { SEC_ASN1_INLINE,
  95.   offsetof(CERTCertificate,validity),
  96.   CERT_ValidityTemplate },
  97.     { SEC_ASN1_SAVE,
  98.   offsetof(CERTCertificate,derSubject) },
  99.     { SEC_ASN1_INLINE,
  100.   offsetof(CERTCertificate,subject),
  101.   CERT_NameTemplate },
  102.     { SEC_ASN1_SAVE,
  103.   offsetof(CERTCertificate,derPublicKey) },
  104.     { SEC_ASN1_INLINE,
  105.   offsetof(CERTCertificate,subjectPublicKeyInfo),
  106.   CERT_SubjectPublicKeyInfoTemplate },
  107.     { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
  108.   offsetof(CERTCertificate,issuerID),
  109.   SEC_ObjectIDTemplate },
  110.     { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 2,
  111.   offsetof(CERTCertificate,subjectID),
  112.   SEC_ObjectIDTemplate },
  113.     { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | 
  114.   SEC_ASN1_CONTEXT_SPECIFIC | 3,
  115.   offsetof(CERTCertificate,extensions),
  116.   CERT_SequenceOfCertExtensionTemplate },
  117.     { 0 }
  118. };
  119. const SEC_ASN1Template SEC_SignedCertificateTemplate[] =
  120. {
  121.     { SEC_ASN1_SEQUENCE,
  122.   0, NULL, sizeof(CERTCertificate) },
  123.     { SEC_ASN1_SAVE, 
  124.   offsetof(CERTCertificate,signatureWrap.data) },
  125.     { SEC_ASN1_INLINE, 
  126.   0, CERT_CertificateTemplate },
  127.     { SEC_ASN1_INLINE,
  128.   offsetof(CERTCertificate,signatureWrap.signatureAlgorithm),
  129.   SECOID_AlgorithmIDTemplate },
  130.     { SEC_ASN1_BIT_STRING,
  131.   offsetof(CERTCertificate,signatureWrap.signature) },
  132.     { 0 }
  133. };
  134. /*
  135.  * Find the subjectName in a DER encoded certificate
  136.  */
  137. const SEC_ASN1Template SEC_CertSubjectTemplate[] = {
  138.     { SEC_ASN1_SEQUENCE,
  139.   0, NULL, sizeof(SECItem) },
  140.     { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | 
  141.   SEC_ASN1_CONTEXT_SPECIFIC | 0,
  142.   0, SEC_SkipTemplate }, /* version */
  143.     { SEC_ASN1_SKIP }, /* serial number */
  144.     { SEC_ASN1_SKIP }, /* signature algorithm */
  145.     { SEC_ASN1_SKIP }, /* issuer */
  146.     { SEC_ASN1_SKIP }, /* validity */
  147.     { SEC_ASN1_ANY, 0, NULL }, /* subject */
  148.     { SEC_ASN1_SKIP_REST },
  149.     { 0 }
  150. };
  151. /*
  152.  * Find the issuerName in a DER encoded certificate
  153.  */
  154. const SEC_ASN1Template SEC_CertIssuerTemplate[] = {
  155.     { SEC_ASN1_SEQUENCE,
  156.   0, NULL, sizeof(SECItem) },
  157.     { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | 
  158.   SEC_ASN1_CONTEXT_SPECIFIC | 0,
  159.   0, SEC_SkipTemplate }, /* version */
  160.     { SEC_ASN1_SKIP }, /* serial number */
  161.     { SEC_ASN1_SKIP }, /* signature algorithm */
  162.     { SEC_ASN1_ANY, 0, NULL }, /* issuer */
  163.     { SEC_ASN1_SKIP_REST },
  164.     { 0 }
  165. };
  166. /*
  167.  * Find the subjectName in a DER encoded certificate
  168.  */
  169. const SEC_ASN1Template SEC_CertSerialNumberTemplate[] = {
  170.     { SEC_ASN1_SEQUENCE,
  171.   0, NULL, sizeof(SECItem) },
  172.     { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | 
  173.   SEC_ASN1_CONTEXT_SPECIFIC | 0,
  174.   0, SEC_SkipTemplate }, /* version */
  175.     { SEC_ASN1_ANY, 0, NULL }, /* serial number */
  176.     { SEC_ASN1_SKIP_REST },
  177.     { 0 }
  178. };
  179. /*
  180.  * Find the issuer and serialNumber in a DER encoded certificate.
  181.  * This data is used as the database lookup key since its the unique
  182.  * identifier of a certificate.
  183.  */
  184. const SEC_ASN1Template CERT_CertKeyTemplate[] = {
  185.     { SEC_ASN1_SEQUENCE,
  186.   0, NULL, sizeof(CERTCertKey) },
  187.     { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | 
  188.   SEC_ASN1_CONTEXT_SPECIFIC | 0,
  189.   0, SEC_SkipTemplate }, /* version */ 
  190.     { SEC_ASN1_INTEGER,
  191.   offsetof(CERTCertKey,serialNumber) },
  192.     { SEC_ASN1_SKIP }, /* signature algorithm */
  193.     { SEC_ASN1_ANY,
  194.   offsetof(CERTCertKey,derIssuer) },
  195.     { SEC_ASN1_SKIP_REST },
  196.     { 0 }
  197. };
  198. SECStatus
  199. CERT_KeyFromIssuerAndSN(PRArenaPool *arena, SECItem *issuer, SECItem *sn,
  200. SECItem *key)
  201. {
  202.     key->len = sn->len + issuer->len;
  203.     
  204.     key->data = (unsigned char*)PORT_ArenaAlloc(arena, key->len);
  205.     if ( !key->data ) {
  206. goto loser;
  207.     }
  208.     /* copy the serialNumber */
  209.     PORT_Memcpy(key->data, sn->data, sn->len);
  210.     /* copy the issuer */
  211.     PORT_Memcpy(&key->data[sn->len], issuer->data, issuer->len);
  212.     return(SECSuccess);
  213. loser:
  214.     return(SECFailure);
  215. }
  216. /*
  217.  * Extract the subject name from a DER certificate
  218.  */
  219. SECStatus
  220. CERT_NameFromDERCert(SECItem *derCert, SECItem *derName)
  221. {
  222.     int rv;
  223.     PRArenaPool *arena;
  224.     CERTSignedData sd;
  225.     void *tmpptr;
  226.     
  227.     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  228.     
  229.     if ( ! arena ) {
  230. return(SECFailure);
  231.     }
  232.    
  233.     PORT_Memset(&sd, 0, sizeof(CERTSignedData));
  234.     rv = SEC_ASN1DecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert);
  235.     
  236.     if ( rv ) {
  237. goto loser;
  238.     }
  239.     
  240.     PORT_Memset(derName, 0, sizeof(SECItem));
  241.     rv = SEC_ASN1DecodeItem(arena, derName, SEC_CertSubjectTemplate, &sd.data);
  242.     if ( rv ) {
  243. goto loser;
  244.     }
  245.     tmpptr = derName->data;
  246.     derName->data = (unsigned char*)PORT_Alloc(derName->len);
  247.     if ( derName->data == NULL ) {
  248. goto loser;
  249.     }
  250.     
  251.     PORT_Memcpy(derName->data, tmpptr, derName->len);
  252.     
  253.     PORT_FreeArena(arena, PR_FALSE);
  254.     return(SECSuccess);
  255. loser:
  256.     PORT_FreeArena(arena, PR_FALSE);
  257.     return(SECFailure);
  258. }
  259. SECStatus
  260. CERT_IssuerNameFromDERCert(SECItem *derCert, SECItem *derName)
  261. {
  262.     int rv;
  263.     PRArenaPool *arena;
  264.     CERTSignedData sd;
  265.     void *tmpptr;
  266.     
  267.     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  268.     
  269.     if ( ! arena ) {
  270. return(SECFailure);
  271.     }
  272.    
  273.     PORT_Memset(&sd, 0, sizeof(CERTSignedData));
  274.     rv = SEC_ASN1DecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert);
  275.     
  276.     if ( rv ) {
  277. goto loser;
  278.     }
  279.     
  280.     PORT_Memset(derName, 0, sizeof(SECItem));
  281.     rv = SEC_ASN1DecodeItem(arena, derName, SEC_CertIssuerTemplate, &sd.data);
  282.     if ( rv ) {
  283. goto loser;
  284.     }
  285.     tmpptr = derName->data;
  286.     derName->data = (unsigned char*)PORT_Alloc(derName->len);
  287.     if ( derName->data == NULL ) {
  288. goto loser;
  289.     }
  290.     
  291.     PORT_Memcpy(derName->data, tmpptr, derName->len);
  292.     
  293.     PORT_FreeArena(arena, PR_FALSE);
  294.     return(SECSuccess);
  295. loser:
  296.     PORT_FreeArena(arena, PR_FALSE);
  297.     return(SECFailure);
  298. }
  299. SECStatus
  300. CERT_SerialNumberFromDERCert(SECItem *derCert, SECItem *derName)
  301. {
  302.     int rv;
  303.     PRArenaPool *arena;
  304.     CERTSignedData sd;
  305.     void *tmpptr;
  306.     
  307.     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  308.     
  309.     if ( ! arena ) {
  310. return(SECFailure);
  311.     }
  312.    
  313.     PORT_Memset(&sd, 0, sizeof(CERTSignedData));
  314.     rv = SEC_ASN1DecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert);
  315.     
  316.     if ( rv ) {
  317. goto loser;
  318.     }
  319.     
  320.     PORT_Memset(derName, 0, sizeof(SECItem));
  321.     rv = SEC_ASN1DecodeItem(arena, derName, SEC_CertSerialNumberTemplate, &sd.data);
  322.     if ( rv ) {
  323. goto loser;
  324.     }
  325.     tmpptr = derName->data;
  326.     derName->data = (unsigned char*)PORT_Alloc(derName->len);
  327.     if ( derName->data == NULL ) {
  328. goto loser;
  329.     }
  330.     
  331.     PORT_Memcpy(derName->data, tmpptr, derName->len);
  332.     
  333.     PORT_FreeArena(arena, PR_FALSE);
  334.     return(SECSuccess);
  335. loser:
  336.     PORT_FreeArena(arena, PR_FALSE);
  337.     return(SECFailure);
  338. }
  339. /*
  340.  * Generate a database key, based on serial number and issuer, from a
  341.  * DER certificate.
  342.  */
  343. SECStatus
  344. CERT_KeyFromDERCert(PRArenaPool *arena, SECItem *derCert, SECItem *key)
  345. {
  346.     int rv;
  347.     CERTSignedData sd;
  348.     CERTCertKey certkey;
  349.     PORT_Memset(&sd, 0, sizeof(CERTSignedData));    
  350.     PORT_Memset(&certkey, 0, sizeof(CERTCertKey));    
  351.     PORT_Memset(&sd, 0, sizeof(CERTSignedData));
  352.     rv = SEC_ASN1DecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert);
  353.     
  354.     if ( rv ) {
  355. goto loser;
  356.     }
  357.     
  358.     PORT_Memset(&certkey, 0, sizeof(CERTCertKey));
  359.     rv = SEC_ASN1DecodeItem(arena, &certkey, CERT_CertKeyTemplate, &sd.data);
  360.     if ( rv ) {
  361. goto loser;
  362.     }
  363.     return(CERT_KeyFromIssuerAndSN(arena, &certkey.derIssuer,
  364.    &certkey.serialNumber, key));
  365. loser:
  366.     return(SECFailure);
  367. }
  368. /*
  369.  * fill in keyUsage field of the cert based on the cert extension
  370.  * if the extension is not critical, then we allow all uses
  371.  */
  372. static SECStatus
  373. GetKeyUsage(CERTCertificate *cert)
  374. {
  375.     SECStatus rv;
  376.     SECItem tmpitem;
  377.     
  378.     rv = CERT_FindKeyUsageExtension(cert, &tmpitem);
  379.     if ( rv == SECSuccess ) {
  380. /* remember the actual value of the extension */
  381. cert->rawKeyUsage = tmpitem.data[0];
  382. cert->keyUsagePresent = PR_TRUE;
  383. cert->keyUsage = tmpitem.data[0];
  384. PORT_Free(tmpitem.data);
  385. tmpitem.data = NULL;
  386.     } else {
  387. /* if the extension is not present, then we allow all uses */
  388. cert->keyUsage = KU_ALL;
  389. cert->rawKeyUsage = KU_ALL;
  390. cert->keyUsagePresent = PR_FALSE;
  391.     }
  392.     if ( CERT_GovtApprovedBitSet(cert) ) {
  393. cert->keyUsage |= KU_NS_GOVT_APPROVED;
  394. cert->rawKeyUsage |= KU_NS_GOVT_APPROVED;
  395.     }
  396.     
  397.     return(SECSuccess);
  398. }
  399. /*
  400.  * determine if a fortezza V1 Cert is a CA or not.
  401.  */
  402. static PRBool
  403. fortezzaIsCA( CERTCertificate *cert) {
  404.     PRBool isCA = PR_FALSE;
  405.     CERTSubjectPublicKeyInfo *spki = &cert->subjectPublicKeyInfo;
  406.     int tag;
  407.     tag = SECOID_GetAlgorithmTag(&spki->algorithm);
  408.     if ((tag == SEC_OID_MISSI_KEA_DSS_OLD) ||
  409.        (tag == SEC_OID_MISSI_KEA_DSS) ||
  410.        (tag == SEC_OID_MISSI_DSS_OLD) ||
  411.        (tag == SEC_OID_MISSI_DSS) ) {
  412. SECItem rawkey;
  413. unsigned char *rawptr;
  414. unsigned char *end;
  415. int len;
  416.         rawkey = spki->subjectPublicKey;
  417. DER_ConvertBitString(&rawkey);
  418. rawptr = rawkey.data;
  419. end = rawkey.data + rawkey.len;
  420. /* version */
  421. rawptr += sizeof(((SECKEYPublicKey*)0)->u.fortezza.KMID)+2;
  422. /* clearance (the string up to the first byte with the hi-bit on */
  423. while ((rawptr < end) && (*rawptr++ & 0x80));
  424. if (rawptr >= end) { return PR_FALSE; }
  425. /* KEAPrivilege (the string up to the first byte with the hi-bit on */
  426. while ((rawptr < end) && (*rawptr++ & 0x80));
  427. if (rawptr >= end) { return PR_FALSE; }
  428. /* skip the key */
  429. len = (*rawptr << 8) | rawptr[1];
  430. rawptr += 2 + len;
  431. /* shared key */
  432. if (rawptr >= end) { return PR_FALSE; }
  433. /* DSS Version is next */
  434. rawptr += 2;
  435. /* DSSPrivilege (the string up to the first byte with the hi-bit on */
  436. if (*rawptr & 0x30) isCA = PR_TRUE;
  437.         
  438.    }
  439.    return isCA;
  440. }
  441. static SECStatus
  442. findOIDinOIDSeqByTagNum(CERTOidSequence *seq, SECOidTag tagnum)
  443. {
  444.     SECItem **oids;
  445.     SECItem *oid;
  446.     SECStatus rv = SECFailure;
  447.     
  448.     if (seq != NULL) {
  449. oids = seq->oids;
  450. while (oids != NULL && *oids != NULL) {
  451.     oid = *oids;
  452.     if (SECOID_FindOIDTag(oid) == tagnum) {
  453. rv = SECSuccess;
  454. break;
  455.     }
  456.     oids++;
  457. }
  458.     }
  459.     return rv;
  460. }
  461. /*
  462.  * fill in nsCertType field of the cert based on the cert extension
  463.  */
  464. SECStatus
  465. CERT_GetCertType(CERTCertificate *cert)
  466. {
  467.     SECStatus rv;
  468.     SECItem tmpitem;
  469.     SECItem encodedExtKeyUsage;
  470.     CERTOidSequence *extKeyUsage = NULL;
  471.     PRBool basicConstraintPresent = PR_FALSE;
  472.     CERTBasicConstraints basicConstraint;
  473.     tmpitem.data = NULL;
  474.     CERT_FindNSCertTypeExtension(cert, &tmpitem);
  475.     rv = CERT_FindCertExtension(cert, SEC_OID_X509_EXT_KEY_USAGE, 
  476. &encodedExtKeyUsage);
  477.     if (rv == SECSuccess) {
  478. extKeyUsage = CERT_DecodeOidSequence(&encodedExtKeyUsage);
  479.     }
  480.     rv = CERT_FindBasicConstraintExten(cert, &basicConstraint);
  481.     if (rv == SECSuccess) {
  482. basicConstraintPresent = PR_TRUE;
  483.     }
  484.     if (tmpitem.data != NULL || extKeyUsage != NULL) {
  485. if (tmpitem.data == NULL) {
  486.     cert->nsCertType = 0;
  487. } else {
  488.     cert->nsCertType = tmpitem.data[0];
  489. }
  490. /* free tmpitem data pointer to avoid memory leak */
  491. PORT_Free(tmpitem.data);
  492. tmpitem.data = NULL;
  493. /*
  494.  * for this release, we will allow SSL certs with an email address
  495.  * to be used for email
  496.  */
  497. if ( ( cert->nsCertType & NS_CERT_TYPE_SSL_CLIENT ) &&
  498.     cert->emailAddr ) {
  499.     cert->nsCertType |= NS_CERT_TYPE_EMAIL;
  500. }
  501. /*
  502.  * for this release, we will allow SSL intermediate CAs to be
  503.  * email intermediate CAs too.
  504.  */
  505. if ( cert->nsCertType & NS_CERT_TYPE_SSL_CA ) {
  506.     cert->nsCertType |= NS_CERT_TYPE_EMAIL_CA;
  507. }
  508. /*
  509.  * allow a cert with the extended key usage of EMail Protect
  510.  * to be used for email or as an email CA, if basic constraints
  511.  * indicates that it is a CA.
  512.  */
  513. if (findOIDinOIDSeqByTagNum(extKeyUsage, 
  514.     SEC_OID_EXT_KEY_USAGE_EMAIL_PROTECT) ==
  515.     SECSuccess) {
  516.     if (basicConstraintPresent == PR_TRUE &&
  517. (basicConstraint.isCA)) {
  518. cert->nsCertType |= NS_CERT_TYPE_EMAIL_CA;
  519.     } else {
  520. cert->nsCertType |= NS_CERT_TYPE_EMAIL;
  521.     }
  522. }
  523. if (findOIDinOIDSeqByTagNum(extKeyUsage, 
  524.     SEC_OID_EXT_KEY_USAGE_SERVER_AUTH) ==
  525.     SECSuccess){
  526.     if (basicConstraintPresent == PR_TRUE &&
  527. (basicConstraint.isCA)) {
  528. cert->nsCertType |= NS_CERT_TYPE_SSL_CA;
  529.     } else {
  530. cert->nsCertType |= NS_CERT_TYPE_SSL_SERVER;
  531.     }
  532. }
  533. if (findOIDinOIDSeqByTagNum(extKeyUsage,
  534.     SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH) ==
  535.     SECSuccess){
  536.     if (basicConstraintPresent == PR_TRUE &&
  537. (basicConstraint.isCA)) {
  538. cert->nsCertType |= NS_CERT_TYPE_SSL_CA;
  539.     } else {
  540. cert->nsCertType |= NS_CERT_TYPE_SSL_CLIENT;
  541.     }
  542. }
  543. if (findOIDinOIDSeqByTagNum(extKeyUsage,
  544.     SEC_OID_EXT_KEY_USAGE_CODE_SIGN) ==
  545.     SECSuccess) {
  546.     if (basicConstraintPresent == PR_TRUE &&
  547. (basicConstraint.isCA)) {
  548. cert->nsCertType |= NS_CERT_TYPE_OBJECT_SIGNING_CA;
  549.     } else {
  550. cert->nsCertType |= NS_CERT_TYPE_OBJECT_SIGNING;
  551.     }
  552. }
  553. if (findOIDinOIDSeqByTagNum(extKeyUsage,
  554.     SEC_OID_EXT_KEY_USAGE_TIME_STAMP) ==
  555.     SECSuccess) {
  556.     cert->nsCertType |= EXT_KEY_USAGE_TIME_STAMP;
  557. }
  558. if (findOIDinOIDSeqByTagNum(extKeyUsage,
  559.     SEC_OID_OCSP_RESPONDER) == 
  560.     SECSuccess) {
  561.     cert->nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER;
  562. }
  563.     } else {
  564. /* if no extension, then allow any ssl or email (no ca or object
  565.  * signing)
  566.  */
  567. cert->nsCertType = NS_CERT_TYPE_SSL_CLIENT | NS_CERT_TYPE_SSL_SERVER |
  568.     NS_CERT_TYPE_EMAIL;
  569.         /* if the basic constraint extension says the cert is a CA, then
  570.    allow SSL CA and EMAIL CA and Status Responder */
  571. if ((basicConstraintPresent == PR_TRUE)
  572.     && (basicConstraint.isCA)) {
  573.         cert->nsCertType |= NS_CERT_TYPE_SSL_CA;
  574.         cert->nsCertType |= NS_CERT_TYPE_EMAIL_CA;
  575. cert->nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER;
  576. } else if (CERT_IsCACert(cert, NULL) == PR_TRUE) {
  577. cert->nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER;
  578. }
  579. /* if the cert is a fortezza CA cert, then allow SSL CA and EMAIL CA */
  580. if (fortezzaIsCA(cert)) {
  581.         cert->nsCertType |= NS_CERT_TYPE_SSL_CA;
  582.         cert->nsCertType |= NS_CERT_TYPE_EMAIL_CA;
  583. }
  584.     }
  585.     if (extKeyUsage != NULL) {
  586. PORT_Free(encodedExtKeyUsage.data);
  587. CERT_DestroyOidSequence(extKeyUsage);
  588.     }
  589.     return(SECSuccess);
  590. }
  591. /*
  592.  * cert_GetKeyID() - extract or generate the subjectKeyID from a certificate
  593.  */
  594. SECStatus
  595. cert_GetKeyID(CERTCertificate *cert)
  596. {
  597.     SECItem tmpitem;
  598.     SECStatus rv;
  599.     SECKEYPublicKey *key;
  600.     
  601.     cert->subjectKeyID.len = 0;
  602.     /* see of the cert has a key identifier extension */
  603.     rv = CERT_FindSubjectKeyIDExten(cert, &tmpitem);
  604.     if ( rv == SECSuccess ) {
  605. cert->subjectKeyID.data = (unsigned char*) PORT_ArenaAlloc(cert->arena, tmpitem.len);
  606. if ( cert->subjectKeyID.data != NULL ) {
  607.     PORT_Memcpy(cert->subjectKeyID.data, tmpitem.data, tmpitem.len);
  608.     cert->subjectKeyID.len = tmpitem.len;
  609.     cert->keyIDGenerated = PR_FALSE;
  610. }
  611. PORT_Free(tmpitem.data);
  612.     }
  613.     
  614.     /* if the cert doesn't have a key identifier extension and the cert is
  615.      * a V1 fortezza certificate, use the cert's 8 byte KMID as the
  616.      * key identifier.  */
  617.     key = CERT_KMIDPublicKey(cert);
  618.     if (key != NULL) {
  619. if (key->keyType == fortezzaKey) {
  620.     cert->subjectKeyID.data = (unsigned char *)PORT_ArenaAlloc(cert->arena, 8);
  621.     if ( cert->subjectKeyID.data != NULL ) {
  622.         PORT_Memcpy(cert->subjectKeyID.data, key->u.fortezza.KMID, 8);
  623.         cert->subjectKeyID.len = 8;
  624.         cert->keyIDGenerated = PR_FALSE;
  625.     }
  626. }
  627. SECKEY_DestroyPublicKey(key);
  628.     }
  629.     /* if the cert doesn't have a key identifier extension, then generate one*/
  630.     if ( cert->subjectKeyID.len == 0 ) {
  631. /*
  632.  * pkix says that if the subjectKeyID is not present, then we should
  633.  * use the SHA-1 hash of the DER-encoded publicKeyInfo from the cert
  634.  */
  635. cert->subjectKeyID.data = (unsigned char *)PORT_ArenaAlloc(cert->arena, SHA1_LENGTH);
  636. if ( cert->subjectKeyID.data != NULL ) {
  637.     rv = SHA1_HashBuf(cert->subjectKeyID.data,
  638.       cert->derPublicKey.data,
  639.       cert->derPublicKey.len);
  640.     if ( rv == SECSuccess ) {
  641. cert->subjectKeyID.len = SHA1_LENGTH;
  642.     }
  643. }
  644.     }
  645.     if ( cert->subjectKeyID.len == 0 ) {
  646. return(SECFailure);
  647.     }
  648.     return(SECSuccess);
  649. }
  650. /*
  651.  * take a DER certificate and decode it into a certificate structure
  652.  */
  653. CERTCertificate *
  654. CERT_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER,
  655.  char *nickname)
  656. {
  657.     CERTCertificate *cert;
  658.     PRArenaPool *arena;
  659.     void *data;
  660.     int rv;
  661.     int len;
  662.     char *tmpname;
  663.     
  664.     /* make a new arena */
  665.     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  666.     
  667.     if ( !arena ) {
  668. return 0;
  669.     }
  670.     /* allocate the certificate structure */
  671.     cert = (CERTCertificate *)PORT_ArenaZAlloc(arena, sizeof(CERTCertificate));
  672.     
  673.     if ( !cert ) {
  674. goto loser;
  675.     }
  676.     
  677.     cert->arena = arena;
  678.     
  679.     if ( copyDER ) {
  680. /* copy the DER data for the cert into this arena */
  681. data = (void *)PORT_ArenaAlloc(arena, derSignedCert->len);
  682. if ( !data ) {
  683.     goto loser;
  684. }
  685. cert->derCert.data = (unsigned char *)data;
  686. cert->derCert.len = derSignedCert->len;
  687. PORT_Memcpy(data, derSignedCert->data, derSignedCert->len);
  688.     } else {
  689. /* point to passed in DER data */
  690. cert->derCert = *derSignedCert;
  691.     }
  692.     /* decode the certificate info */
  693.     rv = SEC_ASN1DecodeItem(arena, cert, SEC_SignedCertificateTemplate,
  694.     &cert->derCert);
  695.     if ( rv ) {
  696. goto loser;
  697.     }
  698.     if (cert_HasUnknownCriticalExten (cert->extensions) == PR_TRUE) {
  699. PORT_SetError(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION);
  700. goto loser;
  701.     }
  702.     /* generate and save the database key for the cert */
  703.     rv = CERT_KeyFromDERCert(arena, &cert->derCert, &cert->certKey);
  704.     if ( rv ) {
  705. goto loser;
  706.     }
  707.     /* set the nickname */
  708.     if ( nickname == NULL ) {
  709. cert->nickname = NULL;
  710.     } else {
  711. /* copy and install the nickname */
  712. len = PORT_Strlen(nickname) + 1;
  713. cert->nickname = (char*)PORT_ArenaAlloc(arena, len);
  714. if ( cert->nickname == NULL ) {
  715.     goto loser;
  716. }
  717. PORT_Memcpy(cert->nickname, nickname, len);
  718.     }
  719.     /* set the email address */
  720.     cert->emailAddr = CERT_GetCertificateEmailAddress(cert);
  721.     
  722.     /* initialize the subjectKeyID */
  723.     rv = cert_GetKeyID(cert);
  724.     if ( rv != SECSuccess ) {
  725. goto loser;
  726.     }
  727.     /* initialize keyUsage */
  728.     rv = GetKeyUsage(cert);
  729.     if ( rv != SECSuccess ) {
  730. goto loser;
  731.     }
  732.     /* initialize the certType */
  733.     rv = CERT_GetCertType(cert);
  734.     if ( rv != SECSuccess ) {
  735. goto loser;
  736.     }
  737.     tmpname = CERT_NameToAscii(&cert->subject);
  738.     if ( tmpname != NULL ) {
  739. cert->subjectName = PORT_ArenaStrdup(cert->arena, tmpname);
  740. PORT_Free(tmpname);
  741.     }
  742.     
  743.     tmpname = CERT_NameToAscii(&cert->issuer);
  744.     if ( tmpname != NULL ) {
  745. cert->issuerName = PORT_ArenaStrdup(cert->arena, tmpname);
  746. PORT_Free(tmpname);
  747.     }
  748.     
  749.     cert->referenceCount = 1;
  750.     cert->slot = NULL;
  751.     cert->pkcs11ID = CK_INVALID_KEY;
  752.     cert->dbnickname = NULL;
  753.     
  754.     return(cert);
  755.     
  756. loser:
  757.     if ( arena ) {
  758. PORT_FreeArena(arena, PR_FALSE);
  759.     }
  760.     
  761.     return(0);
  762. }
  763. /*
  764. ** Amount of time that a certifiate is allowed good before it is actually
  765. ** good. This is used for pending certificates, ones that are about to be
  766. ** valid. The slop is designed to allow for some variance in the clocks
  767. ** of the machine checking the certificate.
  768. */
  769. #define PENDING_SLOP (24L*60L*60L)
  770. SECStatus
  771. CERT_GetCertTimes(CERTCertificate *c, int64 *notBefore, int64 *notAfter)
  772. {
  773.     int rv;
  774.     
  775.     /* convert DER not-before time */
  776.     rv = DER_UTCTimeToTime(notBefore, &c->validity.notBefore);
  777.     if (rv) {
  778. return(SECFailure);
  779.     }
  780.     
  781.     /* convert DER not-after time */
  782.     rv = DER_UTCTimeToTime(notAfter, &c->validity.notAfter);
  783.     if (rv) {
  784. return(SECFailure);
  785.     }
  786.     return(SECSuccess);
  787. }
  788. /*
  789.  * Check the validity times of a certificate
  790.  */
  791. SECCertTimeValidity
  792. CERT_CheckCertValidTimes(CERTCertificate *c, int64 t, PRBool allowOverride)
  793. {
  794.     int64 notBefore, notAfter, pendingSlop;
  795.     SECStatus rv;
  796.     /* if cert is already marked OK, then don't bother to check */
  797.     if ( allowOverride && c->timeOK ) {
  798.         return(secCertTimeValid);
  799.     }
  800.     rv = CERT_GetCertTimes(c, &notBefore, &notAfter);
  801.     
  802.     if (rv) {
  803. return(secCertTimeExpired); /*XXX is this the right thing to do here?*/
  804.     }
  805.     
  806.     LL_I2L(pendingSlop, PENDING_SLOP);
  807.     LL_SUB(notBefore, notBefore, pendingSlop);
  808.     if ( LL_CMP( t, <, notBefore ) ) {
  809. PORT_SetError(SEC_ERROR_EXPIRED_CERTIFICATE);
  810. return(secCertTimeNotValidYet);
  811.     }
  812.     if ( LL_CMP( t, >, notAfter) ) {
  813. PORT_SetError(SEC_ERROR_EXPIRED_CERTIFICATE);
  814. return(secCertTimeExpired);
  815.     }
  816.     return(secCertTimeValid);
  817. }
  818. SECStatus
  819. SEC_GetCrlTimes(CERTCrl *date, int64 *notBefore, int64 *notAfter)
  820. {
  821.     int rv;
  822.     
  823.     /* convert DER not-before time */
  824.     rv = DER_UTCTimeToTime(notBefore, &date->lastUpdate);
  825.     if (rv) {
  826. return(SECFailure);
  827.     }
  828.     
  829.     /* convert DER not-after time */
  830.     if (date->nextUpdate.data) {
  831. rv = DER_UTCTimeToTime(notAfter, &date->nextUpdate);
  832. if (rv) {
  833.     return(SECFailure);
  834. }
  835.     }
  836.     else {
  837. LL_I2L(*notAfter, 0L);
  838.     }
  839.     return(SECSuccess);
  840. }
  841. /* These routines should probably be combined with the cert
  842.  * routines using an common extraction routine.
  843.  */
  844. SECCertTimeValidity
  845. SEC_CheckCrlTimes(CERTCrl *crl, int64 t) {
  846.     int64 notBefore, notAfter, pendingSlop;
  847.     SECStatus rv;
  848.     rv = SEC_GetCrlTimes(crl, &notBefore, &notAfter);
  849.     
  850.     if (rv) {
  851. return(secCertTimeExpired); 
  852.     }
  853.     LL_I2L(pendingSlop, PENDING_SLOP);
  854.     LL_SUB(notBefore, notBefore, pendingSlop);
  855.     if ( LL_CMP( t, <, notBefore ) ) {
  856. return(secCertTimeNotValidYet);
  857.     }
  858.     /* If next update is omitted and the test for notBefore passes, then
  859.        we assume that the crl is up to date.
  860.      */
  861.     if ( LL_IS_ZERO(notAfter) ) {
  862. return(secCertTimeValid);
  863.     }
  864.     if ( LL_CMP( t, >, notAfter) ) {
  865. return(secCertTimeExpired);
  866.     }
  867.     return(secCertTimeValid);
  868. }
  869. PRBool
  870. SEC_CrlIsNewer(CERTCrl *inNew, CERTCrl *old) {
  871.     int64 newNotBefore, newNotAfter;
  872.     int64 oldNotBefore, oldNotAfter;
  873.     SECStatus rv;
  874.     /* problems with the new CRL? reject it */
  875.     rv = SEC_GetCrlTimes(inNew, &newNotBefore, &newNotAfter);
  876.     if (rv) return PR_FALSE;
  877.     /* problems with the old CRL? replace it */
  878.     rv = SEC_GetCrlTimes(old, &oldNotBefore, &oldNotAfter);
  879.     if (rv) return PR_TRUE;
  880.     /* Question: what about the notAfter's? */
  881.     return ((PRBool)LL_CMP(oldNotBefore, <, newNotBefore));
  882. }
  883.    
  884. /*
  885.  * return required key usage and cert type based on cert usage 
  886.  */
  887. SECStatus
  888. CERT_KeyUsageAndTypeForCertUsage(SECCertUsage usage,
  889.  PRBool ca,
  890.  unsigned int *retKeyUsage,
  891.  unsigned int *retCertType)
  892. {
  893.     unsigned int requiredKeyUsage = 0;
  894.     unsigned int requiredCertType = 0;
  895.     
  896.     if ( ca ) {
  897. switch ( usage ) {
  898.   case certUsageSSLServerWithStepUp:
  899.     requiredKeyUsage = KU_NS_GOVT_APPROVED | KU_KEY_CERT_SIGN;
  900.     requiredCertType = NS_CERT_TYPE_SSL_CA;
  901.     break;
  902.   case certUsageSSLClient:
  903.     requiredKeyUsage = KU_KEY_CERT_SIGN;
  904.     requiredCertType = NS_CERT_TYPE_SSL_CA;
  905.     break;
  906.   case certUsageSSLServer:
  907.     requiredKeyUsage = KU_KEY_CERT_SIGN;
  908.     requiredCertType = NS_CERT_TYPE_SSL_CA;
  909.     break;
  910.   case certUsageSSLCA:
  911.     requiredKeyUsage = KU_KEY_CERT_SIGN;
  912.     requiredCertType = NS_CERT_TYPE_SSL_CA;
  913.     break;
  914.   case certUsageEmailSigner:
  915.     requiredKeyUsage = KU_KEY_CERT_SIGN;
  916.     requiredCertType = NS_CERT_TYPE_EMAIL_CA;
  917.     break;
  918.   case certUsageEmailRecipient:
  919.     requiredKeyUsage = KU_KEY_CERT_SIGN;
  920.     requiredCertType = NS_CERT_TYPE_EMAIL_CA;
  921.     break;
  922.   case certUsageObjectSigner:
  923.     requiredKeyUsage = KU_KEY_CERT_SIGN;
  924.     requiredCertType = NS_CERT_TYPE_OBJECT_SIGNING_CA;
  925.     break;
  926.   case certUsageAnyCA:
  927.   case certUsageStatusResponder:
  928.     requiredKeyUsage = KU_KEY_CERT_SIGN;
  929.     requiredCertType = NS_CERT_TYPE_OBJECT_SIGNING_CA |
  930. NS_CERT_TYPE_EMAIL_CA |
  931.     NS_CERT_TYPE_SSL_CA;
  932.     break;
  933.   default:
  934.     PORT_Assert(0);
  935.     goto loser;
  936. }
  937.     } else {
  938. switch ( usage ) {
  939.   case certUsageSSLClient:
  940.     requiredKeyUsage = KU_DIGITAL_SIGNATURE;
  941.     requiredCertType = NS_CERT_TYPE_SSL_CLIENT;
  942.     break;
  943.   case certUsageSSLServer:
  944.     requiredKeyUsage = KU_KEY_AGREEMENT_OR_ENCIPHERMENT;
  945.     requiredCertType = NS_CERT_TYPE_SSL_SERVER;
  946.     break;
  947.   case certUsageSSLServerWithStepUp:
  948.     requiredKeyUsage = KU_KEY_AGREEMENT_OR_ENCIPHERMENT |
  949. KU_NS_GOVT_APPROVED;
  950.     requiredCertType = NS_CERT_TYPE_SSL_SERVER;
  951.     break;
  952.   case certUsageSSLCA:
  953.     requiredKeyUsage = KU_KEY_CERT_SIGN;
  954.     requiredCertType = NS_CERT_TYPE_SSL_CA;
  955.     break;
  956.   case certUsageEmailSigner:
  957.     requiredKeyUsage = KU_DIGITAL_SIGNATURE;
  958.     requiredCertType = NS_CERT_TYPE_EMAIL;
  959.     break;
  960.   case certUsageEmailRecipient:
  961.     requiredKeyUsage = KU_KEY_AGREEMENT_OR_ENCIPHERMENT;
  962.     requiredCertType = NS_CERT_TYPE_EMAIL;
  963.     break;
  964.   case certUsageObjectSigner:
  965.     requiredKeyUsage = KU_DIGITAL_SIGNATURE;
  966.     requiredCertType = NS_CERT_TYPE_OBJECT_SIGNING;
  967.     break;
  968.   case certUsageStatusResponder:
  969.     requiredKeyUsage = KU_DIGITAL_SIGNATURE;
  970.     requiredCertType = EXT_KEY_USAGE_STATUS_RESPONDER;
  971.     break;
  972.   default:
  973.     PORT_Assert(0);
  974.     goto loser;
  975. }
  976.     }
  977.     if ( retKeyUsage != NULL ) {
  978. *retKeyUsage = requiredKeyUsage;
  979.     }
  980.     if ( retCertType != NULL ) {
  981. *retCertType = requiredCertType;
  982.     }
  983.     return(SECSuccess);
  984. loser:
  985.     return(SECFailure);
  986. }
  987. /*
  988.  * check the key usage of a cert against a set of required values
  989.  */
  990. SECStatus
  991. CERT_CheckKeyUsage(CERTCertificate *cert, unsigned int requiredUsage)
  992. {
  993.     SECKEYPublicKey *key;
  994.     
  995.     /* choose between key agreement or key encipherment based on key
  996.      * type in cert
  997.      */
  998.     if ( requiredUsage & KU_KEY_AGREEMENT_OR_ENCIPHERMENT ) {
  999. key = CERT_ExtractPublicKey(cert);
  1000. if ( ( key->keyType == keaKey ) || ( key->keyType == fortezzaKey ) ||
  1001.      ( key->keyType == dhKey ) ) {
  1002.     requiredUsage |= KU_KEY_AGREEMENT;
  1003. } else {
  1004.     requiredUsage |= KU_KEY_ENCIPHERMENT;
  1005. /* now turn off the special bit */
  1006. requiredUsage &= (~KU_KEY_AGREEMENT_OR_ENCIPHERMENT);
  1007. SECKEY_DestroyPublicKey(key);
  1008.     }
  1009.     if ( ( cert->keyUsage & requiredUsage ) != requiredUsage ) {
  1010. return(SECFailure);
  1011.     }
  1012.     return(SECSuccess);
  1013. }
  1014. CERTCertificate *
  1015. CERT_DupCertificate(CERTCertificate *c)
  1016. {
  1017.     if (c) {
  1018. CERT_LockCertRefCount(c);
  1019. ++c->referenceCount;
  1020. CERT_UnlockCertRefCount(c);
  1021.     }
  1022.     return c;
  1023. }
  1024. /*
  1025.  * Allow use of default cert database, so that apps(such as mozilla) don't
  1026.  * have to pass the handle all over the place.
  1027.  */
  1028. static CERTCertDBHandle *default_cert_db_handle = 0;
  1029. void
  1030. CERT_SetDefaultCertDB(CERTCertDBHandle *handle)
  1031. {
  1032.     default_cert_db_handle = handle;
  1033.     
  1034.     return;
  1035. }
  1036. CERTCertDBHandle *
  1037. CERT_GetDefaultCertDB(void)
  1038. {
  1039.     return(default_cert_db_handle);
  1040. }
  1041. /*
  1042.  * Open volatile certificate database and index databases.  This is a
  1043.  * fallback if the real databases can't be opened or created.  It is only
  1044.  * resident in memory, so it will not be persistent.  We do this so that
  1045.  * we don't crash if the databases can't be created.
  1046.  */
  1047. SECStatus
  1048. CERT_OpenVolatileCertDB(CERTCertDBHandle *handle)
  1049. {
  1050.     /*
  1051.      * Open the memory resident perm cert database.
  1052.      */
  1053.     handle->permCertDB = dbopen( 0, O_RDWR | O_CREAT, 0600, DB_HASH, 0 );
  1054.     if ( !handle->permCertDB ) {
  1055. goto loser;
  1056.     }
  1057.     /*
  1058.      * Open the memory resident decoded cert database.
  1059.      */
  1060.     handle->tempCertDB = dbopen( 0, O_RDWR | O_CREAT, 0600, DB_HASH, 0 );
  1061.     if ( !handle->tempCertDB ) {
  1062. goto loser;
  1063.     }
  1064.     handle->dbMon = PR_NewMonitor();
  1065.     PORT_Assert(handle->dbMon != NULL);
  1066.     handle->spkDigestInfo = NULL;
  1067.     handle->statusConfig = NULL;
  1068.     /* initialize the cert database */
  1069.     (void) CERT_InitCertDB(handle);
  1070.     return (SECSuccess);
  1071.     
  1072. loser:
  1073.     PORT_SetError(SEC_ERROR_BAD_DATABASE);
  1074.     if ( handle->permCertDB ) {
  1075. (* handle->permCertDB->close)(handle->permCertDB);
  1076. handle->permCertDB = 0;
  1077.     }
  1078.     if ( handle->tempCertDB ) {
  1079. (* handle->tempCertDB->close)(handle->tempCertDB);
  1080. handle->tempCertDB = 0;
  1081.     }
  1082.     return(SECFailure);
  1083. }
  1084. /* XXX this would probably be okay/better as an xp routine? */
  1085. static void
  1086. sec_lower_string(char *s)
  1087. {
  1088.     if ( s == NULL ) {
  1089. return;
  1090.     }
  1091.     
  1092.     while ( *s ) {
  1093. *s = PORT_Tolower(*s);
  1094. s++;
  1095.     }
  1096.     
  1097.     return;
  1098. }
  1099. /*
  1100. ** Add a domain name to the list of names that the user has explicitly
  1101. ** allowed (despite cert name mismatches) for use with a server cert.
  1102. */
  1103. SECStatus
  1104. CERT_AddOKDomainName(CERTCertificate *cert, const char *hn)
  1105. {
  1106.     CERTOKDomainName *domainOK;
  1107.     int               newNameLen;
  1108.     if (!hn || !(newNameLen = strlen(hn))) {
  1109.      PORT_SetError(SEC_ERROR_INVALID_ARGS);
  1110. return SECFailure;
  1111.     }
  1112.     domainOK = (CERTOKDomainName *)PORT_ArenaZAlloc(cert->arena, 
  1113.                                   (sizeof *domainOK) + newNameLen);
  1114.     if (!domainOK) 
  1115.      return SECFailure; /* error code is already set. */
  1116.     PORT_Strcpy(domainOK->name, hn);
  1117.     sec_lower_string(domainOK->name);
  1118.     /* put at head of list. */
  1119.     domainOK->next = cert->domainOK;
  1120.     cert->domainOK = domainOK;
  1121.     return SECSuccess;
  1122. }
  1123. /* Make sure that the name of the host we are connecting to matches the
  1124.  * name that is incoded in the common-name component of the certificate
  1125.  * that they are using.
  1126.  */
  1127. SECStatus
  1128. CERT_VerifyCertName(CERTCertificate *cert, const char *hn)
  1129. {
  1130.     char *    cn;
  1131.     char *    domain;
  1132.     char *    hndomain;
  1133.     char *    hostname;
  1134.     int       regvalid;
  1135.     int       match;
  1136.     SECStatus rv;
  1137.     CERTOKDomainName *domainOK;
  1138.     if (!hn || !strlen(hn)) {
  1139.      PORT_SetError(SEC_ERROR_INVALID_ARGS);
  1140. return SECFailure;
  1141.     }
  1142.     hostname = PORT_Strdup(hn);
  1143.     if ( hostname == NULL ) {
  1144. return(SECFailure);
  1145.     }
  1146.     sec_lower_string(hostname);
  1147.     /* if the name is one that the user has already approved, it's OK. */
  1148.     for (domainOK = cert->domainOK; domainOK; domainOK = domainOK->next) {
  1149. if (0 == PORT_Strcmp(hostname, domainOK->name)) {
  1150.     PORT_Free(hostname);
  1151.     return SECSuccess;
  1152.      }
  1153.     }
  1154.     /* try the cert extension first, then the common name */
  1155.     cn = CERT_FindNSStringExtension(cert, SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME);
  1156.     if ( cn == NULL ) {
  1157. cn = CERT_GetCommonName(&cert->subject);
  1158.     }
  1159.     
  1160.     sec_lower_string(cn);
  1161.     if ( cn ) {
  1162. if ( ( hndomain = PORT_Strchr(hostname, '.') ) == NULL ) {
  1163.     /* No domain in server name */
  1164.     if ( ( domain = PORT_Strchr(cn, '.') ) != NULL ) {
  1165. /* there is a domain in the cn string, so chop it off */
  1166. *domain = '';
  1167.     }
  1168. }
  1169. regvalid = PORT_RegExpValid(cn);
  1170. if ( regvalid == NON_SXP ) {
  1171.     /* compare entire hostname with cert name */
  1172.     if ( PORT_Strcmp(hostname, cn) == 0 ) {
  1173. rv = SECSuccess;
  1174. goto done;
  1175.     }
  1176.     
  1177.     if ( hndomain ) {
  1178. /* compare just domain name with cert name */
  1179. if ( PORT_Strcmp(hndomain+1, cn) == 0 ) {
  1180.     rv = SECSuccess;
  1181.     goto done;
  1182. }
  1183.     }
  1184.     PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
  1185.     rv = SECFailure;
  1186.     goto done;
  1187.     
  1188. } else {
  1189.     /* try to match the shexp */
  1190.     match = PORT_RegExpCaseSearch(hostname, cn);
  1191.     if ( match == 0 ) {
  1192. rv = SECSuccess;
  1193.     } else {
  1194. PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
  1195. rv = SECFailure;
  1196.     }
  1197.     goto done;
  1198. }
  1199.     }
  1200.     PORT_SetError(SEC_ERROR_NO_MEMORY);
  1201.     rv = SECFailure;
  1202. done:
  1203.     /* free the common name */
  1204.     if ( cn ) {
  1205. PORT_Free(cn);
  1206.     }
  1207.     
  1208.     if ( hostname ) {
  1209. PORT_Free(hostname);
  1210.     }
  1211.     
  1212.     return(rv);
  1213. }
  1214. PRBool
  1215. CERT_CompareCerts(CERTCertificate *c1, CERTCertificate *c2)
  1216. {
  1217.     SECComparison comp;
  1218.     
  1219.     comp = SECITEM_CompareItem(&c1->derCert, &c2->derCert);
  1220.     if ( comp == SECEqual ) { /* certs are the same */
  1221. return(PR_TRUE);
  1222.     } else {
  1223. return(PR_FALSE);
  1224.     }
  1225. }
  1226. static SECStatus
  1227. StringsEqual(char *s1, char *s2) {
  1228.     if ( ( s1 == NULL ) || ( s2 == NULL ) ) {
  1229. if ( s1 != s2 ) { /* only one is null */
  1230.     return(SECFailure);
  1231. }
  1232. return(SECSuccess); /* both are null */
  1233.     }
  1234.     if ( PORT_Strcmp( s1, s2 ) != 0 ) {
  1235. return(SECFailure); /* not equal */
  1236.     }
  1237.     return(SECSuccess); /* strings are equal */
  1238. }
  1239. PRBool
  1240. CERT_CompareCertsForRedirection(CERTCertificate *c1, CERTCertificate *c2)
  1241. {
  1242.     SECComparison comp;
  1243.     char *c1str, *c2str;
  1244.     SECStatus eq;
  1245.     
  1246.     comp = SECITEM_CompareItem(&c1->derCert, &c2->derCert);
  1247.     if ( comp == SECEqual ) { /* certs are the same */
  1248. return(PR_TRUE);
  1249.     }
  1250.     /* check if they are issued by the same CA */
  1251.     comp = SECITEM_CompareItem(&c1->derIssuer, &c2->derIssuer);
  1252.     if ( comp != SECEqual ) { /* different issuer */
  1253. return(PR_FALSE);
  1254.     }
  1255.     /* check country name */
  1256.     c1str = CERT_GetCountryName(&c1->subject);
  1257.     c2str = CERT_GetCountryName(&c2->subject);
  1258.     eq = StringsEqual(c1str, c2str);
  1259.     PORT_Free(c1str);
  1260.     PORT_Free(c2str);
  1261.     if ( eq != SECSuccess ) {
  1262. return(PR_FALSE);
  1263.     }
  1264.     /* check locality name */
  1265.     c1str = CERT_GetLocalityName(&c1->subject);
  1266.     c2str = CERT_GetLocalityName(&c2->subject);
  1267.     eq = StringsEqual(c1str, c2str);
  1268.     PORT_Free(c1str);
  1269.     PORT_Free(c2str);
  1270.     if ( eq != SECSuccess ) {
  1271. return(PR_FALSE);
  1272.     }
  1273.     /* check state name */
  1274.     c1str = CERT_GetStateName(&c1->subject);
  1275.     c2str = CERT_GetStateName(&c2->subject);
  1276.     eq = StringsEqual(c1str, c2str);
  1277.     PORT_Free(c1str);
  1278.     PORT_Free(c2str);
  1279.     if ( eq != SECSuccess ) {
  1280. return(PR_FALSE);
  1281.     }
  1282.     /* check org name */
  1283.     c1str = CERT_GetOrgName(&c1->subject);
  1284.     c2str = CERT_GetOrgName(&c2->subject);
  1285.     eq = StringsEqual(c1str, c2str);
  1286.     PORT_Free(c1str);
  1287.     PORT_Free(c2str);
  1288.     if ( eq != SECSuccess ) {
  1289. return(PR_FALSE);
  1290.     }
  1291. #ifdef NOTDEF
  1292.     /* check orgUnit name */
  1293.     /*
  1294.      * We need to revisit this and decide which fields should be allowed to be
  1295.      * different
  1296.      */
  1297.     c1str = CERT_GetOrgUnitName(&c1->subject);
  1298.     c2str = CERT_GetOrgUnitName(&c2->subject);
  1299.     eq = StringsEqual(c1str, c2str);
  1300.     PORT_Free(c1str);
  1301.     PORT_Free(c2str);
  1302.     if ( eq != SECSuccess ) {
  1303. return(PR_FALSE);
  1304.     }
  1305. #endif
  1306.     return(PR_TRUE); /* all fields but common name are the same */
  1307. }
  1308. /* CERT_CertChainFromCert and CERT_DestroyCertificateList moved
  1309.    to certhigh.c */
  1310. CERTIssuerAndSN *
  1311. CERT_GetCertIssuerAndSN(PRArenaPool *arena, CERTCertificate *cert)
  1312. {
  1313.     CERTIssuerAndSN *result;
  1314.     SECStatus rv;
  1315.     if ( arena == NULL ) {
  1316. arena = cert->arena;
  1317.     }
  1318.     
  1319.     result = (CERTIssuerAndSN*)PORT_ArenaZAlloc(arena, sizeof(*result));
  1320.     if (result == NULL) {
  1321. PORT_SetError (SEC_ERROR_NO_MEMORY);
  1322. return NULL;
  1323.     }
  1324.     rv = SECITEM_CopyItem(arena, &result->derIssuer, &cert->derIssuer);
  1325.     if (rv != SECSuccess)
  1326. return NULL;
  1327.     rv = CERT_CopyName(arena, &result->issuer, &cert->issuer);
  1328.     if (rv != SECSuccess)
  1329. return NULL;
  1330.     rv = SECITEM_CopyItem(arena, &result->serialNumber, &cert->serialNumber);
  1331.     if (rv != SECSuccess)
  1332. return NULL;
  1333.     return result;
  1334. }
  1335. char *
  1336. CERT_MakeCANickname(CERTCertificate *cert)
  1337. {
  1338.     char *firstname = NULL;
  1339.     char *org = NULL;
  1340.     char *nickname = NULL;
  1341.     int count;
  1342.     CERTCertificate *dummycert;
  1343.     CERTCertDBHandle *handle;
  1344.     
  1345.     handle = cert->dbhandle;
  1346.     
  1347.     nickname = CERT_GetNickName(cert, handle, cert->arena);
  1348.     if (nickname == NULL) {
  1349. firstname = CERT_GetCommonName(&cert->subject);
  1350. if ( firstname == NULL ) {
  1351.     firstname = CERT_GetOrgUnitName(&cert->subject);
  1352. }
  1353. org = CERT_GetOrgName(&cert->issuer);
  1354. if ( org == NULL ) {
  1355.     goto loser;
  1356. }
  1357.     
  1358. count = 1;
  1359. while ( 1 ) {
  1360.     if ( firstname ) {
  1361. if ( count == 1 ) {
  1362.     nickname = PR_smprintf("%s - %s", firstname, org);
  1363. } else {
  1364.     nickname = PR_smprintf("%s - %s #%d", firstname, org, count);
  1365. }
  1366.     } else {
  1367. if ( count == 1 ) {
  1368.     nickname = PR_smprintf("%s", org);
  1369. } else {
  1370.     nickname = PR_smprintf("%s #%d", org, count);
  1371. }
  1372.     }
  1373.     if ( nickname == NULL ) {
  1374. goto loser;
  1375.     }
  1376.     /* look up the nickname to make sure it isn't in use already */
  1377.     dummycert = CERT_FindCertByNickname(handle, nickname);
  1378.     if ( dummycert == NULL ) {
  1379. goto done;
  1380.     }
  1381.     /* found a cert, destroy it and loop */
  1382.     CERT_DestroyCertificate(dummycert);
  1383.     /* free the nickname */
  1384.     PORT_Free(nickname);
  1385.     count++;
  1386. }
  1387.     }
  1388. loser:
  1389.     if ( nickname ) {
  1390. PORT_Free(nickname);
  1391.     }
  1392.     nickname = "";
  1393.     
  1394. done:
  1395.     if ( firstname ) {
  1396. PORT_Free(firstname);
  1397.     }
  1398.     if ( org ) {
  1399. PORT_Free(org);
  1400.     }
  1401.     
  1402.     return(nickname);
  1403. }
  1404. /* CERT_Import_CAChain moved to certhigh.c */
  1405. void
  1406. CERT_DestroyCrl (CERTSignedCrl *crl)
  1407. {
  1408.     SEC_DestroyCrl (crl);
  1409. }
  1410. /*
  1411.  * Does a cert belong to a CA?  We decide based on perm database trust
  1412.  * flags, Netscape Cert Type Extension, and KeyUsage Extension.
  1413.  */
  1414. PRBool
  1415. CERT_IsCACert(CERTCertificate *cert, unsigned int *rettype)
  1416. {
  1417.     CERTCertTrust *trust;
  1418.     SECStatus rv;
  1419.     unsigned int type;
  1420.     PRBool ret;
  1421.     ret = PR_FALSE;
  1422.     type = 0;
  1423.     
  1424.     if ( cert->isperm ) {
  1425. trust = cert->trust;
  1426. if ( ( trust->sslFlags & CERTDB_VALID_CA ) == CERTDB_VALID_CA ) {
  1427.     ret = PR_TRUE;
  1428.     type |= NS_CERT_TYPE_SSL_CA;
  1429. }
  1430. if ( ( trust->emailFlags & CERTDB_VALID_CA ) == CERTDB_VALID_CA ) {
  1431.     ret = PR_TRUE;
  1432.     type |= NS_CERT_TYPE_EMAIL_CA;
  1433. }
  1434. if ( ( trust->objectSigningFlags & CERTDB_VALID_CA ) ==
  1435.     CERTDB_VALID_CA ) {
  1436.     ret = PR_TRUE;
  1437.     type |= NS_CERT_TYPE_OBJECT_SIGNING_CA;
  1438. }
  1439.     } else {
  1440. if ( cert->nsCertType &
  1441.     ( NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA |
  1442.      NS_CERT_TYPE_OBJECT_SIGNING_CA ) ) {
  1443.     ret = PR_TRUE;
  1444.     type = (cert->nsCertType & NS_CERT_TYPE_CA);
  1445. } else {
  1446.     CERTBasicConstraints constraints;
  1447.     rv = CERT_FindBasicConstraintExten(cert, &constraints);
  1448.     if ( rv == SECSuccess ) {
  1449. if ( constraints.isCA ) {
  1450.     ret = PR_TRUE;
  1451.     type = (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA);
  1452. }
  1453.     } 
  1454. /* finally check if it's a FORTEZZA V1 CA */
  1455. if (ret == PR_FALSE) {
  1456.     if (fortezzaIsCA(cert)) {
  1457. ret = PR_TRUE;
  1458. type = (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA);
  1459.     }
  1460. }
  1461.     }
  1462.     if ( rettype != NULL ) {
  1463. *rettype = type;
  1464.     }
  1465.     
  1466.     return(ret);
  1467. }
  1468. /*
  1469.  * is certa newer than certb?  If one is expired, pick the other one.
  1470.  */
  1471. PRBool
  1472. CERT_IsNewer(CERTCertificate *certa, CERTCertificate *certb)
  1473. {
  1474.     int64 notBeforeA, notAfterA, notBeforeB, notAfterB, now;
  1475.     SECStatus rv;
  1476.     PRBool newerbefore, newerafter;
  1477.     
  1478.     rv = CERT_GetCertTimes(certa, &notBeforeA, &notAfterA);
  1479.     if ( rv != SECSuccess ) {
  1480. return(PR_FALSE);
  1481.     }
  1482.     
  1483.     rv = CERT_GetCertTimes(certb, &notBeforeB, &notAfterB);
  1484.     if ( rv != SECSuccess ) {
  1485. return(PR_TRUE);
  1486.     }
  1487.     newerbefore = PR_FALSE;
  1488.     if ( LL_CMP(notBeforeA, >, notBeforeB) ) {
  1489. newerbefore = PR_TRUE;
  1490.     }
  1491.     newerafter = PR_FALSE;
  1492.     if ( LL_CMP(notAfterA, >, notAfterB) ) {
  1493. newerafter = PR_TRUE;
  1494.     }
  1495.     
  1496.     if ( newerbefore && newerafter ) {
  1497. return(PR_TRUE);
  1498.     }
  1499.     
  1500.     if ( ( !newerbefore ) && ( !newerafter ) ) {
  1501. return(PR_FALSE);
  1502.     }
  1503.     /* get current UTC time */
  1504.     now = PR_Now();
  1505.     if ( newerbefore ) {
  1506. /* cert A was issued after cert B, but expires sooner */
  1507. /* if A is expired, then pick B */
  1508. if ( LL_CMP(notAfterA, <, now ) ) {
  1509.     return(PR_FALSE);
  1510. }
  1511. return(PR_TRUE);
  1512.     } else {
  1513. /* cert B was issued after cert A, but expires sooner */
  1514. /* if B is expired, then pick A */
  1515. if ( LL_CMP(notAfterB, <, now ) ) {
  1516.     return(PR_TRUE);
  1517. }
  1518. return(PR_FALSE);
  1519.     }
  1520. }
  1521. void
  1522. CERT_DestroyCertArray(CERTCertificate **certs, unsigned int ncerts)
  1523. {
  1524.     unsigned int i;
  1525.     
  1526.     if ( certs ) {
  1527. for ( i = 0; i < ncerts; i++ ) {
  1528.     if ( certs[i] ) {
  1529. CERT_DestroyCertificate(certs[i]);
  1530.     }
  1531. }
  1532. PORT_Free(certs);
  1533.     }
  1534.     
  1535.     return;
  1536. }
  1537. char *
  1538. CERT_FixupEmailAddr(char *emailAddr)
  1539. {
  1540.     char *retaddr;
  1541.     char *str;
  1542.     if ( emailAddr == NULL ) {
  1543. return(NULL);
  1544.     }
  1545.     
  1546.     /* copy the string */
  1547.     str = retaddr = PORT_Strdup(emailAddr);
  1548.     if ( str == NULL ) {
  1549. return(NULL);
  1550.     }
  1551.     
  1552.     /* make it lower case */
  1553.     while ( *str ) {
  1554. *str = tolower( *str );
  1555. str++;
  1556.     }
  1557.     
  1558.     return(retaddr);
  1559. }
  1560. /*
  1561.  * NOTE - don't allow encode of govt-approved or invisible bits
  1562.  */
  1563. SECStatus
  1564. CERT_DecodeTrustString(CERTCertTrust *trust, char *trusts)
  1565. {
  1566.     int i;
  1567.     unsigned int *pflags;
  1568.     
  1569.     trust->sslFlags = 0;
  1570.     trust->emailFlags = 0;
  1571.     trust->objectSigningFlags = 0;
  1572.     pflags = &trust->sslFlags;
  1573.     
  1574.     for (i=0; i < PORT_Strlen(trusts); i++) {
  1575. switch (trusts[i]) {
  1576.   case 'p':
  1577.       *pflags = *pflags | CERTDB_VALID_PEER;
  1578.       break;
  1579.   case 'P':
  1580.       *pflags = *pflags | CERTDB_TRUSTED | CERTDB_VALID_PEER;
  1581.       break;
  1582.   case 'w':
  1583.       *pflags = *pflags | CERTDB_SEND_WARN;
  1584.       break;
  1585.   case 'c':
  1586.       *pflags = *pflags | CERTDB_VALID_CA;
  1587.       break;
  1588.   case 'T':
  1589.       *pflags = *pflags | CERTDB_TRUSTED_CLIENT_CA | CERTDB_VALID_CA;
  1590.       break;
  1591.   case 'C' :
  1592.       *pflags = *pflags | CERTDB_TRUSTED_CA | CERTDB_VALID_CA;
  1593.       break;
  1594.   case 'u':
  1595.       *pflags = *pflags | CERTDB_USER;
  1596.       break;
  1597. #ifdef DEBUG_NSSTEAM_ONLY
  1598.   case 'i':
  1599.       *pflags = *pflags | CERTDB_INVISIBLE_CA;
  1600.       break;
  1601.   case 'g':
  1602.       *pflags = *pflags | CERTDB_GOVT_APPROVED_CA;
  1603.       break;
  1604. #endif /* DEBUG_NSSTEAM_ONLY */
  1605.   case ',':
  1606.       if ( pflags == &trust->sslFlags ) {
  1607.   pflags = &trust->emailFlags;
  1608.       } else {
  1609.   pflags = &trust->objectSigningFlags;
  1610.       }
  1611.       break;
  1612.   default:
  1613.       return SECFailure;
  1614. }
  1615.     }
  1616.     return SECSuccess;
  1617. }
  1618. static void
  1619. EncodeFlags(char *trusts, unsigned int flags)
  1620. {
  1621.     if (flags & CERTDB_VALID_CA)
  1622. if (!(flags & CERTDB_TRUSTED_CA) &&
  1623.     !(flags & CERTDB_TRUSTED_CLIENT_CA))
  1624.     PORT_Strcat(trusts, "c");
  1625.     if (flags & CERTDB_VALID_PEER)
  1626. if (!(flags & CERTDB_TRUSTED))
  1627.     PORT_Strcat(trusts, "p");
  1628.     if (flags & CERTDB_TRUSTED_CA)
  1629. PORT_Strcat(trusts, "C");
  1630.     if (flags & CERTDB_TRUSTED_CLIENT_CA)
  1631. PORT_Strcat(trusts, "T");
  1632.     if (flags & CERTDB_TRUSTED)
  1633. PORT_Strcat(trusts, "P");
  1634.     if (flags & CERTDB_USER)
  1635. PORT_Strcat(trusts, "u");
  1636.     if (flags & CERTDB_SEND_WARN)
  1637. PORT_Strcat(trusts, "w");
  1638.     if (flags & CERTDB_INVISIBLE_CA)
  1639. PORT_Strcat(trusts, "I");
  1640.     if (flags & CERTDB_GOVT_APPROVED_CA)
  1641. PORT_Strcat(trusts, "G");
  1642.     return;
  1643. }
  1644. char *
  1645. CERT_EncodeTrustString(CERTCertTrust *trust)
  1646. {
  1647.     char tmpTrustSSL[32];
  1648.     char tmpTrustEmail[32];
  1649.     char tmpTrustSigning[32];
  1650.     char *retstr = NULL;
  1651.     if ( trust ) {
  1652. tmpTrustSSL[0] = '';
  1653. tmpTrustEmail[0] = '';
  1654. tmpTrustSigning[0] = '';
  1655.     
  1656. EncodeFlags(tmpTrustSSL, trust->sslFlags);
  1657. EncodeFlags(tmpTrustEmail, trust->emailFlags);
  1658. EncodeFlags(tmpTrustSigning, trust->objectSigningFlags);
  1659.     
  1660. retstr = PR_smprintf("%s,%s,%s", tmpTrustSSL, tmpTrustEmail,
  1661.      tmpTrustSigning);
  1662.     }
  1663.     
  1664.     return(retstr);
  1665. }
  1666. SECStatus
  1667. CERT_ImportCerts(CERTCertDBHandle *certdb, SECCertUsage usage,
  1668.  unsigned int ncerts, SECItem **derCerts,
  1669.  CERTCertificate ***retCerts, PRBool keepCerts,
  1670.  PRBool caOnly, char *nickname)
  1671. {
  1672.     int i;
  1673.     CERTCertificate **certs = NULL;
  1674.     SECStatus rv;
  1675.     int fcerts;
  1676.     if ( ncerts ) {
  1677. certs = (CERTCertificate**)PORT_ZAlloc(sizeof(CERTCertificate *) * ncerts );
  1678. if ( certs == NULL ) {
  1679.     return(SECFailure);
  1680. }
  1681.     
  1682. /* decode all of the certs into the temporary DB */
  1683. for ( i = 0, fcerts= 0; i < ncerts; i++) {
  1684.     certs[fcerts] = CERT_NewTempCertificate(certdb, derCerts[i], NULL,
  1685.        PR_FALSE, PR_TRUE);
  1686.     if (certs[fcerts]) fcerts++;
  1687. }
  1688. if ( keepCerts ) {
  1689.     for ( i = 0; i < fcerts; i++ ) {
  1690. SECKEY_UpdateCertPQG(certs[i]);
  1691. if(CERT_IsCACert(certs[i], NULL) && (fcerts > 1)) {
  1692.     /* if we are importing only a single cert and specifying
  1693.      * a nickname, we want to use that nickname if it a CA,
  1694.      * otherwise if there are more than one cert, we don't
  1695.      * know which cert it belongs to.
  1696.      */
  1697.     rv = CERT_SaveImportedCert(certs[i], usage, caOnly, NULL);
  1698. } else {
  1699.     rv = CERT_SaveImportedCert(certs[i], usage, caOnly, 
  1700.                         nickname);
  1701. }
  1702. /* don't care if it fails - keep going */
  1703.     }
  1704. }
  1705.     }
  1706.     if ( retCerts ) {
  1707. *retCerts = certs;
  1708.     } else {
  1709. CERT_DestroyCertArray(certs, fcerts);
  1710.     }
  1711.     return(SECSuccess);
  1712.     
  1713. #if 0 /* dead code here - why ?? XXX */
  1714. loser:
  1715.     if ( retCerts ) {
  1716. *retCerts = NULL;
  1717.     }
  1718.     if ( certs ) {
  1719. CERT_DestroyCertArray(certs, ncerts);
  1720.     }    
  1721.     return(SECFailure);
  1722. #endif
  1723. }
  1724. /*
  1725.  * a real list of certificates - need to convert CERTCertificateList
  1726.  * stuff and ASN 1 encoder/decoder over to using this...
  1727.  */
  1728. CERTCertList *
  1729. CERT_NewCertList(void)
  1730. {
  1731.     PRArenaPool *arena = NULL;
  1732.     CERTCertList *ret = NULL;
  1733.     
  1734.     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  1735.     if ( arena == NULL ) {
  1736. goto loser;
  1737.     }
  1738.     
  1739.     ret = (CERTCertList *)PORT_ArenaZAlloc(arena, sizeof(CERTCertList));
  1740.     if ( ret == NULL ) {
  1741. goto loser;
  1742.     }
  1743.     
  1744.     ret->arena = arena;
  1745.     
  1746.     PR_INIT_CLIST(&ret->list);
  1747.     
  1748.     return(ret);
  1749. loser:
  1750.     if ( arena != NULL ) {
  1751. PORT_FreeArena(arena, PR_FALSE);
  1752.     }
  1753.     
  1754.     return(NULL);
  1755. }
  1756. void
  1757. CERT_DestroyCertList(CERTCertList *certs)
  1758. {
  1759.     PRCList *node;
  1760.     while( !PR_CLIST_IS_EMPTY(&certs->list) ) {
  1761. node = PR_LIST_HEAD(&certs->list);
  1762. CERT_DestroyCertificate(((CERTCertListNode *)node)->cert);
  1763. PR_REMOVE_LINK(node);
  1764.     }
  1765.     
  1766.     PORT_FreeArena(certs->arena, PR_FALSE);
  1767.     
  1768.     return;
  1769. }
  1770. void
  1771. CERT_RemoveCertListNode(CERTCertListNode *node)
  1772. {
  1773.     CERT_DestroyCertificate(node->cert);
  1774.     PR_REMOVE_LINK(&node->links);
  1775.     return;
  1776. }
  1777. SECStatus
  1778. CERT_AddCertToListTail(CERTCertList *certs, CERTCertificate *cert)
  1779. {
  1780.     CERTCertListNode *node;
  1781.     
  1782.     node = (CERTCertListNode *)PORT_ArenaZAlloc(certs->arena,
  1783. sizeof(CERTCertListNode));
  1784.     if ( node == NULL ) {
  1785. goto loser;
  1786.     }
  1787.     
  1788.     PR_INSERT_BEFORE(&node->links, &certs->list);
  1789.     /* certs->count++; */
  1790.     node->cert = cert;
  1791.     return(SECSuccess);
  1792.     
  1793. loser:
  1794.     return(SECFailure);
  1795. }
  1796. /*
  1797.  * Sort callback function to determine if cert a is newer than cert b.
  1798.  * Not valid certs are considered older than valid certs.
  1799.  */
  1800. PRBool
  1801. CERT_SortCBValidity(CERTCertificate *certa,
  1802.     CERTCertificate *certb,
  1803.     void *arg)
  1804. {
  1805.     int64 sorttime;
  1806.     int64 notBeforeA, notAfterA, notBeforeB, notAfterB;
  1807.     SECStatus rv;
  1808.     PRBool newerbefore, newerafter;
  1809.     PRBool aNotValid = PR_FALSE, bNotValid = PR_FALSE;
  1810.     sorttime = *(int64 *)arg;
  1811.     
  1812.     rv = CERT_GetCertTimes(certa, &notBeforeA, &notAfterA);
  1813.     if ( rv != SECSuccess ) {
  1814. return(PR_FALSE);
  1815.     }
  1816.     
  1817.     rv = CERT_GetCertTimes(certb, &notBeforeB, &notAfterB);
  1818.     if ( rv != SECSuccess ) {
  1819. return(PR_TRUE);
  1820.     }
  1821.     newerbefore = PR_FALSE;
  1822.     if ( LL_CMP(notBeforeA, >, notBeforeB) ) {
  1823. newerbefore = PR_TRUE;
  1824.     }
  1825.     newerafter = PR_FALSE;
  1826.     if ( LL_CMP(notAfterA, >, notAfterB) ) {
  1827. newerafter = PR_TRUE;
  1828.     }
  1829.     /* check if A is valid at sorttime */
  1830.     if ( CERT_CheckCertValidTimes(certa, sorttime, PR_FALSE)
  1831. != secCertTimeValid ) {
  1832. aNotValid = PR_TRUE;
  1833.     }
  1834.     /* check if B is valid at sorttime */
  1835.     if ( CERT_CheckCertValidTimes(certb, sorttime, PR_FALSE)
  1836. != secCertTimeValid ) {
  1837. bNotValid = PR_TRUE;
  1838.     }
  1839.     /* a is valid, b is not */
  1840.     if ( bNotValid && ( ! aNotValid ) ) {
  1841. return(PR_TRUE);
  1842.     }
  1843.     /* b is valid, a is not */
  1844.     if ( aNotValid && ( ! bNotValid ) ) {
  1845. return(PR_FALSE);
  1846.     }
  1847.     
  1848.     /* a and b are either valid or not valid */
  1849.     if ( newerbefore && newerafter ) {
  1850. return(PR_TRUE);
  1851.     }
  1852.     
  1853.     if ( ( !newerbefore ) && ( !newerafter ) ) {
  1854. return(PR_FALSE);
  1855.     }
  1856.     if ( newerbefore ) {
  1857. /* cert A was issued after cert B, but expires sooner */
  1858. return(PR_TRUE);
  1859.     } else {
  1860. /* cert B was issued after cert A, but expires sooner */
  1861. return(PR_FALSE);
  1862.     }
  1863. }
  1864. SECStatus
  1865. CERT_AddCertToListSorted(CERTCertList *certs,
  1866.  CERTCertificate *cert,
  1867.  CERTSortCallback f,
  1868.  void *arg)
  1869. {
  1870.     CERTCertListNode *node;
  1871.     CERTCertListNode *head;
  1872.     PRBool ret;
  1873.     
  1874.     node = (CERTCertListNode *)PORT_ArenaZAlloc(certs->arena,
  1875. sizeof(CERTCertListNode));
  1876.     if ( node == NULL ) {
  1877. goto loser;
  1878.     }
  1879.     
  1880.     head = CERT_LIST_HEAD(certs);
  1881.     
  1882.     while ( !CERT_LIST_END(head, certs) ) {
  1883. /* if cert is already in the list, then don't add it again */
  1884. if ( cert == head->cert ) {
  1885.     /*XXX*/
  1886.     /* don't keep a reference */
  1887.     CERT_DestroyCertificate(cert);
  1888.     goto done;
  1889. }
  1890. ret = (* f)(cert, head->cert, arg);
  1891. /* if sort function succeeds, then insert before current node */
  1892. if ( ret ) {
  1893.     PR_INSERT_BEFORE(&node->links, &head->links);
  1894.     goto done;
  1895. }
  1896. head = CERT_LIST_NEXT(head);
  1897.     }
  1898.     /* if we get to the end, then just insert it at the tail */
  1899.     PR_INSERT_BEFORE(&node->links, &certs->list);
  1900. done:    
  1901.     /* certs->count++; */
  1902.     node->cert = cert;
  1903.     return(SECSuccess);
  1904.     
  1905. loser:
  1906.     return(SECFailure);
  1907. }
  1908. /* This routine is here because pcertdb.c still has a call to it.
  1909.  * The SMIME profile code in pcertdb.c should be split into high (find
  1910.  * the email cert) and low (store the profile) code.  At that point, we
  1911.  * can move this to certhigh.c where it belongs.
  1912.  *
  1913.  * remove certs from a list that don't have keyUsage and certType
  1914.  * that match the given usage.
  1915.  */
  1916. SECStatus
  1917. CERT_FilterCertListByUsage(CERTCertList *certList, SECCertUsage usage,
  1918.    PRBool ca)
  1919. {
  1920.     unsigned int requiredKeyUsage;
  1921.     unsigned int requiredCertType;
  1922.     CERTCertListNode *node, *savenode;
  1923.     PRBool bad;
  1924.     SECStatus rv;
  1925.     unsigned int certType;
  1926.     PRBool dummyret;
  1927.     
  1928.     if (certList == NULL) goto loser;
  1929.     rv = CERT_KeyUsageAndTypeForCertUsage(usage, ca, &requiredKeyUsage,
  1930.   &requiredCertType);
  1931.     if ( rv != SECSuccess ) {
  1932. goto loser;
  1933.     }
  1934.     node = CERT_LIST_HEAD(certList);
  1935.     while ( !CERT_LIST_END(node, certList) ) {
  1936. bad = PR_FALSE;
  1937. /* bad key usage */
  1938. if ( CERT_CheckKeyUsage(node->cert, requiredKeyUsage )
  1939.     != SECSuccess ) {
  1940.     bad = PR_TRUE;
  1941. }
  1942. /* bad cert type */
  1943. if ( ca ) {
  1944.     /* This function returns a more comprehensive cert type that
  1945.      * takes trust flags into consideration.  Should probably
  1946.      * fix the cert decoding code to do this.
  1947.      */
  1948.     dummyret = CERT_IsCACert(node->cert, &certType);
  1949. } else {
  1950.     certType = node->cert->nsCertType;
  1951. }
  1952. if ( ! ( certType & requiredCertType ) ) {
  1953.     bad = PR_TRUE;
  1954. }
  1955. if ( bad ) {
  1956.     /* remove the node if it is bad */
  1957.     savenode = CERT_LIST_NEXT(node);
  1958.     CERT_RemoveCertListNode(node);
  1959.     node = savenode;
  1960. } else {
  1961.     node = CERT_LIST_NEXT(node);
  1962. }
  1963.     }
  1964.     return(SECSuccess);
  1965.     
  1966. loser:
  1967.     return(SECFailure);
  1968. }
  1969. /*
  1970.  * Acquire the global lock on the cert database.
  1971.  * This lock is currently used for the following operations:
  1972.  * adding or deleting a cert to either the temp or perm databases
  1973.  * converting a temp to perm or perm to temp
  1974.  * changing(maybe just adding????) the trust of a cert
  1975.  *      chaning the DB status checking Configuration
  1976.  */
  1977. void
  1978. CERT_LockDB(CERTCertDBHandle *handle)
  1979. {
  1980.     PR_EnterMonitor(handle->dbMon);
  1981.     return;
  1982. }
  1983. /*
  1984.  * Free the global cert database lock.
  1985.  */
  1986. void
  1987. CERT_UnlockDB(CERTCertDBHandle *handle)
  1988. {
  1989.     PRStatus prstat;
  1990.     
  1991.     prstat = PR_ExitMonitor(handle->dbMon);
  1992.     
  1993.     PORT_Assert(prstat == PR_SUCCESS);
  1994.     
  1995.     return;
  1996. }
  1997. static PRLock *certRefCountLock = NULL;
  1998. /*
  1999.  * Acquire the cert reference count lock
  2000.  * There is currently one global lock for all certs, but I'm putting a cert
  2001.  * arg here so that it will be easy to make it per-cert in the future if
  2002.  * that turns out to be necessary.
  2003.  */
  2004. void
  2005. CERT_LockCertRefCount(CERTCertificate *cert)
  2006. {
  2007.     if ( certRefCountLock == NULL ) {
  2008. nss_InitLock(&certRefCountLock);
  2009. PORT_Assert(certRefCountLock != NULL);
  2010.     }
  2011.     
  2012.     PR_Lock(certRefCountLock);
  2013.     return;
  2014. }
  2015. /*
  2016.  * Free the cert reference count lock
  2017.  */
  2018. void
  2019. CERT_UnlockCertRefCount(CERTCertificate *cert)
  2020. {
  2021.     PRStatus prstat;
  2022.     PORT_Assert(certRefCountLock != NULL);
  2023.     
  2024.     prstat = PR_Unlock(certRefCountLock);
  2025.     
  2026.     PORT_Assert(prstat == PR_SUCCESS);
  2027.     return;
  2028. }
  2029. static PRLock *certTrustLock = NULL;
  2030. /*
  2031.  * Acquire the cert trust lock
  2032.  * There is currently one global lock for all certs, but I'm putting a cert
  2033.  * arg here so that it will be easy to make it per-cert in the future if
  2034.  * that turns out to be necessary.
  2035.  */
  2036. void
  2037. CERT_LockCertTrust(CERTCertificate *cert)
  2038. {
  2039.     if ( certTrustLock == NULL ) {
  2040. nss_InitLock(&certTrustLock);
  2041. PORT_Assert(certTrustLock != NULL);
  2042.     }
  2043.     
  2044.     PR_Lock(certTrustLock);
  2045.     return;
  2046. }
  2047. /*
  2048.  * Free the cert trust lock
  2049.  */
  2050. void
  2051. CERT_UnlockCertTrust(CERTCertificate *cert)
  2052. {
  2053.     PRStatus prstat;
  2054.     PORT_Assert(certTrustLock != NULL);
  2055.     
  2056.     prstat = PR_Unlock(certTrustLock);
  2057.     
  2058.     PORT_Assert(prstat == PR_SUCCESS);
  2059.     return;
  2060. }
  2061. /*
  2062.  * Get the StatusConfig data for this handle
  2063.  */
  2064. CERTStatusConfig *
  2065. CERT_GetStatusConfig(CERTCertDBHandle *handle)
  2066. {
  2067.   return handle->statusConfig;
  2068. }
  2069. /*
  2070.  * Set the StatusConfig data for this handle.  There
  2071.  * should not be another configuration set.
  2072.  */
  2073. void
  2074. CERT_SetStatusConfig(CERTCertDBHandle *handle, CERTStatusConfig *statusConfig)
  2075. {
  2076.   PORT_Assert(handle->statusConfig == NULL);
  2077.   handle->statusConfig = statusConfig;
  2078. }