Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

Side by Side Diff: nss/lib/certdb/certdb.c

Issue 1843333003: Update NSPR to 4.12 and NSS to 3.23 on iOS (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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, &notBefore, &notAfter); 959 rv = CERT_GetCertTimes(c, &notBefore, &notAfter);
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, &notBefore, &notAfter); 1019 rv = SEC_GetCrlTimes(crl, &notBefore, &notAfter);
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(&notBeforeA, &val_a->notBefore) || 2150 if (SECSuccess != DER_DecodeTimeChoice(&notBeforeA, &val_a->notBefore) ||
2182 SECSuccess != DER_DecodeTimeChoice(&notBeforeB, &val_b->notBefore) || 2151 SECSuccess != DER_DecodeTimeChoice(&notBeforeB, &val_b->notBefore) ||
2183 SECSuccess != DER_DecodeTimeChoice(&notAfterA, &val_a->notAfter) || 2152 SECSuccess != DER_DecodeTimeChoice(&notAfterA, &val_a->notAfter) ||
2184 SECSuccess != DER_DecodeTimeChoice(&notAfterB, &val_b->notAfter) ) { 2153 SECSuccess != DER_DecodeTimeChoice(&notAfterB, &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, &notBeforeA, &notAfterA); 2189 rv = CERT_GetCertTimes(certa, &notBeforeA, &notAfterA);
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, &notBeforeB, &notAfterB); 2194 rv = CERT_GetCertTimes(certb, &notBeforeB, &notAfterB);
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, &notBeforeA, &notAfterA); 2617 rv = CERT_GetCertTimes(certa, &notBeforeA, &notAfterA);
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, &notBeforeB, &notAfterB); 2622 rv = CERT_GetCertTimes(certb, &notBeforeB, &notAfterB);
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
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
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 }
OLDNEW
« no previous file with comments | « nss/lib/certdb/certdb.h ('k') | nss/lib/certdb/certi.h » ('j') | nss/lib/util/secoid.c » ('J')

Powered by Google App Engine
This is Rietveld 408576698