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 |