| OLD | NEW |
| 1 /* This Source Code Form is subject to the terms of the Mozilla Public | 1 /* This Source Code Form is subject to the terms of the Mozilla Public |
| 2 * License, v. 2.0. If a copy of the MPL was not distributed with this | 2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
| 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| 4 | 4 |
| 5 /* | 5 /* |
| 6 * Certificate handling code | 6 * Certificate handling code |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 #include "nssilock.h" | 9 #include "nssilock.h" |
| 10 #include "prmon.h" | 10 #include "prmon.h" |
| 11 #include "prtime.h" | 11 #include "prtime.h" |
| 12 #include "cert.h" | 12 #include "cert.h" |
| 13 #include "certi.h" | 13 #include "certi.h" |
| 14 #include "secder.h" | 14 #include "secder.h" |
| 15 #include "secoid.h" | 15 #include "secoid.h" |
| 16 #include "secasn1.h" | 16 #include "secasn1.h" |
| 17 #include "genname.h" | 17 #include "genname.h" |
| 18 #include "keyhi.h" | 18 #include "keyhi.h" |
| 19 #include "secitem.h" | 19 #include "secitem.h" |
| 20 #include "certdb.h" | 20 #include "certdb.h" |
| 21 #include "prprf.h" | 21 #include "prprf.h" |
| 22 #include "sechash.h" | 22 #include "sechash.h" |
| 23 #include "prlong.h" | 23 #include "prlong.h" |
| 24 #include "certxutl.h" | 24 #include "certxutl.h" |
| 25 #include "portreg.h" | 25 #include "portreg.h" |
| 26 #include "secerr.h" | 26 #include "secerr.h" |
| 27 #include "sslerr.h" | 27 #include "sslerr.h" |
| 28 #include "pk11func.h" | 28 #include "pk11func.h" |
| 29 #include "xconst.h" /* for CERT_DecodeAltNameExtension */ | 29 #include "xconst.h" /* for CERT_DecodeAltNameExtension */ |
| 30 | 30 |
| 31 #include "pki.h" | 31 #include "pki.h" |
| 32 #include "pki3hack.h" | 32 #include "pki3hack.h" |
| 33 | 33 |
| 34 SEC_ASN1_MKSUB(CERT_TimeChoiceTemplate) | 34 SEC_ASN1_MKSUB(CERT_TimeChoiceTemplate) |
| 35 SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate) | 35 SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate) |
| 36 SEC_ASN1_MKSUB(SEC_BitStringTemplate) | 36 SEC_ASN1_MKSUB(SEC_BitStringTemplate) |
| 37 SEC_ASN1_MKSUB(SEC_IntegerTemplate) | 37 SEC_ASN1_MKSUB(SEC_IntegerTemplate) |
| 38 SEC_ASN1_MKSUB(SEC_SkipTemplate) | 38 SEC_ASN1_MKSUB(SEC_SkipTemplate) |
| 39 | 39 |
| 40 /* | 40 /* |
| 41 * Certificate database handling code | 41 * Certificate database handling code |
| 42 */ | 42 */ |
| 43 | 43 |
| 44 | |
| 45 const SEC_ASN1Template CERT_CertExtensionTemplate[] = { | 44 const SEC_ASN1Template CERT_CertExtensionTemplate[] = { |
| 46 { SEC_ASN1_SEQUENCE, | 45 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTCertExtension) }, |
| 47 » 0, NULL, sizeof(CERTCertExtension) }, | 46 { SEC_ASN1_OBJECT_ID, offsetof(CERTCertExtension, id) }, |
| 48 { SEC_ASN1_OBJECT_ID, | 47 { SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN, /* XXX DER_DEFAULT */ |
| 49 » offsetof(CERTCertExtension,id) }, | 48 offsetof(CERTCertExtension, critical) }, |
| 50 { SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN,» » /* XXX DER_DEFAULT */ | 49 { SEC_ASN1_OCTET_STRING, offsetof(CERTCertExtension, value) }, |
| 51 » offsetof(CERTCertExtension,critical) }, | 50 { 0 } |
| 52 { SEC_ASN1_OCTET_STRING, | |
| 53 » offsetof(CERTCertExtension,value) }, | |
| 54 { 0, } | |
| 55 }; | 51 }; |
| 56 | 52 |
| 57 const SEC_ASN1Template CERT_SequenceOfCertExtensionTemplate[] = { | 53 const SEC_ASN1Template CERT_SequenceOfCertExtensionTemplate[] = { |
| 58 { SEC_ASN1_SEQUENCE_OF, 0, CERT_CertExtensionTemplate } | 54 { SEC_ASN1_SEQUENCE_OF, 0, CERT_CertExtensionTemplate } |
| 59 }; | 55 }; |
| 60 | 56 |
| 61 const SEC_ASN1Template CERT_TimeChoiceTemplate[] = { | 57 const SEC_ASN1Template CERT_TimeChoiceTemplate[] = { |
| 62 { SEC_ASN1_CHOICE, offsetof(SECItem, type), 0, sizeof(SECItem) }, | 58 { SEC_ASN1_CHOICE, offsetof(SECItem, type), 0, sizeof(SECItem) }, |
| 63 { SEC_ASN1_UTC_TIME, 0, 0, siUTCTime }, | 59 { SEC_ASN1_UTC_TIME, 0, 0, siUTCTime }, |
| 64 { SEC_ASN1_GENERALIZED_TIME, 0, 0, siGeneralizedTime }, | 60 { SEC_ASN1_GENERALIZED_TIME, 0, 0, siGeneralizedTime }, |
| 65 { 0 } | 61 { 0 } |
| 66 }; | 62 }; |
| 67 | 63 |
| 68 const SEC_ASN1Template CERT_ValidityTemplate[] = { | 64 const SEC_ASN1Template CERT_ValidityTemplate[] = { |
| 69 { SEC_ASN1_SEQUENCE, | 65 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTValidity) }, |
| 70 » 0, NULL, sizeof(CERTValidity) }, | 66 { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(CERTValidity, notBefore), |
| 71 { SEC_ASN1_INLINE | SEC_ASN1_XTRN, | 67 SEC_ASN1_SUB(CERT_TimeChoiceTemplate), 0 }, |
| 72 offsetof(CERTValidity,notBefore), | 68 { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(CERTValidity, notAfter), |
| 73 SEC_ASN1_SUB(CERT_TimeChoiceTemplate), 0 }, | 69 SEC_ASN1_SUB(CERT_TimeChoiceTemplate), 0 }, |
| 74 { SEC_ASN1_INLINE | SEC_ASN1_XTRN, | |
| 75 offsetof(CERTValidity,notAfter), | |
| 76 SEC_ASN1_SUB(CERT_TimeChoiceTemplate), 0 }, | |
| 77 { 0 } | 70 { 0 } |
| 78 }; | 71 }; |
| 79 | 72 |
| 80 const SEC_ASN1Template CERT_CertificateTemplate[] = { | 73 const SEC_ASN1Template CERT_CertificateTemplate[] = { |
| 81 { SEC_ASN1_SEQUENCE, | 74 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTCertificate) }, |
| 82 0, NULL, sizeof(CERTCertificate) }, | 75 { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | |
| 83 { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | | 76 SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, /* XXX DER_DEFAULT */ |
| 84 » SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, /* XXX DER_DEFAULT */ | 77 offsetof(CERTCertificate, version), |
| 85 » offsetof(CERTCertificate,version), | 78 SEC_ASN1_SUB(SEC_IntegerTemplate) }, |
| 86 » SEC_ASN1_SUB(SEC_IntegerTemplate) }, | 79 { SEC_ASN1_INTEGER, offsetof(CERTCertificate, serialNumber) }, |
| 87 { SEC_ASN1_INTEGER, | 80 { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(CERTCertificate, signature), |
| 88 » offsetof(CERTCertificate,serialNumber) }, | 81 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, |
| 89 { SEC_ASN1_INLINE | SEC_ASN1_XTRN, | 82 { SEC_ASN1_SAVE, offsetof(CERTCertificate, derIssuer) }, |
| 90 » offsetof(CERTCertificate,signature), | 83 { SEC_ASN1_INLINE, offsetof(CERTCertificate, issuer), CERT_NameTemplate }, |
| 91 » SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, | 84 { SEC_ASN1_INLINE, offsetof(CERTCertificate, validity), |
| 92 { SEC_ASN1_SAVE, | 85 CERT_ValidityTemplate }, |
| 93 » offsetof(CERTCertificate,derIssuer) }, | 86 { SEC_ASN1_SAVE, offsetof(CERTCertificate, derSubject) }, |
| 94 { SEC_ASN1_INLINE, | 87 { SEC_ASN1_INLINE, offsetof(CERTCertificate, subject), CERT_NameTemplate }, |
| 95 » offsetof(CERTCertificate,issuer), | 88 { SEC_ASN1_SAVE, offsetof(CERTCertificate, derPublicKey) }, |
| 96 » CERT_NameTemplate }, | 89 { SEC_ASN1_INLINE, offsetof(CERTCertificate, subjectPublicKeyInfo), |
| 97 { SEC_ASN1_INLINE, | 90 CERT_SubjectPublicKeyInfoTemplate }, |
| 98 » offsetof(CERTCertificate,validity), | 91 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1, |
| 99 » CERT_ValidityTemplate }, | 92 offsetof(CERTCertificate, issuerID), |
| 100 { SEC_ASN1_SAVE, | 93 SEC_ASN1_SUB(SEC_BitStringTemplate) }, |
| 101 » offsetof(CERTCertificate,derSubject) }, | 94 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2, |
| 102 { SEC_ASN1_INLINE, | 95 offsetof(CERTCertificate, subjectID), |
| 103 » offsetof(CERTCertificate,subject), | 96 SEC_ASN1_SUB(SEC_BitStringTemplate) }, |
| 104 » CERT_NameTemplate }, | 97 { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | |
| 105 { SEC_ASN1_SAVE, | 98 SEC_ASN1_CONTEXT_SPECIFIC | 3, |
| 106 » offsetof(CERTCertificate,derPublicKey) }, | 99 offsetof(CERTCertificate, extensions), |
| 107 { SEC_ASN1_INLINE, | 100 CERT_SequenceOfCertExtensionTemplate }, |
| 108 » offsetof(CERTCertificate,subjectPublicKeyInfo), | |
| 109 » CERT_SubjectPublicKeyInfoTemplate }, | |
| 110 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1, | |
| 111 » offsetof(CERTCertificate,issuerID), | |
| 112 » SEC_ASN1_SUB(SEC_BitStringTemplate) }, | |
| 113 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2, | |
| 114 » offsetof(CERTCertificate,subjectID), | |
| 115 » SEC_ASN1_SUB(SEC_BitStringTemplate) }, | |
| 116 { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | | |
| 117 » SEC_ASN1_CONTEXT_SPECIFIC | 3, | |
| 118 » offsetof(CERTCertificate,extensions), | |
| 119 » CERT_SequenceOfCertExtensionTemplate }, | |
| 120 { 0 } | 101 { 0 } |
| 121 }; | 102 }; |
| 122 | 103 |
| 123 const SEC_ASN1Template SEC_SignedCertificateTemplate[] = | 104 const SEC_ASN1Template SEC_SignedCertificateTemplate[] = { |
| 124 { | 105 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTCertificate) }, |
| 125 { SEC_ASN1_SEQUENCE, | 106 { SEC_ASN1_SAVE, offsetof(CERTCertificate, signatureWrap.data) }, |
| 126 » 0, NULL, sizeof(CERTCertificate) }, | 107 { SEC_ASN1_INLINE, 0, CERT_CertificateTemplate }, |
| 127 { SEC_ASN1_SAVE, | |
| 128 » offsetof(CERTCertificate,signatureWrap.data) }, | |
| 129 { SEC_ASN1_INLINE, | |
| 130 » 0, CERT_CertificateTemplate }, | |
| 131 { SEC_ASN1_INLINE | SEC_ASN1_XTRN, | 108 { SEC_ASN1_INLINE | SEC_ASN1_XTRN, |
| 132 » offsetof(CERTCertificate,signatureWrap.signatureAlgorithm), | 109 offsetof(CERTCertificate, signatureWrap.signatureAlgorithm), |
| 133 » SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, | 110 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, |
| 134 { SEC_ASN1_BIT_STRING, | 111 { SEC_ASN1_BIT_STRING, offsetof(CERTCertificate, signatureWrap.signature) }, |
| 135 » offsetof(CERTCertificate,signatureWrap.signature) }, | |
| 136 { 0 } | 112 { 0 } |
| 137 }; | 113 }; |
| 138 | 114 |
| 139 /* | 115 /* |
| 140 * Find the subjectName in a DER encoded certificate | 116 * Find the subjectName in a DER encoded certificate |
| 141 */ | 117 */ |
| 142 const SEC_ASN1Template SEC_CertSubjectTemplate[] = { | 118 const SEC_ASN1Template SEC_CertSubjectTemplate[] = { |
| 143 { SEC_ASN1_SEQUENCE, | 119 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECItem) }, |
| 144 » 0, NULL, sizeof(SECItem) }, | 120 { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | |
| 145 { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | | 121 SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, |
| 146 » SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, | 122 0, SEC_ASN1_SUB(SEC_SkipTemplate) }, /* version */ |
| 147 » 0, SEC_ASN1_SUB(SEC_SkipTemplate) },» /* version */ | 123 { SEC_ASN1_SKIP }, /* serial number */ |
| 148 { SEC_ASN1_SKIP },» » /* serial number */ | 124 { SEC_ASN1_SKIP }, /* signature algorithm */ |
| 149 { SEC_ASN1_SKIP },» » /* signature algorithm */ | 125 { SEC_ASN1_SKIP }, /* issuer */ |
| 150 { SEC_ASN1_SKIP },» » /* issuer */ | 126 { SEC_ASN1_SKIP }, /* validity */ |
| 151 { SEC_ASN1_SKIP },» » /* validity */ | 127 { SEC_ASN1_ANY, 0, NULL }, /* subject */ |
| 152 { SEC_ASN1_ANY, 0, NULL },» » /* subject */ | |
| 153 { SEC_ASN1_SKIP_REST }, | 128 { SEC_ASN1_SKIP_REST }, |
| 154 { 0 } | 129 { 0 } |
| 155 }; | 130 }; |
| 156 | 131 |
| 157 /* | 132 /* |
| 158 * Find the issuerName in a DER encoded certificate | 133 * Find the issuerName in a DER encoded certificate |
| 159 */ | 134 */ |
| 160 const SEC_ASN1Template SEC_CertIssuerTemplate[] = { | 135 const SEC_ASN1Template SEC_CertIssuerTemplate[] = { |
| 161 { SEC_ASN1_SEQUENCE, | 136 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECItem) }, |
| 162 » 0, NULL, sizeof(SECItem) }, | 137 { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | |
| 163 { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | | 138 SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, |
| 164 » SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, | 139 0, SEC_ASN1_SUB(SEC_SkipTemplate) }, /* version */ |
| 165 » 0, SEC_ASN1_SUB(SEC_SkipTemplate) },» /* version */ | 140 { SEC_ASN1_SKIP }, /* serial number */ |
| 166 { SEC_ASN1_SKIP },» » /* serial number */ | 141 { SEC_ASN1_SKIP }, /* signature algorithm */ |
| 167 { SEC_ASN1_SKIP },» » /* signature algorithm */ | 142 { SEC_ASN1_ANY, 0, NULL }, /* issuer */ |
| 168 { SEC_ASN1_ANY, 0, NULL },» » /* issuer */ | |
| 169 { SEC_ASN1_SKIP_REST }, | 143 { SEC_ASN1_SKIP_REST }, |
| 170 { 0 } | 144 { 0 } |
| 171 }; | 145 }; |
| 172 /* | 146 /* |
| 173 * Find the subjectName in a DER encoded certificate | 147 * Find the subjectName in a DER encoded certificate |
| 174 */ | 148 */ |
| 175 const SEC_ASN1Template SEC_CertSerialNumberTemplate[] = { | 149 const SEC_ASN1Template SEC_CertSerialNumberTemplate[] = { |
| 176 { SEC_ASN1_SEQUENCE, | 150 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECItem) }, |
| 177 » 0, NULL, sizeof(SECItem) }, | 151 { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | |
| 178 { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | | 152 SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, |
| 179 » SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, | 153 0, SEC_ASN1_SUB(SEC_SkipTemplate) }, /* version */ |
| 180 » 0, SEC_ASN1_SUB(SEC_SkipTemplate) },» /* version */ | 154 { SEC_ASN1_ANY, 0, NULL }, /* serial number */ |
| 181 { SEC_ASN1_ANY, 0, NULL }, /* serial number */ | |
| 182 { SEC_ASN1_SKIP_REST }, | 155 { SEC_ASN1_SKIP_REST }, |
| 183 { 0 } | 156 { 0 } |
| 184 }; | 157 }; |
| 185 | 158 |
| 186 /* | 159 /* |
| 187 * Find the issuer and serialNumber in a DER encoded certificate. | 160 * Find the issuer and serialNumber in a DER encoded certificate. |
| 188 * This data is used as the database lookup key since its the unique | 161 * This data is used as the database lookup key since its the unique |
| 189 * identifier of a certificate. | 162 * identifier of a certificate. |
| 190 */ | 163 */ |
| 191 const SEC_ASN1Template CERT_CertKeyTemplate[] = { | 164 const SEC_ASN1Template CERT_CertKeyTemplate[] = { |
| 192 { SEC_ASN1_SEQUENCE, | 165 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTCertKey) }, |
| 193 » 0, NULL, sizeof(CERTCertKey) }, | 166 { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | |
| 194 { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | | 167 SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, |
| 195 » SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, | 168 0, SEC_ASN1_SUB(SEC_SkipTemplate) }, /* version */ |
| 196 » 0, SEC_ASN1_SUB(SEC_SkipTemplate) },» /* version */ | 169 { SEC_ASN1_INTEGER, offsetof(CERTCertKey, serialNumber) }, |
| 197 { SEC_ASN1_INTEGER, | 170 { SEC_ASN1_SKIP }, /* signature algorithm */ |
| 198 » offsetof(CERTCertKey,serialNumber) }, | 171 { SEC_ASN1_ANY, offsetof(CERTCertKey, derIssuer) }, |
| 199 { SEC_ASN1_SKIP },» » /* signature algorithm */ | |
| 200 { SEC_ASN1_ANY, | |
| 201 » offsetof(CERTCertKey,derIssuer) }, | |
| 202 { SEC_ASN1_SKIP_REST }, | 172 { SEC_ASN1_SKIP_REST }, |
| 203 { 0 } | 173 { 0 } |
| 204 }; | 174 }; |
| 205 | 175 |
| 206 SEC_ASN1_CHOOSER_IMPLEMENT(CERT_TimeChoiceTemplate) | 176 SEC_ASN1_CHOOSER_IMPLEMENT(CERT_TimeChoiceTemplate) |
| 207 SEC_ASN1_CHOOSER_IMPLEMENT(CERT_CertificateTemplate) | 177 SEC_ASN1_CHOOSER_IMPLEMENT(CERT_CertificateTemplate) |
| 208 SEC_ASN1_CHOOSER_IMPLEMENT(SEC_SignedCertificateTemplate) | 178 SEC_ASN1_CHOOSER_IMPLEMENT(SEC_SignedCertificateTemplate) |
| 209 SEC_ASN1_CHOOSER_IMPLEMENT(CERT_SequenceOfCertExtensionTemplate) | 179 SEC_ASN1_CHOOSER_IMPLEMENT(CERT_SequenceOfCertExtensionTemplate) |
| 210 | 180 |
| 211 SECStatus | 181 SECStatus |
| 212 CERT_KeyFromIssuerAndSN(PLArenaPool *arena, SECItem *issuer, SECItem *sn, | 182 CERT_KeyFromIssuerAndSN(PLArenaPool *arena, SECItem *issuer, SECItem *sn, |
| 213 » » » SECItem *key) | 183 SECItem *key) |
| 214 { | 184 { |
| 215 key->len = sn->len + issuer->len; | 185 key->len = sn->len + issuer->len; |
| 216 | 186 |
| 217 if ((sn->data == NULL) || (issuer->data == NULL)) { | 187 if ((sn->data == NULL) || (issuer->data == NULL)) { |
| 218 » goto loser; | 188 goto loser; |
| 219 } | 189 } |
| 220 | 190 |
| 221 key->data = (unsigned char*)PORT_ArenaAlloc(arena, key->len); | 191 key->data = (unsigned char *)PORT_ArenaAlloc(arena, key->len); |
| 222 if ( !key->data ) { | 192 if (!key->data) { |
| 223 » goto loser; | 193 goto loser; |
| 224 } | 194 } |
| 225 | 195 |
| 226 /* copy the serialNumber */ | 196 /* copy the serialNumber */ |
| 227 PORT_Memcpy(key->data, sn->data, sn->len); | 197 PORT_Memcpy(key->data, sn->data, sn->len); |
| 228 | 198 |
| 229 /* copy the issuer */ | 199 /* copy the issuer */ |
| 230 PORT_Memcpy(&key->data[sn->len], issuer->data, issuer->len); | 200 PORT_Memcpy(&key->data[sn->len], issuer->data, issuer->len); |
| 231 | 201 |
| 232 return(SECSuccess); | 202 return (SECSuccess); |
| 233 | 203 |
| 234 loser: | 204 loser: |
| 235 return(SECFailure); | 205 return (SECFailure); |
| 236 } | 206 } |
| 237 | 207 |
| 238 | |
| 239 /* | 208 /* |
| 240 * Extract the subject name from a DER certificate | 209 * Extract the subject name from a DER certificate |
| 241 */ | 210 */ |
| 242 SECStatus | 211 SECStatus |
| 243 CERT_NameFromDERCert(SECItem *derCert, SECItem *derName) | 212 CERT_NameFromDERCert(SECItem *derCert, SECItem *derName) |
| 244 { | 213 { |
| 245 int rv; | 214 int rv; |
| 246 PLArenaPool *arena; | 215 PLArenaPool *arena; |
| 247 CERTSignedData sd; | 216 CERTSignedData sd; |
| 248 void *tmpptr; | 217 void *tmpptr; |
| 249 | 218 |
| 250 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 219 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
| 251 | 220 |
| 252 if ( ! arena ) { | 221 if (!arena) { |
| 253 » return(SECFailure); | 222 return (SECFailure); |
| 254 } | 223 } |
| 255 | 224 |
| 256 PORT_Memset(&sd, 0, sizeof(CERTSignedData)); | 225 PORT_Memset(&sd, 0, sizeof(CERTSignedData)); |
| 257 rv = SEC_QuickDERDecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert); | 226 rv = SEC_QuickDERDecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert); |
| 258 | 227 |
| 259 if ( rv ) { | 228 if (rv) { |
| 260 » goto loser; | 229 goto loser; |
| 261 } | 230 } |
| 262 | 231 |
| 263 PORT_Memset(derName, 0, sizeof(SECItem)); | 232 PORT_Memset(derName, 0, sizeof(SECItem)); |
| 264 rv = SEC_QuickDERDecodeItem(arena, derName, SEC_CertSubjectTemplate, &sd.dat
a); | 233 rv = SEC_QuickDERDecodeItem(arena, derName, SEC_CertSubjectTemplate, |
| 234 &sd.data); |
| 265 | 235 |
| 266 if ( rv ) { | 236 if (rv) { |
| 267 » goto loser; | 237 goto loser; |
| 268 } | 238 } |
| 269 | 239 |
| 270 tmpptr = derName->data; | 240 tmpptr = derName->data; |
| 271 derName->data = (unsigned char*)PORT_Alloc(derName->len); | 241 derName->data = (unsigned char *)PORT_Alloc(derName->len); |
| 272 if ( derName->data == NULL ) { | 242 if (derName->data == NULL) { |
| 273 » goto loser; | 243 goto loser; |
| 274 } | 244 } |
| 275 | 245 |
| 276 PORT_Memcpy(derName->data, tmpptr, derName->len); | 246 PORT_Memcpy(derName->data, tmpptr, derName->len); |
| 277 | 247 |
| 278 PORT_FreeArena(arena, PR_FALSE); | 248 PORT_FreeArena(arena, PR_FALSE); |
| 279 return(SECSuccess); | 249 return (SECSuccess); |
| 280 | 250 |
| 281 loser: | 251 loser: |
| 282 PORT_FreeArena(arena, PR_FALSE); | 252 PORT_FreeArena(arena, PR_FALSE); |
| 283 return(SECFailure); | 253 return (SECFailure); |
| 284 } | 254 } |
| 285 | 255 |
| 286 SECStatus | 256 SECStatus |
| 287 CERT_IssuerNameFromDERCert(SECItem *derCert, SECItem *derName) | 257 CERT_IssuerNameFromDERCert(SECItem *derCert, SECItem *derName) |
| 288 { | 258 { |
| 289 int rv; | 259 int rv; |
| 290 PLArenaPool *arena; | 260 PLArenaPool *arena; |
| 291 CERTSignedData sd; | 261 CERTSignedData sd; |
| 292 void *tmpptr; | 262 void *tmpptr; |
| 293 | 263 |
| 294 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 264 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
| 295 | 265 |
| 296 if ( ! arena ) { | 266 if (!arena) { |
| 297 » return(SECFailure); | 267 return (SECFailure); |
| 298 } | 268 } |
| 299 | 269 |
| 300 PORT_Memset(&sd, 0, sizeof(CERTSignedData)); | 270 PORT_Memset(&sd, 0, sizeof(CERTSignedData)); |
| 301 rv = SEC_QuickDERDecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert); | 271 rv = SEC_QuickDERDecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert); |
| 302 | 272 |
| 303 if ( rv ) { | 273 if (rv) { |
| 304 » goto loser; | 274 goto loser; |
| 305 } | 275 } |
| 306 | 276 |
| 307 PORT_Memset(derName, 0, sizeof(SECItem)); | 277 PORT_Memset(derName, 0, sizeof(SECItem)); |
| 308 rv = SEC_QuickDERDecodeItem(arena, derName, SEC_CertIssuerTemplate, &sd.data
); | 278 rv = SEC_QuickDERDecodeItem(arena, derName, SEC_CertIssuerTemplate, |
| 279 &sd.data); |
| 309 | 280 |
| 310 if ( rv ) { | 281 if (rv) { |
| 311 » goto loser; | 282 goto loser; |
| 312 } | 283 } |
| 313 | 284 |
| 314 tmpptr = derName->data; | 285 tmpptr = derName->data; |
| 315 derName->data = (unsigned char*)PORT_Alloc(derName->len); | 286 derName->data = (unsigned char *)PORT_Alloc(derName->len); |
| 316 if ( derName->data == NULL ) { | 287 if (derName->data == NULL) { |
| 317 » goto loser; | 288 goto loser; |
| 318 } | 289 } |
| 319 | 290 |
| 320 PORT_Memcpy(derName->data, tmpptr, derName->len); | 291 PORT_Memcpy(derName->data, tmpptr, derName->len); |
| 321 | 292 |
| 322 PORT_FreeArena(arena, PR_FALSE); | 293 PORT_FreeArena(arena, PR_FALSE); |
| 323 return(SECSuccess); | 294 return (SECSuccess); |
| 324 | 295 |
| 325 loser: | 296 loser: |
| 326 PORT_FreeArena(arena, PR_FALSE); | 297 PORT_FreeArena(arena, PR_FALSE); |
| 327 return(SECFailure); | 298 return (SECFailure); |
| 328 } | 299 } |
| 329 | 300 |
| 330 SECStatus | 301 SECStatus |
| 331 CERT_SerialNumberFromDERCert(SECItem *derCert, SECItem *derName) | 302 CERT_SerialNumberFromDERCert(SECItem *derCert, SECItem *derName) |
| 332 { | 303 { |
| 333 int rv; | 304 int rv; |
| 334 PLArenaPool *arena; | 305 PLArenaPool *arena; |
| 335 CERTSignedData sd; | 306 CERTSignedData sd; |
| 336 void *tmpptr; | 307 void *tmpptr; |
| 337 | 308 |
| 338 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 309 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
| 339 | 310 |
| 340 if ( ! arena ) { | 311 if (!arena) { |
| 341 » return(SECFailure); | 312 return (SECFailure); |
| 342 } | 313 } |
| 343 | 314 |
| 344 PORT_Memset(&sd, 0, sizeof(CERTSignedData)); | 315 PORT_Memset(&sd, 0, sizeof(CERTSignedData)); |
| 345 rv = SEC_QuickDERDecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert); | 316 rv = SEC_QuickDERDecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert); |
| 346 | 317 |
| 347 if ( rv ) { | 318 if (rv) { |
| 348 » goto loser; | 319 goto loser; |
| 349 } | 320 } |
| 350 | 321 |
| 351 PORT_Memset(derName, 0, sizeof(SECItem)); | 322 PORT_Memset(derName, 0, sizeof(SECItem)); |
| 352 rv = SEC_QuickDERDecodeItem(arena, derName, SEC_CertSerialNumberTemplate, &s
d.data); | 323 rv = SEC_QuickDERDecodeItem(arena, derName, SEC_CertSerialNumberTemplate, |
| 324 &sd.data); |
| 353 | 325 |
| 354 if ( rv ) { | 326 if (rv) { |
| 355 » goto loser; | 327 goto loser; |
| 356 } | 328 } |
| 357 | 329 |
| 358 tmpptr = derName->data; | 330 tmpptr = derName->data; |
| 359 derName->data = (unsigned char*)PORT_Alloc(derName->len); | 331 derName->data = (unsigned char *)PORT_Alloc(derName->len); |
| 360 if ( derName->data == NULL ) { | 332 if (derName->data == NULL) { |
| 361 » goto loser; | 333 goto loser; |
| 362 } | 334 } |
| 363 | 335 |
| 364 PORT_Memcpy(derName->data, tmpptr, derName->len); | 336 PORT_Memcpy(derName->data, tmpptr, derName->len); |
| 365 | 337 |
| 366 PORT_FreeArena(arena, PR_FALSE); | 338 PORT_FreeArena(arena, PR_FALSE); |
| 367 return(SECSuccess); | 339 return (SECSuccess); |
| 368 | 340 |
| 369 loser: | 341 loser: |
| 370 PORT_FreeArena(arena, PR_FALSE); | 342 PORT_FreeArena(arena, PR_FALSE); |
| 371 return(SECFailure); | 343 return (SECFailure); |
| 372 } | 344 } |
| 373 | 345 |
| 374 /* | 346 /* |
| 375 * Generate a database key, based on serial number and issuer, from a | 347 * Generate a database key, based on serial number and issuer, from a |
| 376 * DER certificate. | 348 * DER certificate. |
| 377 */ | 349 */ |
| 378 SECStatus | 350 SECStatus |
| 379 CERT_KeyFromDERCert(PLArenaPool *reqArena, SECItem *derCert, SECItem *key) | 351 CERT_KeyFromDERCert(PLArenaPool *reqArena, SECItem *derCert, SECItem *key) |
| 380 { | 352 { |
| 381 int rv; | 353 int rv; |
| 382 CERTSignedData sd; | 354 CERTSignedData sd; |
| 383 CERTCertKey certkey; | 355 CERTCertKey certkey; |
| 384 | 356 |
| 385 if (!reqArena) { | 357 if (!reqArena) { |
| 386 PORT_SetError(SEC_ERROR_INVALID_ARGS); | 358 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 387 return SECFailure; | 359 return SECFailure; |
| 388 } | 360 } |
| 389 | 361 |
| 390 PORT_Memset(&sd, 0, sizeof(CERTSignedData)); | 362 PORT_Memset(&sd, 0, sizeof(CERTSignedData)); |
| 391 rv = SEC_QuickDERDecodeItem(reqArena, &sd, CERT_SignedDataTemplate, | 363 rv = |
| 392 derCert); | 364 SEC_QuickDERDecodeItem(reqArena, &sd, CERT_SignedDataTemplate, derCert); |
| 393 | 365 |
| 394 if ( rv ) { | 366 if (rv) { |
| 395 » goto loser; | 367 goto loser; |
| 396 } | 368 } |
| 397 | 369 |
| 398 PORT_Memset(&certkey, 0, sizeof(CERTCertKey)); | 370 PORT_Memset(&certkey, 0, sizeof(CERTCertKey)); |
| 399 rv = SEC_QuickDERDecodeItem(reqArena, &certkey, CERT_CertKeyTemplate, | 371 rv = SEC_QuickDERDecodeItem(reqArena, &certkey, CERT_CertKeyTemplate, |
| 400 &sd.data); | 372 &sd.data); |
| 401 | 373 |
| 402 if ( rv ) { | 374 if (rv) { |
| 403 » goto loser; | 375 goto loser; |
| 404 } | 376 } |
| 405 | 377 |
| 406 return(CERT_KeyFromIssuerAndSN(reqArena, &certkey.derIssuer, | 378 return (CERT_KeyFromIssuerAndSN(reqArena, &certkey.derIssuer, |
| 407 » » » » &certkey.serialNumber, key)); | 379 &certkey.serialNumber, key)); |
| 408 loser: | 380 loser: |
| 409 return(SECFailure); | 381 return (SECFailure); |
| 410 } | 382 } |
| 411 | 383 |
| 412 /* | 384 /* |
| 413 * fill in keyUsage field of the cert based on the cert extension | 385 * fill in keyUsage field of the cert based on the cert extension |
| 414 * if the extension is not critical, then we allow all uses | 386 * if the extension is not critical, then we allow all uses |
| 415 */ | 387 */ |
| 416 static SECStatus | 388 static SECStatus |
| 417 GetKeyUsage(CERTCertificate *cert) | 389 GetKeyUsage(CERTCertificate *cert) |
| 418 { | 390 { |
| 419 SECStatus rv; | 391 SECStatus rv; |
| 420 SECItem tmpitem; | 392 SECItem tmpitem; |
| 421 | 393 |
| 422 rv = CERT_FindKeyUsageExtension(cert, &tmpitem); | 394 rv = CERT_FindKeyUsageExtension(cert, &tmpitem); |
| 423 if ( rv == SECSuccess ) { | 395 if (rv == SECSuccess) { |
| 424 » /* remember the actual value of the extension */ | 396 /* remember the actual value of the extension */ |
| 425 » cert->rawKeyUsage = tmpitem.data[0]; | 397 cert->rawKeyUsage = tmpitem.data[0]; |
| 426 » cert->keyUsagePresent = PR_TRUE; | 398 cert->keyUsagePresent = PR_TRUE; |
| 427 » cert->keyUsage = tmpitem.data[0]; | 399 cert->keyUsage = tmpitem.data[0]; |
| 428 | 400 |
| 429 » PORT_Free(tmpitem.data); | 401 PORT_Free(tmpitem.data); |
| 430 » tmpitem.data = NULL; | 402 tmpitem.data = NULL; |
| 431 » | |
| 432 } else { | 403 } else { |
| 433 » /* if the extension is not present, then we allow all uses */ | 404 /* if the extension is not present, then we allow all uses */ |
| 434 » cert->keyUsage = KU_ALL; | 405 cert->keyUsage = KU_ALL; |
| 435 » cert->rawKeyUsage = KU_ALL; | 406 cert->rawKeyUsage = KU_ALL; |
| 436 » cert->keyUsagePresent = PR_FALSE; | 407 cert->keyUsagePresent = PR_FALSE; |
| 437 } | 408 } |
| 438 | 409 |
| 439 if ( CERT_GovtApprovedBitSet(cert) ) { | 410 if (CERT_GovtApprovedBitSet(cert)) { |
| 440 » cert->keyUsage |= KU_NS_GOVT_APPROVED; | 411 cert->keyUsage |= KU_NS_GOVT_APPROVED; |
| 441 » cert->rawKeyUsage |= KU_NS_GOVT_APPROVED; | 412 cert->rawKeyUsage |= KU_NS_GOVT_APPROVED; |
| 442 } | 413 } |
| 443 | 414 |
| 444 return(SECSuccess); | 415 return (SECSuccess); |
| 445 } | 416 } |
| 446 | 417 |
| 447 | |
| 448 static SECStatus | 418 static SECStatus |
| 449 findOIDinOIDSeqByTagNum(CERTOidSequence *seq, SECOidTag tagnum) | 419 findOIDinOIDSeqByTagNum(CERTOidSequence *seq, SECOidTag tagnum) |
| 450 { | 420 { |
| 451 SECItem **oids; | 421 SECItem **oids; |
| 452 SECItem *oid; | 422 SECItem *oid; |
| 453 SECStatus rv = SECFailure; | 423 SECStatus rv = SECFailure; |
| 454 | 424 |
| 455 if (seq != NULL) { | 425 if (seq != NULL) { |
| 456 » oids = seq->oids; | 426 oids = seq->oids; |
| 457 » while (oids != NULL && *oids != NULL) { | 427 while (oids != NULL && *oids != NULL) { |
| 458 » oid = *oids; | 428 oid = *oids; |
| 459 » if (SECOID_FindOIDTag(oid) == tagnum) { | 429 if (SECOID_FindOIDTag(oid) == tagnum) { |
| 460 » » rv = SECSuccess; | 430 rv = SECSuccess; |
| 461 » » break; | 431 break; |
| 462 » } | 432 } |
| 463 » oids++; | 433 oids++; |
| 464 » } | 434 } |
| 465 } | 435 } |
| 466 return rv; | 436 return rv; |
| 467 } | 437 } |
| 468 | 438 |
| 469 /* | 439 /* |
| 470 * fill in nsCertType field of the cert based on the cert extension | 440 * fill in nsCertType field of the cert based on the cert extension |
| 471 */ | 441 */ |
| 472 SECStatus | 442 SECStatus |
| 473 cert_GetCertType(CERTCertificate *cert) | 443 cert_GetCertType(CERTCertificate *cert) |
| 474 { | 444 { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 493 SECItem tmpitem; | 463 SECItem tmpitem; |
| 494 SECItem encodedExtKeyUsage; | 464 SECItem encodedExtKeyUsage; |
| 495 CERTOidSequence *extKeyUsage = NULL; | 465 CERTOidSequence *extKeyUsage = NULL; |
| 496 PRBool basicConstraintPresent = PR_FALSE; | 466 PRBool basicConstraintPresent = PR_FALSE; |
| 497 CERTBasicConstraints basicConstraint; | 467 CERTBasicConstraints basicConstraint; |
| 498 PRUint32 nsCertType = 0; | 468 PRUint32 nsCertType = 0; |
| 499 | 469 |
| 500 tmpitem.data = NULL; | 470 tmpitem.data = NULL; |
| 501 CERT_FindNSCertTypeExtension(cert, &tmpitem); | 471 CERT_FindNSCertTypeExtension(cert, &tmpitem); |
| 502 encodedExtKeyUsage.data = NULL; | 472 encodedExtKeyUsage.data = NULL; |
| 503 rv = CERT_FindCertExtension(cert, SEC_OID_X509_EXT_KEY_USAGE, | 473 rv = CERT_FindCertExtension(cert, SEC_OID_X509_EXT_KEY_USAGE, |
| 504 » » » » &encodedExtKeyUsage); | 474 &encodedExtKeyUsage); |
| 505 if (rv == SECSuccess) { | 475 if (rv == SECSuccess) { |
| 506 » extKeyUsage = CERT_DecodeOidSequence(&encodedExtKeyUsage); | 476 extKeyUsage = CERT_DecodeOidSequence(&encodedExtKeyUsage); |
| 507 } | 477 } |
| 508 rv = CERT_FindBasicConstraintExten(cert, &basicConstraint); | 478 rv = CERT_FindBasicConstraintExten(cert, &basicConstraint); |
| 509 if (rv == SECSuccess) { | 479 if (rv == SECSuccess) { |
| 510 » basicConstraintPresent = PR_TRUE; | 480 basicConstraintPresent = PR_TRUE; |
| 511 } | 481 } |
| 512 if (tmpitem.data != NULL || extKeyUsage != NULL) { | 482 if (tmpitem.data != NULL || extKeyUsage != NULL) { |
| 513 » if (tmpitem.data == NULL) { | 483 if (tmpitem.data == NULL) { |
| 514 » nsCertType = 0; | 484 nsCertType = 0; |
| 515 » } else { | 485 } else { |
| 516 » nsCertType = tmpitem.data[0]; | 486 nsCertType = tmpitem.data[0]; |
| 517 » } | 487 } |
| 518 | 488 |
| 519 » /* free tmpitem data pointer to avoid memory leak */ | 489 /* free tmpitem data pointer to avoid memory leak */ |
| 520 » PORT_Free(tmpitem.data); | 490 PORT_Free(tmpitem.data); |
| 521 » tmpitem.data = NULL; | 491 tmpitem.data = NULL; |
| 522 » | 492 |
| 523 » /* | 493 /* |
| 524 » * for this release, we will allow SSL certs with an email address | 494 * for this release, we will allow SSL certs with an email address |
| 525 » * to be used for email | 495 * to be used for email |
| 526 » */ | 496 */ |
| 527 » if ( ( nsCertType & NS_CERT_TYPE_SSL_CLIENT ) && | 497 if ((nsCertType & NS_CERT_TYPE_SSL_CLIENT) && cert->emailAddr && |
| 528 » cert->emailAddr && cert->emailAddr[0]) { | 498 cert->emailAddr[0]) { |
| 529 » nsCertType |= NS_CERT_TYPE_EMAIL; | 499 nsCertType |= NS_CERT_TYPE_EMAIL; |
| 530 » } | 500 } |
| 531 » /* | 501 /* |
| 532 » * for this release, we will allow SSL intermediate CAs to be | 502 * for this release, we will allow SSL intermediate CAs to be |
| 533 » * email intermediate CAs too. | 503 * email intermediate CAs too. |
| 534 » */ | 504 */ |
| 535 » if ( nsCertType & NS_CERT_TYPE_SSL_CA ) { | 505 if (nsCertType & NS_CERT_TYPE_SSL_CA) { |
| 536 » nsCertType |= NS_CERT_TYPE_EMAIL_CA; | 506 nsCertType |= NS_CERT_TYPE_EMAIL_CA; |
| 537 » } | 507 } |
| 538 » /* | 508 /* |
| 539 » * allow a cert with the extended key usage of EMail Protect | 509 * allow a cert with the extended key usage of EMail Protect |
| 540 » * to be used for email or as an email CA, if basic constraints | 510 * to be used for email or as an email CA, if basic constraints |
| 541 » * indicates that it is a CA. | 511 * indicates that it is a CA. |
| 542 » */ | 512 */ |
| 543 » if (findOIDinOIDSeqByTagNum(extKeyUsage, | 513 if (findOIDinOIDSeqByTagNum(extKeyUsage, |
| 544 » » » » SEC_OID_EXT_KEY_USAGE_EMAIL_PROTECT) == | 514 SEC_OID_EXT_KEY_USAGE_EMAIL_PROTECT) == |
| 545 » SECSuccess) { | 515 SECSuccess) { |
| 546 » if (basicConstraintPresent == PR_TRUE && | 516 if (basicConstraintPresent == PR_TRUE && (basicConstraint.isCA)) { |
| 547 » » (basicConstraint.isCA)) { | 517 nsCertType |= NS_CERT_TYPE_EMAIL_CA; |
| 548 » » nsCertType |= NS_CERT_TYPE_EMAIL_CA; | 518 } else { |
| 549 » } else { | 519 nsCertType |= NS_CERT_TYPE_EMAIL; |
| 550 » » nsCertType |= NS_CERT_TYPE_EMAIL; | 520 } |
| 551 » } | 521 } |
| 552 » } | 522 if (findOIDinOIDSeqByTagNum( |
| 553 » if (findOIDinOIDSeqByTagNum(extKeyUsage, | 523 extKeyUsage, SEC_OID_EXT_KEY_USAGE_SERVER_AUTH) == SECSuccess) { |
| 554 » » » » SEC_OID_EXT_KEY_USAGE_SERVER_AUTH) == | 524 if (basicConstraintPresent == PR_TRUE && (basicConstraint.isCA)) { |
| 555 » SECSuccess){ | 525 nsCertType |= NS_CERT_TYPE_SSL_CA; |
| 556 » if (basicConstraintPresent == PR_TRUE && | 526 } else { |
| 557 » » (basicConstraint.isCA)) { | 527 nsCertType |= NS_CERT_TYPE_SSL_SERVER; |
| 558 » » nsCertType |= NS_CERT_TYPE_SSL_CA; | 528 } |
| 559 » } else { | 529 } |
| 560 » » nsCertType |= NS_CERT_TYPE_SSL_SERVER; | 530 /* |
| 561 » } | 531 * Treat certs with step-up OID as also having SSL server type. |
| 562 » } | 532 * COMODO needs this behaviour until June 2020. See Bug 737802. |
| 563 » /* | 533 */ |
| 564 » * Treat certs with step-up OID as also having SSL server type. | 534 if (findOIDinOIDSeqByTagNum(extKeyUsage, |
| 565 » * COMODO needs this behaviour until June 2020. See Bug 737802. | 535 SEC_OID_NS_KEY_USAGE_GOVT_APPROVED) == |
| 566 » */ | 536 SECSuccess) { |
| 567 » if (findOIDinOIDSeqByTagNum(extKeyUsage, | 537 if (basicConstraintPresent == PR_TRUE && (basicConstraint.isCA)) { |
| 568 » » » » SEC_OID_NS_KEY_USAGE_GOVT_APPROVED) == | 538 nsCertType |= NS_CERT_TYPE_SSL_CA; |
| 569 » SECSuccess){ | 539 } else { |
| 570 » if (basicConstraintPresent == PR_TRUE && | 540 nsCertType |= NS_CERT_TYPE_SSL_SERVER; |
| 571 » » (basicConstraint.isCA)) { | 541 } |
| 572 » » nsCertType |= NS_CERT_TYPE_SSL_CA; | 542 } |
| 573 » } else { | 543 if (findOIDinOIDSeqByTagNum( |
| 574 » » nsCertType |= NS_CERT_TYPE_SSL_SERVER; | 544 extKeyUsage, SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH) == SECSuccess) { |
| 575 » } | 545 if (basicConstraintPresent == PR_TRUE && (basicConstraint.isCA)) { |
| 576 » } | 546 nsCertType |= NS_CERT_TYPE_SSL_CA; |
| 577 » if (findOIDinOIDSeqByTagNum(extKeyUsage, | 547 } else { |
| 578 » » » » SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH) == | 548 nsCertType |= NS_CERT_TYPE_SSL_CLIENT; |
| 579 » SECSuccess){ | 549 } |
| 580 » if (basicConstraintPresent == PR_TRUE && | 550 } |
| 581 » » (basicConstraint.isCA)) { | 551 if (findOIDinOIDSeqByTagNum( |
| 582 » » nsCertType |= NS_CERT_TYPE_SSL_CA; | 552 extKeyUsage, SEC_OID_EXT_KEY_USAGE_CODE_SIGN) == SECSuccess) { |
| 583 » } else { | 553 if (basicConstraintPresent == PR_TRUE && (basicConstraint.isCA)) { |
| 584 » » nsCertType |= NS_CERT_TYPE_SSL_CLIENT; | 554 nsCertType |= NS_CERT_TYPE_OBJECT_SIGNING_CA; |
| 585 » } | 555 } else { |
| 586 » } | 556 nsCertType |= NS_CERT_TYPE_OBJECT_SIGNING; |
| 587 » if (findOIDinOIDSeqByTagNum(extKeyUsage, | 557 } |
| 588 » » » » SEC_OID_EXT_KEY_USAGE_CODE_SIGN) == | 558 } |
| 589 » SECSuccess) { | 559 if (findOIDinOIDSeqByTagNum( |
| 590 » if (basicConstraintPresent == PR_TRUE && | 560 extKeyUsage, SEC_OID_EXT_KEY_USAGE_TIME_STAMP) == SECSuccess) { |
| 591 » » (basicConstraint.isCA)) { | 561 nsCertType |= EXT_KEY_USAGE_TIME_STAMP; |
| 592 » » nsCertType |= NS_CERT_TYPE_OBJECT_SIGNING_CA; | 562 } |
| 593 » } else { | 563 if (findOIDinOIDSeqByTagNum(extKeyUsage, SEC_OID_OCSP_RESPONDER) == |
| 594 » » nsCertType |= NS_CERT_TYPE_OBJECT_SIGNING; | 564 SECSuccess) { |
| 595 » } | 565 nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER; |
| 596 » } | 566 } |
| 597 » if (findOIDinOIDSeqByTagNum(extKeyUsage, | |
| 598 » » » » SEC_OID_EXT_KEY_USAGE_TIME_STAMP) == | |
| 599 » SECSuccess) { | |
| 600 » nsCertType |= EXT_KEY_USAGE_TIME_STAMP; | |
| 601 » } | |
| 602 » if (findOIDinOIDSeqByTagNum(extKeyUsage, | |
| 603 » » » » SEC_OID_OCSP_RESPONDER) == | |
| 604 » SECSuccess) { | |
| 605 » nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER; | |
| 606 » } | |
| 607 } else { | 567 } else { |
| 608 » /* If no NS Cert Type extension and no EKU extension, then */ | 568 /* If no NS Cert Type extension and no EKU extension, then */ |
| 609 » nsCertType = 0; | 569 nsCertType = 0; |
| 610 » if (CERT_IsCACert(cert, &nsCertType)) | 570 if (CERT_IsCACert(cert, &nsCertType)) |
| 611 » nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER; | 571 nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER; |
| 612 » /* if the basic constraint extension says the cert is a CA, then | 572 /* if the basic constraint extension says the cert is a CA, then |
| 613 » allow SSL CA and EMAIL CA and Status Responder */ | 573 allow SSL CA and EMAIL CA and Status Responder */ |
| 614 » if (basicConstraintPresent && basicConstraint.isCA ) { | 574 if (basicConstraintPresent && basicConstraint.isCA) { |
| 615 » nsCertType |= (NS_CERT_TYPE_SSL_CA | | 575 nsCertType |= (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA | |
| 616 » » NS_CERT_TYPE_EMAIL_CA | | 576 EXT_KEY_USAGE_STATUS_RESPONDER); |
| 617 » » EXT_KEY_USAGE_STATUS_RESPONDER); | 577 } |
| 618 » } | 578 /* allow any ssl or email (no ca or object signing. */ |
| 619 » /* allow any ssl or email (no ca or object signing. */ | 579 nsCertType |= NS_CERT_TYPE_SSL_CLIENT | NS_CERT_TYPE_SSL_SERVER | |
| 620 » nsCertType |= NS_CERT_TYPE_SSL_CLIENT | NS_CERT_TYPE_SSL_SERVER | | 580 NS_CERT_TYPE_EMAIL; |
| 621 » NS_CERT_TYPE_EMAIL; | |
| 622 } | 581 } |
| 623 | 582 |
| 624 if (encodedExtKeyUsage.data != NULL) { | 583 if (encodedExtKeyUsage.data != NULL) { |
| 625 » PORT_Free(encodedExtKeyUsage.data); | 584 PORT_Free(encodedExtKeyUsage.data); |
| 626 } | 585 } |
| 627 if (extKeyUsage != NULL) { | 586 if (extKeyUsage != NULL) { |
| 628 » CERT_DestroyOidSequence(extKeyUsage); | 587 CERT_DestroyOidSequence(extKeyUsage); |
| 629 } | 588 } |
| 630 return nsCertType; | 589 return nsCertType; |
| 631 } | 590 } |
| 632 | 591 |
| 633 /* | 592 /* |
| 634 * cert_GetKeyID() - extract or generate the subjectKeyID from a certificate | 593 * cert_GetKeyID() - extract or generate the subjectKeyID from a certificate |
| 635 */ | 594 */ |
| 636 SECStatus | 595 SECStatus |
| 637 cert_GetKeyID(CERTCertificate *cert) | 596 cert_GetKeyID(CERTCertificate *cert) |
| 638 { | 597 { |
| 639 SECItem tmpitem; | 598 SECItem tmpitem; |
| 640 SECStatus rv; | 599 SECStatus rv; |
| 641 | 600 |
| 642 cert->subjectKeyID.len = 0; | 601 cert->subjectKeyID.len = 0; |
| 643 | 602 |
| 644 /* see of the cert has a key identifier extension */ | 603 /* see of the cert has a key identifier extension */ |
| 645 rv = CERT_FindSubjectKeyIDExtension(cert, &tmpitem); | 604 rv = CERT_FindSubjectKeyIDExtension(cert, &tmpitem); |
| 646 if ( rv == SECSuccess ) { | 605 if (rv == SECSuccess) { |
| 647 » cert->subjectKeyID.data = (unsigned char*) PORT_ArenaAlloc(cert->arena,
tmpitem.len); | 606 cert->subjectKeyID.data = |
| 648 » if ( cert->subjectKeyID.data != NULL ) { | 607 (unsigned char *)PORT_ArenaAlloc(cert->arena, tmpitem.len); |
| 649 » PORT_Memcpy(cert->subjectKeyID.data, tmpitem.data, tmpitem.len); | 608 if (cert->subjectKeyID.data != NULL) { |
| 650 » cert->subjectKeyID.len = tmpitem.len; | 609 PORT_Memcpy(cert->subjectKeyID.data, tmpitem.data, tmpitem.len); |
| 651 » cert->keyIDGenerated = PR_FALSE; | 610 cert->subjectKeyID.len = tmpitem.len; |
| 652 » } | 611 cert->keyIDGenerated = PR_FALSE; |
| 653 » | 612 } |
| 654 » PORT_Free(tmpitem.data); | 613 |
| 655 } | 614 PORT_Free(tmpitem.data); |
| 656 | |
| 657 /* if the cert doesn't have a key identifier extension, then generate one*/ | |
| 658 if ( cert->subjectKeyID.len == 0 ) { | |
| 659 » /* | |
| 660 » * pkix says that if the subjectKeyID is not present, then we should | |
| 661 » * use the SHA-1 hash of the DER-encoded publicKeyInfo from the cert | |
| 662 » */ | |
| 663 » cert->subjectKeyID.data = (unsigned char *)PORT_ArenaAlloc(cert->arena,
SHA1_LENGTH); | |
| 664 » if ( cert->subjectKeyID.data != NULL ) { | |
| 665 » rv = PK11_HashBuf(SEC_OID_SHA1,cert->subjectKeyID.data, | |
| 666 » » » cert->derPublicKey.data, | |
| 667 » » » cert->derPublicKey.len); | |
| 668 » if ( rv == SECSuccess ) { | |
| 669 » » cert->subjectKeyID.len = SHA1_LENGTH; | |
| 670 » } | |
| 671 » } | |
| 672 } | 615 } |
| 673 | 616 |
| 674 if ( cert->subjectKeyID.len == 0 ) { | 617 /* if the cert doesn't have a key identifier extension, then generate one*/ |
| 675 » return(SECFailure); | 618 if (cert->subjectKeyID.len == 0) { |
| 619 /* |
| 620 * pkix says that if the subjectKeyID is not present, then we should |
| 621 * use the SHA-1 hash of the DER-encoded publicKeyInfo from the cert |
| 622 */ |
| 623 cert->subjectKeyID.data = |
| 624 (unsigned char *)PORT_ArenaAlloc(cert->arena, SHA1_LENGTH); |
| 625 if (cert->subjectKeyID.data != NULL) { |
| 626 rv = PK11_HashBuf(SEC_OID_SHA1, cert->subjectKeyID.data, |
| 627 cert->derPublicKey.data, cert->derPublicKey.len); |
| 628 if (rv == SECSuccess) { |
| 629 cert->subjectKeyID.len = SHA1_LENGTH; |
| 630 } |
| 631 } |
| 676 } | 632 } |
| 677 return(SECSuccess); | |
| 678 | 633 |
| 634 if (cert->subjectKeyID.len == 0) { |
| 635 return (SECFailure); |
| 636 } |
| 637 return (SECSuccess); |
| 679 } | 638 } |
| 680 | 639 |
| 681 static PRBool | 640 static PRBool |
| 682 cert_IsRootCert(CERTCertificate *cert) | 641 cert_IsRootCert(CERTCertificate *cert) |
| 683 { | 642 { |
| 684 SECStatus rv; | 643 SECStatus rv; |
| 685 SECItem tmpitem; | 644 SECItem tmpitem; |
| 686 | 645 |
| 687 /* cache the authKeyID extension, if present */ | 646 /* cache the authKeyID extension, if present */ |
| 688 cert->authKeyID = CERT_FindAuthKeyIDExten(cert->arena, cert); | 647 cert->authKeyID = CERT_FindAuthKeyIDExten(cert->arena, cert); |
| 689 | 648 |
| 690 /* it MUST be self-issued to be a root */ | 649 /* it MUST be self-issued to be a root */ |
| 691 if (cert->derIssuer.len == 0 || | 650 if (cert->derIssuer.len == 0 || |
| 692 !SECITEM_ItemsAreEqual(&cert->derIssuer, &cert->derSubject)) | 651 !SECITEM_ItemsAreEqual(&cert->derIssuer, &cert->derSubject)) { |
| 693 { | 652 return PR_FALSE; |
| 694 » return PR_FALSE; | |
| 695 } | 653 } |
| 696 | 654 |
| 697 /* check the authKeyID extension */ | 655 /* check the authKeyID extension */ |
| 698 if (cert->authKeyID) { | 656 if (cert->authKeyID) { |
| 699 » /* authority key identifier is present */ | 657 /* authority key identifier is present */ |
| 700 » if (cert->authKeyID->keyID.len > 0) { | 658 if (cert->authKeyID->keyID.len > 0) { |
| 701 » /* the keyIdentifier field is set, look for subjectKeyID */ | 659 /* the keyIdentifier field is set, look for subjectKeyID */ |
| 702 » rv = CERT_FindSubjectKeyIDExtension(cert, &tmpitem); | 660 rv = CERT_FindSubjectKeyIDExtension(cert, &tmpitem); |
| 703 » if (rv == SECSuccess) { | 661 if (rv == SECSuccess) { |
| 704 » » PRBool match; | 662 PRBool match; |
| 705 » » /* also present, they MUST match for it to be a root */ | 663 /* also present, they MUST match for it to be a root */ |
| 706 » » match = SECITEM_ItemsAreEqual(&cert->authKeyID->keyID, | 664 match = |
| 707 » » &tmpitem); | 665 SECITEM_ItemsAreEqual(&cert->authKeyID->keyID, &tmpitem); |
| 708 » » PORT_Free(tmpitem.data); | 666 PORT_Free(tmpitem.data); |
| 709 » » if (!match) return PR_FALSE; /* else fall through */ | 667 if (!match) |
| 710 » } else { | 668 return PR_FALSE; /* else fall through */ |
| 711 » » /* the subject key ID is required when AKI is present */ | 669 } else { |
| 712 » » return PR_FALSE; | 670 /* the subject key ID is required when AKI is present */ |
| 713 » } | 671 return PR_FALSE; |
| 714 » } | 672 } |
| 715 » if (cert->authKeyID->authCertIssuer) { | 673 } |
| 716 » SECItem *caName; | 674 if (cert->authKeyID->authCertIssuer) { |
| 717 » caName = (SECItem *)CERT_GetGeneralNameByType( | 675 SECItem *caName; |
| 718 » cert->authKeyID->authCertIssuer, | 676 caName = (SECItem *)CERT_GetGeneralNameByType( |
| 719 » certDirectoryName, PR_TRUE); | 677 cert->authKeyID->authCertIssuer, certDirectoryName, PR_TRUE); |
| 720 » if (caName) { | 678 if (caName) { |
| 721 » » if (!SECITEM_ItemsAreEqual(&cert->derIssuer, caName)) { | 679 if (!SECITEM_ItemsAreEqual(&cert->derIssuer, caName)) { |
| 722 » » return PR_FALSE; | 680 return PR_FALSE; |
| 723 » » } /* else fall through */ | 681 } /* else fall through */ |
| 724 » } /* else ??? could not get general name as directory name? */ | 682 } /* else ??? could not get general name as directory name? */ |
| 725 » } | 683 } |
| 726 » if (cert->authKeyID->authCertSerialNumber.len > 0) { | 684 if (cert->authKeyID->authCertSerialNumber.len > 0) { |
| 727 » if (!SECITEM_ItemsAreEqual(&cert->serialNumber, | 685 if (!SECITEM_ItemsAreEqual( |
| 728 » &cert->authKeyID->authCertSerialNumber)) { | 686 &cert->serialNumber, |
| 729 » » return PR_FALSE; | 687 &cert->authKeyID->authCertSerialNumber)) { |
| 730 » } /* else fall through */ | 688 return PR_FALSE; |
| 731 » } | 689 } /* else fall through */ |
| 732 » /* all of the AKI fields that were present passed the test */ | 690 } |
| 733 » return PR_TRUE; | 691 /* all of the AKI fields that were present passed the test */ |
| 692 return PR_TRUE; |
| 734 } | 693 } |
| 735 /* else the AKI was not present, so this is a root */ | 694 /* else the AKI was not present, so this is a root */ |
| 736 return PR_TRUE; | 695 return PR_TRUE; |
| 737 } | 696 } |
| 738 | 697 |
| 739 /* | 698 /* |
| 740 * take a DER certificate and decode it into a certificate structure | 699 * take a DER certificate and decode it into a certificate structure |
| 741 */ | 700 */ |
| 742 CERTCertificate * | 701 CERTCertificate * |
| 743 CERT_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER, | 702 CERT_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER, |
| 744 » » » char *nickname) | 703 char *nickname) |
| 745 { | 704 { |
| 746 CERTCertificate *cert; | 705 CERTCertificate *cert; |
| 747 PLArenaPool *arena; | 706 PLArenaPool *arena; |
| 748 void *data; | 707 void *data; |
| 749 int rv; | 708 int rv; |
| 750 int len; | 709 int len; |
| 751 char *tmpname; | 710 char *tmpname; |
| 752 | 711 |
| 753 /* make a new arena */ | 712 /* make a new arena */ |
| 754 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 713 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
| 755 | 714 |
| 756 if ( !arena ) { | 715 if (!arena) { |
| 757 » return 0; | 716 return 0; |
| 758 } | 717 } |
| 759 | 718 |
| 760 /* allocate the certificate structure */ | 719 /* allocate the certificate structure */ |
| 761 cert = (CERTCertificate *)PORT_ArenaZAlloc(arena, sizeof(CERTCertificate)); | 720 cert = (CERTCertificate *)PORT_ArenaZAlloc(arena, sizeof(CERTCertificate)); |
| 762 | 721 |
| 763 if ( !cert ) { | 722 if (!cert) { |
| 764 » goto loser; | 723 goto loser; |
| 765 } | 724 } |
| 766 | 725 |
| 767 cert->arena = arena; | 726 cert->arena = arena; |
| 768 | 727 |
| 769 if ( copyDER ) { | 728 if (copyDER) { |
| 770 » /* copy the DER data for the cert into this arena */ | 729 /* copy the DER data for the cert into this arena */ |
| 771 » data = (void *)PORT_ArenaAlloc(arena, derSignedCert->len); | 730 data = (void *)PORT_ArenaAlloc(arena, derSignedCert->len); |
| 772 » if ( !data ) { | 731 if (!data) { |
| 773 » goto loser; | 732 goto loser; |
| 774 » } | 733 } |
| 775 » cert->derCert.data = (unsigned char *)data; | 734 cert->derCert.data = (unsigned char *)data; |
| 776 » cert->derCert.len = derSignedCert->len; | 735 cert->derCert.len = derSignedCert->len; |
| 777 » PORT_Memcpy(data, derSignedCert->data, derSignedCert->len); | 736 PORT_Memcpy(data, derSignedCert->data, derSignedCert->len); |
| 778 } else { | 737 } else { |
| 779 » /* point to passed in DER data */ | 738 /* point to passed in DER data */ |
| 780 » cert->derCert = *derSignedCert; | 739 cert->derCert = *derSignedCert; |
| 781 } | 740 } |
| 782 | 741 |
| 783 /* decode the certificate info */ | 742 /* decode the certificate info */ |
| 784 rv = SEC_QuickDERDecodeItem(arena, cert, SEC_SignedCertificateTemplate, | 743 rv = SEC_QuickDERDecodeItem(arena, cert, SEC_SignedCertificateTemplate, |
| 785 » » &cert->derCert); | 744 &cert->derCert); |
| 786 | 745 |
| 787 if ( rv ) { | 746 if (rv) { |
| 788 » goto loser; | 747 goto loser; |
| 789 } | 748 } |
| 790 | 749 |
| 791 if (cert_HasUnknownCriticalExten (cert->extensions) == PR_TRUE) { | 750 if (cert_HasUnknownCriticalExten(cert->extensions) == PR_TRUE) { |
| 792 cert->options.bits.hasUnsupportedCriticalExt = PR_TRUE; | 751 cert->options.bits.hasUnsupportedCriticalExt = PR_TRUE; |
| 793 } | 752 } |
| 794 | 753 |
| 795 /* generate and save the database key for the cert */ | 754 /* generate and save the database key for the cert */ |
| 796 rv = CERT_KeyFromIssuerAndSN(arena, &cert->derIssuer, &cert->serialNumber, | 755 rv = CERT_KeyFromIssuerAndSN(arena, &cert->derIssuer, &cert->serialNumber, |
| 797 » » » &cert->certKey); | 756 &cert->certKey); |
| 798 if ( rv ) { | 757 if (rv) { |
| 799 » goto loser; | 758 goto loser; |
| 800 } | 759 } |
| 801 | 760 |
| 802 /* set the nickname */ | 761 /* set the nickname */ |
| 803 if ( nickname == NULL ) { | 762 if (nickname == NULL) { |
| 804 » cert->nickname = NULL; | 763 cert->nickname = NULL; |
| 805 } else { | 764 } else { |
| 806 » /* copy and install the nickname */ | 765 /* copy and install the nickname */ |
| 807 » len = PORT_Strlen(nickname) + 1; | 766 len = PORT_Strlen(nickname) + 1; |
| 808 » cert->nickname = (char*)PORT_ArenaAlloc(arena, len); | 767 cert->nickname = (char *)PORT_ArenaAlloc(arena, len); |
| 809 » if ( cert->nickname == NULL ) { | 768 if (cert->nickname == NULL) { |
| 810 » goto loser; | 769 goto loser; |
| 811 » } | 770 } |
| 812 | 771 |
| 813 » PORT_Memcpy(cert->nickname, nickname, len); | 772 PORT_Memcpy(cert->nickname, nickname, len); |
| 814 } | 773 } |
| 815 | 774 |
| 816 /* set the email address */ | 775 /* set the email address */ |
| 817 cert->emailAddr = cert_GetCertificateEmailAddresses(cert); | 776 cert->emailAddr = cert_GetCertificateEmailAddresses(cert); |
| 818 | 777 |
| 819 /* initialize the subjectKeyID */ | 778 /* initialize the subjectKeyID */ |
| 820 rv = cert_GetKeyID(cert); | 779 rv = cert_GetKeyID(cert); |
| 821 if ( rv != SECSuccess ) { | 780 if (rv != SECSuccess) { |
| 822 » goto loser; | 781 goto loser; |
| 823 } | 782 } |
| 824 | 783 |
| 825 /* initialize keyUsage */ | 784 /* initialize keyUsage */ |
| 826 rv = GetKeyUsage(cert); | 785 rv = GetKeyUsage(cert); |
| 827 if ( rv != SECSuccess ) { | 786 if (rv != SECSuccess) { |
| 828 » goto loser; | 787 goto loser; |
| 829 } | 788 } |
| 830 | 789 |
| 831 /* determine if this is a root cert */ | 790 /* determine if this is a root cert */ |
| 832 cert->isRoot = cert_IsRootCert(cert); | 791 cert->isRoot = cert_IsRootCert(cert); |
| 833 | 792 |
| 834 /* initialize the certType */ | 793 /* initialize the certType */ |
| 835 rv = cert_GetCertType(cert); | 794 rv = cert_GetCertType(cert); |
| 836 if ( rv != SECSuccess ) { | 795 if (rv != SECSuccess) { |
| 837 » goto loser; | 796 goto loser; |
| 838 } | 797 } |
| 839 | 798 |
| 840 tmpname = CERT_NameToAscii(&cert->subject); | 799 tmpname = CERT_NameToAscii(&cert->subject); |
| 841 if ( tmpname != NULL ) { | 800 if (tmpname != NULL) { |
| 842 » cert->subjectName = PORT_ArenaStrdup(cert->arena, tmpname); | 801 cert->subjectName = PORT_ArenaStrdup(cert->arena, tmpname); |
| 843 » PORT_Free(tmpname); | 802 PORT_Free(tmpname); |
| 844 } | 803 } |
| 845 | 804 |
| 846 tmpname = CERT_NameToAscii(&cert->issuer); | 805 tmpname = CERT_NameToAscii(&cert->issuer); |
| 847 if ( tmpname != NULL ) { | 806 if (tmpname != NULL) { |
| 848 » cert->issuerName = PORT_ArenaStrdup(cert->arena, tmpname); | 807 cert->issuerName = PORT_ArenaStrdup(cert->arena, tmpname); |
| 849 » PORT_Free(tmpname); | 808 PORT_Free(tmpname); |
| 850 } | 809 } |
| 851 | 810 |
| 852 cert->referenceCount = 1; | 811 cert->referenceCount = 1; |
| 853 cert->slot = NULL; | 812 cert->slot = NULL; |
| 854 cert->pkcs11ID = CK_INVALID_HANDLE; | 813 cert->pkcs11ID = CK_INVALID_HANDLE; |
| 855 cert->dbnickname = NULL; | 814 cert->dbnickname = NULL; |
| 856 | 815 |
| 857 return(cert); | 816 return (cert); |
| 858 | 817 |
| 859 loser: | 818 loser: |
| 860 | 819 |
| 861 if ( arena ) { | 820 if (arena) { |
| 862 » PORT_FreeArena(arena, PR_FALSE); | 821 PORT_FreeArena(arena, PR_FALSE); |
| 863 } | 822 } |
| 864 | 823 |
| 865 return(0); | 824 return (0); |
| 866 } | 825 } |
| 867 | 826 |
| 868 CERTCertificate * | 827 CERTCertificate * |
| 869 __CERT_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER, | 828 __CERT_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER, |
| 870 » » » char *nickname) | 829 char *nickname) |
| 871 { | 830 { |
| 872 return CERT_DecodeDERCertificate(derSignedCert, copyDER, nickname); | 831 return CERT_DecodeDERCertificate(derSignedCert, copyDER, nickname); |
| 873 } | 832 } |
| 874 | 833 |
| 875 | |
| 876 CERTValidity * | 834 CERTValidity * |
| 877 CERT_CreateValidity(PRTime notBefore, PRTime notAfter) | 835 CERT_CreateValidity(PRTime notBefore, PRTime notAfter) |
| 878 { | 836 { |
| 879 CERTValidity *v; | 837 CERTValidity *v; |
| 880 int rv; | 838 int rv; |
| 881 PLArenaPool *arena; | 839 PLArenaPool *arena; |
| 882 | 840 |
| 883 if (notBefore > notAfter) { | 841 if (notBefore > notAfter) { |
| 884 PORT_SetError(SEC_ERROR_INVALID_ARGS); | 842 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 885 return NULL; | 843 return NULL; |
| 886 } | 844 } |
| 887 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 845 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
| 888 | 846 |
| 889 if ( !arena ) { | 847 if (!arena) { |
| 890 » return(0); | 848 return (0); |
| 891 } | 849 } |
| 892 | 850 |
| 893 v = (CERTValidity*) PORT_ArenaZAlloc(arena, sizeof(CERTValidity)); | 851 v = (CERTValidity *)PORT_ArenaZAlloc(arena, sizeof(CERTValidity)); |
| 894 if (v) { | 852 if (v) { |
| 895 » v->arena = arena; | 853 v->arena = arena; |
| 896 » rv = DER_EncodeTimeChoice(arena, &v->notBefore, notBefore); | 854 rv = DER_EncodeTimeChoice(arena, &v->notBefore, notBefore); |
| 897 » if (rv) goto loser; | 855 if (rv) |
| 898 » rv = DER_EncodeTimeChoice(arena, &v->notAfter, notAfter); | 856 goto loser; |
| 899 » if (rv) goto loser; | 857 rv = DER_EncodeTimeChoice(arena, &v->notAfter, notAfter); |
| 858 if (rv) |
| 859 goto loser; |
| 900 } | 860 } |
| 901 return v; | 861 return v; |
| 902 | 862 |
| 903 loser: | 863 loser: |
| 904 CERT_DestroyValidity(v); | 864 CERT_DestroyValidity(v); |
| 905 return 0; | 865 return 0; |
| 906 } | 866 } |
| 907 | 867 |
| 908 SECStatus | 868 SECStatus |
| 909 CERT_CopyValidity(PLArenaPool *arena, CERTValidity *to, CERTValidity *from) | 869 CERT_CopyValidity(PLArenaPool *arena, CERTValidity *to, CERTValidity *from) |
| 910 { | 870 { |
| 911 SECStatus rv; | 871 SECStatus rv; |
| 912 | 872 |
| 913 CERT_DestroyValidity(to); | 873 CERT_DestroyValidity(to); |
| 914 to->arena = arena; | 874 to->arena = arena; |
| 915 | 875 |
| 916 rv = SECITEM_CopyItem(arena, &to->notBefore, &from->notBefore); | 876 rv = SECITEM_CopyItem(arena, &to->notBefore, &from->notBefore); |
| 917 if (rv) return rv; | 877 if (rv) |
| 878 return rv; |
| 918 rv = SECITEM_CopyItem(arena, &to->notAfter, &from->notAfter); | 879 rv = SECITEM_CopyItem(arena, &to->notAfter, &from->notAfter); |
| 919 return rv; | 880 return rv; |
| 920 } | 881 } |
| 921 | 882 |
| 922 void | 883 void |
| 923 CERT_DestroyValidity(CERTValidity *v) | 884 CERT_DestroyValidity(CERTValidity *v) |
| 924 { | 885 { |
| 925 if (v && v->arena) { | 886 if (v && v->arena) { |
| 926 » PORT_FreeArena(v->arena, PR_FALSE); | 887 PORT_FreeArena(v->arena, PR_FALSE); |
| 927 } | 888 } |
| 928 return; | 889 return; |
| 929 } | 890 } |
| 930 | 891 |
| 931 /* | 892 /* |
| 932 ** Amount of time that a certifiate is allowed good before it is actually | 893 ** Amount of time that a certifiate is allowed good before it is actually |
| 933 ** good. This is used for pending certificates, ones that are about to be | 894 ** good. This is used for pending certificates, ones that are about to be |
| 934 ** valid. The slop is designed to allow for some variance in the clocks | 895 ** valid. The slop is designed to allow for some variance in the clocks |
| 935 ** of the machine checking the certificate. | 896 ** of the machine checking the certificate. |
| 936 */ | 897 */ |
| 937 #define PENDING_SLOP (24L*60L*60L)» » /* seconds per day */ | 898 #define PENDING_SLOP (24L * 60L * 60L) /* seconds per day */ |
| 938 static PRInt32 pendingSlop = PENDING_SLOP;» /* seconds */ | 899 static PRInt32 pendingSlop = PENDING_SLOP; /* seconds */ |
| 939 | 900 |
| 940 PRInt32 | 901 PRInt32 |
| 941 CERT_GetSlopTime(void) | 902 CERT_GetSlopTime(void) |
| 942 { | 903 { |
| 943 return pendingSlop;»» » /* seconds */ | 904 return pendingSlop; /* seconds */ |
| 944 } | 905 } |
| 945 | 906 |
| 946 SECStatus | 907 SECStatus CERT_SetSlopTime(PRInt32 slop) /* seconds */ |
| 947 CERT_SetSlopTime(PRInt32 slop)» » /* seconds */ | |
| 948 { | 908 { |
| 949 if (slop < 0) | 909 if (slop < 0) |
| 950 » return SECFailure; | 910 return SECFailure; |
| 951 pendingSlop = slop; | 911 pendingSlop = slop; |
| 952 return SECSuccess; | 912 return SECSuccess; |
| 953 } | 913 } |
| 954 | 914 |
| 955 SECStatus | 915 SECStatus |
| 956 CERT_GetCertTimes(const CERTCertificate *c, PRTime *notBefore, PRTime *notAfter) | 916 CERT_GetCertTimes(const CERTCertificate *c, PRTime *notBefore, PRTime *notAfter) |
| 957 { | 917 { |
| 958 SECStatus rv; | 918 SECStatus rv; |
| 959 | 919 |
| 960 if (!c || !notBefore || !notAfter) { | 920 if (!c || !notBefore || !notAfter) { |
| 961 PORT_SetError(SEC_ERROR_INVALID_ARGS); | 921 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 962 return SECFailure; | 922 return SECFailure; |
| 963 } | 923 } |
| 964 | 924 |
| 965 /* convert DER not-before time */ | 925 /* convert DER not-before time */ |
| 966 rv = DER_DecodeTimeChoice(notBefore, &c->validity.notBefore); | 926 rv = DER_DecodeTimeChoice(notBefore, &c->validity.notBefore); |
| 967 if (rv) { | 927 if (rv) { |
| 968 » return(SECFailure); | 928 return (SECFailure); |
| 969 } | 929 } |
| 970 | 930 |
| 971 /* convert DER not-after time */ | 931 /* convert DER not-after time */ |
| 972 rv = DER_DecodeTimeChoice(notAfter, &c->validity.notAfter); | 932 rv = DER_DecodeTimeChoice(notAfter, &c->validity.notAfter); |
| 973 if (rv) { | 933 if (rv) { |
| 974 » return(SECFailure); | 934 return (SECFailure); |
| 975 } | 935 } |
| 976 | 936 |
| 977 return(SECSuccess); | 937 return (SECSuccess); |
| 978 } | 938 } |
| 979 | 939 |
| 980 /* | 940 /* |
| 981 * Check the validity times of a certificate | 941 * Check the validity times of a certificate |
| 982 */ | 942 */ |
| 983 SECCertTimeValidity | 943 SECCertTimeValidity |
| 984 CERT_CheckCertValidTimes(const CERTCertificate *c, PRTime t, | 944 CERT_CheckCertValidTimes(const CERTCertificate *c, PRTime t, |
| 985 PRBool allowOverride) | 945 PRBool allowOverride) |
| 986 { | 946 { |
| 987 PRTime notBefore, notAfter, llPendingSlop, tmp1; | 947 PRTime notBefore, notAfter, llPendingSlop, tmp1; |
| 988 SECStatus rv; | 948 SECStatus rv; |
| 989 | 949 |
| 990 if (!c) { | 950 if (!c) { |
| 991 PORT_SetError(SEC_ERROR_INVALID_ARGS); | 951 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 992 return(secCertTimeUndetermined); | 952 return (secCertTimeUndetermined); |
| 993 } | 953 } |
| 994 /* if cert is already marked OK, then don't bother to check */ | 954 /* if cert is already marked OK, then don't bother to check */ |
| 995 if ( allowOverride && c->timeOK ) { | 955 if (allowOverride && c->timeOK) { |
| 996 » return(secCertTimeValid); | 956 return (secCertTimeValid); |
| 997 } | 957 } |
| 998 | 958 |
| 999 rv = CERT_GetCertTimes(c, ¬Before, ¬After); | 959 rv = CERT_GetCertTimes(c, ¬Before, ¬After); |
| 1000 | 960 |
| 1001 if (rv) { | 961 if (rv) { |
| 1002 » return(secCertTimeExpired); /*XXX is this the right thing to do here?*/ | 962 return (secCertTimeExpired); /*XXX is this the right thing to do here?*/ |
| 1003 } | 963 } |
| 1004 | 964 |
| 1005 LL_I2L(llPendingSlop, pendingSlop); | 965 LL_I2L(llPendingSlop, pendingSlop); |
| 1006 /* convert to micro seconds */ | 966 /* convert to micro seconds */ |
| 1007 LL_UI2L(tmp1, PR_USEC_PER_SEC); | 967 LL_UI2L(tmp1, PR_USEC_PER_SEC); |
| 1008 LL_MUL(llPendingSlop, llPendingSlop, tmp1); | 968 LL_MUL(llPendingSlop, llPendingSlop, tmp1); |
| 1009 LL_SUB(notBefore, notBefore, llPendingSlop); | 969 LL_SUB(notBefore, notBefore, llPendingSlop); |
| 1010 if ( LL_CMP( t, <, notBefore ) ) { | 970 if (LL_CMP(t, <, notBefore)) { |
| 1011 » PORT_SetError(SEC_ERROR_EXPIRED_CERTIFICATE); | 971 PORT_SetError(SEC_ERROR_EXPIRED_CERTIFICATE); |
| 1012 » return(secCertTimeNotValidYet); | 972 return (secCertTimeNotValidYet); |
| 1013 } | 973 } |
| 1014 if ( LL_CMP( t, >, notAfter) ) { | 974 if (LL_CMP(t, >, notAfter)) { |
| 1015 » PORT_SetError(SEC_ERROR_EXPIRED_CERTIFICATE); | 975 PORT_SetError(SEC_ERROR_EXPIRED_CERTIFICATE); |
| 1016 » return(secCertTimeExpired); | 976 return (secCertTimeExpired); |
| 1017 } | 977 } |
| 1018 | 978 |
| 1019 return(secCertTimeValid); | 979 return (secCertTimeValid); |
| 1020 } | 980 } |
| 1021 | 981 |
| 1022 SECStatus | 982 SECStatus |
| 1023 SEC_GetCrlTimes(CERTCrl *date, PRTime *notBefore, PRTime *notAfter) | 983 SEC_GetCrlTimes(CERTCrl *date, PRTime *notBefore, PRTime *notAfter) |
| 1024 { | 984 { |
| 1025 int rv; | 985 int rv; |
| 1026 | 986 |
| 1027 /* convert DER not-before time */ | 987 /* convert DER not-before time */ |
| 1028 rv = DER_DecodeTimeChoice(notBefore, &date->lastUpdate); | 988 rv = DER_DecodeTimeChoice(notBefore, &date->lastUpdate); |
| 1029 if (rv) { | 989 if (rv) { |
| 1030 » return(SECFailure); | 990 return (SECFailure); |
| 1031 } | 991 } |
| 1032 | 992 |
| 1033 /* convert DER not-after time */ | 993 /* convert DER not-after time */ |
| 1034 if (date->nextUpdate.data) { | 994 if (date->nextUpdate.data) { |
| 1035 » rv = DER_DecodeTimeChoice(notAfter, &date->nextUpdate); | 995 rv = DER_DecodeTimeChoice(notAfter, &date->nextUpdate); |
| 1036 » if (rv) { | 996 if (rv) { |
| 1037 » return(SECFailure); | 997 return (SECFailure); |
| 1038 » } | 998 } |
| 999 } else { |
| 1000 LL_I2L(*notAfter, 0L); |
| 1039 } | 1001 } |
| 1040 else { | 1002 return (SECSuccess); |
| 1041 » LL_I2L(*notAfter, 0L); | |
| 1042 } | |
| 1043 return(SECSuccess); | |
| 1044 } | 1003 } |
| 1045 | 1004 |
| 1046 /* These routines should probably be combined with the cert | 1005 /* These routines should probably be combined with the cert |
| 1047 * routines using an common extraction routine. | 1006 * routines using an common extraction routine. |
| 1048 */ | 1007 */ |
| 1049 SECCertTimeValidity | 1008 SECCertTimeValidity |
| 1050 SEC_CheckCrlTimes(CERTCrl *crl, PRTime t) { | 1009 SEC_CheckCrlTimes(CERTCrl *crl, PRTime t) |
| 1010 { |
| 1051 PRTime notBefore, notAfter, llPendingSlop, tmp1; | 1011 PRTime notBefore, notAfter, llPendingSlop, tmp1; |
| 1052 SECStatus rv; | 1012 SECStatus rv; |
| 1053 | 1013 |
| 1054 if (!crl) { | 1014 if (!crl) { |
| 1055 PORT_SetError(SEC_ERROR_INVALID_ARGS); | 1015 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 1056 return(secCertTimeUndetermined); | 1016 return (secCertTimeUndetermined); |
| 1057 } | 1017 } |
| 1058 | 1018 |
| 1059 rv = SEC_GetCrlTimes(crl, ¬Before, ¬After); | 1019 rv = SEC_GetCrlTimes(crl, ¬Before, ¬After); |
| 1060 | 1020 |
| 1061 if (rv) { | 1021 if (rv) { |
| 1062 » return(secCertTimeExpired); | 1022 return (secCertTimeExpired); |
| 1063 } | 1023 } |
| 1064 | 1024 |
| 1065 LL_I2L(llPendingSlop, pendingSlop); | 1025 LL_I2L(llPendingSlop, pendingSlop); |
| 1066 /* convert to micro seconds */ | 1026 /* convert to micro seconds */ |
| 1067 LL_I2L(tmp1, PR_USEC_PER_SEC); | 1027 LL_I2L(tmp1, PR_USEC_PER_SEC); |
| 1068 LL_MUL(llPendingSlop, llPendingSlop, tmp1); | 1028 LL_MUL(llPendingSlop, llPendingSlop, tmp1); |
| 1069 LL_SUB(notBefore, notBefore, llPendingSlop); | 1029 LL_SUB(notBefore, notBefore, llPendingSlop); |
| 1070 if ( LL_CMP( t, <, notBefore ) ) { | 1030 if (LL_CMP(t, <, notBefore)) { |
| 1071 » PORT_SetError(SEC_ERROR_CRL_EXPIRED); | 1031 PORT_SetError(SEC_ERROR_CRL_EXPIRED); |
| 1072 » return(secCertTimeNotValidYet); | 1032 return (secCertTimeNotValidYet); |
| 1073 } | 1033 } |
| 1074 | 1034 |
| 1075 /* If next update is omitted and the test for notBefore passes, then | 1035 /* If next update is omitted and the test for notBefore passes, then |
| 1076 we assume that the crl is up to date. | 1036 we assume that the crl is up to date. |
| 1077 */ | 1037 */ |
| 1078 if ( LL_IS_ZERO(notAfter) ) { | 1038 if (LL_IS_ZERO(notAfter)) { |
| 1079 » return(secCertTimeValid); | 1039 return (secCertTimeValid); |
| 1080 } | 1040 } |
| 1081 | 1041 |
| 1082 if ( LL_CMP( t, >, notAfter) ) { | 1042 if (LL_CMP(t, >, notAfter)) { |
| 1083 » PORT_SetError(SEC_ERROR_CRL_EXPIRED); | 1043 PORT_SetError(SEC_ERROR_CRL_EXPIRED); |
| 1084 » return(secCertTimeExpired); | 1044 return (secCertTimeExpired); |
| 1085 } | 1045 } |
| 1086 | 1046 |
| 1087 return(secCertTimeValid); | 1047 return (secCertTimeValid); |
| 1088 } | 1048 } |
| 1089 | 1049 |
| 1090 PRBool | 1050 PRBool |
| 1091 SEC_CrlIsNewer(CERTCrl *inNew, CERTCrl *old) { | 1051 SEC_CrlIsNewer(CERTCrl *inNew, CERTCrl *old) |
| 1052 { |
| 1092 PRTime newNotBefore, newNotAfter; | 1053 PRTime newNotBefore, newNotAfter; |
| 1093 PRTime oldNotBefore, oldNotAfter; | 1054 PRTime oldNotBefore, oldNotAfter; |
| 1094 SECStatus rv; | 1055 SECStatus rv; |
| 1095 | 1056 |
| 1096 /* problems with the new CRL? reject it */ | 1057 /* problems with the new CRL? reject it */ |
| 1097 rv = SEC_GetCrlTimes(inNew, &newNotBefore, &newNotAfter); | 1058 rv = SEC_GetCrlTimes(inNew, &newNotBefore, &newNotAfter); |
| 1098 if (rv) return PR_FALSE; | 1059 if (rv) |
| 1060 return PR_FALSE; |
| 1099 | 1061 |
| 1100 /* problems with the old CRL? replace it */ | 1062 /* problems with the old CRL? replace it */ |
| 1101 rv = SEC_GetCrlTimes(old, &oldNotBefore, &oldNotAfter); | 1063 rv = SEC_GetCrlTimes(old, &oldNotBefore, &oldNotAfter); |
| 1102 if (rv) return PR_TRUE; | 1064 if (rv) |
| 1065 return PR_TRUE; |
| 1103 | 1066 |
| 1104 /* Question: what about the notAfter's? */ | 1067 /* Question: what about the notAfter's? */ |
| 1105 return ((PRBool)LL_CMP(oldNotBefore, <, newNotBefore)); | 1068 return ((PRBool)LL_CMP(oldNotBefore, <, newNotBefore)); |
| 1106 } | 1069 } |
| 1107 | 1070 |
| 1108 /* | 1071 /* |
| 1109 * return required key usage and cert type based on cert usage | 1072 * return required key usage and cert type based on cert usage |
| 1110 */ | 1073 */ |
| 1111 SECStatus | 1074 SECStatus |
| 1112 CERT_KeyUsageAndTypeForCertUsage(SECCertUsage usage, | 1075 CERT_KeyUsageAndTypeForCertUsage(SECCertUsage usage, PRBool ca, |
| 1113 » » » » PRBool ca, | 1076 unsigned int *retKeyUsage, |
| 1114 » » » » unsigned int *retKeyUsage, | 1077 unsigned int *retCertType) |
| 1115 » » » » unsigned int *retCertType) | |
| 1116 { | 1078 { |
| 1117 unsigned int requiredKeyUsage = 0; | 1079 unsigned int requiredKeyUsage = 0; |
| 1118 unsigned int requiredCertType = 0; | 1080 unsigned int requiredCertType = 0; |
| 1119 | 1081 |
| 1120 if ( ca ) { | 1082 if (ca) { |
| 1121 » switch ( usage ) { | 1083 switch (usage) { |
| 1122 » case certUsageSSLServerWithStepUp: | 1084 case certUsageSSLServerWithStepUp: |
| 1123 » requiredKeyUsage = KU_NS_GOVT_APPROVED | KU_KEY_CERT_SIGN; | 1085 requiredKeyUsage = KU_NS_GOVT_APPROVED | KU_KEY_CERT_SIGN; |
| 1124 » requiredCertType = NS_CERT_TYPE_SSL_CA; | 1086 requiredCertType = NS_CERT_TYPE_SSL_CA; |
| 1125 » break; | 1087 break; |
| 1126 » case certUsageSSLClient: | 1088 case certUsageSSLClient: |
| 1127 » requiredKeyUsage = KU_KEY_CERT_SIGN; | 1089 requiredKeyUsage = KU_KEY_CERT_SIGN; |
| 1128 » requiredCertType = NS_CERT_TYPE_SSL_CA; | 1090 requiredCertType = NS_CERT_TYPE_SSL_CA; |
| 1129 » break; | 1091 break; |
| 1130 » case certUsageSSLServer: | 1092 case certUsageSSLServer: |
| 1131 » requiredKeyUsage = KU_KEY_CERT_SIGN; | 1093 requiredKeyUsage = KU_KEY_CERT_SIGN; |
| 1132 » requiredCertType = NS_CERT_TYPE_SSL_CA; | 1094 requiredCertType = NS_CERT_TYPE_SSL_CA; |
| 1133 » break; | 1095 break; |
| 1134 » case certUsageSSLCA: | 1096 case certUsageSSLCA: |
| 1135 » requiredKeyUsage = KU_KEY_CERT_SIGN; | 1097 requiredKeyUsage = KU_KEY_CERT_SIGN; |
| 1136 » requiredCertType = NS_CERT_TYPE_SSL_CA; | 1098 requiredCertType = NS_CERT_TYPE_SSL_CA; |
| 1137 » break; | 1099 break; |
| 1138 » case certUsageEmailSigner: | 1100 case certUsageEmailSigner: |
| 1139 » requiredKeyUsage = KU_KEY_CERT_SIGN; | 1101 requiredKeyUsage = KU_KEY_CERT_SIGN; |
| 1140 » requiredCertType = NS_CERT_TYPE_EMAIL_CA; | 1102 requiredCertType = NS_CERT_TYPE_EMAIL_CA; |
| 1141 » break; | 1103 break; |
| 1142 » case certUsageEmailRecipient: | 1104 case certUsageEmailRecipient: |
| 1143 » requiredKeyUsage = KU_KEY_CERT_SIGN; | 1105 requiredKeyUsage = KU_KEY_CERT_SIGN; |
| 1144 » requiredCertType = NS_CERT_TYPE_EMAIL_CA; | 1106 requiredCertType = NS_CERT_TYPE_EMAIL_CA; |
| 1145 » break; | 1107 break; |
| 1146 » case certUsageObjectSigner: | 1108 case certUsageObjectSigner: |
| 1147 » requiredKeyUsage = KU_KEY_CERT_SIGN; | 1109 requiredKeyUsage = KU_KEY_CERT_SIGN; |
| 1148 » requiredCertType = NS_CERT_TYPE_OBJECT_SIGNING_CA; | 1110 requiredCertType = NS_CERT_TYPE_OBJECT_SIGNING_CA; |
| 1149 » break; | 1111 break; |
| 1150 » case certUsageAnyCA: | 1112 case certUsageAnyCA: |
| 1151 » case certUsageVerifyCA: | 1113 case certUsageVerifyCA: |
| 1152 » case certUsageStatusResponder: | 1114 case certUsageStatusResponder: |
| 1153 » requiredKeyUsage = KU_KEY_CERT_SIGN; | 1115 requiredKeyUsage = KU_KEY_CERT_SIGN; |
| 1154 » requiredCertType = NS_CERT_TYPE_OBJECT_SIGNING_CA | | 1116 requiredCertType = NS_CERT_TYPE_OBJECT_SIGNING_CA | |
| 1155 » » NS_CERT_TYPE_EMAIL_CA | | 1117 NS_CERT_TYPE_EMAIL_CA | NS_CERT_TYPE_SSL_CA; |
| 1156 » » NS_CERT_TYPE_SSL_CA; | 1118 break; |
| 1157 » break; | 1119 default: |
| 1158 » default: | 1120 PORT_Assert(0); |
| 1159 » PORT_Assert(0); | 1121 goto loser; |
| 1160 » goto loser; | 1122 } |
| 1161 » } | |
| 1162 } else { | 1123 } else { |
| 1163 » switch ( usage ) { | 1124 switch (usage) { |
| 1164 » case certUsageSSLClient: | 1125 case certUsageSSLClient: |
| 1165 » /* | 1126 /* |
| 1166 » * RFC 5280 lists digitalSignature and keyAgreement for | 1127 * RFC 5280 lists digitalSignature and keyAgreement for |
| 1167 » * id-kp-clientAuth. NSS does not support the *_fixed_dh and | 1128 * id-kp-clientAuth. NSS does not support the *_fixed_dh and |
| 1168 » * *_fixed_ecdh client certificate types. | 1129 * *_fixed_ecdh client certificate types. |
| 1169 » */ | 1130 */ |
| 1170 » requiredKeyUsage = KU_DIGITAL_SIGNATURE; | 1131 requiredKeyUsage = KU_DIGITAL_SIGNATURE; |
| 1171 » requiredCertType = NS_CERT_TYPE_SSL_CLIENT; | 1132 requiredCertType = NS_CERT_TYPE_SSL_CLIENT; |
| 1172 » break; | 1133 break; |
| 1173 » case certUsageSSLServer: | 1134 case certUsageSSLServer: |
| 1174 » requiredKeyUsage = KU_KEY_AGREEMENT_OR_ENCIPHERMENT; | 1135 requiredKeyUsage = KU_KEY_AGREEMENT_OR_ENCIPHERMENT; |
| 1175 » requiredCertType = NS_CERT_TYPE_SSL_SERVER; | 1136 requiredCertType = NS_CERT_TYPE_SSL_SERVER; |
| 1176 » break; | 1137 break; |
| 1177 » case certUsageSSLServerWithStepUp: | 1138 case certUsageSSLServerWithStepUp: |
| 1178 » requiredKeyUsage = KU_KEY_AGREEMENT_OR_ENCIPHERMENT | | 1139 requiredKeyUsage = |
| 1179 » » KU_NS_GOVT_APPROVED; | 1140 KU_KEY_AGREEMENT_OR_ENCIPHERMENT | KU_NS_GOVT_APPROVED; |
| 1180 » requiredCertType = NS_CERT_TYPE_SSL_SERVER; | 1141 requiredCertType = NS_CERT_TYPE_SSL_SERVER; |
| 1181 » break; | 1142 break; |
| 1182 » case certUsageSSLCA: | 1143 case certUsageSSLCA: |
| 1183 » requiredKeyUsage = KU_KEY_CERT_SIGN; | 1144 requiredKeyUsage = KU_KEY_CERT_SIGN; |
| 1184 » requiredCertType = NS_CERT_TYPE_SSL_CA; | 1145 requiredCertType = NS_CERT_TYPE_SSL_CA; |
| 1185 » break; | 1146 break; |
| 1186 » case certUsageEmailSigner: | 1147 case certUsageEmailSigner: |
| 1187 » requiredKeyUsage = KU_DIGITAL_SIGNATURE_OR_NON_REPUDIATION; | 1148 requiredKeyUsage = KU_DIGITAL_SIGNATURE_OR_NON_REPUDIATION; |
| 1188 » requiredCertType = NS_CERT_TYPE_EMAIL; | 1149 requiredCertType = NS_CERT_TYPE_EMAIL; |
| 1189 » break; | 1150 break; |
| 1190 » case certUsageEmailRecipient: | 1151 case certUsageEmailRecipient: |
| 1191 » requiredKeyUsage = KU_KEY_AGREEMENT_OR_ENCIPHERMENT; | 1152 requiredKeyUsage = KU_KEY_AGREEMENT_OR_ENCIPHERMENT; |
| 1192 » requiredCertType = NS_CERT_TYPE_EMAIL; | 1153 requiredCertType = NS_CERT_TYPE_EMAIL; |
| 1193 » break; | 1154 break; |
| 1194 » case certUsageObjectSigner: | 1155 case certUsageObjectSigner: |
| 1195 » /* RFC 5280 lists only digitalSignature for id-kp-codeSigning. */ | 1156 /* RFC 5280 lists only digitalSignature for id-kp-codeSigning. |
| 1196 » requiredKeyUsage = KU_DIGITAL_SIGNATURE; | 1157 */ |
| 1197 » requiredCertType = NS_CERT_TYPE_OBJECT_SIGNING; | 1158 requiredKeyUsage = KU_DIGITAL_SIGNATURE; |
| 1198 » break; | 1159 requiredCertType = NS_CERT_TYPE_OBJECT_SIGNING; |
| 1199 » case certUsageStatusResponder: | 1160 break; |
| 1200 » requiredKeyUsage = KU_DIGITAL_SIGNATURE_OR_NON_REPUDIATION; | 1161 case certUsageStatusResponder: |
| 1201 » requiredCertType = EXT_KEY_USAGE_STATUS_RESPONDER; | 1162 requiredKeyUsage = KU_DIGITAL_SIGNATURE_OR_NON_REPUDIATION; |
| 1202 » break; | 1163 requiredCertType = EXT_KEY_USAGE_STATUS_RESPONDER; |
| 1203 » default: | 1164 break; |
| 1204 » PORT_Assert(0); | 1165 default: |
| 1205 » goto loser; | 1166 PORT_Assert(0); |
| 1206 » } | 1167 goto loser; |
| 1168 } |
| 1207 } | 1169 } |
| 1208 | 1170 |
| 1209 if ( retKeyUsage != NULL ) { | 1171 if (retKeyUsage != NULL) { |
| 1210 » *retKeyUsage = requiredKeyUsage; | 1172 *retKeyUsage = requiredKeyUsage; |
| 1211 } | 1173 } |
| 1212 if ( retCertType != NULL ) { | 1174 if (retCertType != NULL) { |
| 1213 » *retCertType = requiredCertType; | 1175 *retCertType = requiredCertType; |
| 1214 } | 1176 } |
| 1215 | 1177 |
| 1216 return(SECSuccess); | 1178 return (SECSuccess); |
| 1217 loser: | 1179 loser: |
| 1218 return(SECFailure); | 1180 return (SECFailure); |
| 1219 } | 1181 } |
| 1220 | 1182 |
| 1221 /* | 1183 /* |
| 1222 * check the key usage of a cert against a set of required values | 1184 * check the key usage of a cert against a set of required values |
| 1223 */ | 1185 */ |
| 1224 SECStatus | 1186 SECStatus |
| 1225 CERT_CheckKeyUsage(CERTCertificate *cert, unsigned int requiredUsage) | 1187 CERT_CheckKeyUsage(CERTCertificate *cert, unsigned int requiredUsage) |
| 1226 { | 1188 { |
| 1227 if (!cert) { | 1189 if (!cert) { |
| 1228 PORT_SetError(SEC_ERROR_INVALID_ARGS); | 1190 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 1229 » return SECFailure; | 1191 return SECFailure; |
| 1230 } | 1192 } |
| 1231 /* choose between key agreement or key encipherment based on key | 1193 /* choose between key agreement or key encipherment based on key |
| 1232 * type in cert | 1194 * type in cert |
| 1233 */ | 1195 */ |
| 1234 if ( requiredUsage & KU_KEY_AGREEMENT_OR_ENCIPHERMENT ) { | 1196 if (requiredUsage & KU_KEY_AGREEMENT_OR_ENCIPHERMENT) { |
| 1235 » KeyType keyType = CERT_GetCertKeyType(&cert->subjectPublicKeyInfo); | 1197 KeyType keyType = CERT_GetCertKeyType(&cert->subjectPublicKeyInfo); |
| 1236 » /* turn off the special bit */ | 1198 /* turn off the special bit */ |
| 1237 » requiredUsage &= (~KU_KEY_AGREEMENT_OR_ENCIPHERMENT); | 1199 requiredUsage &= (~KU_KEY_AGREEMENT_OR_ENCIPHERMENT); |
| 1238 | 1200 |
| 1239 » switch (keyType) { | 1201 switch (keyType) { |
| 1240 » case rsaKey: | 1202 case rsaKey: |
| 1241 » requiredUsage |= KU_KEY_ENCIPHERMENT; | 1203 requiredUsage |= KU_KEY_ENCIPHERMENT; |
| 1242 » break; | 1204 break; |
| 1243 » case dsaKey: | 1205 case dsaKey: |
| 1244 » requiredUsage |= KU_DIGITAL_SIGNATURE; | 1206 requiredUsage |= KU_DIGITAL_SIGNATURE; |
| 1245 » break; | 1207 break; |
| 1246 » case dhKey: | 1208 case dhKey: |
| 1247 » requiredUsage |= KU_KEY_AGREEMENT; | 1209 requiredUsage |= KU_KEY_AGREEMENT; |
| 1248 » break; | 1210 break; |
| 1249 » case ecKey: | 1211 case ecKey: |
| 1250 » /* Accept either signature or agreement. */ | 1212 /* Accept either signature or agreement. */ |
| 1251 » if (!(cert->keyUsage & (KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT))) | 1213 if (!(cert->keyUsage & |
| 1252 » » goto loser; | 1214 (KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT))) |
| 1253 » break; | 1215 goto loser; |
| 1254 » default: | 1216 break; |
| 1255 » goto loser; | 1217 default: |
| 1256 » } | 1218 goto loser; |
| 1219 } |
| 1257 } | 1220 } |
| 1258 | 1221 |
| 1259 /* Allow either digital signature or non-repudiation */ | 1222 /* Allow either digital signature or non-repudiation */ |
| 1260 if ( requiredUsage & KU_DIGITAL_SIGNATURE_OR_NON_REPUDIATION ) { | 1223 if (requiredUsage & KU_DIGITAL_SIGNATURE_OR_NON_REPUDIATION) { |
| 1261 » /* turn off the special bit */ | 1224 /* turn off the special bit */ |
| 1262 » requiredUsage &= (~KU_DIGITAL_SIGNATURE_OR_NON_REPUDIATION); | 1225 requiredUsage &= (~KU_DIGITAL_SIGNATURE_OR_NON_REPUDIATION); |
| 1263 | 1226 |
| 1264 if (!(cert->keyUsage & (KU_DIGITAL_SIGNATURE | KU_NON_REPUDIATION))) | 1227 if (!(cert->keyUsage & (KU_DIGITAL_SIGNATURE | KU_NON_REPUDIATION))) |
| 1265 goto loser; | 1228 goto loser; |
| 1266 } | 1229 } |
| 1267 | 1230 |
| 1268 if ( (cert->keyUsage & requiredUsage) == requiredUsage ) | 1231 if ((cert->keyUsage & requiredUsage) == requiredUsage) |
| 1269 » return SECSuccess; | 1232 return SECSuccess; |
| 1270 | 1233 |
| 1271 loser: | 1234 loser: |
| 1272 PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE); | 1235 PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE); |
| 1273 return SECFailure; | 1236 return SECFailure; |
| 1274 } | 1237 } |
| 1275 | 1238 |
| 1276 | |
| 1277 CERTCertificate * | 1239 CERTCertificate * |
| 1278 CERT_DupCertificate(CERTCertificate *c) | 1240 CERT_DupCertificate(CERTCertificate *c) |
| 1279 { | 1241 { |
| 1280 if (c) { | 1242 if (c) { |
| 1281 » NSSCertificate *tmp = STAN_GetNSSCertificate(c); | 1243 NSSCertificate *tmp = STAN_GetNSSCertificate(c); |
| 1282 » nssCertificate_AddRef(tmp); | 1244 nssCertificate_AddRef(tmp); |
| 1283 } | 1245 } |
| 1284 return c; | 1246 return c; |
| 1285 } | 1247 } |
| 1286 | 1248 |
| 1287 /* | 1249 /* |
| 1288 * Allow use of default cert database, so that apps(such as mozilla) don't | 1250 * Allow use of default cert database, so that apps(such as mozilla) don't |
| 1289 * have to pass the handle all over the place. | 1251 * have to pass the handle all over the place. |
| 1290 */ | 1252 */ |
| 1291 static CERTCertDBHandle *default_cert_db_handle = 0; | 1253 static CERTCertDBHandle *default_cert_db_handle = 0; |
| 1292 | 1254 |
| 1293 void | 1255 void |
| 1294 CERT_SetDefaultCertDB(CERTCertDBHandle *handle) | 1256 CERT_SetDefaultCertDB(CERTCertDBHandle *handle) |
| 1295 { | 1257 { |
| 1296 default_cert_db_handle = handle; | 1258 default_cert_db_handle = handle; |
| 1297 | 1259 |
| 1298 return; | 1260 return; |
| 1299 } | 1261 } |
| 1300 | 1262 |
| 1301 CERTCertDBHandle * | 1263 CERTCertDBHandle * |
| 1302 CERT_GetDefaultCertDB(void) | 1264 CERT_GetDefaultCertDB(void) |
| 1303 { | 1265 { |
| 1304 return(default_cert_db_handle); | 1266 return (default_cert_db_handle); |
| 1305 } | 1267 } |
| 1306 | 1268 |
| 1307 /* XXX this would probably be okay/better as an xp routine? */ | 1269 /* XXX this would probably be okay/better as an xp routine? */ |
| 1308 static void | 1270 static void |
| 1309 sec_lower_string(char *s) | 1271 sec_lower_string(char *s) |
| 1310 { | 1272 { |
| 1311 if ( s == NULL ) { | 1273 if (s == NULL) { |
| 1312 » return; | 1274 return; |
| 1313 } | 1275 } |
| 1314 | 1276 |
| 1315 while ( *s ) { | 1277 while (*s) { |
| 1316 » *s = PORT_Tolower(*s); | 1278 *s = PORT_Tolower(*s); |
| 1317 » s++; | 1279 s++; |
| 1318 } | 1280 } |
| 1319 | 1281 |
| 1320 return; | 1282 return; |
| 1321 } | 1283 } |
| 1322 | 1284 |
| 1323 static PRBool | 1285 static PRBool |
| 1324 cert_IsIPAddr(const char *hn) | 1286 cert_IsIPAddr(const char *hn) |
| 1325 { | 1287 { |
| 1326 PRBool isIPaddr = PR_FALSE; | 1288 PRBool isIPaddr = PR_FALSE; |
| 1327 PRNetAddr netAddr; | 1289 PRNetAddr netAddr; |
| 1328 isIPaddr = (PR_SUCCESS == PR_StringToNetAddr(hn, &netAddr)); | 1290 isIPaddr = (PR_SUCCESS == PR_StringToNetAddr(hn, &netAddr)); |
| 1329 return isIPaddr; | 1291 return isIPaddr; |
| 1330 } | 1292 } |
| 1331 | 1293 |
| 1332 /* | 1294 /* |
| 1333 ** Add a domain name to the list of names that the user has explicitly | 1295 ** Add a domain name to the list of names that the user has explicitly |
| 1334 ** allowed (despite cert name mismatches) for use with a server cert. | 1296 ** allowed (despite cert name mismatches) for use with a server cert. |
| 1335 */ | 1297 */ |
| 1336 SECStatus | 1298 SECStatus |
| 1337 CERT_AddOKDomainName(CERTCertificate *cert, const char *hn) | 1299 CERT_AddOKDomainName(CERTCertificate *cert, const char *hn) |
| 1338 { | 1300 { |
| 1339 CERTOKDomainName *domainOK; | 1301 CERTOKDomainName *domainOK; |
| 1340 int» newNameLen; | 1302 int newNameLen; |
| 1341 | 1303 |
| 1342 if (!hn || !(newNameLen = strlen(hn))) { | 1304 if (!hn || !(newNameLen = strlen(hn))) { |
| 1343 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 1305 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 1344 » return SECFailure; | 1306 return SECFailure; |
| 1345 } | 1307 } |
| 1346 domainOK = (CERTOKDomainName *)PORT_ArenaZAlloc(cert->arena, | 1308 domainOK = (CERTOKDomainName *)PORT_ArenaZAlloc( |
| 1347 » » » » (sizeof *domainOK) + newNameLen); | 1309 cert->arena, (sizeof *domainOK) + newNameLen); |
| 1348 if (!domainOK) | 1310 if (!domainOK) |
| 1349 » return SECFailure;» /* error code is already set. */ | 1311 return SECFailure; /* error code is already set. */ |
| 1350 | 1312 |
| 1351 PORT_Strcpy(domainOK->name, hn); | 1313 PORT_Strcpy(domainOK->name, hn); |
| 1352 sec_lower_string(domainOK->name); | 1314 sec_lower_string(domainOK->name); |
| 1353 | 1315 |
| 1354 /* put at head of list. */ | 1316 /* put at head of list. */ |
| 1355 domainOK->next = cert->domainOK; | 1317 domainOK->next = cert->domainOK; |
| 1356 cert->domainOK = domainOK; | 1318 cert->domainOK = domainOK; |
| 1357 return SECSuccess; | 1319 return SECSuccess; |
| 1358 } | 1320 } |
| 1359 | 1321 |
| 1360 /* returns SECSuccess if hn matches pattern cn, | 1322 /* returns SECSuccess if hn matches pattern cn, |
| 1361 ** returns SECFailure with SSL_ERROR_BAD_CERT_DOMAIN if no match, | 1323 ** returns SECFailure with SSL_ERROR_BAD_CERT_DOMAIN if no match, |
| 1362 ** returns SECFailure with some other error code if another error occurs. | 1324 ** returns SECFailure with some other error code if another error occurs. |
| 1363 ** | 1325 ** |
| 1364 ** This function may modify string cn, so caller must pass a modifiable copy. | 1326 ** This function may modify string cn, so caller must pass a modifiable copy. |
| 1365 */ | 1327 */ |
| 1366 static SECStatus | 1328 static SECStatus |
| 1367 cert_TestHostName(char * cn, const char * hn) | 1329 cert_TestHostName(char *cn, const char *hn) |
| 1368 { | 1330 { |
| 1369 static int useShellExp = -1; | 1331 static int useShellExp = -1; |
| 1370 | 1332 |
| 1371 if (useShellExp < 0) { | 1333 if (useShellExp < 0) { |
| 1372 useShellExp = (NULL != PR_GetEnv("NSS_USE_SHEXP_IN_CERT_NAME")); | 1334 useShellExp = (NULL != PR_GetEnvSecure("NSS_USE_SHEXP_IN_CERT_NAME")); |
| 1373 } | 1335 } |
| 1374 if (useShellExp) { | 1336 if (useShellExp) { |
| 1375 » /* Backward compatible code, uses Shell Expressions (SHEXP). */ | 1337 /* Backward compatible code, uses Shell Expressions (SHEXP). */ |
| 1376 » int regvalid = PORT_RegExpValid(cn); | 1338 int regvalid = PORT_RegExpValid(cn); |
| 1377 » if (regvalid != NON_SXP) { | 1339 if (regvalid != NON_SXP) { |
| 1378 » SECStatus rv; | 1340 SECStatus rv; |
| 1379 » /* cn is a regular expression, try to match the shexp */ | 1341 /* cn is a regular expression, try to match the shexp */ |
| 1380 » int match = PORT_RegExpCaseSearch(hn, cn); | 1342 int match = PORT_RegExpCaseSearch(hn, cn); |
| 1381 | 1343 |
| 1382 » if ( match == 0 ) { | 1344 if (match == 0) { |
| 1383 » » rv = SECSuccess; | 1345 rv = SECSuccess; |
| 1384 » } else { | 1346 } else { |
| 1385 » » PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN); | 1347 PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN); |
| 1386 » » rv = SECFailure; | 1348 rv = SECFailure; |
| 1387 » } | 1349 } |
| 1388 » return rv; | 1350 return rv; |
| 1389 » } | 1351 } |
| 1390 } else { | 1352 } else { |
| 1391 » /* New approach conforms to RFC 6125. */ | 1353 /* New approach conforms to RFC 6125. */ |
| 1392 » char *wildcard = PORT_Strchr(cn, '*'); | 1354 char *wildcard = PORT_Strchr(cn, '*'); |
| 1393 » char *firstcndot = PORT_Strchr(cn, '.'); | 1355 char *firstcndot = PORT_Strchr(cn, '.'); |
| 1394 » char *secondcndot = firstcndot ? PORT_Strchr(firstcndot+1, '.') : NULL; | 1356 char *secondcndot = |
| 1395 » char *firsthndot = PORT_Strchr(hn, '.'); | 1357 firstcndot ? PORT_Strchr(firstcndot + 1, '.') : NULL; |
| 1358 char *firsthndot = PORT_Strchr(hn, '.'); |
| 1396 | 1359 |
| 1397 » /* For a cn pattern to be considered valid, the wildcard character... | 1360 /* For a cn pattern to be considered valid, the wildcard character... |
| 1398 » * - may occur only in a DNS name with at least 3 components, and | 1361 * - may occur only in a DNS name with at least 3 components, and |
| 1399 » * - may occur only as last character in the first component, and | 1362 * - may occur only as last character in the first component, and |
| 1400 » * - may be preceded by additional characters, and | 1363 * - may be preceded by additional characters, and |
| 1401 » * - must not be preceded by an IDNA ACE prefix (xn--) | 1364 * - must not be preceded by an IDNA ACE prefix (xn--) |
| 1402 » */ | 1365 */ |
| 1403 » if (wildcard && secondcndot && secondcndot[1] && firsthndot | 1366 if (wildcard && secondcndot && secondcndot[1] && firsthndot && |
| 1404 » && firstcndot - wildcard == 1 /* wildcard is last char in first co
mponent */ | 1367 firstcndot - wildcard == 1 /* wildcard is last char in fir
st component */ |
| 1405 » && secondcndot - firstcndot > 1 /* second component is non-empty */ | 1368 && secondcndot - firstcndot > 1 /* second component is non-empt
y */ |
| 1406 » && PORT_Strrchr(cn, '*') == wildcard /* only one wildcard in cn */ | 1369 && PORT_Strrchr(cn, '*') == wildcard /* only one wildcard in cn */ |
| 1407 » && !PORT_Strncasecmp(cn, hn, wildcard - cn) | 1370 && !PORT_Strncasecmp(cn, hn, wildcard - cn) && |
| 1408 » && !PORT_Strcasecmp(firstcndot, firsthndot) | 1371 !PORT_Strcasecmp(firstcndot, firsthndot) |
| 1409 » /* If hn starts with xn--, then cn must start with wildcard */ | 1372 /* If hn starts with xn--, then cn must start with wildcard */ |
| 1410 » && (PORT_Strncasecmp(hn, "xn--", 4) || wildcard == cn)) { | 1373 && (PORT_Strncasecmp(hn, "xn--", 4) || wildcard == cn)) { |
| 1411 » /* valid wildcard pattern match */ | 1374 /* valid wildcard pattern match */ |
| 1412 » return SECSuccess; | 1375 return SECSuccess; |
| 1413 » } | 1376 } |
| 1414 } | 1377 } |
| 1415 /* String cn has no wildcard or shell expression. | 1378 /* String cn has no wildcard or shell expression. |
| 1416 * Compare entire string hn with cert name. | 1379 * Compare entire string hn with cert name. |
| 1417 */ | 1380 */ |
| 1418 if (PORT_Strcasecmp(hn, cn) == 0) { | 1381 if (PORT_Strcasecmp(hn, cn) == 0) { |
| 1419 » return SECSuccess; | 1382 return SECSuccess; |
| 1420 } | 1383 } |
| 1421 | 1384 |
| 1422 PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN); | 1385 PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN); |
| 1423 return SECFailure; | 1386 return SECFailure; |
| 1424 } | 1387 } |
| 1425 | 1388 |
| 1426 | |
| 1427 SECStatus | 1389 SECStatus |
| 1428 cert_VerifySubjectAltName(const CERTCertificate *cert, const char *hn) | 1390 cert_VerifySubjectAltName(const CERTCertificate *cert, const char *hn) |
| 1429 { | 1391 { |
| 1430 PLArenaPool * arena = NULL; | 1392 PLArenaPool *arena = NULL; |
| 1431 CERTGeneralName * nameList = NULL; | 1393 CERTGeneralName *nameList = NULL; |
| 1432 CERTGeneralName * current; | 1394 CERTGeneralName *current; |
| 1433 char * cn; | 1395 char *cn; |
| 1434 int cnBufLen; | 1396 int cnBufLen; |
| 1435 int DNSextCount = 0; | 1397 int DNSextCount = 0; |
| 1436 int IPextCount = 0; | 1398 int IPextCount = 0; |
| 1437 PRBool isIPaddr = PR_FALSE; | 1399 PRBool isIPaddr = PR_FALSE; |
| 1438 SECStatus rv = SECFailure; | 1400 SECStatus rv = SECFailure; |
| 1439 SECItem subAltName; | 1401 SECItem subAltName; |
| 1440 PRNetAddr netAddr; | 1402 PRNetAddr netAddr; |
| 1441 char cnbuf[128]; | 1403 char cnbuf[128]; |
| 1442 | 1404 |
| 1443 subAltName.data = NULL; | 1405 subAltName.data = NULL; |
| 1444 cn = cnbuf; | 1406 cn = cnbuf; |
| 1445 cnBufLen = sizeof cnbuf; | 1407 cnBufLen = sizeof cnbuf; |
| 1446 | 1408 |
| 1447 rv = CERT_FindCertExtension(cert, SEC_OID_X509_SUBJECT_ALT_NAME, | 1409 rv = CERT_FindCertExtension(cert, SEC_OID_X509_SUBJECT_ALT_NAME, |
| 1448 » » » » &subAltName); | 1410 &subAltName); |
| 1449 if (rv != SECSuccess) { | 1411 if (rv != SECSuccess) { |
| 1450 » goto fail; | 1412 goto fail; |
| 1451 } | 1413 } |
| 1452 isIPaddr = (PR_SUCCESS == PR_StringToNetAddr(hn, &netAddr)); | 1414 isIPaddr = (PR_SUCCESS == PR_StringToNetAddr(hn, &netAddr)); |
| 1453 rv = SECFailure; | 1415 rv = SECFailure; |
| 1454 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 1416 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
| 1455 if (!arena) | 1417 if (!arena) |
| 1456 » goto fail; | 1418 goto fail; |
| 1457 | 1419 |
| 1458 nameList = current = CERT_DecodeAltNameExtension(arena, &subAltName); | 1420 nameList = current = CERT_DecodeAltNameExtension(arena, &subAltName); |
| 1459 if (!current) | 1421 if (!current) |
| 1460 » goto fail; | 1422 goto fail; |
| 1461 | 1423 |
| 1462 do { | 1424 do { |
| 1463 » switch (current->type) { | 1425 switch (current->type) { |
| 1464 » case certDNSName: | 1426 case certDNSName: |
| 1465 » if (!isIPaddr) { | 1427 if (!isIPaddr) { |
| 1466 » » /* DNS name current->name.other.data is not null terminated. | 1428 /* DNS name current->name.other.data is not null terminated. |
| 1467 » » ** so must copy it. | 1429 ** so must copy it. |
| 1468 » » */ | 1430 */ |
| 1469 » » int cnLen = current->name.other.len; | 1431 int cnLen = current->name.other.len; |
| 1470 » » rv = CERT_RFC1485_EscapeAndQuote(cn, cnBufLen, | 1432 rv = CERT_RFC1485_EscapeAndQuote( |
| 1471 » » » » » (char *)current->name.other.data, | 1433 cn, cnBufLen, (char *)current->name.other.data, cnLen); |
| 1472 » » » » » cnLen); | 1434 if (rv != SECSuccess && |
| 1473 » » if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_OUTPUT_LEN)
{ | 1435 PORT_GetError() == SEC_ERROR_OUTPUT_LEN) { |
| 1474 » » cnBufLen = cnLen * 3 + 3; /* big enough for worst case */ | 1436 cnBufLen = |
| 1475 » » cn = (char *)PORT_ArenaAlloc(arena, cnBufLen); | 1437 cnLen * 3 + 3; /* big enough for worst case */ |
| 1476 » » if (!cn) | 1438 cn = (char *)PORT_ArenaAlloc(arena, cnBufLen); |
| 1477 » » » goto fail; | 1439 if (!cn) |
| 1478 » » rv = CERT_RFC1485_EscapeAndQuote(cn, cnBufLen, | 1440 goto fail; |
| 1479 » » » » » (char *)current->name.other.data, | 1441 rv = CERT_RFC1485_EscapeAndQuote( |
| 1480 » » » » » cnLen); | 1442 cn, cnBufLen, (char *)current->name.other.data, |
| 1481 » » } | 1443 cnLen); |
| 1482 » » if (rv == SECSuccess) | 1444 } |
| 1483 » » rv = cert_TestHostName(cn ,hn); | 1445 if (rv == SECSuccess) |
| 1484 » » if (rv == SECSuccess) | 1446 rv = cert_TestHostName(cn, hn); |
| 1485 » » goto finish; | 1447 if (rv == SECSuccess) |
| 1486 » } | 1448 goto finish; |
| 1487 » DNSextCount++; | 1449 } |
| 1488 » break; | 1450 DNSextCount++; |
| 1489 » case certIPAddress: | 1451 break; |
| 1490 » if (isIPaddr) { | 1452 case certIPAddress: |
| 1491 » » int match = 0; | 1453 if (isIPaddr) { |
| 1492 » » PRIPv6Addr v6Addr; | 1454 int match = 0; |
| 1493 » » if (current->name.other.len == 4 && /* IP v4 address */ | 1455 PRIPv6Addr v6Addr; |
| 1494 » » netAddr.inet.family == PR_AF_INET) { | 1456 if (current->name.other.len == 4 && /* IP v4 address */ |
| 1495 » » match = !memcmp(&netAddr.inet.ip, | 1457 netAddr.inet.family == PR_AF_INET) { |
| 1496 » » current->name.other.data, 4); | 1458 match = !memcmp(&netAddr.inet.ip, |
| 1497 » » } else if (current->name.other.len == 16 && /* IP v6 address */ | 1459 current->name.other.data, 4); |
| 1498 » » netAddr.ipv6.family == PR_AF_INET6) { | 1460 } else if (current->name.other.len == |
| 1499 » » match = !memcmp(&netAddr.ipv6.ip, | 1461 16 && /* IP v6 address */ |
| 1500 » » current->name.other.data, 16); | 1462 netAddr.ipv6.family == PR_AF_INET6) { |
| 1501 » » } else if (current->name.other.len == 16 && /* IP v6 address */ | 1463 match = !memcmp(&netAddr.ipv6.ip, |
| 1502 » » netAddr.inet.family == PR_AF_INET) { | 1464 current->name.other.data, 16); |
| 1503 » » /* convert netAddr to ipv6, then compare. */ | 1465 } else if (current->name.other.len == |
| 1504 » » /* ipv4 must be in Network Byte Order on input. */ | 1466 16 && /* IP v6 address */ |
| 1505 » » PR_ConvertIPv4AddrToIPv6(netAddr.inet.ip, &v6Addr); | 1467 netAddr.inet.family == PR_AF_INET) { |
| 1506 » » match = !memcmp(&v6Addr, current->name.other.data, 16); | 1468 /* convert netAddr to ipv6, then compare. */ |
| 1507 » » } else if (current->name.other.len == 4 && /* IP v4 address */ | 1469 /* ipv4 must be in Network Byte Order on input. */ |
| 1508 » » netAddr.inet.family == PR_AF_INET6) { | 1470 PR_ConvertIPv4AddrToIPv6(netAddr.inet.ip, &v6Addr); |
| 1509 » » /* convert netAddr to ipv6, then compare. */ | 1471 match = !memcmp(&v6Addr, current->name.other.data, 16); |
| 1510 » » PRUint32 ipv4 = (current->name.other.data[0] << 24) | | 1472 } else if (current->name.other.len == 4 && /* IP v4 address
*/ |
| 1511 » » (current->name.other.data[1] << 16) | | 1473 netAddr.inet.family == PR_AF_INET6) { |
| 1512 » » » » (current->name.other.data[2] << 8) | | 1474 /* convert netAddr to ipv6, then compare. */ |
| 1513 » » » » current->name.other.data[3]; | 1475 PRUint32 ipv4 = (current->name.other.data[0] << 24) | |
| 1514 » » /* ipv4 must be in Network Byte Order on input. */ | 1476 (current->name.other.data[1] << 16) | |
| 1515 » » PR_ConvertIPv4AddrToIPv6(PR_htonl(ipv4), &v6Addr); | 1477 (current->name.other.data[2] << 8) | |
| 1516 » » match = !memcmp(&netAddr.ipv6.ip, &v6Addr, 16); | 1478 current->name.other.data[3]; |
| 1517 » » } | 1479 /* ipv4 must be in Network Byte Order on input. */ |
| 1518 » » if (match) { | 1480 PR_ConvertIPv4AddrToIPv6(PR_htonl(ipv4), &v6Addr); |
| 1519 » » rv = SECSuccess; | 1481 match = !memcmp(&netAddr.ipv6.ip, &v6Addr, 16); |
| 1520 » » goto finish; | 1482 } |
| 1521 » » } | 1483 if (match) { |
| 1522 » } | 1484 rv = SECSuccess; |
| 1523 » IPextCount++; | 1485 goto finish; |
| 1524 » break; | 1486 } |
| 1525 » default: | 1487 } |
| 1526 » break; | 1488 IPextCount++; |
| 1527 » } | 1489 break; |
| 1528 » current = CERT_GetNextGeneralName(current); | 1490 default: |
| 1491 break; |
| 1492 } |
| 1493 current = CERT_GetNextGeneralName(current); |
| 1529 } while (current != nameList); | 1494 } while (current != nameList); |
| 1530 | 1495 |
| 1531 fail: | 1496 fail: |
| 1532 | 1497 |
| 1533 if (!(isIPaddr ? IPextCount : DNSextCount)) { | 1498 if (!(isIPaddr ? IPextCount : DNSextCount)) { |
| 1534 » /* no relevant value in the extension was found. */ | 1499 /* no relevant value in the extension was found. */ |
| 1535 » PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND); | 1500 PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND); |
| 1536 } else { | 1501 } else { |
| 1537 » PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN); | 1502 PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN); |
| 1538 } | 1503 } |
| 1539 rv = SECFailure; | 1504 rv = SECFailure; |
| 1540 | 1505 |
| 1541 finish: | 1506 finish: |
| 1542 | 1507 |
| 1543 /* Don't free nameList, it's part of the arena. */ | 1508 /* Don't free nameList, it's part of the arena. */ |
| 1544 if (arena) { | 1509 if (arena) { |
| 1545 » PORT_FreeArena(arena, PR_FALSE); | 1510 PORT_FreeArena(arena, PR_FALSE); |
| 1546 } | 1511 } |
| 1547 | 1512 |
| 1548 if (subAltName.data) { | 1513 if (subAltName.data) { |
| 1549 » SECITEM_FreeItem(&subAltName, PR_FALSE); | 1514 SECITEM_FreeItem(&subAltName, PR_FALSE); |
| 1550 } | 1515 } |
| 1551 | 1516 |
| 1552 return rv; | 1517 return rv; |
| 1553 } | 1518 } |
| 1554 | 1519 |
| 1555 /* | 1520 /* |
| 1556 * If found: | 1521 * If found: |
| 1557 * - subAltName contains the extension (caller must free) | 1522 * - subAltName contains the extension (caller must free) |
| 1558 * - return value is the decoded namelist (allocated off arena) | 1523 * - return value is the decoded namelist (allocated off arena) |
| 1559 * if not found, or if failure to decode: | 1524 * if not found, or if failure to decode: |
| 1560 * - return value is NULL | 1525 * - return value is NULL |
| 1561 */ | 1526 */ |
| 1562 CERTGeneralName * | 1527 CERTGeneralName * |
| 1563 cert_GetSubjectAltNameList(const CERTCertificate *cert, PLArenaPool *arena) | 1528 cert_GetSubjectAltNameList(const CERTCertificate *cert, PLArenaPool *arena) |
| 1564 { | 1529 { |
| 1565 CERTGeneralName * nameList = NULL; | 1530 CERTGeneralName *nameList = NULL; |
| 1566 SECStatus rv = SECFailure; | 1531 SECStatus rv = SECFailure; |
| 1567 SECItem subAltName; | 1532 SECItem subAltName; |
| 1568 | 1533 |
| 1569 if (!cert || !arena) | 1534 if (!cert || !arena) |
| 1570 return NULL; | 1535 return NULL; |
| 1571 | 1536 |
| 1572 subAltName.data = NULL; | 1537 subAltName.data = NULL; |
| 1573 | 1538 |
| 1574 rv = CERT_FindCertExtension(cert, SEC_OID_X509_SUBJECT_ALT_NAME, | 1539 rv = CERT_FindCertExtension(cert, SEC_OID_X509_SUBJECT_ALT_NAME, |
| 1575 &subAltName); | 1540 &subAltName); |
| 1576 if (rv != SECSuccess) | 1541 if (rv != SECSuccess) |
| 1577 return NULL; | 1542 return NULL; |
| 1578 | 1543 |
| 1579 nameList = CERT_DecodeAltNameExtension(arena, &subAltName); | 1544 nameList = CERT_DecodeAltNameExtension(arena, &subAltName); |
| 1580 SECITEM_FreeItem(&subAltName, PR_FALSE); | 1545 SECITEM_FreeItem(&subAltName, PR_FALSE); |
| 1581 return nameList; | 1546 return nameList; |
| 1582 } | 1547 } |
| 1583 | 1548 |
| 1584 PRUint32 | 1549 PRUint32 |
| 1585 cert_CountDNSPatterns(CERTGeneralName *firstName) | 1550 cert_CountDNSPatterns(CERTGeneralName *firstName) |
| 1586 { | 1551 { |
| 1587 CERTGeneralName * current; | 1552 CERTGeneralName *current; |
| 1588 PRUint32 count = 0; | 1553 PRUint32 count = 0; |
| 1589 | 1554 |
| 1590 if (!firstName) | 1555 if (!firstName) |
| 1591 return 0; | 1556 return 0; |
| 1592 | 1557 |
| 1593 current = firstName; | 1558 current = firstName; |
| 1594 do { | 1559 do { |
| 1595 switch (current->type) { | 1560 switch (current->type) { |
| 1596 case certDNSName: | 1561 case certDNSName: |
| 1597 case certIPAddress: | 1562 case certIPAddress: |
| 1598 ++count; | 1563 ++count; |
| 1599 break; | 1564 break; |
| 1600 default: | 1565 default: |
| 1601 break; | 1566 break; |
| 1602 } | 1567 } |
| 1603 current = CERT_GetNextGeneralName(current); | 1568 current = CERT_GetNextGeneralName(current); |
| 1604 } while (current != firstName); | 1569 } while (current != firstName); |
| 1605 | 1570 |
| 1606 return count; | 1571 return count; |
| 1607 } | 1572 } |
| 1608 | 1573 |
| 1609 #ifndef INET6_ADDRSTRLEN | 1574 #ifndef INET6_ADDRSTRLEN |
| 1610 #define INET6_ADDRSTRLEN 46 | 1575 #define INET6_ADDRSTRLEN 46 |
| 1611 #endif | 1576 #endif |
| 1612 | 1577 |
| 1613 /* will fill nickNames, | 1578 /* will fill nickNames, |
| 1614 * will allocate all data from nickNames->arena, | 1579 * will allocate all data from nickNames->arena, |
| 1615 * numberOfGeneralNames should have been obtained from cert_CountDNSPatterns, | 1580 * numberOfGeneralNames should have been obtained from cert_CountDNSPatterns, |
| 1616 * will ensure the numberOfGeneralNames matches the number of output entries. | 1581 * will ensure the numberOfGeneralNames matches the number of output entries. |
| 1617 */ | 1582 */ |
| 1618 SECStatus | 1583 SECStatus |
| 1619 cert_GetDNSPatternsFromGeneralNames(CERTGeneralName *firstName, | 1584 cert_GetDNSPatternsFromGeneralNames(CERTGeneralName *firstName, |
| 1620 PRUint32 numberOfGeneralNames, | 1585 PRUint32 numberOfGeneralNames, |
| 1621 CERTCertNicknames *nickNames) | 1586 CERTCertNicknames *nickNames) |
| 1622 { | 1587 { |
| 1623 CERTGeneralName *currentInput; | 1588 CERTGeneralName *currentInput; |
| 1624 char **currentOutput; | 1589 char **currentOutput; |
| 1625 | 1590 |
| 1626 if (!firstName || !nickNames || !numberOfGeneralNames) | 1591 if (!firstName || !nickNames || !numberOfGeneralNames) |
| 1627 return SECFailure; | 1592 return SECFailure; |
| 1628 | 1593 |
| 1629 nickNames->numnicknames = numberOfGeneralNames; | 1594 nickNames->numnicknames = numberOfGeneralNames; |
| 1630 nickNames->nicknames = PORT_ArenaAlloc(nickNames->arena, | 1595 nickNames->nicknames = PORT_ArenaAlloc( |
| 1631 sizeof(char *) * numberOfGeneralNames); | 1596 nickNames->arena, sizeof(char *) * numberOfGeneralNames); |
| 1632 if (!nickNames->nicknames) | 1597 if (!nickNames->nicknames) |
| 1633 return SECFailure; | 1598 return SECFailure; |
| 1634 | 1599 |
| 1635 currentInput = firstName; | 1600 currentInput = firstName; |
| 1636 currentOutput = nickNames->nicknames; | 1601 currentOutput = nickNames->nicknames; |
| 1637 do { | 1602 do { |
| 1638 char *cn = NULL; | 1603 char *cn = NULL; |
| 1639 char ipbuf[INET6_ADDRSTRLEN]; | 1604 char ipbuf[INET6_ADDRSTRLEN]; |
| 1640 PRNetAddr addr; | 1605 PRNetAddr addr; |
| 1641 | 1606 |
| 1642 if (numberOfGeneralNames < 1) { | 1607 if (numberOfGeneralNames < 1) { |
| 1643 /* internal consistency error */ | 1608 /* internal consistency error */ |
| 1644 return SECFailure; | 1609 return SECFailure; |
| 1645 } | 1610 } |
| 1646 | 1611 |
| 1647 switch (currentInput->type) { | 1612 switch (currentInput->type) { |
| 1648 case certDNSName: | 1613 case certDNSName: |
| 1649 /* DNS name currentInput->name.other.data is not null terminated. | 1614 /* DNS name currentInput->name.other.data is not null |
| 1650 ** so must copy it. | 1615 *terminated. |
| 1651 */ | 1616 ** so must copy it. |
| 1652 cn = (char *)PORT_ArenaAlloc(nickNames->arena, | 1617 */ |
| 1653 currentInput->name.other.len + 1); | 1618 cn = (char *)PORT_ArenaAlloc(nickNames->arena, |
| 1654 if (!cn) | 1619 currentInput->name.other.len + 1); |
| 1655 return SECFailure; | 1620 if (!cn) |
| 1656 PORT_Memcpy(cn, currentInput->name.other.data, | 1621 return SECFailure; |
| 1622 PORT_Memcpy(cn, currentInput->name.other.data, |
| 1657 currentInput->name.other.len); | 1623 currentInput->name.other.len); |
| 1658 cn[currentInput->name.other.len] = 0; | 1624 cn[currentInput->name.other.len] = 0; |
| 1659 break; | 1625 break; |
| 1660 case certIPAddress: | 1626 case certIPAddress: |
| 1661 if (currentInput->name.other.len == 4) { | 1627 if (currentInput->name.other.len == 4) { |
| 1662 addr.inet.family = PR_AF_INET; | 1628 addr.inet.family = PR_AF_INET; |
| 1663 memcpy(&addr.inet.ip, currentInput->name.other.data, | 1629 memcpy(&addr.inet.ip, currentInput->name.other.data, |
| 1664 currentInput->name.other.len); | 1630 currentInput->name.other.len); |
| 1665 } else if (currentInput->name.other.len == 16) { | 1631 } else if (currentInput->name.other.len == 16) { |
| 1666 addr.ipv6.family = PR_AF_INET6; | 1632 addr.ipv6.family = PR_AF_INET6; |
| 1667 memcpy(&addr.ipv6.ip, currentInput->name.other.data, | 1633 memcpy(&addr.ipv6.ip, currentInput->name.other.data, |
| 1668 currentInput->name.other.len); | 1634 currentInput->name.other.len); |
| 1669 } | 1635 } |
| 1670 if (PR_NetAddrToString(&addr, ipbuf, sizeof(ipbuf)) == PR_FAILURE) | 1636 if (PR_NetAddrToString(&addr, ipbuf, sizeof(ipbuf)) == |
| 1671 return SECFailure; | 1637 PR_FAILURE) |
| 1672 cn = PORT_ArenaStrdup(nickNames->arena, ipbuf); | 1638 return SECFailure; |
| 1673 if (!cn) | 1639 cn = PORT_ArenaStrdup(nickNames->arena, ipbuf); |
| 1674 return SECFailure; | 1640 if (!cn) |
| 1675 break; | 1641 return SECFailure; |
| 1676 default: | 1642 break; |
| 1677 break; | 1643 default: |
| 1644 break; |
| 1678 } | 1645 } |
| 1679 if (cn) { | 1646 if (cn) { |
| 1680 *currentOutput = cn; | 1647 *currentOutput = cn; |
| 1681 nickNames->totallen += PORT_Strlen(cn); | 1648 nickNames->totallen += PORT_Strlen(cn); |
| 1682 ++currentOutput; | 1649 ++currentOutput; |
| 1683 --numberOfGeneralNames; | 1650 --numberOfGeneralNames; |
| 1684 } | 1651 } |
| 1685 currentInput = CERT_GetNextGeneralName(currentInput); | 1652 currentInput = CERT_GetNextGeneralName(currentInput); |
| 1686 } while (currentInput != firstName); | 1653 } while (currentInput != firstName); |
| 1687 | 1654 |
| 1688 return (numberOfGeneralNames == 0) ? SECSuccess : SECFailure; | 1655 return (numberOfGeneralNames == 0) ? SECSuccess : SECFailure; |
| 1689 } | 1656 } |
| 1690 | 1657 |
| 1691 /* | 1658 /* |
| 1692 * Collect all valid DNS names from the given cert. | 1659 * Collect all valid DNS names from the given cert. |
| 1693 * The output arena will reference some temporaray data, | 1660 * The output arena will reference some temporaray data, |
| 1694 * but this saves us from dealing with two arenas. | 1661 * but this saves us from dealing with two arenas. |
| 1695 * The caller may free all data by freeing CERTCertNicknames->arena. | 1662 * The caller may free all data by freeing CERTCertNicknames->arena. |
| 1696 */ | 1663 */ |
| 1697 CERTCertNicknames * | 1664 CERTCertNicknames * |
| 1698 CERT_GetValidDNSPatternsFromCert(CERTCertificate *cert) | 1665 CERT_GetValidDNSPatternsFromCert(CERTCertificate *cert) |
| 1699 { | 1666 { |
| 1700 CERTGeneralName *generalNames; | 1667 CERTGeneralName *generalNames; |
| 1701 CERTCertNicknames *nickNames; | 1668 CERTCertNicknames *nickNames; |
| 1702 PLArenaPool *arena; | 1669 PLArenaPool *arena; |
| 1703 char *singleName; | 1670 char *singleName; |
| 1704 | 1671 |
| 1705 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 1672 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
| 1706 if (!arena) { | 1673 if (!arena) { |
| 1707 return NULL; | 1674 return NULL; |
| 1708 } | 1675 } |
| 1709 | 1676 |
| 1710 nickNames = PORT_ArenaAlloc(arena, sizeof(CERTCertNicknames)); | 1677 nickNames = PORT_ArenaAlloc(arena, sizeof(CERTCertNicknames)); |
| 1711 if (!nickNames) { | 1678 if (!nickNames) { |
| 1712 PORT_FreeArena(arena, PR_FALSE); | 1679 PORT_FreeArena(arena, PR_FALSE); |
| 1713 return NULL; | 1680 return NULL; |
| 1714 } | 1681 } |
| 1715 | 1682 |
| 1716 /* init the structure */ | 1683 /* init the structure */ |
| 1717 nickNames->arena = arena; | 1684 nickNames->arena = arena; |
| 1718 nickNames->head = NULL; | 1685 nickNames->head = NULL; |
| 1719 nickNames->numnicknames = 0; | 1686 nickNames->numnicknames = 0; |
| 1720 nickNames->nicknames = NULL; | 1687 nickNames->nicknames = NULL; |
| 1721 nickNames->totallen = 0; | 1688 nickNames->totallen = 0; |
| 1722 | 1689 |
| 1723 generalNames = cert_GetSubjectAltNameList(cert, arena); | 1690 generalNames = cert_GetSubjectAltNameList(cert, arena); |
| 1724 if (generalNames) { | 1691 if (generalNames) { |
| 1725 SECStatus rv_getnames = SECFailure; | 1692 SECStatus rv_getnames = SECFailure; |
| 1726 PRUint32 numNames = cert_CountDNSPatterns(generalNames); | 1693 PRUint32 numNames = cert_CountDNSPatterns(generalNames); |
| 1727 | 1694 |
| 1728 if (numNames) { | 1695 if (numNames) { |
| 1729 rv_getnames = cert_GetDNSPatternsFromGeneralNames(generalNames, | 1696 rv_getnames = cert_GetDNSPatternsFromGeneralNames( |
| 1730 numNames, nickNames); | 1697 generalNames, numNames, nickNames); |
| 1731 } | |
| 1732 | |
| 1733 /* if there were names, we'll exit now, either with success or failure */ | |
| 1734 if (numNames) { | |
| 1735 if (rv_getnames == SECSuccess) { | |
| 1736 return nickNames; | |
| 1737 } | 1698 } |
| 1738 | 1699 |
| 1739 /* failure to produce output */ | 1700 /* if there were names, we'll exit now, either with success or failure |
| 1740 PORT_FreeArena(arena, PR_FALSE); | 1701 */ |
| 1741 return NULL; | 1702 if (numNames) { |
| 1742 } | 1703 if (rv_getnames == SECSuccess) { |
| 1704 return nickNames; |
| 1705 } |
| 1706 |
| 1707 /* failure to produce output */ |
| 1708 PORT_FreeArena(arena, PR_FALSE); |
| 1709 return NULL; |
| 1710 } |
| 1743 } | 1711 } |
| 1744 | 1712 |
| 1745 /* no SAN extension or no names found in extension */ | 1713 /* no SAN extension or no names found in extension */ |
| 1746 singleName = CERT_GetCommonName(&cert->subject); | 1714 singleName = CERT_GetCommonName(&cert->subject); |
| 1747 if (singleName) { | 1715 if (singleName) { |
| 1748 nickNames->numnicknames = 1; | 1716 nickNames->numnicknames = 1; |
| 1749 nickNames->nicknames = PORT_ArenaAlloc(arena, sizeof(char *)); | 1717 nickNames->nicknames = PORT_ArenaAlloc(arena, sizeof(char *)); |
| 1750 if (nickNames->nicknames) { | 1718 if (nickNames->nicknames) { |
| 1751 *nickNames->nicknames = PORT_ArenaStrdup(arena, singleName); | 1719 *nickNames->nicknames = PORT_ArenaStrdup(arena, singleName); |
| 1752 } | 1720 } |
| 1753 PORT_Free(singleName); | 1721 PORT_Free(singleName); |
| 1754 | 1722 |
| 1755 /* Did we allocate both the buffer of pointers and the string? */ | 1723 /* Did we allocate both the buffer of pointers and the string? */ |
| 1756 if (nickNames->nicknames && *nickNames->nicknames) { | 1724 if (nickNames->nicknames && *nickNames->nicknames) { |
| 1757 return nickNames; | 1725 return nickNames; |
| 1758 } | 1726 } |
| 1759 } | 1727 } |
| 1760 | 1728 |
| 1761 PORT_FreeArena(arena, PR_FALSE); | 1729 PORT_FreeArena(arena, PR_FALSE); |
| 1762 return NULL; | 1730 return NULL; |
| 1763 } | 1731 } |
| 1764 | 1732 |
| 1765 /* Make sure that the name of the host we are connecting to matches the | 1733 /* Make sure that the name of the host we are connecting to matches the |
| 1766 * name that is incoded in the common-name component of the certificate | 1734 * name that is incoded in the common-name component of the certificate |
| 1767 * that they are using. | 1735 * that they are using. |
| 1768 */ | 1736 */ |
| 1769 SECStatus | 1737 SECStatus |
| 1770 CERT_VerifyCertName(const CERTCertificate *cert, const char *hn) | 1738 CERT_VerifyCertName(const CERTCertificate *cert, const char *hn) |
| 1771 { | 1739 { |
| 1772 char * cn; | 1740 char *cn; |
| 1773 SECStatus rv; | 1741 SECStatus rv; |
| 1774 CERTOKDomainName *domainOK; | 1742 CERTOKDomainName *domainOK; |
| 1775 | 1743 |
| 1776 if (!hn || !strlen(hn)) { | 1744 if (!hn || !strlen(hn)) { |
| 1777 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 1745 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 1778 » return SECFailure; | 1746 return SECFailure; |
| 1779 } | 1747 } |
| 1780 | 1748 |
| 1781 /* if the name is one that the user has already approved, it's OK. */ | 1749 /* if the name is one that the user has already approved, it's OK. */ |
| 1782 for (domainOK = cert->domainOK; domainOK; domainOK = domainOK->next) { | 1750 for (domainOK = cert->domainOK; domainOK; domainOK = domainOK->next) { |
| 1783 » if (0 == PORT_Strcasecmp(hn, domainOK->name)) { | 1751 if (0 == PORT_Strcasecmp(hn, domainOK->name)) { |
| 1784 » return SECSuccess; | 1752 return SECSuccess; |
| 1785 » } | 1753 } |
| 1786 } | 1754 } |
| 1787 | 1755 |
| 1788 /* Per RFC 2818, if the SubjectAltName extension is present, it must | 1756 /* Per RFC 2818, if the SubjectAltName extension is present, it must |
| 1789 ** be used as the cert's identity. | 1757 ** be used as the cert's identity. |
| 1790 */ | 1758 */ |
| 1791 rv = cert_VerifySubjectAltName(cert, hn); | 1759 rv = cert_VerifySubjectAltName(cert, hn); |
| 1792 if (rv == SECSuccess || PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND) | 1760 if (rv == SECSuccess || PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND) |
| 1793 » return rv; | 1761 return rv; |
| 1794 | 1762 |
| 1795 cn = CERT_GetCommonName(&cert->subject); | 1763 cn = CERT_GetCommonName(&cert->subject); |
| 1796 if ( cn ) { | 1764 if (cn) { |
| 1797 PRBool isIPaddr = cert_IsIPAddr(hn); | 1765 PRBool isIPaddr = cert_IsIPAddr(hn); |
| 1798 if (isIPaddr) { | 1766 if (isIPaddr) { |
| 1799 if (PORT_Strcasecmp(hn, cn) == 0) { | 1767 if (PORT_Strcasecmp(hn, cn) == 0) { |
| 1800 rv = SECSuccess; | 1768 rv = SECSuccess; |
| 1801 } else { | 1769 } else { |
| 1802 PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN); | 1770 PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN); |
| 1803 rv = SECFailure; | 1771 rv = SECFailure; |
| 1804 } | 1772 } |
| 1805 } else { | 1773 } else { |
| 1806 rv = cert_TestHostName(cn, hn); | 1774 rv = cert_TestHostName(cn, hn); |
| 1807 } | 1775 } |
| 1808 » PORT_Free(cn); | 1776 PORT_Free(cn); |
| 1809 } else | 1777 } else |
| 1810 » PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN); | 1778 PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN); |
| 1811 return rv; | 1779 return rv; |
| 1812 } | 1780 } |
| 1813 | 1781 |
| 1814 PRBool | 1782 PRBool |
| 1815 CERT_CompareCerts(const CERTCertificate *c1, const CERTCertificate *c2) | 1783 CERT_CompareCerts(const CERTCertificate *c1, const CERTCertificate *c2) |
| 1816 { | 1784 { |
| 1817 SECComparison comp; | 1785 SECComparison comp; |
| 1818 | 1786 |
| 1819 comp = SECITEM_CompareItem(&c1->derCert, &c2->derCert); | 1787 comp = SECITEM_CompareItem(&c1->derCert, &c2->derCert); |
| 1820 if ( comp == SECEqual ) { /* certs are the same */ | 1788 if (comp == SECEqual) { /* certs are the same */ |
| 1821 » return(PR_TRUE); | 1789 return (PR_TRUE); |
| 1822 } else { | 1790 } else { |
| 1823 » return(PR_FALSE); | 1791 return (PR_FALSE); |
| 1824 } | 1792 } |
| 1825 } | 1793 } |
| 1826 | 1794 |
| 1827 static SECStatus | 1795 static SECStatus |
| 1828 StringsEqual(char *s1, char *s2) { | 1796 StringsEqual(char *s1, char *s2) |
| 1829 if ( ( s1 == NULL ) || ( s2 == NULL ) ) { | 1797 { |
| 1830 » if ( s1 != s2 ) { /* only one is null */ | 1798 if ((s1 == NULL) || (s2 == NULL)) { |
| 1831 » return(SECFailure); | 1799 if (s1 != s2) { /* only one is null */ |
| 1832 » } | 1800 return (SECFailure); |
| 1833 » return(SECSuccess); /* both are null */ | 1801 } |
| 1834 } | 1802 return (SECSuccess); /* both are null */ |
| 1835 » | |
| 1836 if ( PORT_Strcmp( s1, s2 ) != 0 ) { | |
| 1837 » return(SECFailure); /* not equal */ | |
| 1838 } | 1803 } |
| 1839 | 1804 |
| 1840 return(SECSuccess); /* strings are equal */ | 1805 if (PORT_Strcmp(s1, s2) != 0) { |
| 1806 return (SECFailure); /* not equal */ |
| 1807 } |
| 1808 |
| 1809 return (SECSuccess); /* strings are equal */ |
| 1841 } | 1810 } |
| 1842 | 1811 |
| 1843 | |
| 1844 PRBool | 1812 PRBool |
| 1845 CERT_CompareCertsForRedirection(CERTCertificate *c1, CERTCertificate *c2) | 1813 CERT_CompareCertsForRedirection(CERTCertificate *c1, CERTCertificate *c2) |
| 1846 { | 1814 { |
| 1847 SECComparison comp; | 1815 SECComparison comp; |
| 1848 char *c1str, *c2str; | 1816 char *c1str, *c2str; |
| 1849 SECStatus eq; | 1817 SECStatus eq; |
| 1850 | 1818 |
| 1851 comp = SECITEM_CompareItem(&c1->derCert, &c2->derCert); | 1819 comp = SECITEM_CompareItem(&c1->derCert, &c2->derCert); |
| 1852 if ( comp == SECEqual ) { /* certs are the same */ | 1820 if (comp == SECEqual) { /* certs are the same */ |
| 1853 » return(PR_TRUE); | 1821 return (PR_TRUE); |
| 1854 } | 1822 } |
| 1855 » | 1823 |
| 1856 /* check if they are issued by the same CA */ | 1824 /* check if they are issued by the same CA */ |
| 1857 comp = SECITEM_CompareItem(&c1->derIssuer, &c2->derIssuer); | 1825 comp = SECITEM_CompareItem(&c1->derIssuer, &c2->derIssuer); |
| 1858 if ( comp != SECEqual ) { /* different issuer */ | 1826 if (comp != SECEqual) { /* different issuer */ |
| 1859 » return(PR_FALSE); | 1827 return (PR_FALSE); |
| 1860 } | 1828 } |
| 1861 | 1829 |
| 1862 /* check country name */ | 1830 /* check country name */ |
| 1863 c1str = CERT_GetCountryName(&c1->subject); | 1831 c1str = CERT_GetCountryName(&c1->subject); |
| 1864 c2str = CERT_GetCountryName(&c2->subject); | 1832 c2str = CERT_GetCountryName(&c2->subject); |
| 1865 eq = StringsEqual(c1str, c2str); | 1833 eq = StringsEqual(c1str, c2str); |
| 1866 PORT_Free(c1str); | 1834 PORT_Free(c1str); |
| 1867 PORT_Free(c2str); | 1835 PORT_Free(c2str); |
| 1868 if ( eq != SECSuccess ) { | 1836 if (eq != SECSuccess) { |
| 1869 » return(PR_FALSE); | 1837 return (PR_FALSE); |
| 1870 } | 1838 } |
| 1871 | 1839 |
| 1872 /* check locality name */ | 1840 /* check locality name */ |
| 1873 c1str = CERT_GetLocalityName(&c1->subject); | 1841 c1str = CERT_GetLocalityName(&c1->subject); |
| 1874 c2str = CERT_GetLocalityName(&c2->subject); | 1842 c2str = CERT_GetLocalityName(&c2->subject); |
| 1875 eq = StringsEqual(c1str, c2str); | 1843 eq = StringsEqual(c1str, c2str); |
| 1876 PORT_Free(c1str); | 1844 PORT_Free(c1str); |
| 1877 PORT_Free(c2str); | 1845 PORT_Free(c2str); |
| 1878 if ( eq != SECSuccess ) { | 1846 if (eq != SECSuccess) { |
| 1879 » return(PR_FALSE); | 1847 return (PR_FALSE); |
| 1880 } | 1848 } |
| 1881 » | 1849 |
| 1882 /* check state name */ | 1850 /* check state name */ |
| 1883 c1str = CERT_GetStateName(&c1->subject); | 1851 c1str = CERT_GetStateName(&c1->subject); |
| 1884 c2str = CERT_GetStateName(&c2->subject); | 1852 c2str = CERT_GetStateName(&c2->subject); |
| 1885 eq = StringsEqual(c1str, c2str); | 1853 eq = StringsEqual(c1str, c2str); |
| 1886 PORT_Free(c1str); | 1854 PORT_Free(c1str); |
| 1887 PORT_Free(c2str); | 1855 PORT_Free(c2str); |
| 1888 if ( eq != SECSuccess ) { | 1856 if (eq != SECSuccess) { |
| 1889 » return(PR_FALSE); | 1857 return (PR_FALSE); |
| 1890 } | 1858 } |
| 1891 | 1859 |
| 1892 /* check org name */ | 1860 /* check org name */ |
| 1893 c1str = CERT_GetOrgName(&c1->subject); | 1861 c1str = CERT_GetOrgName(&c1->subject); |
| 1894 c2str = CERT_GetOrgName(&c2->subject); | 1862 c2str = CERT_GetOrgName(&c2->subject); |
| 1895 eq = StringsEqual(c1str, c2str); | 1863 eq = StringsEqual(c1str, c2str); |
| 1896 PORT_Free(c1str); | 1864 PORT_Free(c1str); |
| 1897 PORT_Free(c2str); | 1865 PORT_Free(c2str); |
| 1898 if ( eq != SECSuccess ) { | 1866 if (eq != SECSuccess) { |
| 1899 » return(PR_FALSE); | 1867 return (PR_FALSE); |
| 1900 } | 1868 } |
| 1901 | 1869 |
| 1902 #ifdef NOTDEF» | 1870 #ifdef NOTDEF |
| 1903 /* check orgUnit name */ | 1871 /* check orgUnit name */ |
| 1904 /* | 1872 /* |
| 1905 * We need to revisit this and decide which fields should be allowed to be | 1873 * We need to revisit this and decide which fields should be allowed to be |
| 1906 * different | 1874 * different |
| 1907 */ | 1875 */ |
| 1908 c1str = CERT_GetOrgUnitName(&c1->subject); | 1876 c1str = CERT_GetOrgUnitName(&c1->subject); |
| 1909 c2str = CERT_GetOrgUnitName(&c2->subject); | 1877 c2str = CERT_GetOrgUnitName(&c2->subject); |
| 1910 eq = StringsEqual(c1str, c2str); | 1878 eq = StringsEqual(c1str, c2str); |
| 1911 PORT_Free(c1str); | 1879 PORT_Free(c1str); |
| 1912 PORT_Free(c2str); | 1880 PORT_Free(c2str); |
| 1913 if ( eq != SECSuccess ) { | 1881 if (eq != SECSuccess) { |
| 1914 » return(PR_FALSE); | 1882 return (PR_FALSE); |
| 1915 } | 1883 } |
| 1916 #endif | 1884 #endif |
| 1917 | 1885 |
| 1918 return(PR_TRUE); /* all fields but common name are the same */ | 1886 return (PR_TRUE); /* all fields but common name are the same */ |
| 1919 } | 1887 } |
| 1920 | 1888 |
| 1921 | |
| 1922 /* CERT_CertChainFromCert and CERT_DestroyCertificateList moved | 1889 /* CERT_CertChainFromCert and CERT_DestroyCertificateList moved |
| 1923 to certhigh.c */ | 1890 to certhigh.c */ |
| 1924 | 1891 |
| 1925 | |
| 1926 CERTIssuerAndSN * | 1892 CERTIssuerAndSN * |
| 1927 CERT_GetCertIssuerAndSN(PLArenaPool *arena, CERTCertificate *cert) | 1893 CERT_GetCertIssuerAndSN(PLArenaPool *arena, CERTCertificate *cert) |
| 1928 { | 1894 { |
| 1929 CERTIssuerAndSN *result; | 1895 CERTIssuerAndSN *result; |
| 1930 SECStatus rv; | 1896 SECStatus rv; |
| 1931 | 1897 |
| 1932 if ( arena == NULL ) { | 1898 if (arena == NULL) { |
| 1933 » arena = cert->arena; | 1899 arena = cert->arena; |
| 1934 } | 1900 } |
| 1935 | 1901 |
| 1936 result = (CERTIssuerAndSN*)PORT_ArenaZAlloc(arena, sizeof(*result)); | 1902 result = (CERTIssuerAndSN *)PORT_ArenaZAlloc(arena, sizeof(*result)); |
| 1937 if (result == NULL) { | 1903 if (result == NULL) { |
| 1938 » PORT_SetError (SEC_ERROR_NO_MEMORY); | 1904 PORT_SetError(SEC_ERROR_NO_MEMORY); |
| 1939 » return NULL; | 1905 return NULL; |
| 1940 } | 1906 } |
| 1941 | 1907 |
| 1942 rv = SECITEM_CopyItem(arena, &result->derIssuer, &cert->derIssuer); | 1908 rv = SECITEM_CopyItem(arena, &result->derIssuer, &cert->derIssuer); |
| 1943 if (rv != SECSuccess) | 1909 if (rv != SECSuccess) |
| 1944 » return NULL; | 1910 return NULL; |
| 1945 | 1911 |
| 1946 rv = CERT_CopyName(arena, &result->issuer, &cert->issuer); | 1912 rv = CERT_CopyName(arena, &result->issuer, &cert->issuer); |
| 1947 if (rv != SECSuccess) | 1913 if (rv != SECSuccess) |
| 1948 » return NULL; | 1914 return NULL; |
| 1949 | 1915 |
| 1950 rv = SECITEM_CopyItem(arena, &result->serialNumber, &cert->serialNumber); | 1916 rv = SECITEM_CopyItem(arena, &result->serialNumber, &cert->serialNumber); |
| 1951 if (rv != SECSuccess) | 1917 if (rv != SECSuccess) |
| 1952 » return NULL; | 1918 return NULL; |
| 1953 | 1919 |
| 1954 return result; | 1920 return result; |
| 1955 } | 1921 } |
| 1956 | 1922 |
| 1957 char * | 1923 char * |
| 1958 CERT_MakeCANickname(CERTCertificate *cert) | 1924 CERT_MakeCANickname(CERTCertificate *cert) |
| 1959 { | 1925 { |
| 1960 char *firstname = NULL; | 1926 char *firstname = NULL; |
| 1961 char *org = NULL; | 1927 char *org = NULL; |
| 1962 char *nickname = NULL; | 1928 char *nickname = NULL; |
| 1963 int count; | 1929 int count; |
| 1964 CERTCertificate *dummycert; | 1930 CERTCertificate *dummycert; |
| 1965 | 1931 |
| 1966 firstname = CERT_GetCommonName(&cert->subject); | 1932 firstname = CERT_GetCommonName(&cert->subject); |
| 1967 if ( firstname == NULL ) { | 1933 if (firstname == NULL) { |
| 1968 » firstname = CERT_GetOrgUnitName(&cert->subject); | 1934 firstname = CERT_GetOrgUnitName(&cert->subject); |
| 1969 } | 1935 } |
| 1970 | 1936 |
| 1971 org = CERT_GetOrgName(&cert->issuer); | 1937 org = CERT_GetOrgName(&cert->issuer); |
| 1972 if (org == NULL) { | 1938 if (org == NULL) { |
| 1973 » org = CERT_GetDomainComponentName(&cert->issuer); | 1939 org = CERT_GetDomainComponentName(&cert->issuer); |
| 1974 » if (org == NULL) { | 1940 if (org == NULL) { |
| 1975 » if (firstname) { | 1941 if (firstname) { |
| 1976 » » org = firstname; | 1942 org = firstname; |
| 1977 » » firstname = NULL; | 1943 firstname = NULL; |
| 1978 » } else { | 1944 } else { |
| 1979 » » org = PORT_Strdup("Unknown CA"); | 1945 org = PORT_Strdup("Unknown CA"); |
| 1980 » } | 1946 } |
| 1981 » } | 1947 } |
| 1982 } | 1948 } |
| 1983 | 1949 |
| 1984 /* can only fail if PORT_Strdup fails, in which case | 1950 /* can only fail if PORT_Strdup fails, in which case |
| 1985 * we're having memory problems. */ | 1951 * we're having memory problems. */ |
| 1986 if (org == NULL) { | 1952 if (org == NULL) { |
| 1987 » goto done; | 1953 goto done; |
| 1988 } | 1954 } |
| 1989 | 1955 |
| 1990 | |
| 1991 count = 1; | 1956 count = 1; |
| 1992 while ( 1 ) { | 1957 while (1) { |
| 1993 | 1958 |
| 1994 » if ( firstname ) { | 1959 if (firstname) { |
| 1995 » if ( count == 1 ) { | 1960 if (count == 1) { |
| 1996 » » nickname = PR_smprintf("%s - %s", firstname, org); | 1961 nickname = PR_smprintf("%s - %s", firstname, org); |
| 1997 » } else { | 1962 } else { |
| 1998 » » nickname = PR_smprintf("%s - %s #%d", firstname, org, count); | 1963 nickname = PR_smprintf("%s - %s #%d", firstname, org, count); |
| 1999 » } | 1964 } |
| 2000 » } else { | 1965 } else { |
| 2001 » if ( count == 1 ) { | 1966 if (count == 1) { |
| 2002 » » nickname = PR_smprintf("%s", org); | 1967 nickname = PR_smprintf("%s", org); |
| 2003 » } else { | 1968 } else { |
| 2004 » » nickname = PR_smprintf("%s #%d", org, count); | 1969 nickname = PR_smprintf("%s #%d", org, count); |
| 2005 » } | 1970 } |
| 2006 » } | 1971 } |
| 2007 » if ( nickname == NULL ) { | 1972 if (nickname == NULL) { |
| 2008 » goto done; | 1973 goto done; |
| 2009 » } | 1974 } |
| 2010 | 1975 |
| 2011 » /* look up the nickname to make sure it isn't in use already */ | 1976 /* look up the nickname to make sure it isn't in use already */ |
| 2012 » dummycert = CERT_FindCertByNickname(cert->dbhandle, nickname); | 1977 dummycert = CERT_FindCertByNickname(cert->dbhandle, nickname); |
| 2013 | 1978 |
| 2014 » if ( dummycert == NULL ) { | 1979 if (dummycert == NULL) { |
| 2015 » goto done; | 1980 goto done; |
| 2016 » } | 1981 } |
| 2017 » | |
| 2018 » /* found a cert, destroy it and loop */ | |
| 2019 » CERT_DestroyCertificate(dummycert); | |
| 2020 | 1982 |
| 2021 » /* free the nickname */ | 1983 /* found a cert, destroy it and loop */ |
| 2022 » PORT_Free(nickname); | 1984 CERT_DestroyCertificate(dummycert); |
| 2023 | 1985 |
| 2024 » count++; | 1986 /* free the nickname */ |
| 1987 PORT_Free(nickname); |
| 1988 |
| 1989 count++; |
| 2025 } | 1990 } |
| 2026 | 1991 |
| 2027 done: | 1992 done: |
| 2028 if ( firstname ) { | 1993 if (firstname) { |
| 2029 » PORT_Free(firstname); | 1994 PORT_Free(firstname); |
| 2030 } | 1995 } |
| 2031 if ( org ) { | 1996 if (org) { |
| 2032 » PORT_Free(org); | 1997 PORT_Free(org); |
| 2033 } | 1998 } |
| 2034 | 1999 |
| 2035 return(nickname); | 2000 return (nickname); |
| 2036 } | 2001 } |
| 2037 | 2002 |
| 2038 /* CERT_Import_CAChain moved to certhigh.c */ | 2003 /* CERT_Import_CAChain moved to certhigh.c */ |
| 2039 | 2004 |
| 2040 void | 2005 void |
| 2041 CERT_DestroyCrl (CERTSignedCrl *crl) | 2006 CERT_DestroyCrl(CERTSignedCrl *crl) |
| 2042 { | 2007 { |
| 2043 SEC_DestroyCrl (crl); | 2008 SEC_DestroyCrl(crl); |
| 2044 } | 2009 } |
| 2045 | 2010 |
| 2046 static int | 2011 static int |
| 2047 cert_Version(CERTCertificate *cert) | 2012 cert_Version(CERTCertificate *cert) |
| 2048 { | 2013 { |
| 2049 int version = 0; | 2014 int version = 0; |
| 2050 if (cert && cert->version.data && cert->version.len) { | 2015 if (cert && cert->version.data && cert->version.len) { |
| 2051 » version = DER_GetInteger(&cert->version); | 2016 version = DER_GetInteger(&cert->version); |
| 2052 » if (version < 0) | 2017 if (version < 0) |
| 2053 » version = 0; | 2018 version = 0; |
| 2054 } | 2019 } |
| 2055 return version; | 2020 return version; |
| 2056 } | 2021 } |
| 2057 | 2022 |
| 2058 static unsigned int | 2023 static unsigned int |
| 2059 cert_ComputeTrustOverrides(CERTCertificate *cert, unsigned int cType) | 2024 cert_ComputeTrustOverrides(CERTCertificate *cert, unsigned int cType) |
| 2060 { | 2025 { |
| 2061 CERTCertTrust trust; | 2026 CERTCertTrust trust; |
| 2062 SECStatus rv = SECFailure; | 2027 SECStatus rv = SECFailure; |
| 2063 | 2028 |
| 2064 rv = CERT_GetCertTrust(cert, &trust); | 2029 rv = CERT_GetCertTrust(cert, &trust); |
| 2065 | 2030 |
| 2066 if (rv == SECSuccess && (trust.sslFlags | | 2031 if (rv == SECSuccess && |
| 2067 » » trust.emailFlags | | 2032 (trust.sslFlags | trust.emailFlags | trust.objectSigningFlags)) { |
| 2068 » » trust.objectSigningFlags)) { | |
| 2069 | 2033 |
| 2070 » if (trust.sslFlags & (CERTDB_TERMINAL_RECORD|CERTDB_TRUSTED)) | 2034 if (trust.sslFlags & (CERTDB_TERMINAL_RECORD | CERTDB_TRUSTED)) |
| 2071 » cType |= NS_CERT_TYPE_SSL_SERVER|NS_CERT_TYPE_SSL_CLIENT; | 2035 cType |= NS_CERT_TYPE_SSL_SERVER | NS_CERT_TYPE_SSL_CLIENT; |
| 2072 » if (trust.sslFlags & (CERTDB_VALID_CA|CERTDB_TRUSTED_CA)) | 2036 if (trust.sslFlags & (CERTDB_VALID_CA | CERTDB_TRUSTED_CA)) |
| 2073 » cType |= NS_CERT_TYPE_SSL_CA; | 2037 cType |= NS_CERT_TYPE_SSL_CA; |
| 2074 #if defined(CERTDB_NOT_TRUSTED) | 2038 #if defined(CERTDB_NOT_TRUSTED) |
| 2075 » if (trust.sslFlags & CERTDB_NOT_TRUSTED) | 2039 if (trust.sslFlags & CERTDB_NOT_TRUSTED) |
| 2076 » cType &= ~(NS_CERT_TYPE_SSL_SERVER|NS_CERT_TYPE_SSL_CLIENT| | 2040 cType &= ~(NS_CERT_TYPE_SSL_SERVER | NS_CERT_TYPE_SSL_CLIENT | |
| 2077 » NS_CERT_TYPE_SSL_CA); | 2041 NS_CERT_TYPE_SSL_CA); |
| 2078 #endif | 2042 #endif |
| 2079 » if (trust.emailFlags & (CERTDB_TERMINAL_RECORD|CERTDB_TRUSTED)) | 2043 if (trust.emailFlags & (CERTDB_TERMINAL_RECORD | CERTDB_TRUSTED)) |
| 2080 » cType |= NS_CERT_TYPE_EMAIL; | 2044 cType |= NS_CERT_TYPE_EMAIL; |
| 2081 » if (trust.emailFlags & (CERTDB_VALID_CA|CERTDB_TRUSTED_CA)) | 2045 if (trust.emailFlags & (CERTDB_VALID_CA | CERTDB_TRUSTED_CA)) |
| 2082 » cType |= NS_CERT_TYPE_EMAIL_CA; | 2046 cType |= NS_CERT_TYPE_EMAIL_CA; |
| 2083 #if defined(CERTDB_NOT_TRUSTED) | 2047 #if defined(CERTDB_NOT_TRUSTED) |
| 2084 » if (trust.emailFlags & CERTDB_NOT_TRUSTED) | 2048 if (trust.emailFlags & CERTDB_NOT_TRUSTED) |
| 2085 » cType &= ~(NS_CERT_TYPE_EMAIL|NS_CERT_TYPE_EMAIL_CA); | 2049 cType &= ~(NS_CERT_TYPE_EMAIL | NS_CERT_TYPE_EMAIL_CA); |
| 2086 #endif | 2050 #endif |
| 2087 » if (trust.objectSigningFlags & (CERTDB_TERMINAL_RECORD|CERTDB_TRUSTED)) | 2051 if (trust.objectSigningFlags & |
| 2088 » cType |= NS_CERT_TYPE_OBJECT_SIGNING; | 2052 (CERTDB_TERMINAL_RECORD | CERTDB_TRUSTED)) |
| 2089 » if (trust.objectSigningFlags & (CERTDB_VALID_CA|CERTDB_TRUSTED_CA)) | 2053 cType |= NS_CERT_TYPE_OBJECT_SIGNING; |
| 2090 » cType |= NS_CERT_TYPE_OBJECT_SIGNING_CA; | 2054 if (trust.objectSigningFlags & (CERTDB_VALID_CA | CERTDB_TRUSTED_CA)) |
| 2055 cType |= NS_CERT_TYPE_OBJECT_SIGNING_CA; |
| 2091 #if defined(CERTDB_NOT_TRUSTED) | 2056 #if defined(CERTDB_NOT_TRUSTED) |
| 2092 » if (trust.objectSigningFlags & CERTDB_NOT_TRUSTED) | 2057 if (trust.objectSigningFlags & CERTDB_NOT_TRUSTED) |
| 2093 » cType &= ~(NS_CERT_TYPE_OBJECT_SIGNING| | 2058 cType &= |
| 2094 » NS_CERT_TYPE_OBJECT_SIGNING_CA); | 2059 ~(NS_CERT_TYPE_OBJECT_SIGNING | NS_CERT_TYPE_OBJECT_SIGNING_CA); |
| 2095 #endif | 2060 #endif |
| 2096 } | 2061 } |
| 2097 return cType; | 2062 return cType; |
| 2098 } | 2063 } |
| 2099 | 2064 |
| 2100 /* | 2065 /* |
| 2101 * Does a cert belong to a CA? We decide based on perm database trust | 2066 * Does a cert belong to a CA? We decide based on perm database trust |
| 2102 * flags, Netscape Cert Type Extension, and KeyUsage Extension. | 2067 * flags, Netscape Cert Type Extension, and KeyUsage Extension. |
| 2103 */ | 2068 */ |
| 2104 PRBool | 2069 PRBool |
| 2105 CERT_IsCACert(CERTCertificate *cert, unsigned int *rettype) | 2070 CERT_IsCACert(CERTCertificate *cert, unsigned int *rettype) |
| 2106 { | 2071 { |
| 2107 unsigned int cType = cert->nsCertType; | 2072 unsigned int cType = cert->nsCertType; |
| 2108 PRBool ret = PR_FALSE; | 2073 PRBool ret = PR_FALSE; |
| 2109 | 2074 |
| 2110 if (cType & (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA | | 2075 if (cType & (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA | |
| 2111 NS_CERT_TYPE_OBJECT_SIGNING_CA)) { | 2076 NS_CERT_TYPE_OBJECT_SIGNING_CA)) { |
| 2112 ret = PR_TRUE; | 2077 ret = PR_TRUE; |
| 2113 } else { | 2078 } else { |
| 2114 » SECStatus rv; | 2079 SECStatus rv; |
| 2115 » CERTBasicConstraints constraints; | 2080 CERTBasicConstraints constraints; |
| 2116 | 2081 |
| 2117 » rv = CERT_FindBasicConstraintExten(cert, &constraints); | 2082 rv = CERT_FindBasicConstraintExten(cert, &constraints); |
| 2118 » if (rv == SECSuccess && constraints.isCA) { | 2083 if (rv == SECSuccess && constraints.isCA) { |
| 2119 » ret = PR_TRUE; | 2084 ret = PR_TRUE; |
| 2120 » cType |= (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA); | 2085 cType |= (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA); |
| 2121 » } | 2086 } |
| 2122 } | 2087 } |
| 2123 | 2088 |
| 2124 /* finally check if it's an X.509 v1 root CA */ | 2089 /* finally check if it's an X.509 v1 root CA */ |
| 2125 if (!ret && | 2090 if (!ret && |
| 2126 (cert->isRoot && cert_Version(cert) < SEC_CERTIFICATE_VERSION_3)) { | 2091 (cert->isRoot && cert_Version(cert) < SEC_CERTIFICATE_VERSION_3)) { |
| 2127 » ret = PR_TRUE; | 2092 ret = PR_TRUE; |
| 2128 » cType |= (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA); | 2093 cType |= (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA); |
| 2129 } | 2094 } |
| 2130 /* Now apply trust overrides, if any */ | 2095 /* Now apply trust overrides, if any */ |
| 2131 cType = cert_ComputeTrustOverrides(cert, cType); | 2096 cType = cert_ComputeTrustOverrides(cert, cType); |
| 2132 ret = (cType & (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA | | 2097 ret = (cType & (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA | |
| 2133 NS_CERT_TYPE_OBJECT_SIGNING_CA)) ? PR_TRUE : PR_FALSE; | 2098 NS_CERT_TYPE_OBJECT_SIGNING_CA)) |
| 2099 ? PR_TRUE |
| 2100 : PR_FALSE; |
| 2134 | 2101 |
| 2135 if (rettype != NULL) { | 2102 if (rettype != NULL) { |
| 2136 » *rettype = cType; | 2103 *rettype = cType; |
| 2137 } | 2104 } |
| 2138 return ret; | 2105 return ret; |
| 2139 } | 2106 } |
| 2140 | 2107 |
| 2141 PRBool | 2108 PRBool |
| 2142 CERT_IsCADERCert(SECItem *derCert, unsigned int *type) { | 2109 CERT_IsCADERCert(SECItem *derCert, unsigned int *type) |
| 2110 { |
| 2143 CERTCertificate *cert; | 2111 CERTCertificate *cert; |
| 2144 PRBool isCA; | 2112 PRBool isCA; |
| 2145 | 2113 |
| 2146 /* This is okay -- only looks at extensions */ | 2114 /* This is okay -- only looks at extensions */ |
| 2147 cert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL); | 2115 cert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL); |
| 2148 if (cert == NULL) return PR_FALSE; | 2116 if (cert == NULL) |
| 2117 return PR_FALSE; |
| 2149 | 2118 |
| 2150 isCA = CERT_IsCACert(cert,type); | 2119 isCA = CERT_IsCACert(cert, type); |
| 2151 CERT_DestroyCertificate (cert); | 2120 CERT_DestroyCertificate(cert); |
| 2152 return isCA; | 2121 return isCA; |
| 2153 } | 2122 } |
| 2154 | 2123 |
| 2155 PRBool | 2124 PRBool |
| 2156 CERT_IsRootDERCert(SECItem *derCert) | 2125 CERT_IsRootDERCert(SECItem *derCert) |
| 2157 { | 2126 { |
| 2158 CERTCertificate *cert; | 2127 CERTCertificate *cert; |
| 2159 PRBool isRoot; | 2128 PRBool isRoot; |
| 2160 | 2129 |
| 2161 /* This is okay -- only looks at extensions */ | 2130 /* This is okay -- only looks at extensions */ |
| 2162 cert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL); | 2131 cert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL); |
| 2163 if (cert == NULL) return PR_FALSE; | 2132 if (cert == NULL) |
| 2133 return PR_FALSE; |
| 2164 | 2134 |
| 2165 isRoot = cert->isRoot; | 2135 isRoot = cert->isRoot; |
| 2166 CERT_DestroyCertificate (cert); | 2136 CERT_DestroyCertificate(cert); |
| 2167 return isRoot; | 2137 return isRoot; |
| 2168 } | 2138 } |
| 2169 | 2139 |
| 2170 CERTCompareValidityStatus | 2140 CERTCompareValidityStatus |
| 2171 CERT_CompareValidityTimes(CERTValidity* val_a, CERTValidity* val_b) | 2141 CERT_CompareValidityTimes(CERTValidity *val_a, CERTValidity *val_b) |
| 2172 { | 2142 { |
| 2173 PRTime notBeforeA, notBeforeB, notAfterA, notAfterB; | 2143 PRTime notBeforeA, notBeforeB, notAfterA, notAfterB; |
| 2174 | 2144 |
| 2175 if (!val_a || !val_b) | 2145 if (!val_a || !val_b) { |
| 2176 { | |
| 2177 PORT_SetError(SEC_ERROR_INVALID_ARGS); | 2146 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 2178 return certValidityUndetermined; | 2147 return certValidityUndetermined; |
| 2179 } | 2148 } |
| 2180 | 2149 |
| 2181 if ( SECSuccess != DER_DecodeTimeChoice(¬BeforeA, &val_a->notBefore) || | 2150 if (SECSuccess != DER_DecodeTimeChoice(¬BeforeA, &val_a->notBefore) || |
| 2182 SECSuccess != DER_DecodeTimeChoice(¬BeforeB, &val_b->notBefore) || | 2151 SECSuccess != DER_DecodeTimeChoice(¬BeforeB, &val_b->notBefore) || |
| 2183 SECSuccess != DER_DecodeTimeChoice(¬AfterA, &val_a->notAfter) || | 2152 SECSuccess != DER_DecodeTimeChoice(¬AfterA, &val_a->notAfter) || |
| 2184 SECSuccess != DER_DecodeTimeChoice(¬AfterB, &val_b->notAfter) ) { | 2153 SECSuccess != DER_DecodeTimeChoice(¬AfterB, &val_b->notAfter)) { |
| 2185 return certValidityUndetermined; | 2154 return certValidityUndetermined; |
| 2186 } | 2155 } |
| 2187 | 2156 |
| 2188 /* sanity check */ | 2157 /* sanity check */ |
| 2189 if (LL_CMP(notBeforeA,>,notAfterA) || LL_CMP(notBeforeB,>,notAfterB)) { | 2158 if (LL_CMP(notBeforeA, >, notAfterA) || LL_CMP(notBeforeB, >, notAfterB)) { |
| 2190 PORT_SetError(SEC_ERROR_INVALID_TIME); | 2159 PORT_SetError(SEC_ERROR_INVALID_TIME); |
| 2191 return certValidityUndetermined; | 2160 return certValidityUndetermined; |
| 2192 } | 2161 } |
| 2193 | 2162 |
| 2194 if (LL_CMP(notAfterA,!=,notAfterB)) { | 2163 if (LL_CMP(notAfterA, !=, notAfterB)) { |
| 2195 /* one cert validity goes farther into the future, select it */ | 2164 /* one cert validity goes farther into the future, select it */ |
| 2196 return LL_CMP(notAfterA,<,notAfterB) ? | 2165 return LL_CMP(notAfterA, <, notAfterB) ? certValidityChooseB |
| 2197 certValidityChooseB : certValidityChooseA; | 2166 : certValidityChooseA; |
| 2198 } | 2167 } |
| 2199 /* the two certs have the same expiration date */ | 2168 /* the two certs have the same expiration date */ |
| 2200 PORT_Assert(LL_CMP(notAfterA, == , notAfterB)); | 2169 PORT_Assert(LL_CMP(notAfterA, ==, notAfterB)); |
| 2201 /* do they also have the same start date ? */ | 2170 /* do they also have the same start date ? */ |
| 2202 if (LL_CMP(notBeforeA,==,notBeforeB)) { | 2171 if (LL_CMP(notBeforeA, ==, notBeforeB)) { |
| 2203 » return certValidityEqual; | 2172 return certValidityEqual; |
| 2204 } | 2173 } |
| 2205 /* choose cert with the later start date */ | 2174 /* choose cert with the later start date */ |
| 2206 return LL_CMP(notBeforeA,<,notBeforeB) ? | 2175 return LL_CMP(notBeforeA, <, notBeforeB) ? certValidityChooseB |
| 2207 certValidityChooseB : certValidityChooseA; | 2176 : certValidityChooseA; |
| 2208 } | 2177 } |
| 2209 | 2178 |
| 2210 /* | 2179 /* |
| 2211 * is certa newer than certb? If one is expired, pick the other one. | 2180 * is certa newer than certb? If one is expired, pick the other one. |
| 2212 */ | 2181 */ |
| 2213 PRBool | 2182 PRBool |
| 2214 CERT_IsNewer(CERTCertificate *certa, CERTCertificate *certb) | 2183 CERT_IsNewer(CERTCertificate *certa, CERTCertificate *certb) |
| 2215 { | 2184 { |
| 2216 PRTime notBeforeA, notAfterA, notBeforeB, notAfterB, now; | 2185 PRTime notBeforeA, notAfterA, notBeforeB, notAfterB, now; |
| 2217 SECStatus rv; | 2186 SECStatus rv; |
| 2218 PRBool newerbefore, newerafter; | 2187 PRBool newerbefore, newerafter; |
| 2219 | 2188 |
| 2220 rv = CERT_GetCertTimes(certa, ¬BeforeA, ¬AfterA); | 2189 rv = CERT_GetCertTimes(certa, ¬BeforeA, ¬AfterA); |
| 2221 if ( rv != SECSuccess ) { | 2190 if (rv != SECSuccess) { |
| 2222 » return(PR_FALSE); | 2191 return (PR_FALSE); |
| 2223 } | 2192 } |
| 2224 | 2193 |
| 2225 rv = CERT_GetCertTimes(certb, ¬BeforeB, ¬AfterB); | 2194 rv = CERT_GetCertTimes(certb, ¬BeforeB, ¬AfterB); |
| 2226 if ( rv != SECSuccess ) { | 2195 if (rv != SECSuccess) { |
| 2227 » return(PR_TRUE); | 2196 return (PR_TRUE); |
| 2228 } | 2197 } |
| 2229 | 2198 |
| 2230 newerbefore = PR_FALSE; | 2199 newerbefore = PR_FALSE; |
| 2231 if ( LL_CMP(notBeforeA, >, notBeforeB) ) { | 2200 if (LL_CMP(notBeforeA, >, notBeforeB)) { |
| 2232 » newerbefore = PR_TRUE; | 2201 newerbefore = PR_TRUE; |
| 2233 } | 2202 } |
| 2234 | 2203 |
| 2235 newerafter = PR_FALSE; | 2204 newerafter = PR_FALSE; |
| 2236 if ( LL_CMP(notAfterA, >, notAfterB) ) { | 2205 if (LL_CMP(notAfterA, >, notAfterB)) { |
| 2237 » newerafter = PR_TRUE; | 2206 newerafter = PR_TRUE; |
| 2238 } | 2207 } |
| 2239 | 2208 |
| 2240 if ( newerbefore && newerafter ) { | 2209 if (newerbefore && newerafter) { |
| 2241 » return(PR_TRUE); | 2210 return (PR_TRUE); |
| 2242 } | 2211 } |
| 2243 | 2212 |
| 2244 if ( ( !newerbefore ) && ( !newerafter ) ) { | 2213 if ((!newerbefore) && (!newerafter)) { |
| 2245 » return(PR_FALSE); | 2214 return (PR_FALSE); |
| 2246 } | 2215 } |
| 2247 | 2216 |
| 2248 /* get current time */ | 2217 /* get current time */ |
| 2249 now = PR_Now(); | 2218 now = PR_Now(); |
| 2250 | 2219 |
| 2251 if ( newerbefore ) { | 2220 if (newerbefore) { |
| 2252 » /* cert A was issued after cert B, but expires sooner */ | 2221 /* cert A was issued after cert B, but expires sooner */ |
| 2253 » /* if A is expired, then pick B */ | 2222 /* if A is expired, then pick B */ |
| 2254 » if ( LL_CMP(notAfterA, <, now ) ) { | 2223 if (LL_CMP(notAfterA, <, now)) { |
| 2255 » return(PR_FALSE); | 2224 return (PR_FALSE); |
| 2256 » } | 2225 } |
| 2257 » return(PR_TRUE); | 2226 return (PR_TRUE); |
| 2258 } else { | 2227 } else { |
| 2259 » /* cert B was issued after cert A, but expires sooner */ | 2228 /* cert B was issued after cert A, but expires sooner */ |
| 2260 » /* if B is expired, then pick A */ | 2229 /* if B is expired, then pick A */ |
| 2261 » if ( LL_CMP(notAfterB, <, now ) ) { | 2230 if (LL_CMP(notAfterB, <, now)) { |
| 2262 » return(PR_TRUE); | 2231 return (PR_TRUE); |
| 2263 » } | 2232 } |
| 2264 » return(PR_FALSE); | 2233 return (PR_FALSE); |
| 2265 } | 2234 } |
| 2266 } | 2235 } |
| 2267 | 2236 |
| 2268 void | 2237 void |
| 2269 CERT_DestroyCertArray(CERTCertificate **certs, unsigned int ncerts) | 2238 CERT_DestroyCertArray(CERTCertificate **certs, unsigned int ncerts) |
| 2270 { | 2239 { |
| 2271 unsigned int i; | 2240 unsigned int i; |
| 2272 | |
| 2273 if ( certs ) { | |
| 2274 for ( i = 0; i < ncerts; i++ ) { | |
| 2275 if ( certs[i] ) { | |
| 2276 CERT_DestroyCertificate(certs[i]); | |
| 2277 } | |
| 2278 } | |
| 2279 | 2241 |
| 2280 » PORT_Free(certs); | 2242 if (certs) { |
| 2243 for (i = 0; i < ncerts; i++) { |
| 2244 if (certs[i]) { |
| 2245 CERT_DestroyCertificate(certs[i]); |
| 2246 } |
| 2247 } |
| 2248 |
| 2249 PORT_Free(certs); |
| 2281 } | 2250 } |
| 2282 | 2251 |
| 2283 return; | 2252 return; |
| 2284 } | 2253 } |
| 2285 | 2254 |
| 2286 char * | 2255 char * |
| 2287 CERT_FixupEmailAddr(const char *emailAddr) | 2256 CERT_FixupEmailAddr(const char *emailAddr) |
| 2288 { | 2257 { |
| 2289 char *retaddr; | 2258 char *retaddr; |
| 2290 char *str; | 2259 char *str; |
| 2291 | 2260 |
| 2292 if ( emailAddr == NULL ) { | 2261 if (emailAddr == NULL) { |
| 2293 » return(NULL); | 2262 return (NULL); |
| 2294 } | 2263 } |
| 2295 | 2264 |
| 2296 /* copy the string */ | 2265 /* copy the string */ |
| 2297 str = retaddr = PORT_Strdup(emailAddr); | 2266 str = retaddr = PORT_Strdup(emailAddr); |
| 2298 if ( str == NULL ) { | 2267 if (str == NULL) { |
| 2299 » return(NULL); | 2268 return (NULL); |
| 2300 } | 2269 } |
| 2301 | 2270 |
| 2302 /* make it lower case */ | 2271 /* make it lower case */ |
| 2303 while ( *str ) { | 2272 while (*str) { |
| 2304 » *str = tolower( *str ); | 2273 *str = tolower(*str); |
| 2305 » str++; | 2274 str++; |
| 2306 } | 2275 } |
| 2307 | 2276 |
| 2308 return(retaddr); | 2277 return (retaddr); |
| 2309 } | 2278 } |
| 2310 | 2279 |
| 2311 /* | 2280 /* |
| 2312 * NOTE - don't allow encode of govt-approved or invisible bits | 2281 * NOTE - don't allow encode of govt-approved or invisible bits |
| 2313 */ | 2282 */ |
| 2314 SECStatus | 2283 SECStatus |
| 2315 CERT_DecodeTrustString(CERTCertTrust *trust, const char *trusts) | 2284 CERT_DecodeTrustString(CERTCertTrust *trust, const char *trusts) |
| 2316 { | 2285 { |
| 2317 unsigned int i; | 2286 unsigned int i; |
| 2318 unsigned int *pflags; | 2287 unsigned int *pflags; |
| 2319 | 2288 |
| 2320 if (!trust) { | 2289 if (!trust) { |
| 2321 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 2290 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 2322 » return SECFailure; | 2291 return SECFailure; |
| 2323 } | 2292 } |
| 2324 trust->sslFlags = 0; | 2293 trust->sslFlags = 0; |
| 2325 trust->emailFlags = 0; | 2294 trust->emailFlags = 0; |
| 2326 trust->objectSigningFlags = 0; | 2295 trust->objectSigningFlags = 0; |
| 2327 if (!trusts) { | 2296 if (!trusts) { |
| 2328 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 2297 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 2329 » return SECFailure; | 2298 return SECFailure; |
| 2330 } | 2299 } |
| 2331 | 2300 |
| 2332 pflags = &trust->sslFlags; | 2301 pflags = &trust->sslFlags; |
| 2333 | 2302 |
| 2334 for (i=0; i < PORT_Strlen(trusts); i++) { | 2303 for (i = 0; i < PORT_Strlen(trusts); i++) { |
| 2335 » switch (trusts[i]) { | 2304 switch (trusts[i]) { |
| 2336 » case 'p': | 2305 case 'p': |
| 2337 » *pflags = *pflags | CERTDB_TERMINAL_RECORD; | 2306 *pflags = *pflags | CERTDB_TERMINAL_RECORD; |
| 2338 » break; | 2307 break; |
| 2339 | 2308 |
| 2340 » case 'P': | 2309 case 'P': |
| 2341 » *pflags = *pflags | CERTDB_TRUSTED | CERTDB_TERMINAL_RECORD; | 2310 *pflags = *pflags | CERTDB_TRUSTED | CERTDB_TERMINAL_RECORD; |
| 2342 » break; | 2311 break; |
| 2343 | 2312 |
| 2344 » case 'w': | 2313 case 'w': |
| 2345 » *pflags = *pflags | CERTDB_SEND_WARN; | 2314 *pflags = *pflags | CERTDB_SEND_WARN; |
| 2346 » break; | 2315 break; |
| 2347 | 2316 |
| 2348 » case 'c': | 2317 case 'c': |
| 2349 » *pflags = *pflags | CERTDB_VALID_CA; | 2318 *pflags = *pflags | CERTDB_VALID_CA; |
| 2350 » break; | 2319 break; |
| 2351 | 2320 |
| 2352 » case 'T': | 2321 case 'T': |
| 2353 » *pflags = *pflags | CERTDB_TRUSTED_CLIENT_CA | CERTDB_VALID_CA; | 2322 *pflags = *pflags | CERTDB_TRUSTED_CLIENT_CA | CERTDB_VALID_CA; |
| 2354 » break; | 2323 break; |
| 2355 | 2324 |
| 2356 » case 'C' : | 2325 case 'C': |
| 2357 » *pflags = *pflags | CERTDB_TRUSTED_CA | CERTDB_VALID_CA; | 2326 *pflags = *pflags | CERTDB_TRUSTED_CA | CERTDB_VALID_CA; |
| 2358 » break; | 2327 break; |
| 2359 | 2328 |
| 2360 » case 'u': | 2329 case 'u': |
| 2361 » *pflags = *pflags | CERTDB_USER; | 2330 *pflags = *pflags | CERTDB_USER; |
| 2362 » break; | 2331 break; |
| 2363 | 2332 |
| 2364 » case 'i': | 2333 case 'i': |
| 2365 » *pflags = *pflags | CERTDB_INVISIBLE_CA; | 2334 *pflags = *pflags | CERTDB_INVISIBLE_CA; |
| 2366 » break; | 2335 break; |
| 2367 » case 'g': | 2336 case 'g': |
| 2368 » *pflags = *pflags | CERTDB_GOVT_APPROVED_CA; | 2337 *pflags = *pflags | CERTDB_GOVT_APPROVED_CA; |
| 2369 » break; | 2338 break; |
| 2370 | 2339 |
| 2371 » case ',': | 2340 case ',': |
| 2372 » if ( pflags == &trust->sslFlags ) { | 2341 if (pflags == &trust->sslFlags) { |
| 2373 » » pflags = &trust->emailFlags; | 2342 pflags = &trust->emailFlags; |
| 2374 » } else { | 2343 } else { |
| 2375 » » pflags = &trust->objectSigningFlags; | 2344 pflags = &trust->objectSigningFlags; |
| 2376 » } | 2345 } |
| 2377 » break; | 2346 break; |
| 2378 » default: | 2347 default: |
| 2379 PORT_SetError(SEC_ERROR_INVALID_ARGS); | 2348 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 2380 » return SECFailure; | 2349 return SECFailure; |
| 2381 » } | 2350 } |
| 2382 } | 2351 } |
| 2383 | 2352 |
| 2384 return SECSuccess; | 2353 return SECSuccess; |
| 2385 } | 2354 } |
| 2386 | 2355 |
| 2387 static void | 2356 static void |
| 2388 EncodeFlags(char *trusts, unsigned int flags) | 2357 EncodeFlags(char *trusts, unsigned int flags) |
| 2389 { | 2358 { |
| 2390 if (flags & CERTDB_VALID_CA) | 2359 if (flags & CERTDB_VALID_CA) |
| 2391 » if (!(flags & CERTDB_TRUSTED_CA) && | 2360 if (!(flags & CERTDB_TRUSTED_CA) && !(flags & CERTDB_TRUSTED_CLIENT_CA)) |
| 2392 » !(flags & CERTDB_TRUSTED_CLIENT_CA)) | 2361 PORT_Strcat(trusts, "c"); |
| 2393 » PORT_Strcat(trusts, "c"); | |
| 2394 if (flags & CERTDB_TERMINAL_RECORD) | 2362 if (flags & CERTDB_TERMINAL_RECORD) |
| 2395 » if (!(flags & CERTDB_TRUSTED)) | 2363 if (!(flags & CERTDB_TRUSTED)) |
| 2396 » PORT_Strcat(trusts, "p"); | 2364 PORT_Strcat(trusts, "p"); |
| 2397 if (flags & CERTDB_TRUSTED_CA) | 2365 if (flags & CERTDB_TRUSTED_CA) |
| 2398 » PORT_Strcat(trusts, "C"); | 2366 PORT_Strcat(trusts, "C"); |
| 2399 if (flags & CERTDB_TRUSTED_CLIENT_CA) | 2367 if (flags & CERTDB_TRUSTED_CLIENT_CA) |
| 2400 » PORT_Strcat(trusts, "T"); | 2368 PORT_Strcat(trusts, "T"); |
| 2401 if (flags & CERTDB_TRUSTED) | 2369 if (flags & CERTDB_TRUSTED) |
| 2402 » PORT_Strcat(trusts, "P"); | 2370 PORT_Strcat(trusts, "P"); |
| 2403 if (flags & CERTDB_USER) | 2371 if (flags & CERTDB_USER) |
| 2404 » PORT_Strcat(trusts, "u"); | 2372 PORT_Strcat(trusts, "u"); |
| 2405 if (flags & CERTDB_SEND_WARN) | 2373 if (flags & CERTDB_SEND_WARN) |
| 2406 » PORT_Strcat(trusts, "w"); | 2374 PORT_Strcat(trusts, "w"); |
| 2407 if (flags & CERTDB_INVISIBLE_CA) | 2375 if (flags & CERTDB_INVISIBLE_CA) |
| 2408 » PORT_Strcat(trusts, "I"); | 2376 PORT_Strcat(trusts, "I"); |
| 2409 if (flags & CERTDB_GOVT_APPROVED_CA) | 2377 if (flags & CERTDB_GOVT_APPROVED_CA) |
| 2410 » PORT_Strcat(trusts, "G"); | 2378 PORT_Strcat(trusts, "G"); |
| 2411 return; | 2379 return; |
| 2412 } | 2380 } |
| 2413 | 2381 |
| 2414 char * | 2382 char * |
| 2415 CERT_EncodeTrustString(CERTCertTrust *trust) | 2383 CERT_EncodeTrustString(CERTCertTrust *trust) |
| 2416 { | 2384 { |
| 2417 char tmpTrustSSL[32]; | 2385 char tmpTrustSSL[32]; |
| 2418 char tmpTrustEmail[32]; | 2386 char tmpTrustEmail[32]; |
| 2419 char tmpTrustSigning[32]; | 2387 char tmpTrustSigning[32]; |
| 2420 char *retstr = NULL; | 2388 char *retstr = NULL; |
| 2421 | 2389 |
| 2422 if ( trust ) { | 2390 if (trust) { |
| 2423 » tmpTrustSSL[0] = '\0'; | 2391 tmpTrustSSL[0] = '\0'; |
| 2424 » tmpTrustEmail[0] = '\0'; | 2392 tmpTrustEmail[0] = '\0'; |
| 2425 » tmpTrustSigning[0] = '\0'; | 2393 tmpTrustSigning[0] = '\0'; |
| 2426 | 2394 |
| 2427 » EncodeFlags(tmpTrustSSL, trust->sslFlags); | 2395 EncodeFlags(tmpTrustSSL, trust->sslFlags); |
| 2428 » EncodeFlags(tmpTrustEmail, trust->emailFlags); | 2396 EncodeFlags(tmpTrustEmail, trust->emailFlags); |
| 2429 » EncodeFlags(tmpTrustSigning, trust->objectSigningFlags); | 2397 EncodeFlags(tmpTrustSigning, trust->objectSigningFlags); |
| 2430 | 2398 |
| 2431 » retstr = PR_smprintf("%s,%s,%s", tmpTrustSSL, tmpTrustEmail, | 2399 retstr = PR_smprintf("%s,%s,%s", tmpTrustSSL, tmpTrustEmail, |
| 2432 » » » tmpTrustSigning); | 2400 tmpTrustSigning); |
| 2433 } | 2401 } |
| 2434 | 2402 |
| 2435 return(retstr); | 2403 return (retstr); |
| 2436 } | 2404 } |
| 2437 | 2405 |
| 2438 SECStatus | 2406 SECStatus |
| 2439 CERT_ImportCerts(CERTCertDBHandle *certdb, SECCertUsage usage, | 2407 CERT_ImportCerts(CERTCertDBHandle *certdb, SECCertUsage usage, |
| 2440 » » unsigned int ncerts, SECItem **derCerts, | 2408 unsigned int ncerts, SECItem **derCerts, |
| 2441 » » CERTCertificate ***retCerts, PRBool keepCerts, | 2409 CERTCertificate ***retCerts, PRBool keepCerts, PRBool caOnly, |
| 2442 » » PRBool caOnly, char *nickname) | 2410 char *nickname) |
| 2443 { | 2411 { |
| 2444 unsigned int i; | 2412 unsigned int i; |
| 2445 CERTCertificate **certs = NULL; | 2413 CERTCertificate **certs = NULL; |
| 2446 unsigned int fcerts = 0; | 2414 unsigned int fcerts = 0; |
| 2447 | 2415 |
| 2448 if ( ncerts ) { | 2416 if (ncerts) { |
| 2449 » certs = PORT_ZNewArray(CERTCertificate*, ncerts); | 2417 certs = PORT_ZNewArray(CERTCertificate *, ncerts); |
| 2450 » if ( certs == NULL ) { | 2418 if (certs == NULL) { |
| 2451 » return(SECFailure); | 2419 return (SECFailure); |
| 2452 » } | 2420 } |
| 2453 | |
| 2454 » /* decode all of the certs into the temporary DB */ | |
| 2455 » for ( i = 0, fcerts= 0; i < ncerts; i++) { | |
| 2456 » certs[fcerts] = CERT_NewTempCertificate(certdb, | |
| 2457 » derCerts[i], | |
| 2458 » NULL, | |
| 2459 » PR_FALSE, | |
| 2460 » PR_TRUE); | |
| 2461 » if (certs[fcerts]) { | |
| 2462 » » SECItem subjKeyID = {siBuffer, NULL, 0}; | |
| 2463 » » if (CERT_FindSubjectKeyIDExtension(certs[fcerts], | |
| 2464 » » &subjKeyID) == SECSuccess) { | |
| 2465 » » if (subjKeyID.data) { | |
| 2466 » » » cert_AddSubjectKeyIDMapping(&subjKeyID, certs[fcerts]); | |
| 2467 » » } | |
| 2468 » » SECITEM_FreeItem(&subjKeyID, PR_FALSE); | |
| 2469 » » } | |
| 2470 » » fcerts++; | |
| 2471 » } | |
| 2472 » } | |
| 2473 | 2421 |
| 2474 » if ( keepCerts ) { | 2422 /* decode all of the certs into the temporary DB */ |
| 2475 » for ( i = 0; i < fcerts; i++ ) { | 2423 for (i = 0, fcerts = 0; i < ncerts; i++) { |
| 2476 char* canickname = NULL; | 2424 certs[fcerts] = CERT_NewTempCertificate(certdb, derCerts[i], NULL, |
| 2425 PR_FALSE, PR_TRUE); |
| 2426 if (certs[fcerts]) { |
| 2427 SECItem subjKeyID = { siBuffer, NULL, 0 }; |
| 2428 if (CERT_FindSubjectKeyIDExtension(certs[fcerts], &subjKeyID) == |
| 2429 SECSuccess) { |
| 2430 if (subjKeyID.data) { |
| 2431 cert_AddSubjectKeyIDMapping(&subjKeyID, certs[fcerts]); |
| 2432 } |
| 2433 SECITEM_FreeItem(&subjKeyID, PR_FALSE); |
| 2434 } |
| 2435 fcerts++; |
| 2436 } |
| 2437 } |
| 2438 |
| 2439 if (keepCerts) { |
| 2440 for (i = 0; i < fcerts; i++) { |
| 2441 char *canickname = NULL; |
| 2477 PRBool isCA; | 2442 PRBool isCA; |
| 2478 | 2443 |
| 2479 » » SECKEY_UpdateCertPQG(certs[i]); | 2444 SECKEY_UpdateCertPQG(certs[i]); |
| 2480 | 2445 |
| 2481 isCA = CERT_IsCACert(certs[i], NULL); | 2446 isCA = CERT_IsCACert(certs[i], NULL); |
| 2482 if ( isCA ) { | 2447 if (isCA) { |
| 2483 canickname = CERT_MakeCANickname(certs[i]); | 2448 canickname = CERT_MakeCANickname(certs[i]); |
| 2484 } | 2449 } |
| 2485 | 2450 |
| 2486 » » if(isCA && (fcerts > 1)) { | 2451 if (isCA && (fcerts > 1)) { |
| 2487 » » /* if we are importing only a single cert and specifying | 2452 /* if we are importing only a single cert and specifying |
| 2488 » » * a nickname, we want to use that nickname if it a CA, | 2453 * a nickname, we want to use that nickname if it a CA, |
| 2489 » » * otherwise if there are more than one cert, we don't | 2454 * otherwise if there are more than one cert, we don't |
| 2490 » » * know which cert it belongs to. But we still may try | 2455 * know which cert it belongs to. But we still may try |
| 2491 * the individual canickname from the cert itself. | 2456 * the individual canickname from the cert itself. |
| 2492 » » */ | 2457 */ |
| 2493 /* Bug 1192442 - propagate errors from these calls. */ | 2458 /* Bug 1192442 - propagate errors from these calls. */ |
| 2494 » » (void)CERT_AddTempCertToPerm(certs[i], canickname, NULL); | 2459 (void)CERT_AddTempCertToPerm(certs[i], canickname, NULL); |
| 2495 » » } else { | 2460 } else { |
| 2496 » » (void)CERT_AddTempCertToPerm(certs[i], | 2461 (void)CERT_AddTempCertToPerm( |
| 2497 nickname?nickname:canickname, N
ULL); | 2462 certs[i], nickname ? nickname : canickname, NULL); |
| 2498 » » } | 2463 } |
| 2499 | 2464 |
| 2500 PORT_Free(canickname); | 2465 PORT_Free(canickname); |
| 2501 » » /* don't care if it fails - keep going */ | 2466 /* don't care if it fails - keep going */ |
| 2502 » } | 2467 } |
| 2503 » } | 2468 } |
| 2504 } | 2469 } |
| 2505 | 2470 |
| 2506 if ( retCerts ) { | 2471 if (retCerts) { |
| 2507 » *retCerts = certs; | 2472 *retCerts = certs; |
| 2508 } else { | 2473 } else { |
| 2509 » if (certs) { | 2474 if (certs) { |
| 2510 » CERT_DestroyCertArray(certs, fcerts); | 2475 CERT_DestroyCertArray(certs, fcerts); |
| 2511 » } | 2476 } |
| 2512 } | 2477 } |
| 2513 | 2478 |
| 2514 return (fcerts || !ncerts) ? SECSuccess : SECFailure; | 2479 return (fcerts || !ncerts) ? SECSuccess : SECFailure; |
| 2515 } | 2480 } |
| 2516 | 2481 |
| 2517 /* | 2482 /* |
| 2518 * a real list of certificates - need to convert CERTCertificateList | 2483 * a real list of certificates - need to convert CERTCertificateList |
| 2519 * stuff and ASN 1 encoder/decoder over to using this... | 2484 * stuff and ASN 1 encoder/decoder over to using this... |
| 2520 */ | 2485 */ |
| 2521 CERTCertList * | 2486 CERTCertList * |
| 2522 CERT_NewCertList(void) | 2487 CERT_NewCertList(void) |
| 2523 { | 2488 { |
| 2524 PLArenaPool *arena = NULL; | 2489 PLArenaPool *arena = NULL; |
| 2525 CERTCertList *ret = NULL; | 2490 CERTCertList *ret = NULL; |
| 2526 | 2491 |
| 2527 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 2492 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
| 2528 if ( arena == NULL ) { | 2493 if (arena == NULL) { |
| 2529 » goto loser; | 2494 goto loser; |
| 2530 } | 2495 } |
| 2531 | 2496 |
| 2532 ret = (CERTCertList *)PORT_ArenaZAlloc(arena, sizeof(CERTCertList)); | 2497 ret = (CERTCertList *)PORT_ArenaZAlloc(arena, sizeof(CERTCertList)); |
| 2533 if ( ret == NULL ) { | 2498 if (ret == NULL) { |
| 2534 » goto loser; | 2499 goto loser; |
| 2535 } | 2500 } |
| 2536 | 2501 |
| 2537 ret->arena = arena; | 2502 ret->arena = arena; |
| 2538 | 2503 |
| 2539 PR_INIT_CLIST(&ret->list); | 2504 PR_INIT_CLIST(&ret->list); |
| 2540 | 2505 |
| 2541 return(ret); | 2506 return (ret); |
| 2542 | 2507 |
| 2543 loser: | 2508 loser: |
| 2544 if ( arena != NULL ) { | 2509 if (arena != NULL) { |
| 2545 » PORT_FreeArena(arena, PR_FALSE); | 2510 PORT_FreeArena(arena, PR_FALSE); |
| 2546 } | 2511 } |
| 2547 | 2512 |
| 2548 return(NULL); | 2513 return (NULL); |
| 2549 } | 2514 } |
| 2550 | 2515 |
| 2551 void | 2516 void |
| 2552 CERT_DestroyCertList(CERTCertList *certs) | 2517 CERT_DestroyCertList(CERTCertList *certs) |
| 2553 { | 2518 { |
| 2554 PRCList *node; | 2519 PRCList *node; |
| 2555 | 2520 |
| 2556 while( !PR_CLIST_IS_EMPTY(&certs->list) ) { | 2521 while (!PR_CLIST_IS_EMPTY(&certs->list)) { |
| 2557 » node = PR_LIST_HEAD(&certs->list); | 2522 node = PR_LIST_HEAD(&certs->list); |
| 2558 » CERT_DestroyCertificate(((CERTCertListNode *)node)->cert); | 2523 CERT_DestroyCertificate(((CERTCertListNode *)node)->cert); |
| 2559 » PR_REMOVE_LINK(node); | 2524 PR_REMOVE_LINK(node); |
| 2560 } | 2525 } |
| 2561 | 2526 |
| 2562 PORT_FreeArena(certs->arena, PR_FALSE); | 2527 PORT_FreeArena(certs->arena, PR_FALSE); |
| 2563 | 2528 |
| 2564 return; | 2529 return; |
| 2565 } | 2530 } |
| 2566 | 2531 |
| 2567 void | 2532 void |
| 2568 CERT_RemoveCertListNode(CERTCertListNode *node) | 2533 CERT_RemoveCertListNode(CERTCertListNode *node) |
| 2569 { | 2534 { |
| 2570 CERT_DestroyCertificate(node->cert); | 2535 CERT_DestroyCertificate(node->cert); |
| 2571 PR_REMOVE_LINK(&node->links); | 2536 PR_REMOVE_LINK(&node->links); |
| 2572 return; | 2537 return; |
| 2573 } | 2538 } |
| 2574 | 2539 |
| 2575 | |
| 2576 SECStatus | 2540 SECStatus |
| 2577 CERT_AddCertToListTailWithData(CERTCertList *certs, | 2541 CERT_AddCertToListTailWithData(CERTCertList *certs, CERTCertificate *cert, |
| 2578 » » » » CERTCertificate *cert, void *appData) | 2542 void *appData) |
| 2579 { | 2543 { |
| 2580 CERTCertListNode *node; | 2544 CERTCertListNode *node; |
| 2581 | 2545 |
| 2582 node = (CERTCertListNode *)PORT_ArenaZAlloc(certs->arena, | 2546 node = (CERTCertListNode *)PORT_ArenaZAlloc(certs->arena, |
| 2583 » » » » » » sizeof(CERTCertListNode)); | 2547 sizeof(CERTCertListNode)); |
| 2584 if ( node == NULL ) { | 2548 if (node == NULL) { |
| 2585 » goto loser; | 2549 goto loser; |
| 2586 } | 2550 } |
| 2587 | 2551 |
| 2588 PR_INSERT_BEFORE(&node->links, &certs->list); | 2552 PR_INSERT_BEFORE(&node->links, &certs->list); |
| 2589 /* certs->count++; */ | 2553 /* certs->count++; */ |
| 2590 node->cert = cert; | 2554 node->cert = cert; |
| 2591 node->appData = appData; | 2555 node->appData = appData; |
| 2592 return(SECSuccess); | 2556 return (SECSuccess); |
| 2593 | 2557 |
| 2594 loser: | 2558 loser: |
| 2595 return(SECFailure); | 2559 return (SECFailure); |
| 2596 } | 2560 } |
| 2597 | 2561 |
| 2598 SECStatus | 2562 SECStatus |
| 2599 CERT_AddCertToListTail(CERTCertList *certs, CERTCertificate *cert) | 2563 CERT_AddCertToListTail(CERTCertList *certs, CERTCertificate *cert) |
| 2600 { | 2564 { |
| 2601 return CERT_AddCertToListTailWithData(certs, cert, NULL); | 2565 return CERT_AddCertToListTailWithData(certs, cert, NULL); |
| 2602 } | 2566 } |
| 2603 | 2567 |
| 2604 SECStatus | 2568 SECStatus |
| 2605 CERT_AddCertToListHeadWithData(CERTCertList *certs, | 2569 CERT_AddCertToListHeadWithData(CERTCertList *certs, CERTCertificate *cert, |
| 2606 » » » » » CERTCertificate *cert, void *appData) | 2570 void *appData) |
| 2607 { | 2571 { |
| 2608 CERTCertListNode *node; | 2572 CERTCertListNode *node; |
| 2609 CERTCertListNode *head; | 2573 CERTCertListNode *head; |
| 2610 | 2574 |
| 2611 head = CERT_LIST_HEAD(certs); | 2575 head = CERT_LIST_HEAD(certs); |
| 2612 | 2576 |
| 2613 if (head == NULL) return CERT_AddCertToListTail(certs,cert); | 2577 if (head == NULL) |
| 2578 return CERT_AddCertToListTail(certs, cert); |
| 2614 | 2579 |
| 2615 node = (CERTCertListNode *)PORT_ArenaZAlloc(certs->arena, | 2580 node = (CERTCertListNode *)PORT_ArenaZAlloc(certs->arena, |
| 2616 » » » » » » sizeof(CERTCertListNode)); | 2581 sizeof(CERTCertListNode)); |
| 2617 if ( node == NULL ) { | 2582 if (node == NULL) { |
| 2618 » goto loser; | 2583 goto loser; |
| 2619 } | 2584 } |
| 2620 | 2585 |
| 2621 PR_INSERT_BEFORE(&node->links, &head->links); | 2586 PR_INSERT_BEFORE(&node->links, &head->links); |
| 2622 /* certs->count++; */ | 2587 /* certs->count++; */ |
| 2623 node->cert = cert; | 2588 node->cert = cert; |
| 2624 node->appData = appData; | 2589 node->appData = appData; |
| 2625 return(SECSuccess); | 2590 return (SECSuccess); |
| 2626 | 2591 |
| 2627 loser: | 2592 loser: |
| 2628 return(SECFailure); | 2593 return (SECFailure); |
| 2629 } | 2594 } |
| 2630 | 2595 |
| 2631 SECStatus | 2596 SECStatus |
| 2632 CERT_AddCertToListHead(CERTCertList *certs, CERTCertificate *cert) | 2597 CERT_AddCertToListHead(CERTCertList *certs, CERTCertificate *cert) |
| 2633 { | 2598 { |
| 2634 return CERT_AddCertToListHeadWithData(certs, cert, NULL); | 2599 return CERT_AddCertToListHeadWithData(certs, cert, NULL); |
| 2635 } | 2600 } |
| 2636 | 2601 |
| 2637 /* | 2602 /* |
| 2638 * Sort callback function to determine if cert a is newer than cert b. | 2603 * Sort callback function to determine if cert a is newer than cert b. |
| 2639 * Not valid certs are considered older than valid certs. | 2604 * Not valid certs are considered older than valid certs. |
| 2640 */ | 2605 */ |
| 2641 PRBool | 2606 PRBool |
| 2642 CERT_SortCBValidity(CERTCertificate *certa, | 2607 CERT_SortCBValidity(CERTCertificate *certa, CERTCertificate *certb, void *arg) |
| 2643 » » CERTCertificate *certb, | |
| 2644 » » void *arg) | |
| 2645 { | 2608 { |
| 2646 PRTime sorttime; | 2609 PRTime sorttime; |
| 2647 PRTime notBeforeA, notAfterA, notBeforeB, notAfterB; | 2610 PRTime notBeforeA, notAfterA, notBeforeB, notAfterB; |
| 2648 SECStatus rv; | 2611 SECStatus rv; |
| 2649 PRBool newerbefore, newerafter; | 2612 PRBool newerbefore, newerafter; |
| 2650 PRBool aNotValid = PR_FALSE, bNotValid = PR_FALSE; | 2613 PRBool aNotValid = PR_FALSE, bNotValid = PR_FALSE; |
| 2651 | 2614 |
| 2652 sorttime = *(PRTime *)arg; | 2615 sorttime = *(PRTime *)arg; |
| 2653 | 2616 |
| 2654 rv = CERT_GetCertTimes(certa, ¬BeforeA, ¬AfterA); | 2617 rv = CERT_GetCertTimes(certa, ¬BeforeA, ¬AfterA); |
| 2655 if ( rv != SECSuccess ) { | 2618 if (rv != SECSuccess) { |
| 2656 » return(PR_FALSE); | 2619 return (PR_FALSE); |
| 2657 } | 2620 } |
| 2658 | 2621 |
| 2659 rv = CERT_GetCertTimes(certb, ¬BeforeB, ¬AfterB); | 2622 rv = CERT_GetCertTimes(certb, ¬BeforeB, ¬AfterB); |
| 2660 if ( rv != SECSuccess ) { | 2623 if (rv != SECSuccess) { |
| 2661 » return(PR_TRUE); | 2624 return (PR_TRUE); |
| 2662 } | 2625 } |
| 2663 newerbefore = PR_FALSE; | 2626 newerbefore = PR_FALSE; |
| 2664 if ( LL_CMP(notBeforeA, >, notBeforeB) ) { | 2627 if (LL_CMP(notBeforeA, >, notBeforeB)) { |
| 2665 » newerbefore = PR_TRUE; | 2628 newerbefore = PR_TRUE; |
| 2666 } | 2629 } |
| 2667 newerafter = PR_FALSE; | 2630 newerafter = PR_FALSE; |
| 2668 if ( LL_CMP(notAfterA, >, notAfterB) ) { | 2631 if (LL_CMP(notAfterA, >, notAfterB)) { |
| 2669 » newerafter = PR_TRUE; | 2632 newerafter = PR_TRUE; |
| 2670 } | 2633 } |
| 2671 | 2634 |
| 2672 /* check if A is valid at sorttime */ | 2635 /* check if A is valid at sorttime */ |
| 2673 if ( CERT_CheckCertValidTimes(certa, sorttime, PR_FALSE) | 2636 if (CERT_CheckCertValidTimes(certa, sorttime, PR_FALSE) != |
| 2674 » != secCertTimeValid ) { | 2637 secCertTimeValid) { |
| 2675 » aNotValid = PR_TRUE; | 2638 aNotValid = PR_TRUE; |
| 2676 } | 2639 } |
| 2677 | 2640 |
| 2678 /* check if B is valid at sorttime */ | 2641 /* check if B is valid at sorttime */ |
| 2679 if ( CERT_CheckCertValidTimes(certb, sorttime, PR_FALSE) | 2642 if (CERT_CheckCertValidTimes(certb, sorttime, PR_FALSE) != |
| 2680 » != secCertTimeValid ) { | 2643 secCertTimeValid) { |
| 2681 » bNotValid = PR_TRUE; | 2644 bNotValid = PR_TRUE; |
| 2682 } | 2645 } |
| 2683 | 2646 |
| 2684 /* a is valid, b is not */ | 2647 /* a is valid, b is not */ |
| 2685 if ( bNotValid && ( ! aNotValid ) ) { | 2648 if (bNotValid && (!aNotValid)) { |
| 2686 » return(PR_TRUE); | 2649 return (PR_TRUE); |
| 2687 } | 2650 } |
| 2688 | 2651 |
| 2689 /* b is valid, a is not */ | 2652 /* b is valid, a is not */ |
| 2690 if ( aNotValid && ( ! bNotValid ) ) { | 2653 if (aNotValid && (!bNotValid)) { |
| 2691 » return(PR_FALSE); | 2654 return (PR_FALSE); |
| 2692 } | |
| 2693 | |
| 2694 /* a and b are either valid or not valid */ | |
| 2695 if ( newerbefore && newerafter ) { | |
| 2696 » return(PR_TRUE); | |
| 2697 } | |
| 2698 | |
| 2699 if ( ( !newerbefore ) && ( !newerafter ) ) { | |
| 2700 » return(PR_FALSE); | |
| 2701 } | 2655 } |
| 2702 | 2656 |
| 2703 if ( newerbefore ) { | 2657 /* a and b are either valid or not valid */ |
| 2704 » /* cert A was issued after cert B, but expires sooner */ | 2658 if (newerbefore && newerafter) { |
| 2705 » return(PR_TRUE); | 2659 return (PR_TRUE); |
| 2660 } |
| 2661 |
| 2662 if ((!newerbefore) && (!newerafter)) { |
| 2663 return (PR_FALSE); |
| 2664 } |
| 2665 |
| 2666 if (newerbefore) { |
| 2667 /* cert A was issued after cert B, but expires sooner */ |
| 2668 return (PR_TRUE); |
| 2706 } else { | 2669 } else { |
| 2707 » /* cert B was issued after cert A, but expires sooner */ | 2670 /* cert B was issued after cert A, but expires sooner */ |
| 2708 » return(PR_FALSE); | 2671 return (PR_FALSE); |
| 2709 } | 2672 } |
| 2710 } | 2673 } |
| 2711 | 2674 |
| 2712 | |
| 2713 SECStatus | 2675 SECStatus |
| 2714 CERT_AddCertToListSorted(CERTCertList *certs, | 2676 CERT_AddCertToListSorted(CERTCertList *certs, CERTCertificate *cert, |
| 2715 » » » CERTCertificate *cert, | 2677 CERTSortCallback f, void *arg) |
| 2716 » » » CERTSortCallback f, | |
| 2717 » » » void *arg) | |
| 2718 { | 2678 { |
| 2719 CERTCertListNode *node; | 2679 CERTCertListNode *node; |
| 2720 CERTCertListNode *head; | 2680 CERTCertListNode *head; |
| 2721 PRBool ret; | 2681 PRBool ret; |
| 2722 | 2682 |
| 2723 node = (CERTCertListNode *)PORT_ArenaZAlloc(certs->arena, | 2683 node = (CERTCertListNode *)PORT_ArenaZAlloc(certs->arena, |
| 2724 » » » » » » sizeof(CERTCertListNode)); | 2684 sizeof(CERTCertListNode)); |
| 2725 if ( node == NULL ) { | 2685 if (node == NULL) { |
| 2726 » goto loser; | 2686 goto loser; |
| 2727 } | 2687 } |
| 2728 | 2688 |
| 2729 head = CERT_LIST_HEAD(certs); | 2689 head = CERT_LIST_HEAD(certs); |
| 2730 | |
| 2731 while ( !CERT_LIST_END(head, certs) ) { | |
| 2732 | 2690 |
| 2733 » /* if cert is already in the list, then don't add it again */ | 2691 while (!CERT_LIST_END(head, certs)) { |
| 2734 » if ( cert == head->cert ) { | |
| 2735 » /*XXX*/ | |
| 2736 » /* don't keep a reference */ | |
| 2737 » CERT_DestroyCertificate(cert); | |
| 2738 » goto done; | |
| 2739 » } | |
| 2740 » | |
| 2741 » ret = (* f)(cert, head->cert, arg); | |
| 2742 » /* if sort function succeeds, then insert before current node */ | |
| 2743 » if ( ret ) { | |
| 2744 » PR_INSERT_BEFORE(&node->links, &head->links); | |
| 2745 » goto done; | |
| 2746 » } | |
| 2747 | 2692 |
| 2748 » head = CERT_LIST_NEXT(head); | 2693 /* if cert is already in the list, then don't add it again */ |
| 2694 if (cert == head->cert) { |
| 2695 /*XXX*/ |
| 2696 /* don't keep a reference */ |
| 2697 CERT_DestroyCertificate(cert); |
| 2698 goto done; |
| 2699 } |
| 2700 |
| 2701 ret = (*f)(cert, head->cert, arg); |
| 2702 /* if sort function succeeds, then insert before current node */ |
| 2703 if (ret) { |
| 2704 PR_INSERT_BEFORE(&node->links, &head->links); |
| 2705 goto done; |
| 2706 } |
| 2707 |
| 2708 head = CERT_LIST_NEXT(head); |
| 2749 } | 2709 } |
| 2750 /* if we get to the end, then just insert it at the tail */ | 2710 /* if we get to the end, then just insert it at the tail */ |
| 2751 PR_INSERT_BEFORE(&node->links, &certs->list); | 2711 PR_INSERT_BEFORE(&node->links, &certs->list); |
| 2752 | 2712 |
| 2753 done: | 2713 done: |
| 2754 /* certs->count++; */ | 2714 /* certs->count++; */ |
| 2755 node->cert = cert; | 2715 node->cert = cert; |
| 2756 return(SECSuccess); | 2716 return (SECSuccess); |
| 2757 | 2717 |
| 2758 loser: | 2718 loser: |
| 2759 return(SECFailure); | 2719 return (SECFailure); |
| 2760 } | 2720 } |
| 2761 | 2721 |
| 2762 /* This routine is here because pcertdb.c still has a call to it. | 2722 /* This routine is here because pcertdb.c still has a call to it. |
| 2763 * The SMIME profile code in pcertdb.c should be split into high (find | 2723 * The SMIME profile code in pcertdb.c should be split into high (find |
| 2764 * the email cert) and low (store the profile) code. At that point, we | 2724 * the email cert) and low (store the profile) code. At that point, we |
| 2765 * can move this to certhigh.c where it belongs. | 2725 * can move this to certhigh.c where it belongs. |
| 2766 * | 2726 * |
| 2767 * remove certs from a list that don't have keyUsage and certType | 2727 * remove certs from a list that don't have keyUsage and certType |
| 2768 * that match the given usage. | 2728 * that match the given usage. |
| 2769 */ | 2729 */ |
| 2770 SECStatus | 2730 SECStatus |
| 2771 CERT_FilterCertListByUsage(CERTCertList *certList, SECCertUsage usage, | 2731 CERT_FilterCertListByUsage(CERTCertList *certList, SECCertUsage usage, |
| 2772 » » » PRBool ca) | 2732 PRBool ca) |
| 2773 { | 2733 { |
| 2774 unsigned int requiredKeyUsage; | 2734 unsigned int requiredKeyUsage; |
| 2775 unsigned int requiredCertType; | 2735 unsigned int requiredCertType; |
| 2776 CERTCertListNode *node, *savenode; | 2736 CERTCertListNode *node, *savenode; |
| 2777 SECStatus rv; | 2737 SECStatus rv; |
| 2778 | 2738 |
| 2779 if (certList == NULL) goto loser; | 2739 if (certList == NULL) |
| 2740 goto loser; |
| 2780 | 2741 |
| 2781 rv = CERT_KeyUsageAndTypeForCertUsage(usage, ca, &requiredKeyUsage, | 2742 rv = CERT_KeyUsageAndTypeForCertUsage(usage, ca, &requiredKeyUsage, |
| 2782 » » » » » &requiredCertType); | 2743 &requiredCertType); |
| 2783 if ( rv != SECSuccess ) { | 2744 if (rv != SECSuccess) { |
| 2784 » goto loser; | 2745 goto loser; |
| 2785 } | 2746 } |
| 2786 | 2747 |
| 2787 node = CERT_LIST_HEAD(certList); | 2748 node = CERT_LIST_HEAD(certList); |
| 2788 | |
| 2789 while ( !CERT_LIST_END(node, certList) ) { | |
| 2790 | 2749 |
| 2791 » PRBool bad = (PRBool)(!node->cert); | 2750 while (!CERT_LIST_END(node, certList)) { |
| 2792 | 2751 |
| 2793 » /* bad key usage ? */ | 2752 PRBool bad = (PRBool)(!node->cert); |
| 2794 » if ( !bad && | |
| 2795 » CERT_CheckKeyUsage(node->cert, requiredKeyUsage) != SECSuccess ) { | |
| 2796 » bad = PR_TRUE; | |
| 2797 » } | |
| 2798 » /* bad cert type ? */ | |
| 2799 » if ( !bad ) { | |
| 2800 » unsigned int certType = 0; | |
| 2801 » if ( ca ) { | |
| 2802 » » /* This function returns a more comprehensive cert type that | |
| 2803 » » * takes trust flags into consideration. Should probably | |
| 2804 » » * fix the cert decoding code to do this. | |
| 2805 » » */ | |
| 2806 » » (void)CERT_IsCACert(node->cert, &certType); | |
| 2807 » } else { | |
| 2808 » » certType = node->cert->nsCertType; | |
| 2809 » } | |
| 2810 » if ( !( certType & requiredCertType ) ) { | |
| 2811 » » bad = PR_TRUE; | |
| 2812 » } | |
| 2813 » } | |
| 2814 | 2753 |
| 2815 » if ( bad ) { | 2754 /* bad key usage ? */ |
| 2816 » /* remove the node if it is bad */ | 2755 if (!bad && |
| 2817 » savenode = CERT_LIST_NEXT(node); | 2756 CERT_CheckKeyUsage(node->cert, requiredKeyUsage) != SECSuccess) { |
| 2818 » CERT_RemoveCertListNode(node); | 2757 bad = PR_TRUE; |
| 2819 » node = savenode; | 2758 } |
| 2820 » } else { | 2759 /* bad cert type ? */ |
| 2821 » node = CERT_LIST_NEXT(node); | 2760 if (!bad) { |
| 2822 » } | 2761 unsigned int certType = 0; |
| 2762 if (ca) { |
| 2763 /* This function returns a more comprehensive cert type that |
| 2764 * takes trust flags into consideration. Should probably |
| 2765 * fix the cert decoding code to do this. |
| 2766 */ |
| 2767 (void)CERT_IsCACert(node->cert, &certType); |
| 2768 } else { |
| 2769 certType = node->cert->nsCertType; |
| 2770 } |
| 2771 if (!(certType & requiredCertType)) { |
| 2772 bad = PR_TRUE; |
| 2773 } |
| 2774 } |
| 2775 |
| 2776 if (bad) { |
| 2777 /* remove the node if it is bad */ |
| 2778 savenode = CERT_LIST_NEXT(node); |
| 2779 CERT_RemoveCertListNode(node); |
| 2780 node = savenode; |
| 2781 } else { |
| 2782 node = CERT_LIST_NEXT(node); |
| 2783 } |
| 2823 } | 2784 } |
| 2824 return(SECSuccess); | 2785 return (SECSuccess); |
| 2825 | 2786 |
| 2826 loser: | 2787 loser: |
| 2827 return(SECFailure); | 2788 return (SECFailure); |
| 2828 } | 2789 } |
| 2829 | 2790 |
| 2830 PRBool CERT_IsUserCert(CERTCertificate* cert) | 2791 PRBool |
| 2792 CERT_IsUserCert(CERTCertificate *cert) |
| 2831 { | 2793 { |
| 2832 CERTCertTrust trust; | 2794 CERTCertTrust trust; |
| 2833 SECStatus rv = SECFailure; | 2795 SECStatus rv = SECFailure; |
| 2834 | 2796 |
| 2835 rv = CERT_GetCertTrust(cert, &trust); | 2797 rv = CERT_GetCertTrust(cert, &trust); |
| 2836 if (rv == SECSuccess && | 2798 if (rv == SECSuccess && |
| 2837 ((trust.sslFlags & CERTDB_USER ) || | 2799 ((trust.sslFlags & CERTDB_USER) || (trust.emailFlags & CERTDB_USER) || |
| 2838 (trust.emailFlags & CERTDB_USER ) || | 2800 (trust.objectSigningFlags & CERTDB_USER))) { |
| 2839 (trust.objectSigningFlags & CERTDB_USER )) ) { | |
| 2840 return PR_TRUE; | 2801 return PR_TRUE; |
| 2841 } else { | 2802 } else { |
| 2842 return PR_FALSE; | 2803 return PR_FALSE; |
| 2843 } | 2804 } |
| 2844 } | 2805 } |
| 2845 | 2806 |
| 2846 SECStatus | 2807 SECStatus |
| 2847 CERT_FilterCertListForUserCerts(CERTCertList *certList) | 2808 CERT_FilterCertListForUserCerts(CERTCertList *certList) |
| 2848 { | 2809 { |
| 2849 CERTCertListNode *node, *freenode; | 2810 CERTCertListNode *node, *freenode; |
| 2850 CERTCertificate *cert; | 2811 CERTCertificate *cert; |
| 2851 | 2812 |
| 2852 if (!certList) { | 2813 if (!certList) { |
| 2853 return SECFailure; | 2814 return SECFailure; |
| 2854 } | 2815 } |
| 2855 | 2816 |
| 2856 node = CERT_LIST_HEAD(certList); | 2817 node = CERT_LIST_HEAD(certList); |
| 2857 | 2818 |
| 2858 while ( ! CERT_LIST_END(node, certList) ) { | 2819 while (!CERT_LIST_END(node, certList)) { |
| 2859 » cert = node->cert; | 2820 cert = node->cert; |
| 2860 » if ( PR_TRUE != CERT_IsUserCert(cert) ) { | 2821 if (PR_TRUE != CERT_IsUserCert(cert)) { |
| 2861 » /* Not a User Cert, so remove this cert from the list */ | 2822 /* Not a User Cert, so remove this cert from the list */ |
| 2862 » freenode = node; | 2823 freenode = node; |
| 2863 » node = CERT_LIST_NEXT(node); | 2824 node = CERT_LIST_NEXT(node); |
| 2864 » CERT_RemoveCertListNode(freenode); | 2825 CERT_RemoveCertListNode(freenode); |
| 2865 » } else { | 2826 } else { |
| 2866 » /* Is a User cert, so leave it in the list */ | 2827 /* Is a User cert, so leave it in the list */ |
| 2867 » node = CERT_LIST_NEXT(node); | 2828 node = CERT_LIST_NEXT(node); |
| 2868 » } | 2829 } |
| 2869 } | 2830 } |
| 2870 | 2831 |
| 2871 return(SECSuccess); | 2832 return (SECSuccess); |
| 2872 } | 2833 } |
| 2873 | 2834 |
| 2874 static PZLock *certRefCountLock = NULL; | 2835 static PZLock *certRefCountLock = NULL; |
| 2875 | 2836 |
| 2876 /* | 2837 /* |
| 2877 * Acquire the cert reference count lock | 2838 * Acquire the cert reference count lock |
| 2878 * There is currently one global lock for all certs, but I'm putting a cert | 2839 * There is currently one global lock for all certs, but I'm putting a cert |
| 2879 * arg here so that it will be easy to make it per-cert in the future if | 2840 * arg here so that it will be easy to make it per-cert in the future if |
| 2880 * that turns out to be necessary. | 2841 * that turns out to be necessary. |
| 2881 */ | 2842 */ |
| 2882 void | 2843 void |
| 2883 CERT_LockCertRefCount(CERTCertificate *cert) | 2844 CERT_LockCertRefCount(CERTCertificate *cert) |
| 2884 { | 2845 { |
| 2885 PORT_Assert(certRefCountLock != NULL); | 2846 PORT_Assert(certRefCountLock != NULL); |
| 2886 PZ_Lock(certRefCountLock); | 2847 PZ_Lock(certRefCountLock); |
| 2887 return; | 2848 return; |
| 2888 } | 2849 } |
| 2889 | 2850 |
| 2890 /* | 2851 /* |
| 2891 * Free the cert reference count lock | 2852 * Free the cert reference count lock |
| 2892 */ | 2853 */ |
| 2893 void | 2854 void |
| 2894 CERT_UnlockCertRefCount(CERTCertificate *cert) | 2855 CERT_UnlockCertRefCount(CERTCertificate *cert) |
| 2895 { | 2856 { |
| 2896 PORT_Assert(certRefCountLock != NULL); | 2857 PORT_Assert(certRefCountLock != NULL); |
| 2897 | 2858 |
| 2898 #ifdef DEBUG | 2859 #ifdef DEBUG |
| 2899 { | 2860 { |
| 2900 PRStatus prstat = PZ_Unlock(certRefCountLock); | 2861 PRStatus prstat = PZ_Unlock(certRefCountLock); |
| 2901 PORT_Assert(prstat == PR_SUCCESS); | 2862 PORT_Assert(prstat == PR_SUCCESS); |
| 2902 } | 2863 } |
| 2903 #else | 2864 #else |
| 2904 PZ_Unlock(certRefCountLock); | 2865 PZ_Unlock(certRefCountLock); |
| 2905 #endif | 2866 #endif |
| 2906 } | 2867 } |
| 2907 | 2868 |
| 2908 static PZLock *certTrustLock = NULL; | 2869 static PZLock *certTrustLock = NULL; |
| 2909 | 2870 |
| 2910 /* | 2871 /* |
| 2911 * Acquire the cert trust lock | 2872 * Acquire the cert trust lock |
| 2912 * There is currently one global lock for all certs, but I'm putting a cert | 2873 * There is currently one global lock for all certs, but I'm putting a cert |
| 2913 * arg here so that it will be easy to make it per-cert in the future if | 2874 * arg here so that it will be easy to make it per-cert in the future if |
| 2914 * that turns out to be necessary. | 2875 * that turns out to be necessary. |
| 2915 */ | 2876 */ |
| 2916 void | 2877 void |
| 2917 CERT_LockCertTrust(const CERTCertificate *cert) | 2878 CERT_LockCertTrust(const CERTCertificate *cert) |
| 2918 { | 2879 { |
| 2919 PORT_Assert(certTrustLock != NULL); | 2880 PORT_Assert(certTrustLock != NULL); |
| 2920 PZ_Lock(certTrustLock); | 2881 PZ_Lock(certTrustLock); |
| 2921 return; | 2882 return; |
| 2922 } | 2883 } |
| 2923 | 2884 |
| 2924 SECStatus | 2885 SECStatus |
| 2925 cert_InitLocks(void) | 2886 cert_InitLocks(void) |
| 2926 { | 2887 { |
| 2927 if ( certRefCountLock == NULL ) { | 2888 if (certRefCountLock == NULL) { |
| 2928 certRefCountLock = PZ_NewLock(nssILockRefLock); | 2889 certRefCountLock = PZ_NewLock(nssILockRefLock); |
| 2929 PORT_Assert(certRefCountLock != NULL); | 2890 PORT_Assert(certRefCountLock != NULL); |
| 2930 if (!certRefCountLock) { | 2891 if (!certRefCountLock) { |
| 2931 return SECFailure; | 2892 return SECFailure; |
| 2932 } | 2893 } |
| 2933 } | 2894 } |
| 2934 | 2895 |
| 2935 if ( certTrustLock == NULL ) { | 2896 if (certTrustLock == NULL) { |
| 2936 certTrustLock = PZ_NewLock(nssILockCertDB); | 2897 certTrustLock = PZ_NewLock(nssILockCertDB); |
| 2937 PORT_Assert(certTrustLock != NULL); | 2898 PORT_Assert(certTrustLock != NULL); |
| 2938 if (!certTrustLock) { | 2899 if (!certTrustLock) { |
| 2939 PZ_DestroyLock(certRefCountLock); | 2900 PZ_DestroyLock(certRefCountLock); |
| 2940 certRefCountLock = NULL; | 2901 certRefCountLock = NULL; |
| 2941 return SECFailure; | 2902 return SECFailure; |
| 2942 } | 2903 } |
| 2943 } | 2904 } |
| 2944 | 2905 |
| 2945 return SECSuccess; | 2906 return SECSuccess; |
| 2946 } | 2907 } |
| 2947 | 2908 |
| 2948 SECStatus | 2909 SECStatus |
| 2949 cert_DestroyLocks(void) | 2910 cert_DestroyLocks(void) |
| 2950 { | 2911 { |
| 2951 SECStatus rv = SECSuccess; | 2912 SECStatus rv = SECSuccess; |
| 2952 | 2913 |
| 2953 PORT_Assert(certRefCountLock != NULL); | 2914 PORT_Assert(certRefCountLock != NULL); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2968 return rv; | 2929 return rv; |
| 2969 } | 2930 } |
| 2970 | 2931 |
| 2971 /* | 2932 /* |
| 2972 * Free the cert trust lock | 2933 * Free the cert trust lock |
| 2973 */ | 2934 */ |
| 2974 void | 2935 void |
| 2975 CERT_UnlockCertTrust(const CERTCertificate *cert) | 2936 CERT_UnlockCertTrust(const CERTCertificate *cert) |
| 2976 { | 2937 { |
| 2977 PORT_Assert(certTrustLock != NULL); | 2938 PORT_Assert(certTrustLock != NULL); |
| 2978 | 2939 |
| 2979 #ifdef DEBUG | 2940 #ifdef DEBUG |
| 2980 { | 2941 { |
| 2981 PRStatus prstat = PZ_Unlock(certTrustLock); | 2942 PRStatus prstat = PZ_Unlock(certTrustLock); |
| 2982 PORT_Assert(prstat == PR_SUCCESS); | 2943 PORT_Assert(prstat == PR_SUCCESS); |
| 2983 } | 2944 } |
| 2984 #else | 2945 #else |
| 2985 PZ_Unlock(certTrustLock); | 2946 PZ_Unlock(certTrustLock); |
| 2986 #endif | 2947 #endif |
| 2987 } | 2948 } |
| 2988 | 2949 |
| 2989 | |
| 2990 /* | 2950 /* |
| 2991 * Get the StatusConfig data for this handle | 2951 * Get the StatusConfig data for this handle |
| 2992 */ | 2952 */ |
| 2993 CERTStatusConfig * | 2953 CERTStatusConfig * |
| 2994 CERT_GetStatusConfig(CERTCertDBHandle *handle) | 2954 CERT_GetStatusConfig(CERTCertDBHandle *handle) |
| 2995 { | 2955 { |
| 2996 return handle->statusConfig; | 2956 return handle->statusConfig; |
| 2997 } | 2957 } |
| 2998 | 2958 |
| 2999 /* | 2959 /* |
| 3000 * Set the StatusConfig data for this handle. There | 2960 * Set the StatusConfig data for this handle. There |
| 3001 * should not be another configuration set. | 2961 * should not be another configuration set. |
| 3002 */ | 2962 */ |
| 3003 void | 2963 void |
| 3004 CERT_SetStatusConfig(CERTCertDBHandle *handle, CERTStatusConfig *statusConfig) | 2964 CERT_SetStatusConfig(CERTCertDBHandle *handle, CERTStatusConfig *statusConfig) |
| 3005 { | 2965 { |
| 3006 PORT_Assert(handle->statusConfig == NULL); | 2966 PORT_Assert(handle->statusConfig == NULL); |
| 3007 handle->statusConfig = statusConfig; | 2967 handle->statusConfig = statusConfig; |
| 3008 } | 2968 } |
| 3009 | 2969 |
| 3010 /* | 2970 /* |
| 3011 * Code for dealing with subjKeyID to cert mappings. | 2971 * Code for dealing with subjKeyID to cert mappings. |
| 3012 */ | 2972 */ |
| 3013 | 2973 |
| 3014 static PLHashTable *gSubjKeyIDHash = NULL; | 2974 static PLHashTable *gSubjKeyIDHash = NULL; |
| 3015 static PRLock *gSubjKeyIDLock = NULL; | 2975 static PRLock *gSubjKeyIDLock = NULL; |
| 3016 static PLHashTable *gSubjKeyIDSlotCheckHash = NULL; | 2976 static PLHashTable *gSubjKeyIDSlotCheckHash = NULL; |
| 3017 static PRLock *gSubjKeyIDSlotCheckLock = NULL; | 2977 static PRLock *gSubjKeyIDSlotCheckLock = NULL; |
| 3018 | 2978 |
| 3019 static void *cert_AllocTable(void *pool, PRSize size) | 2979 static void * |
| 2980 cert_AllocTable(void *pool, PRSize size) |
| 3020 { | 2981 { |
| 3021 return PORT_Alloc(size); | 2982 return PORT_Alloc(size); |
| 3022 } | 2983 } |
| 3023 | 2984 |
| 3024 static void cert_FreeTable(void *pool, void *item) | 2985 static void |
| 2986 cert_FreeTable(void *pool, void *item) |
| 3025 { | 2987 { |
| 3026 PORT_Free(item); | 2988 PORT_Free(item); |
| 3027 } | 2989 } |
| 3028 | 2990 |
| 3029 static PLHashEntry* cert_AllocEntry(void *pool, const void *key) | 2991 static PLHashEntry * |
| 2992 cert_AllocEntry(void *pool, const void *key) |
| 3030 { | 2993 { |
| 3031 return PORT_New(PLHashEntry); | 2994 return PORT_New(PLHashEntry); |
| 3032 } | 2995 } |
| 3033 | 2996 |
| 3034 static void cert_FreeEntry(void *pool, PLHashEntry *he, PRUintn flag) | 2997 static void |
| 2998 cert_FreeEntry(void *pool, PLHashEntry *he, PRUintn flag) |
| 3035 { | 2999 { |
| 3036 SECITEM_FreeItem((SECItem*)(he->value), PR_TRUE); | 3000 SECITEM_FreeItem((SECItem *)(he->value), PR_TRUE); |
| 3037 if (flag == HT_FREE_ENTRY) { | 3001 if (flag == HT_FREE_ENTRY) { |
| 3038 SECITEM_FreeItem((SECItem*)(he->key), PR_TRUE); | 3002 SECITEM_FreeItem((SECItem *)(he->key), PR_TRUE); |
| 3039 PORT_Free(he); | 3003 PORT_Free(he); |
| 3040 } | 3004 } |
| 3041 } | 3005 } |
| 3042 | 3006 |
| 3043 static PLHashAllocOps cert_AllocOps = { | 3007 static PLHashAllocOps cert_AllocOps = { cert_AllocTable, cert_FreeTable, |
| 3044 cert_AllocTable, cert_FreeTable, cert_AllocEntry, cert_FreeEntry | 3008 cert_AllocEntry, cert_FreeEntry }; |
| 3045 }; | |
| 3046 | 3009 |
| 3047 SECStatus | 3010 SECStatus |
| 3048 cert_CreateSubjectKeyIDSlotCheckHash(void) | 3011 cert_CreateSubjectKeyIDSlotCheckHash(void) |
| 3049 { | 3012 { |
| 3050 /* | 3013 /* |
| 3051 * This hash is used to remember the series of a slot | 3014 * This hash is used to remember the series of a slot |
| 3052 * when we last checked for user certs | 3015 * when we last checked for user certs |
| 3053 */ | 3016 */ |
| 3054 gSubjKeyIDSlotCheckHash = PL_NewHashTable(0, SECITEM_Hash, | 3017 gSubjKeyIDSlotCheckHash = |
| 3055 SECITEM_HashCompare, | 3018 PL_NewHashTable(0, SECITEM_Hash, SECITEM_HashCompare, |
| 3056 SECITEM_HashCompare, | 3019 SECITEM_HashCompare, &cert_AllocOps, NULL); |
| 3057 &cert_AllocOps, NULL); | |
| 3058 if (!gSubjKeyIDSlotCheckHash) { | 3020 if (!gSubjKeyIDSlotCheckHash) { |
| 3059 PORT_SetError(SEC_ERROR_NO_MEMORY); | 3021 PORT_SetError(SEC_ERROR_NO_MEMORY); |
| 3060 return SECFailure; | 3022 return SECFailure; |
| 3061 } | 3023 } |
| 3062 gSubjKeyIDSlotCheckLock = PR_NewLock(); | 3024 gSubjKeyIDSlotCheckLock = PR_NewLock(); |
| 3063 if (!gSubjKeyIDSlotCheckLock) { | 3025 if (!gSubjKeyIDSlotCheckLock) { |
| 3064 PL_HashTableDestroy(gSubjKeyIDSlotCheckHash); | 3026 PL_HashTableDestroy(gSubjKeyIDSlotCheckHash); |
| 3065 gSubjKeyIDSlotCheckHash = NULL; | 3027 gSubjKeyIDSlotCheckHash = NULL; |
| 3066 PORT_SetError(SEC_ERROR_NO_MEMORY); | 3028 PORT_SetError(SEC_ERROR_NO_MEMORY); |
| 3067 return SECFailure; | 3029 return SECFailure; |
| 3068 } | 3030 } |
| 3069 return SECSuccess; | 3031 return SECSuccess; |
| 3070 } | 3032 } |
| 3071 | 3033 |
| 3072 SECStatus | 3034 SECStatus |
| 3073 cert_CreateSubjectKeyIDHashTable(void) | 3035 cert_CreateSubjectKeyIDHashTable(void) |
| 3074 { | 3036 { |
| 3075 gSubjKeyIDHash = PL_NewHashTable(0, SECITEM_Hash, SECITEM_HashCompare, | 3037 gSubjKeyIDHash = PL_NewHashTable(0, SECITEM_Hash, SECITEM_HashCompare, |
| 3076 SECITEM_HashCompare, | 3038 SECITEM_HashCompare, &cert_AllocOps, NULL); |
| 3077 &cert_AllocOps, NULL); | |
| 3078 if (!gSubjKeyIDHash) { | 3039 if (!gSubjKeyIDHash) { |
| 3079 PORT_SetError(SEC_ERROR_NO_MEMORY); | 3040 PORT_SetError(SEC_ERROR_NO_MEMORY); |
| 3080 return SECFailure; | 3041 return SECFailure; |
| 3081 } | 3042 } |
| 3082 gSubjKeyIDLock = PR_NewLock(); | 3043 gSubjKeyIDLock = PR_NewLock(); |
| 3083 if (!gSubjKeyIDLock) { | 3044 if (!gSubjKeyIDLock) { |
| 3084 PL_HashTableDestroy(gSubjKeyIDHash); | 3045 PL_HashTableDestroy(gSubjKeyIDHash); |
| 3085 gSubjKeyIDHash = NULL; | 3046 gSubjKeyIDHash = NULL; |
| 3086 PORT_SetError(SEC_ERROR_NO_MEMORY); | 3047 PORT_SetError(SEC_ERROR_NO_MEMORY); |
| 3087 return SECFailure; | 3048 return SECFailure; |
| 3088 } | 3049 } |
| 3089 /* initialize the companion hash (for remembering slot series) */ | 3050 /* initialize the companion hash (for remembering slot series) */ |
| 3090 if (cert_CreateSubjectKeyIDSlotCheckHash() != SECSuccess) { | 3051 if (cert_CreateSubjectKeyIDSlotCheckHash() != SECSuccess) { |
| 3091 » cert_DestroySubjectKeyIDHashTable(); | 3052 cert_DestroySubjectKeyIDHashTable(); |
| 3092 » return SECFailure; | 3053 return SECFailure; |
| 3093 } | 3054 } |
| 3094 return SECSuccess; | 3055 return SECSuccess; |
| 3095 } | 3056 } |
| 3096 | 3057 |
| 3097 SECStatus | 3058 SECStatus |
| 3098 cert_AddSubjectKeyIDMapping(SECItem *subjKeyID, CERTCertificate *cert) | 3059 cert_AddSubjectKeyIDMapping(SECItem *subjKeyID, CERTCertificate *cert) |
| 3099 { | 3060 { |
| 3100 SECItem *newKeyID, *oldVal, *newVal; | 3061 SECItem *newKeyID, *oldVal, *newVal; |
| 3101 SECStatus rv = SECFailure; | 3062 SECStatus rv = SECFailure; |
| 3102 | 3063 |
| 3103 if (!gSubjKeyIDLock) { | 3064 if (!gSubjKeyIDLock) { |
| 3104 » /* If one is created, then both are there. So only check for one. */ | 3065 /* If one is created, then both are there. So only check for one. */ |
| 3105 » return SECFailure; | 3066 return SECFailure; |
| 3106 } | 3067 } |
| 3107 | 3068 |
| 3108 newVal = SECITEM_DupItem(&cert->derCert); | 3069 newVal = SECITEM_DupItem(&cert->derCert); |
| 3109 if (!newVal) { | 3070 if (!newVal) { |
| 3110 PORT_SetError(SEC_ERROR_NO_MEMORY); | 3071 PORT_SetError(SEC_ERROR_NO_MEMORY); |
| 3111 goto done; | 3072 goto done; |
| 3112 } | 3073 } |
| 3113 newKeyID = SECITEM_DupItem(subjKeyID); | 3074 newKeyID = SECITEM_DupItem(subjKeyID); |
| 3114 if (!newKeyID) { | 3075 if (!newKeyID) { |
| 3115 SECITEM_FreeItem(newVal, PR_TRUE); | 3076 SECITEM_FreeItem(newVal, PR_TRUE); |
| 3116 PORT_SetError(SEC_ERROR_NO_MEMORY); | 3077 PORT_SetError(SEC_ERROR_NO_MEMORY); |
| 3117 goto done; | 3078 goto done; |
| 3118 } | 3079 } |
| 3119 | 3080 |
| 3120 PR_Lock(gSubjKeyIDLock); | 3081 PR_Lock(gSubjKeyIDLock); |
| 3121 /* The hash table implementation does not free up the memory | 3082 /* The hash table implementation does not free up the memory |
| 3122 * associated with the key of an already existing entry if we add a | 3083 * associated with the key of an already existing entry if we add a |
| 3123 * duplicate, so we would wind up leaking the previously allocated | 3084 * duplicate, so we would wind up leaking the previously allocated |
| 3124 * key if we don't remove before adding. | 3085 * key if we don't remove before adding. |
| 3125 */ | 3086 */ |
| 3126 oldVal = (SECItem*)PL_HashTableLookup(gSubjKeyIDHash, subjKeyID); | 3087 oldVal = (SECItem *)PL_HashTableLookup(gSubjKeyIDHash, subjKeyID); |
| 3127 if (oldVal) { | 3088 if (oldVal) { |
| 3128 PL_HashTableRemove(gSubjKeyIDHash, subjKeyID); | 3089 PL_HashTableRemove(gSubjKeyIDHash, subjKeyID); |
| 3129 } | 3090 } |
| 3130 | 3091 |
| 3131 rv = (PL_HashTableAdd(gSubjKeyIDHash, newKeyID, newVal)) ? SECSuccess : | 3092 rv = (PL_HashTableAdd(gSubjKeyIDHash, newKeyID, newVal)) ? SECSuccess |
| 3132 SECFailure; | 3093 : SECFailure; |
| 3133 PR_Unlock(gSubjKeyIDLock); | 3094 PR_Unlock(gSubjKeyIDLock); |
| 3134 done: | 3095 done: |
| 3135 return rv; | 3096 return rv; |
| 3136 } | 3097 } |
| 3137 | 3098 |
| 3138 SECStatus | 3099 SECStatus |
| 3139 cert_RemoveSubjectKeyIDMapping(SECItem *subjKeyID) | 3100 cert_RemoveSubjectKeyIDMapping(SECItem *subjKeyID) |
| 3140 { | 3101 { |
| 3141 SECStatus rv; | 3102 SECStatus rv; |
| 3142 if (!gSubjKeyIDLock) | 3103 if (!gSubjKeyIDLock) |
| 3143 return SECFailure; | 3104 return SECFailure; |
| 3144 | 3105 |
| 3145 PR_Lock(gSubjKeyIDLock); | 3106 PR_Lock(gSubjKeyIDLock); |
| 3146 rv = (PL_HashTableRemove(gSubjKeyIDHash, subjKeyID)) ? SECSuccess : | 3107 rv = (PL_HashTableRemove(gSubjKeyIDHash, subjKeyID)) ? SECSuccess |
| 3147 SECFailure; | 3108 : SECFailure; |
| 3148 PR_Unlock(gSubjKeyIDLock); | 3109 PR_Unlock(gSubjKeyIDLock); |
| 3149 return rv; | 3110 return rv; |
| 3150 } | 3111 } |
| 3151 | 3112 |
| 3152 SECStatus | 3113 SECStatus |
| 3153 cert_UpdateSubjectKeyIDSlotCheck(SECItem *slotid, int series) | 3114 cert_UpdateSubjectKeyIDSlotCheck(SECItem *slotid, int series) |
| 3154 { | 3115 { |
| 3155 SECItem *oldSeries, *newSlotid, *newSeries; | 3116 SECItem *oldSeries, *newSlotid, *newSeries; |
| 3156 SECStatus rv = SECFailure; | 3117 SECStatus rv = SECFailure; |
| 3157 | 3118 |
| 3158 if (!gSubjKeyIDSlotCheckLock) { | 3119 if (!gSubjKeyIDSlotCheckLock) { |
| 3159 » return rv; | 3120 return rv; |
| 3160 } | 3121 } |
| 3161 | 3122 |
| 3162 newSlotid = SECITEM_DupItem(slotid); | 3123 newSlotid = SECITEM_DupItem(slotid); |
| 3163 newSeries = SECITEM_AllocItem(NULL, NULL, sizeof(int)); | 3124 newSeries = SECITEM_AllocItem(NULL, NULL, sizeof(int)); |
| 3164 if (!newSlotid || !newSeries ) { | 3125 if (!newSlotid || !newSeries) { |
| 3165 PORT_SetError(SEC_ERROR_NO_MEMORY); | 3126 PORT_SetError(SEC_ERROR_NO_MEMORY); |
| 3166 goto loser; | 3127 goto loser; |
| 3167 } | 3128 } |
| 3168 PORT_Memcpy(newSeries->data, &series, sizeof(int)); | 3129 PORT_Memcpy(newSeries->data, &series, sizeof(int)); |
| 3169 | 3130 |
| 3170 PR_Lock(gSubjKeyIDSlotCheckLock); | 3131 PR_Lock(gSubjKeyIDSlotCheckLock); |
| 3171 oldSeries = (SECItem *)PL_HashTableLookup(gSubjKeyIDSlotCheckHash, slotid); | 3132 oldSeries = (SECItem *)PL_HashTableLookup(gSubjKeyIDSlotCheckHash, slotid); |
| 3172 if (oldSeries) { | 3133 if (oldSeries) { |
| 3173 » /* | 3134 /* |
| 3174 » * make sure we don't leak the key of an existing entry | 3135 * make sure we don't leak the key of an existing entry |
| 3175 » * (similar to cert_AddSubjectKeyIDMapping, see comment there) | 3136 * (similar to cert_AddSubjectKeyIDMapping, see comment there) |
| 3176 » */ | 3137 */ |
| 3177 PL_HashTableRemove(gSubjKeyIDSlotCheckHash, slotid); | 3138 PL_HashTableRemove(gSubjKeyIDSlotCheckHash, slotid); |
| 3178 } | 3139 } |
| 3179 rv = (PL_HashTableAdd(gSubjKeyIDSlotCheckHash, newSlotid, newSeries)) ? | 3140 rv = (PL_HashTableAdd(gSubjKeyIDSlotCheckHash, newSlotid, newSeries)) |
| 3180 SECSuccess : SECFailure; | 3141 ? SECSuccess |
| 3142 : SECFailure; |
| 3181 PR_Unlock(gSubjKeyIDSlotCheckLock); | 3143 PR_Unlock(gSubjKeyIDSlotCheckLock); |
| 3182 if (rv == SECSuccess) { | 3144 if (rv == SECSuccess) { |
| 3183 » return rv; | 3145 return rv; |
| 3184 } | 3146 } |
| 3185 | 3147 |
| 3186 loser: | 3148 loser: |
| 3187 if (newSlotid) { | 3149 if (newSlotid) { |
| 3188 SECITEM_FreeItem(newSlotid, PR_TRUE); | 3150 SECITEM_FreeItem(newSlotid, PR_TRUE); |
| 3189 } | 3151 } |
| 3190 if (newSeries) { | 3152 if (newSeries) { |
| 3191 SECITEM_FreeItem(newSeries, PR_TRUE); | 3153 SECITEM_FreeItem(newSeries, PR_TRUE); |
| 3192 } | 3154 } |
| 3193 return rv; | 3155 return rv; |
| 3194 } | 3156 } |
| 3195 | 3157 |
| 3196 int | 3158 int |
| 3197 cert_SubjectKeyIDSlotCheckSeries(SECItem *slotid) | 3159 cert_SubjectKeyIDSlotCheckSeries(SECItem *slotid) |
| 3198 { | 3160 { |
| 3199 SECItem *seriesItem = NULL; | 3161 SECItem *seriesItem = NULL; |
| 3200 int series; | 3162 int series; |
| 3201 | 3163 |
| 3202 if (!gSubjKeyIDSlotCheckLock) { | 3164 if (!gSubjKeyIDSlotCheckLock) { |
| 3203 » PORT_SetError(SEC_ERROR_NOT_INITIALIZED); | 3165 PORT_SetError(SEC_ERROR_NOT_INITIALIZED); |
| 3204 » return -1; | 3166 return -1; |
| 3205 } | 3167 } |
| 3206 | 3168 |
| 3207 PR_Lock(gSubjKeyIDSlotCheckLock); | 3169 PR_Lock(gSubjKeyIDSlotCheckLock); |
| 3208 seriesItem = (SECItem *)PL_HashTableLookup(gSubjKeyIDSlotCheckHash, slotid); | 3170 seriesItem = (SECItem *)PL_HashTableLookup(gSubjKeyIDSlotCheckHash, slotid); |
| 3209 PR_Unlock(gSubjKeyIDSlotCheckLock); | 3171 PR_Unlock(gSubjKeyIDSlotCheckLock); |
| 3210 /* getting a null series just means we haven't registered one yet, | 3172 /* getting a null series just means we haven't registered one yet, |
| 3211 * just return 0 */ | 3173 * just return 0 */ |
| 3212 if (seriesItem == NULL) { | 3174 if (seriesItem == NULL) { |
| 3213 » return 0; | 3175 return 0; |
| 3214 } | 3176 } |
| 3215 /* if we got a series back, assert if it's not the proper length. */ | 3177 /* if we got a series back, assert if it's not the proper length. */ |
| 3216 PORT_Assert(seriesItem->len == sizeof(int)); | 3178 PORT_Assert(seriesItem->len == sizeof(int)); |
| 3217 if (seriesItem->len != sizeof(int)) { | 3179 if (seriesItem->len != sizeof(int)) { |
| 3218 » PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); | 3180 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
| 3219 » return -1; | 3181 return -1; |
| 3220 } | 3182 } |
| 3221 PORT_Memcpy(&series, seriesItem->data, sizeof(int)); | 3183 PORT_Memcpy(&series, seriesItem->data, sizeof(int)); |
| 3222 return series; | 3184 return series; |
| 3223 } | 3185 } |
| 3224 | 3186 |
| 3225 SECStatus | 3187 SECStatus |
| 3226 cert_DestroySubjectKeyIDSlotCheckHash(void) | 3188 cert_DestroySubjectKeyIDSlotCheckHash(void) |
| 3227 { | 3189 { |
| 3228 if (gSubjKeyIDSlotCheckHash) { | 3190 if (gSubjKeyIDSlotCheckHash) { |
| 3229 PR_Lock(gSubjKeyIDSlotCheckLock); | 3191 PR_Lock(gSubjKeyIDSlotCheckLock); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 3244 PL_HashTableDestroy(gSubjKeyIDHash); | 3206 PL_HashTableDestroy(gSubjKeyIDHash); |
| 3245 gSubjKeyIDHash = NULL; | 3207 gSubjKeyIDHash = NULL; |
| 3246 PR_Unlock(gSubjKeyIDLock); | 3208 PR_Unlock(gSubjKeyIDLock); |
| 3247 PR_DestroyLock(gSubjKeyIDLock); | 3209 PR_DestroyLock(gSubjKeyIDLock); |
| 3248 gSubjKeyIDLock = NULL; | 3210 gSubjKeyIDLock = NULL; |
| 3249 } | 3211 } |
| 3250 cert_DestroySubjectKeyIDSlotCheckHash(); | 3212 cert_DestroySubjectKeyIDSlotCheckHash(); |
| 3251 return SECSuccess; | 3213 return SECSuccess; |
| 3252 } | 3214 } |
| 3253 | 3215 |
| 3254 SECItem* | 3216 SECItem * |
| 3255 cert_FindDERCertBySubjectKeyID(SECItem *subjKeyID) | 3217 cert_FindDERCertBySubjectKeyID(SECItem *subjKeyID) |
| 3256 { | 3218 { |
| 3257 SECItem *val; | 3219 SECItem *val; |
| 3258 | 3220 |
| 3259 if (!gSubjKeyIDLock) | 3221 if (!gSubjKeyIDLock) |
| 3260 return NULL; | 3222 return NULL; |
| 3261 | 3223 |
| 3262 PR_Lock(gSubjKeyIDLock); | 3224 PR_Lock(gSubjKeyIDLock); |
| 3263 val = (SECItem*)PL_HashTableLookup(gSubjKeyIDHash, subjKeyID); | 3225 val = (SECItem *)PL_HashTableLookup(gSubjKeyIDHash, subjKeyID); |
| 3264 if (val) { | 3226 if (val) { |
| 3265 val = SECITEM_DupItem(val); | 3227 val = SECITEM_DupItem(val); |
| 3266 } | 3228 } |
| 3267 PR_Unlock(gSubjKeyIDLock); | 3229 PR_Unlock(gSubjKeyIDLock); |
| 3268 return val; | 3230 return val; |
| 3269 } | 3231 } |
| 3270 | 3232 |
| 3271 CERTCertificate* | 3233 CERTCertificate * |
| 3272 CERT_FindCertBySubjectKeyID(CERTCertDBHandle *handle, SECItem *subjKeyID) | 3234 CERT_FindCertBySubjectKeyID(CERTCertDBHandle *handle, SECItem *subjKeyID) |
| 3273 { | 3235 { |
| 3274 CERTCertificate *cert = NULL; | 3236 CERTCertificate *cert = NULL; |
| 3275 SECItem *derCert; | 3237 SECItem *derCert; |
| 3276 | 3238 |
| 3277 derCert = cert_FindDERCertBySubjectKeyID(subjKeyID); | 3239 derCert = cert_FindDERCertBySubjectKeyID(subjKeyID); |
| 3278 if (derCert) { | 3240 if (derCert) { |
| 3279 cert = CERT_FindCertByDERCert(handle, derCert); | 3241 cert = CERT_FindCertByDERCert(handle, derCert); |
| 3280 SECITEM_FreeItem(derCert, PR_TRUE); | 3242 SECITEM_FreeItem(derCert, PR_TRUE); |
| 3281 } | 3243 } |
| 3282 return cert; | 3244 return cert; |
| 3283 } | 3245 } |
| OLD | NEW |