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

Side by Side Diff: nss/lib/certdb/genname.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 #include "plarena.h" 5 #include "plarena.h"
6 #include "seccomon.h" 6 #include "seccomon.h"
7 #include "secitem.h" 7 #include "secitem.h"
8 #include "secoidt.h" 8 #include "secoidt.h"
9 #include "secasn1.h" 9 #include "secasn1.h"
10 #include "secder.h" 10 #include "secder.h"
11 #include "certt.h" 11 #include "certt.h"
12 #include "cert.h" 12 #include "cert.h"
13 #include "certi.h" 13 #include "certi.h"
14 #include "xconst.h" 14 #include "xconst.h"
15 #include "secerr.h" 15 #include "secerr.h"
16 #include "secoid.h" 16 #include "secoid.h"
17 #include "prprf.h" 17 #include "prprf.h"
18 #include "genname.h" 18 #include "genname.h"
19 19
20 SEC_ASN1_MKSUB(SEC_AnyTemplate) 20 SEC_ASN1_MKSUB(SEC_AnyTemplate)
21 SEC_ASN1_MKSUB(SEC_IntegerTemplate) 21 SEC_ASN1_MKSUB(SEC_IntegerTemplate)
22 SEC_ASN1_MKSUB(SEC_IA5StringTemplate) 22 SEC_ASN1_MKSUB(SEC_IA5StringTemplate)
23 SEC_ASN1_MKSUB(SEC_ObjectIDTemplate) 23 SEC_ASN1_MKSUB(SEC_ObjectIDTemplate)
24 SEC_ASN1_MKSUB(SEC_OctetStringTemplate) 24 SEC_ASN1_MKSUB(SEC_OctetStringTemplate)
25 25
26 static const SEC_ASN1Template CERTNameConstraintTemplate[] = { 26 static const SEC_ASN1Template CERTNameConstraintTemplate[] = {
27 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTNameConstraint) }, 27 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTNameConstraint) },
28 { SEC_ASN1_ANY, offsetof(CERTNameConstraint, DERName) }, 28 { SEC_ASN1_ANY, offsetof(CERTNameConstraint, DERName) },
29 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, 29 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
30 offsetof(CERTNameConstraint, min), 30 offsetof(CERTNameConstraint, min), SEC_ASN1_SUB(SEC_IntegerTemplate) },
31 SEC_ASN1_SUB(SEC_IntegerTemplate) }, 31 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
32 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1, 32 offsetof(CERTNameConstraint, max), SEC_ASN1_SUB(SEC_IntegerTemplate) },
33 offsetof(CERTNameConstraint, max), 33 { 0 }
34 SEC_ASN1_SUB(SEC_IntegerTemplate) },
35 { 0, }
36 }; 34 };
37 35
38 const SEC_ASN1Template CERT_NameConstraintSubtreeSubTemplate[] = { 36 const SEC_ASN1Template CERT_NameConstraintSubtreeSubTemplate[] = {
39 { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN, 0, SEC_ASN1_SUB(SEC_AnyTemplate) } 37 { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN, 0, SEC_ASN1_SUB(SEC_AnyTemplate) }
40 }; 38 };
41 39
42 static const SEC_ASN1Template CERTNameConstraintsTemplate[] = { 40 static const SEC_ASN1Template CERTNameConstraintsTemplate[] = {
43 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTNameConstraints) }, 41 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTNameConstraints) },
44 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, 42 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
45 offsetof(CERTNameConstraints, DERPermited), 43 offsetof(CERTNameConstraints, DERPermited),
46 » CERT_NameConstraintSubtreeSubTemplate}, 44 CERT_NameConstraintSubtreeSubTemplate },
47 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, 45 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
48 offsetof(CERTNameConstraints, DERExcluded), 46 offsetof(CERTNameConstraints, DERExcluded),
49 » CERT_NameConstraintSubtreeSubTemplate}, 47 CERT_NameConstraintSubtreeSubTemplate },
50 { 0, } 48 { 0 }
51 }; 49 };
52 50
53
54 static const SEC_ASN1Template CERTOthNameTemplate[] = { 51 static const SEC_ASN1Template CERTOthNameTemplate[] = {
55 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(OtherName) }, 52 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(OtherName) },
56 { SEC_ASN1_OBJECT_ID, 53 { SEC_ASN1_OBJECT_ID, offsetof(OtherName, oid) },
57 » offsetof(OtherName, oid) },
58 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | 54 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
59 SEC_ASN1_XTRN | 0, offsetof(OtherName, name), 55 SEC_ASN1_XTRN | 0,
60 SEC_ASN1_SUB(SEC_AnyTemplate) }, 56 offsetof(OtherName, name), SEC_ASN1_SUB(SEC_AnyTemplate) },
61 { 0, } 57 { 0 }
62 }; 58 };
63 59
64 static const SEC_ASN1Template CERTOtherNameTemplate[] = { 60 static const SEC_ASN1Template CERTOtherNameTemplate[] = {
65 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 0 , 61 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 0,
66 offsetof(CERTGeneralName, name.OthName), CERTOthNameTemplate, 62 offsetof(CERTGeneralName, name.OthName), CERTOthNameTemplate,
67 sizeof(CERTGeneralName) } 63 sizeof(CERTGeneralName) }
68 }; 64 };
69 65
70 static const SEC_ASN1Template CERT_RFC822NameTemplate[] = { 66 static const SEC_ASN1Template CERT_RFC822NameTemplate[] = {
71 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1 , 67 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
72 offsetof(CERTGeneralName, name.other), 68 offsetof(CERTGeneralName, name.other),
73 SEC_ASN1_SUB(SEC_IA5StringTemplate), 69 SEC_ASN1_SUB(SEC_IA5StringTemplate), sizeof(CERTGeneralName) }
74 sizeof (CERTGeneralName)}
75 }; 70 };
76 71
77 static const SEC_ASN1Template CERT_DNSNameTemplate[] = { 72 static const SEC_ASN1Template CERT_DNSNameTemplate[] = {
78 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2 , 73 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2,
79 offsetof(CERTGeneralName, name.other), 74 offsetof(CERTGeneralName, name.other),
80 SEC_ASN1_SUB(SEC_IA5StringTemplate), 75 SEC_ASN1_SUB(SEC_IA5StringTemplate), sizeof(CERTGeneralName) }
81 sizeof (CERTGeneralName)}
82 }; 76 };
83 77
84 static const SEC_ASN1Template CERT_X400AddressTemplate[] = { 78 static const SEC_ASN1Template CERT_X400AddressTemplate[] = {
85 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | SEC_ASN1_XTRN | 3, 79 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | SEC_ASN1_XTRN | 3,
86 offsetof(CERTGeneralName, name.other), SEC_ASN1_SUB(SEC_AnyTemplate), 80 offsetof(CERTGeneralName, name.other), SEC_ASN1_SUB(SEC_AnyTemplate),
87 sizeof (CERTGeneralName)} 81 sizeof(CERTGeneralName) }
88 }; 82 };
89 83
90 static const SEC_ASN1Template CERT_DirectoryNameTemplate[] = { 84 static const SEC_ASN1Template CERT_DirectoryNameTemplate[] = {
91 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | 85 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
92 SEC_ASN1_XTRN | 4, offsetof(CERTGeneralName, derDirectoryName), 86 SEC_ASN1_XTRN | 4,
93 SEC_ASN1_SUB(SEC_AnyTemplate), sizeof (CERTGeneralName)} 87 offsetof(CERTGeneralName, derDirectoryName),
88 SEC_ASN1_SUB(SEC_AnyTemplate), sizeof(CERTGeneralName) }
94 }; 89 };
95 90
96
97 static const SEC_ASN1Template CERT_EDIPartyNameTemplate[] = { 91 static const SEC_ASN1Template CERT_EDIPartyNameTemplate[] = {
98 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | SEC_ASN1_XTRN | 5, 92 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | SEC_ASN1_XTRN | 5,
99 offsetof(CERTGeneralName, name.other), SEC_ASN1_SUB(SEC_AnyTemplate), 93 offsetof(CERTGeneralName, name.other), SEC_ASN1_SUB(SEC_AnyTemplate),
100 sizeof (CERTGeneralName)} 94 sizeof(CERTGeneralName) }
101 }; 95 };
102 96
103 static const SEC_ASN1Template CERT_URITemplate[] = { 97 static const SEC_ASN1Template CERT_URITemplate[] = {
104 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 6 , 98 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 6,
105 offsetof(CERTGeneralName, name.other), 99 offsetof(CERTGeneralName, name.other),
106 SEC_ASN1_SUB(SEC_IA5StringTemplate), 100 SEC_ASN1_SUB(SEC_IA5StringTemplate), sizeof(CERTGeneralName) }
107 sizeof (CERTGeneralName)}
108 }; 101 };
109 102
110 static const SEC_ASN1Template CERT_IPAddressTemplate[] = { 103 static const SEC_ASN1Template CERT_IPAddressTemplate[] = {
111 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 7 , 104 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 7,
112 offsetof(CERTGeneralName, name.other), 105 offsetof(CERTGeneralName, name.other),
113 SEC_ASN1_SUB(SEC_OctetStringTemplate), 106 SEC_ASN1_SUB(SEC_OctetStringTemplate), sizeof(CERTGeneralName) }
114 sizeof (CERTGeneralName)}
115 }; 107 };
116 108
117 static const SEC_ASN1Template CERT_RegisteredIDTemplate[] = { 109 static const SEC_ASN1Template CERT_RegisteredIDTemplate[] = {
118 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 8 , 110 { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 8,
119 offsetof(CERTGeneralName, name.other), 111 offsetof(CERTGeneralName, name.other), SEC_ASN1_SUB(SEC_ObjectIDTemplate),
120 SEC_ASN1_SUB(SEC_ObjectIDTemplate), 112 sizeof(CERTGeneralName) }
121 sizeof (CERTGeneralName)}
122 }; 113 };
123 114
124
125 const SEC_ASN1Template CERT_GeneralNamesTemplate[] = { 115 const SEC_ASN1Template CERT_GeneralNamesTemplate[] = {
126 { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN , 0, SEC_ASN1_SUB(SEC_AnyTemplate) } 116 { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN, 0, SEC_ASN1_SUB(SEC_AnyTemplate) }
127 }; 117 };
128 118
129
130 static struct { 119 static struct {
131 CERTGeneralNameType type; 120 CERTGeneralNameType type;
132 char *name; 121 char *name;
133 } typesArray[] = { 122 } typesArray[] = { { certOtherName, "other" },
134 { certOtherName, "other" }, 123 { certRFC822Name, "email" },
135 { certRFC822Name, "email" }, 124 { certRFC822Name, "rfc822" },
136 { certRFC822Name, "rfc822" }, 125 { certDNSName, "dns" },
137 { certDNSName, "dns" }, 126 { certX400Address, "x400" },
138 { certX400Address, "x400" }, 127 { certX400Address, "x400addr" },
139 { certX400Address, "x400addr" }, 128 { certDirectoryName, "directory" },
140 { certDirectoryName, "directory" }, 129 { certDirectoryName, "dn" },
141 { certDirectoryName, "dn" }, 130 { certEDIPartyName, "edi" },
142 { certEDIPartyName, "edi" }, 131 { certEDIPartyName, "ediparty" },
143 { certEDIPartyName, "ediparty" }, 132 { certURI, "uri" },
144 { certURI, "uri" }, 133 { certIPAddress, "ip" },
145 { certIPAddress, "ip" }, 134 { certIPAddress, "ipaddr" },
146 { certIPAddress, "ipaddr" }, 135 { certRegisterID, "registerid" } };
147 { certRegisterID, "registerid" }
148 };
149 136
150 CERTGeneralNameType 137 CERTGeneralNameType
151 CERT_GetGeneralNameTypeFromString(const char *string) 138 CERT_GetGeneralNameTypeFromString(const char *string)
152 { 139 {
153 int types_count = sizeof(typesArray)/sizeof(typesArray[0]); 140 int types_count = sizeof(typesArray) / sizeof(typesArray[0]);
154 int i; 141 int i;
155 142
156 for (i=0; i < types_count; i++) { 143 for (i = 0; i < types_count; i++) {
157 if (PORT_Strcasecmp(string, typesArray[i].name) == 0) { 144 if (PORT_Strcasecmp(string, typesArray[i].name) == 0) {
158 return typesArray[i].type; 145 return typesArray[i].type;
159 } 146 }
160 } 147 }
161 return 0; 148 return 0;
162 } 149 }
163 150
164 CERTGeneralName * 151 CERTGeneralName *
165 CERT_NewGeneralName(PLArenaPool *arena, CERTGeneralNameType type) 152 CERT_NewGeneralName(PLArenaPool *arena, CERTGeneralNameType type)
166 { 153 {
167 CERTGeneralName *name = arena 154 CERTGeneralName *name = arena ? PORT_ArenaZNew(arena, CERTGeneralName)
168 ? PORT_ArenaZNew(arena, CERTGeneralName) 155 : PORT_ZNew(CERTGeneralName);
169 » : PORT_ZNew(CERTGeneralName);
170 if (name) { 156 if (name) {
171 » name->type = type; 157 name->type = type;
172 » name->l.prev = name->l.next = &name->l; 158 name->l.prev = name->l.next = &name->l;
173 } 159 }
174 return name; 160 return name;
175 } 161 }
176 162
177 /* Copy content of one General Name to another. 163 /* Copy content of one General Name to another.
178 ** Caller has allocated destination general name. 164 ** Caller has allocated destination general name.
179 ** This function does not change the destinate's GeneralName's list linkage. 165 ** This function does not change the destinate's GeneralName's list linkage.
180 */ 166 */
181 SECStatus 167 SECStatus
182 cert_CopyOneGeneralName(PLArenaPool *arena, 168 cert_CopyOneGeneralName(PLArenaPool *arena, CERTGeneralName *dest,
183 » » CERTGeneralName *dest, 169 CERTGeneralName *src)
184 » » CERTGeneralName *src)
185 { 170 {
186 SECStatus rv; 171 SECStatus rv;
187 void *mark = NULL; 172 void *mark = NULL;
188 173
189 PORT_Assert(dest != NULL); 174 PORT_Assert(dest != NULL);
190 dest->type = src->type; 175 dest->type = src->type;
191 176
192 mark = PORT_ArenaMark(arena); 177 mark = PORT_ArenaMark(arena);
193 178
194 switch (src->type) { 179 switch (src->type) {
195 case certDirectoryName: 180 case certDirectoryName:
196 » rv = SECITEM_CopyItem(arena, &dest->derDirectoryName, 181 rv = SECITEM_CopyItem(arena, &dest->derDirectoryName,
197 » » » » &src->derDirectoryName); 182 &src->derDirectoryName);
198 » if (rv == SECSuccess) 183 if (rv == SECSuccess)
199 » rv = CERT_CopyName(arena, &dest->name.directoryName, 184 rv = CERT_CopyName(arena, &dest->name.directoryName,
200 » » » » &src->name.directoryName); 185 &src->name.directoryName);
201 » break; 186 break;
202 187
203 case certOtherName: 188 case certOtherName:
204 » rv = SECITEM_CopyItem(arena, &dest->name.OthName.name, 189 rv = SECITEM_CopyItem(arena, &dest->name.OthName.name,
205 » » » » &src->name.OthName.name); 190 &src->name.OthName.name);
206 » if (rv == SECSuccess) 191 if (rv == SECSuccess)
207 » rv = SECITEM_CopyItem(arena, &dest->name.OthName.oid, 192 rv = SECITEM_CopyItem(arena, &dest->name.OthName.oid,
208 » » » » » &src->name.OthName.oid); 193 &src->name.OthName.oid);
209 » break; 194 break;
210 195
211 default: 196 default:
212 » rv = SECITEM_CopyItem(arena, &dest->name.other, 197 rv = SECITEM_CopyItem(arena, &dest->name.other, &src->name.other);
213 » » » » &src->name.other); 198 break;
214 » break;
215
216 } 199 }
217 if (rv != SECSuccess) { 200 if (rv != SECSuccess) {
218 PORT_ArenaRelease(arena, mark); 201 PORT_ArenaRelease(arena, mark);
219 } else { 202 } else {
220 PORT_ArenaUnmark(arena, mark); 203 PORT_ArenaUnmark(arena, mark);
221 } 204 }
222 return rv; 205 return rv;
223 } 206 }
224 207
225
226 void 208 void
227 CERT_DestroyGeneralNameList(CERTGeneralNameList *list) 209 CERT_DestroyGeneralNameList(CERTGeneralNameList *list)
228 { 210 {
229 PZLock *lock; 211 PZLock *lock;
230 212
231 if (list != NULL) { 213 if (list != NULL) {
232 » lock = list->lock; 214 lock = list->lock;
233 » PZ_Lock(lock); 215 PZ_Lock(lock);
234 » if (--list->refCount <= 0 && list->arena != NULL) { 216 if (--list->refCount <= 0 && list->arena != NULL) {
235 » PORT_FreeArena(list->arena, PR_FALSE); 217 PORT_FreeArena(list->arena, PR_FALSE);
236 » PZ_Unlock(lock); 218 PZ_Unlock(lock);
237 » PZ_DestroyLock(lock); 219 PZ_DestroyLock(lock);
238 » } else { 220 } else {
239 » PZ_Unlock(lock); 221 PZ_Unlock(lock);
240 » } 222 }
241 } 223 }
242 return; 224 return;
243 } 225 }
244 226
245 CERTGeneralNameList * 227 CERTGeneralNameList *
246 CERT_CreateGeneralNameList(CERTGeneralName *name) { 228 CERT_CreateGeneralNameList(CERTGeneralName *name)
229 {
247 PLArenaPool *arena; 230 PLArenaPool *arena;
248 CERTGeneralNameList *list = NULL; 231 CERTGeneralNameList *list = NULL;
249 232
250 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 233 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
251 if (arena == NULL) { 234 if (arena == NULL) {
252 » goto done; 235 goto done;
253 } 236 }
254 list = PORT_ArenaZNew(arena, CERTGeneralNameList); 237 list = PORT_ArenaZNew(arena, CERTGeneralNameList);
255 if (!list) 238 if (!list)
256 » goto loser; 239 goto loser;
257 if (name != NULL) { 240 if (name != NULL) {
258 » SECStatus rv; 241 SECStatus rv;
259 » list->name = CERT_NewGeneralName(arena, (CERTGeneralNameType)0); 242 list->name = CERT_NewGeneralName(arena, (CERTGeneralNameType)0);
260 » if (!list->name) 243 if (!list->name)
261 » goto loser; 244 goto loser;
262 » rv = CERT_CopyGeneralName(arena, list->name, name); 245 rv = CERT_CopyGeneralName(arena, list->name, name);
263 » if (rv != SECSuccess) 246 if (rv != SECSuccess)
264 » goto loser; 247 goto loser;
265 } 248 }
266 list->lock = PZ_NewLock(nssILockList); 249 list->lock = PZ_NewLock(nssILockList);
267 if (!list->lock) 250 if (!list->lock)
268 » goto loser; 251 goto loser;
269 list->arena = arena; 252 list->arena = arena;
270 list->refCount = 1; 253 list->refCount = 1;
271 done: 254 done:
272 return list; 255 return list;
273 256
274 loser: 257 loser:
275 PORT_FreeArena(arena, PR_FALSE); 258 PORT_FreeArena(arena, PR_FALSE);
276 return NULL; 259 return NULL;
277 } 260 }
278 261
279 CERTGeneralName * 262 CERTGeneralName *
280 CERT_GetNextGeneralName(CERTGeneralName *current) 263 CERT_GetNextGeneralName(CERTGeneralName *current)
281 { 264 {
282 PRCList *next; 265 PRCList *next;
283 266
284 next = current->l.next; 267 next = current->l.next;
285 return (CERTGeneralName *) (((char *) next) - offsetof(CERTGeneralName, l)); 268 return (CERTGeneralName *)(((char *)next) - offsetof(CERTGeneralName, l));
286 } 269 }
287 270
288 CERTGeneralName * 271 CERTGeneralName *
289 CERT_GetPrevGeneralName(CERTGeneralName *current) 272 CERT_GetPrevGeneralName(CERTGeneralName *current)
290 { 273 {
291 PRCList *prev; 274 PRCList *prev;
292 prev = current->l.prev; 275 prev = current->l.prev;
293 return (CERTGeneralName *) (((char *) prev) - offsetof(CERTGeneralName, l)); 276 return (CERTGeneralName *)(((char *)prev) - offsetof(CERTGeneralName, l));
294 } 277 }
295 278
296 CERTNameConstraint * 279 CERTNameConstraint *
297 CERT_GetNextNameConstraint(CERTNameConstraint *current) 280 CERT_GetNextNameConstraint(CERTNameConstraint *current)
298 { 281 {
299 PRCList *next; 282 PRCList *next;
300 283
301 next = current->l.next; 284 next = current->l.next;
302 return (CERTNameConstraint *) (((char *) next) - offsetof(CERTNameConstraint , l)); 285 return (CERTNameConstraint *)(((char *)next) -
286 offsetof(CERTNameConstraint, l));
303 } 287 }
304 288
305 CERTNameConstraint * 289 CERTNameConstraint *
306 CERT_GetPrevNameConstraint(CERTNameConstraint *current) 290 CERT_GetPrevNameConstraint(CERTNameConstraint *current)
307 { 291 {
308 PRCList *prev; 292 PRCList *prev;
309 prev = current->l.prev; 293 prev = current->l.prev;
310 return (CERTNameConstraint *) (((char *) prev) - offsetof(CERTNameConstraint , l)); 294 return (CERTNameConstraint *)(((char *)prev) -
295 offsetof(CERTNameConstraint, l));
311 } 296 }
312 297
313 SECItem * 298 SECItem *
314 CERT_EncodeGeneralName(CERTGeneralName *genName, SECItem *dest, PLArenaPool *are na) 299 CERT_EncodeGeneralName(CERTGeneralName *genName, SECItem *dest,
300 PLArenaPool *arena)
315 { 301 {
316 302
317 const SEC_ASN1Template * template; 303 const SEC_ASN1Template *template;
318 304
319 PORT_Assert(arena); 305 PORT_Assert(arena);
320 if (arena == NULL) { 306 if (arena == NULL) {
321 » PORT_SetError(SEC_ERROR_INVALID_ARGS); 307 PORT_SetError(SEC_ERROR_INVALID_ARGS);
322 » return NULL; 308 return NULL;
323 } 309 }
324 /* TODO: mark arena */ 310 /* TODO: mark arena */
325 if (dest == NULL) { 311 if (dest == NULL) {
326 » dest = PORT_ArenaZNew(arena, SECItem); 312 dest = PORT_ArenaZNew(arena, SECItem);
327 » if (!dest) 313 if (!dest)
328 » goto loser; 314 goto loser;
329 } 315 }
330 if (genName->type == certDirectoryName) { 316 if (genName->type == certDirectoryName) {
331 » if (genName->derDirectoryName.data == NULL) { 317 if (genName->derDirectoryName.data == NULL) {
332 » /* The field hasn't been encoded yet. */ 318 /* The field hasn't been encoded yet. */
333 SECItem * pre_dest = 319 SECItem *pre_dest = SEC_ASN1EncodeItem(
334 SEC_ASN1EncodeItem (arena, &(genName->derDirectoryName), 320 arena, &(genName->derDirectoryName),
335 &(genName->name.directoryName), 321 &(genName->name.directoryName), CERT_NameTemplate);
336 CERT_NameTemplate);
337 if (!pre_dest) 322 if (!pre_dest)
338 goto loser; 323 goto loser;
339 » } 324 }
340 » if (genName->derDirectoryName.data == NULL) { 325 if (genName->derDirectoryName.data == NULL) {
341 » goto loser; 326 goto loser;
342 » } 327 }
343 } 328 }
344 switch (genName->type) { 329 switch (genName->type) {
345 case certURI: template = CERT_URITemplate; break; 330 case certURI:
346 case certRFC822Name: template = CERT_RFC822NameTemplate; break; 331 template = CERT_URITemplate;
347 case certDNSName: template = CERT_DNSNameTemplate; break; 332 break;
348 case certIPAddress: template = CERT_IPAddressTemplate; break; 333 case certRFC822Name:
349 case certOtherName: template = CERTOtherNameTemplate; break; 334 template = CERT_RFC822NameTemplate;
350 case certRegisterID: template = CERT_RegisteredIDTemplate; break; 335 break;
351 /* for this type, we expect the value is already encoded */ 336 case certDNSName:
352 case certEDIPartyName: template = CERT_EDIPartyNameTemplate; break; 337 template = CERT_DNSNameTemplate;
353 » /* for this type, we expect the value is already encoded */ 338 break;
354 case certX400Address: template = CERT_X400AddressTemplate; break; 339 case certIPAddress:
355 case certDirectoryName: template = CERT_DirectoryNameTemplate; break; 340 template = CERT_IPAddressTemplate;
356 default: 341 break;
357 » PORT_Assert(0); goto loser; 342 case certOtherName:
343 template = CERTOtherNameTemplate;
344 break;
345 case certRegisterID:
346 template = CERT_RegisteredIDTemplate;
347 break;
348 /* for this type, we expect the value is already encoded */
349 case certEDIPartyName:
350 template = CERT_EDIPartyNameTemplate;
351 break;
352 /* for this type, we expect the value is already encoded */
353 case certX400Address:
354 template = CERT_X400AddressTemplate;
355 break;
356 case certDirectoryName:
357 template = CERT_DirectoryNameTemplate;
358 break;
359 default:
360 PORT_Assert(0);
361 goto loser;
358 } 362 }
359 dest = SEC_ASN1EncodeItem(arena, dest, genName, template); 363 dest = SEC_ASN1EncodeItem(arena, dest, genName, template);
360 if (!dest) { 364 if (!dest) {
361 » goto loser; 365 goto loser;
362 } 366 }
363 /* TODO: unmark arena */ 367 /* TODO: unmark arena */
364 return dest; 368 return dest;
365 loser: 369 loser:
366 /* TODO: release arena back to mark */ 370 /* TODO: release arena back to mark */
367 return NULL; 371 return NULL;
368 } 372 }
369 373
370 SECItem ** 374 SECItem **
371 cert_EncodeGeneralNames(PLArenaPool *arena, CERTGeneralName *names) 375 cert_EncodeGeneralNames(PLArenaPool *arena, CERTGeneralName *names)
372 { 376 {
373 CERTGeneralName *current_name; 377 CERTGeneralName *current_name;
374 SECItem **items = NULL; 378 SECItem **items = NULL;
375 int count = 0; 379 int count = 0;
376 int i; 380 int i;
377 PRCList *head; 381 PRCList *head;
378 382
379 PORT_Assert(arena); 383 PORT_Assert(arena);
380 /* TODO: mark arena */ 384 /* TODO: mark arena */
381 current_name = names; 385 current_name = names;
382 if (names != NULL) { 386 if (names != NULL) {
383 » count = 1; 387 count = 1;
384 } 388 }
385 head = &(names->l); 389 head = &(names->l);
386 while (current_name->l.next != head) { 390 while (current_name->l.next != head) {
387 » current_name = CERT_GetNextGeneralName(current_name); 391 current_name = CERT_GetNextGeneralName(current_name);
388 » ++count; 392 ++count;
389 } 393 }
390 current_name = CERT_GetNextGeneralName(current_name); 394 current_name = CERT_GetNextGeneralName(current_name);
391 items = PORT_ArenaNewArray(arena, SECItem *, count + 1); 395 items = PORT_ArenaNewArray(arena, SECItem *, count + 1);
392 if (items == NULL) { 396 if (items == NULL) {
393 » goto loser; 397 goto loser;
394 } 398 }
395 for (i = 0; i < count; i++) { 399 for (i = 0; i < count; i++) {
396 » items[i] = CERT_EncodeGeneralName(current_name, (SECItem *)NULL, arena); 400 items[i] = CERT_EncodeGeneralName(current_name, (SECItem *)NULL, arena);
397 » if (items[i] == NULL) { 401 if (items[i] == NULL) {
398 » goto loser; 402 goto loser;
399 » } 403 }
400 » current_name = CERT_GetNextGeneralName(current_name); 404 current_name = CERT_GetNextGeneralName(current_name);
401 } 405 }
402 items[i] = NULL; 406 items[i] = NULL;
403 /* TODO: unmark arena */ 407 /* TODO: unmark arena */
404 return items; 408 return items;
405 loser: 409 loser:
406 /* TODO: release arena to mark */ 410 /* TODO: release arena to mark */
407 return NULL; 411 return NULL;
408 } 412 }
409 413
410 CERTGeneralName * 414 CERTGeneralName *
411 CERT_DecodeGeneralName(PLArenaPool *reqArena, 415 CERT_DecodeGeneralName(PLArenaPool *reqArena, SECItem *encodedName,
412 » » SECItem *encodedName, 416 CERTGeneralName *genName)
413 » » CERTGeneralName *genName)
414 { 417 {
415 const SEC_ASN1Template * template; 418 const SEC_ASN1Template *template;
416 CERTGeneralNameType genNameType; 419 CERTGeneralNameType genNameType;
417 SECStatus rv = SECSuccess; 420 SECStatus rv = SECSuccess;
418 SECItem* newEncodedName; 421 SECItem *newEncodedName;
419 422
420 if (!reqArena) { 423 if (!reqArena) {
421 PORT_SetError(SEC_ERROR_INVALID_ARGS); 424 PORT_SetError(SEC_ERROR_INVALID_ARGS);
422 return NULL; 425 return NULL;
423 } 426 }
424 /* make a copy for decoding so the data decoded with QuickDER doesn't 427 /* make a copy for decoding so the data decoded with QuickDER doesn't
425 point to temporary memory */ 428 point to temporary memory */
426 newEncodedName = SECITEM_ArenaDupItem(reqArena, encodedName); 429 newEncodedName = SECITEM_ArenaDupItem(reqArena, encodedName);
427 if (!newEncodedName) { 430 if (!newEncodedName) {
428 return NULL; 431 return NULL;
429 } 432 }
430 /* TODO: mark arena */ 433 /* TODO: mark arena */
431 genNameType = (CERTGeneralNameType)((*(newEncodedName->data) & 0x0f) + 1); 434 genNameType = (CERTGeneralNameType)((*(newEncodedName->data) & 0x0f) + 1);
432 if (genName == NULL) { 435 if (genName == NULL) {
433 » genName = CERT_NewGeneralName(reqArena, genNameType); 436 genName = CERT_NewGeneralName(reqArena, genNameType);
434 » if (!genName) 437 if (!genName)
435 » goto loser; 438 goto loser;
436 } else { 439 } else {
437 » genName->type = genNameType; 440 genName->type = genNameType;
438 » genName->l.prev = genName->l.next = &genName->l; 441 genName->l.prev = genName->l.next = &genName->l;
439 } 442 }
440 443
441 switch (genNameType) { 444 switch (genNameType) {
442 case certURI: » » template = CERT_URITemplate; break; 445 case certURI:
443 case certRFC822Name: » template = CERT_RFC822NameTemplate; break; 446 template = CERT_URITemplate;
444 case certDNSName: » » template = CERT_DNSNameTemplate; break; 447 break;
445 case certIPAddress: » template = CERT_IPAddressTemplate; break; 448 case certRFC822Name:
446 case certOtherName: » template = CERTOtherNameTemplate; break; 449 template = CERT_RFC822NameTemplate;
447 case certRegisterID: » template = CERT_RegisteredIDTemplate; break; 450 break;
448 case certEDIPartyName: » template = CERT_EDIPartyNameTemplate; break; 451 case certDNSName:
449 case certX400Address: » template = CERT_X400AddressTemplate; break; 452 template = CERT_DNSNameTemplate;
450 case certDirectoryName: » template = CERT_DirectoryNameTemplate; break; 453 break;
451 default: 454 case certIPAddress:
452 goto loser; 455 template = CERT_IPAddressTemplate;
456 break;
457 case certOtherName:
458 template = CERTOtherNameTemplate;
459 break;
460 case certRegisterID:
461 template = CERT_RegisteredIDTemplate;
462 break;
463 case certEDIPartyName:
464 template = CERT_EDIPartyNameTemplate;
465 break;
466 case certX400Address:
467 template = CERT_X400AddressTemplate;
468 break;
469 case certDirectoryName:
470 template = CERT_DirectoryNameTemplate;
471 break;
472 default:
473 goto loser;
453 } 474 }
454 rv = SEC_QuickDERDecodeItem(reqArena, genName, template, newEncodedName); 475 rv = SEC_QuickDERDecodeItem(reqArena, genName, template, newEncodedName);
455 if (rv != SECSuccess) 476 if (rv != SECSuccess)
456 » goto loser; 477 goto loser;
457 if (genNameType == certDirectoryName) { 478 if (genNameType == certDirectoryName) {
458 » rv = SEC_QuickDERDecodeItem(reqArena, &(genName->name.directoryName), 479 rv = SEC_QuickDERDecodeItem(reqArena, &(genName->name.directoryName),
459 » » » » CERT_NameTemplate, 480 CERT_NameTemplate,
460 » » » » &(genName->derDirectoryName)); 481 &(genName->derDirectoryName));
461 if (rv != SECSuccess) 482 if (rv != SECSuccess)
462 » goto loser; 483 goto loser;
463 } 484 }
464 485
465 /* TODO: unmark arena */ 486 /* TODO: unmark arena */
466 return genName; 487 return genName;
467 loser: 488 loser:
468 /* TODO: release arena to mark */ 489 /* TODO: release arena to mark */
469 return NULL; 490 return NULL;
470 } 491 }
471 492
472 CERTGeneralName * 493 CERTGeneralName *
473 cert_DecodeGeneralNames (PLArenaPool *arena, 494 cert_DecodeGeneralNames(PLArenaPool *arena, SECItem **encodedGenName)
474 » » » SECItem **encodedGenName)
475 { 495 {
476 PRCList *head = NULL; 496 PRCList *head = NULL;
477 PRCList *tail = NULL; 497 PRCList *tail = NULL;
478 CERTGeneralName *currentName = NULL; 498 CERTGeneralName *currentName = NULL;
479 499
480 PORT_Assert(arena); 500 PORT_Assert(arena);
481 if (!encodedGenName || !arena) { 501 if (!encodedGenName || !arena) {
482 » PORT_SetError(SEC_ERROR_INVALID_ARGS); 502 PORT_SetError(SEC_ERROR_INVALID_ARGS);
483 » return NULL; 503 return NULL;
484 } 504 }
485 /* TODO: mark arena */ 505 /* TODO: mark arena */
486 while (*encodedGenName != NULL) { 506 while (*encodedGenName != NULL) {
487 » currentName = CERT_DecodeGeneralName(arena, *encodedGenName, NULL); 507 currentName = CERT_DecodeGeneralName(arena, *encodedGenName, NULL);
488 » if (currentName == NULL) 508 if (currentName == NULL)
489 » break; 509 break;
490 » if (head == NULL) { 510 if (head == NULL) {
491 » head = &(currentName->l); 511 head = &(currentName->l);
492 » tail = head; 512 tail = head;
493 » } 513 }
494 » currentName->l.next = head; 514 currentName->l.next = head;
495 » currentName->l.prev = tail; 515 currentName->l.prev = tail;
496 » tail = head->prev = tail->next = &(currentName->l); 516 tail = head->prev = tail->next = &(currentName->l);
497 » encodedGenName++; 517 encodedGenName++;
498 } 518 }
499 if (currentName) { 519 if (currentName) {
500 » /* TODO: unmark arena */ 520 /* TODO: unmark arena */
501 » return CERT_GetNextGeneralName(currentName); 521 return CERT_GetNextGeneralName(currentName);
502 } 522 }
503 /* TODO: release arena to mark */ 523 /* TODO: release arena to mark */
504 return NULL; 524 return NULL;
505 } 525 }
506 526
507 void 527 void
508 CERT_DestroyGeneralName(CERTGeneralName *name) 528 CERT_DestroyGeneralName(CERTGeneralName *name)
509 { 529 {
510 cert_DestroyGeneralNames(name); 530 cert_DestroyGeneralNames(name);
511 } 531 }
512 532
513 SECStatus 533 SECStatus
514 cert_DestroyGeneralNames(CERTGeneralName *name) 534 cert_DestroyGeneralNames(CERTGeneralName *name)
515 { 535 {
516 CERTGeneralName *first; 536 CERTGeneralName *first;
517 CERTGeneralName *next = NULL; 537 CERTGeneralName *next = NULL;
518
519 538
520 first = name; 539 first = name;
521 do { 540 do {
522 » next = CERT_GetNextGeneralName(name); 541 next = CERT_GetNextGeneralName(name);
523 » PORT_Free(name); 542 PORT_Free(name);
524 » name = next; 543 name = next;
525 } while (name != first); 544 } while (name != first);
526 return SECSuccess; 545 return SECSuccess;
527 } 546 }
528 547
529 static SECItem * 548 static SECItem *
530 cert_EncodeNameConstraint(CERTNameConstraint *constraint, 549 cert_EncodeNameConstraint(CERTNameConstraint *constraint, SECItem *dest,
531 » » » SECItem *dest, 550 PLArenaPool *arena)
532 » » » PLArenaPool *arena)
533 { 551 {
534 PORT_Assert(arena); 552 PORT_Assert(arena);
535 if (dest == NULL) { 553 if (dest == NULL) {
536 » dest = PORT_ArenaZNew(arena, SECItem); 554 dest = PORT_ArenaZNew(arena, SECItem);
537 » if (dest == NULL) { 555 if (dest == NULL) {
538 » return NULL; 556 return NULL;
539 » } 557 }
540 } 558 }
541 CERT_EncodeGeneralName(&(constraint->name), &(constraint->DERName), arena); 559 CERT_EncodeGeneralName(&(constraint->name), &(constraint->DERName), arena);
542 560
543 dest = SEC_ASN1EncodeItem (arena, dest, constraint, 561 dest =
544 » » » CERTNameConstraintTemplate); 562 SEC_ASN1EncodeItem(arena, dest, constraint, CERTNameConstraintTemplate);
545 return dest; 563 return dest;
546 } 564 }
547 565
548 SECStatus 566 SECStatus
549 cert_EncodeNameConstraintSubTree(CERTNameConstraint *constraints, 567 cert_EncodeNameConstraintSubTree(CERTNameConstraint *constraints,
550 » » » PLArenaPool *arena, 568 PLArenaPool *arena, SECItem ***dest,
551 » » » » SECItem ***dest, 569 PRBool permited)
552 » » » » PRBool permited)
553 { 570 {
554 CERTNameConstraint *current_constraint = constraints; 571 CERTNameConstraint *current_constraint = constraints;
555 SECItem **items = NULL; 572 SECItem **items = NULL;
556 int count = 0; 573 int count = 0;
557 int i; 574 int i;
558 PRCList *head; 575 PRCList *head;
559 576
560 PORT_Assert(arena); 577 PORT_Assert(arena);
561 /* TODO: mark arena */ 578 /* TODO: mark arena */
562 if (constraints != NULL) { 579 if (constraints != NULL) {
563 » count = 1; 580 count = 1;
564 } 581 }
565 head = &constraints->l; 582 head = &constraints->l;
566 while (current_constraint->l.next != head) { 583 while (current_constraint->l.next != head) {
567 » current_constraint = CERT_GetNextNameConstraint(current_constraint); 584 current_constraint = CERT_GetNextNameConstraint(current_constraint);
568 » ++count; 585 ++count;
569 } 586 }
570 current_constraint = CERT_GetNextNameConstraint(current_constraint); 587 current_constraint = CERT_GetNextNameConstraint(current_constraint);
571 items = PORT_ArenaZNewArray(arena, SECItem *, count + 1); 588 items = PORT_ArenaZNewArray(arena, SECItem *, count + 1);
572 if (items == NULL) { 589 if (items == NULL) {
573 » goto loser; 590 goto loser;
574 } 591 }
575 for (i = 0; i < count; i++) { 592 for (i = 0; i < count; i++) {
576 » items[i] = cert_EncodeNameConstraint(current_constraint, 593 items[i] = cert_EncodeNameConstraint(current_constraint,
577 » » » » » (SECItem *) NULL, arena); 594 (SECItem *)NULL, arena);
578 » if (items[i] == NULL) { 595 if (items[i] == NULL) {
579 » goto loser; 596 goto loser;
580 » } 597 }
581 » current_constraint = CERT_GetNextNameConstraint(current_constraint); 598 current_constraint = CERT_GetNextNameConstraint(current_constraint);
582 } 599 }
583 *dest = items; 600 *dest = items;
584 if (*dest == NULL) { 601 if (*dest == NULL) {
585 » goto loser; 602 goto loser;
586 } 603 }
587 /* TODO: unmark arena */ 604 /* TODO: unmark arena */
588 return SECSuccess; 605 return SECSuccess;
589 loser: 606 loser:
590 /* TODO: release arena to mark */ 607 /* TODO: release arena to mark */
591 return SECFailure; 608 return SECFailure;
592 } 609 }
593 610
594 SECStatus 611 SECStatus
595 cert_EncodeNameConstraints(CERTNameConstraints *constraints, 612 cert_EncodeNameConstraints(CERTNameConstraints *constraints, PLArenaPool *arena,
596 » » » PLArenaPool *arena, 613 SECItem *dest)
597 » » » SECItem *dest)
598 { 614 {
599 SECStatus rv = SECSuccess; 615 SECStatus rv = SECSuccess;
600 616
601 PORT_Assert(arena); 617 PORT_Assert(arena);
602 /* TODO: mark arena */ 618 /* TODO: mark arena */
603 if (constraints->permited != NULL) { 619 if (constraints->permited != NULL) {
604 » rv = cert_EncodeNameConstraintSubTree(constraints->permited, arena, 620 rv = cert_EncodeNameConstraintSubTree(
605 » » » » » &constraints->DERPermited, 621 constraints->permited, arena, &constraints->DERPermited, PR_TRUE);
606 » » » » » PR_TRUE); 622 if (rv == SECFailure) {
607 » if (rv == SECFailure) { 623 goto loser;
608 » goto loser; 624 }
609 » }
610 } 625 }
611 if (constraints->excluded != NULL) { 626 if (constraints->excluded != NULL) {
612 » rv = cert_EncodeNameConstraintSubTree(constraints->excluded, arena, 627 rv = cert_EncodeNameConstraintSubTree(
613 » » » » » &constraints->DERExcluded, 628 constraints->excluded, arena, &constraints->DERExcluded, PR_FALSE);
614 » » » » » PR_FALSE); 629 if (rv == SECFailure) {
615 » if (rv == SECFailure) { 630 goto loser;
616 » goto loser; 631 }
617 » }
618 } 632 }
619 dest = SEC_ASN1EncodeItem(arena, dest, constraints, 633 dest = SEC_ASN1EncodeItem(arena, dest, constraints,
620 » » » CERTNameConstraintsTemplate); 634 CERTNameConstraintsTemplate);
621 if (dest == NULL) { 635 if (dest == NULL) {
622 » goto loser; 636 goto loser;
623 } 637 }
624 /* TODO: unmark arena */ 638 /* TODO: unmark arena */
625 return SECSuccess; 639 return SECSuccess;
626 loser: 640 loser:
627 /* TODO: release arena to mark */ 641 /* TODO: release arena to mark */
628 return SECFailure; 642 return SECFailure;
629 } 643 }
630 644
631
632 CERTNameConstraint * 645 CERTNameConstraint *
633 cert_DecodeNameConstraint(PLArenaPool *reqArena, 646 cert_DecodeNameConstraint(PLArenaPool *reqArena, SECItem *encodedConstraint)
634 » » » SECItem *encodedConstraint)
635 { 647 {
636 CERTNameConstraint *constraint; 648 CERTNameConstraint *constraint;
637 SECStatus rv = SECSuccess; 649 SECStatus rv = SECSuccess;
638 CERTGeneralName *temp; 650 CERTGeneralName *temp;
639 SECItem* newEncodedConstraint; 651 SECItem *newEncodedConstraint;
640 652
641 if (!reqArena) { 653 if (!reqArena) {
642 PORT_SetError(SEC_ERROR_INVALID_ARGS); 654 PORT_SetError(SEC_ERROR_INVALID_ARGS);
643 return NULL; 655 return NULL;
644 } 656 }
645 newEncodedConstraint = SECITEM_ArenaDupItem(reqArena, encodedConstraint); 657 newEncodedConstraint = SECITEM_ArenaDupItem(reqArena, encodedConstraint);
646 if (!newEncodedConstraint) { 658 if (!newEncodedConstraint) {
647 return NULL; 659 return NULL;
648 } 660 }
649 /* TODO: mark arena */ 661 /* TODO: mark arena */
650 constraint = PORT_ArenaZNew(reqArena, CERTNameConstraint); 662 constraint = PORT_ArenaZNew(reqArena, CERTNameConstraint);
651 if (!constraint) 663 if (!constraint)
652 » goto loser; 664 goto loser;
653 rv = SEC_QuickDERDecodeItem(reqArena, constraint, 665 rv = SEC_QuickDERDecodeItem(
654 CERTNameConstraintTemplate, 666 reqArena, constraint, CERTNameConstraintTemplate, newEncodedConstraint);
655 newEncodedConstraint);
656 if (rv != SECSuccess) { 667 if (rv != SECSuccess) {
657 » goto loser; 668 goto loser;
658 } 669 }
659 temp = CERT_DecodeGeneralName(reqArena, &(constraint->DERName), 670 temp = CERT_DecodeGeneralName(reqArena, &(constraint->DERName),
660 &(constraint->name)); 671 &(constraint->name));
661 if (temp != &(constraint->name)) { 672 if (temp != &(constraint->name)) {
662 » goto loser; 673 goto loser;
663 } 674 }
664 675
665 /* ### sjlee: since the name constraint contains only one 676 /* ### sjlee: since the name constraint contains only one
666 * CERTGeneralName, the list within CERTGeneralName shouldn't 677 * CERTGeneralName, the list within CERTGeneralName shouldn't
667 * point anywhere else. Otherwise, bad things will happen. 678 * point anywhere else. Otherwise, bad things will happen.
668 */ 679 */
669 constraint->name.l.prev = constraint->name.l.next = &(constraint->name.l); 680 constraint->name.l.prev = constraint->name.l.next = &(constraint->name.l);
670 /* TODO: unmark arena */ 681 /* TODO: unmark arena */
671 return constraint; 682 return constraint;
672 loser: 683 loser:
673 /* TODO: release arena back to mark */ 684 /* TODO: release arena back to mark */
674 return NULL; 685 return NULL;
675 } 686 }
676 687
677 static CERTNameConstraint * 688 static CERTNameConstraint *
678 cert_DecodeNameConstraintSubTree(PLArenaPool *arena, 689 cert_DecodeNameConstraintSubTree(PLArenaPool *arena, SECItem **subTree,
679 » » » » SECItem **subTree, 690 PRBool permited)
680 » » » » PRBool permited)
681 { 691 {
682 CERTNameConstraint *current = NULL; 692 CERTNameConstraint *current = NULL;
683 CERTNameConstraint *first = NULL; 693 CERTNameConstraint *first = NULL;
684 CERTNameConstraint *last = NULL; 694 CERTNameConstraint *last = NULL;
685 int i = 0; 695 int i = 0;
686 696
687 PORT_Assert(arena); 697 PORT_Assert(arena);
688 /* TODO: mark arena */ 698 /* TODO: mark arena */
689 while (subTree[i] != NULL) { 699 while (subTree[i] != NULL) {
690 » current = cert_DecodeNameConstraint(arena, subTree[i]); 700 current = cert_DecodeNameConstraint(arena, subTree[i]);
691 » if (current == NULL) { 701 if (current == NULL) {
692 » goto loser; 702 goto loser;
693 » } 703 }
694 » if (first == NULL) { 704 if (first == NULL) {
695 » first = current; 705 first = current;
696 » } else { 706 } else {
697 » current->l.prev = &(last->l); 707 current->l.prev = &(last->l);
698 » last->l.next = &(current->l); 708 last->l.next = &(current->l);
699 » } 709 }
700 » last = current; 710 last = current;
701 » i++; 711 i++;
702 } 712 }
703 first->l.prev = &(last->l); 713 first->l.prev = &(last->l);
704 last->l.next = &(first->l); 714 last->l.next = &(first->l);
705 /* TODO: unmark arena */ 715 /* TODO: unmark arena */
706 return first; 716 return first;
707 loser: 717 loser:
708 /* TODO: release arena back to mark */ 718 /* TODO: release arena back to mark */
709 return NULL; 719 return NULL;
710 } 720 }
711 721
712 CERTNameConstraints * 722 CERTNameConstraints *
713 cert_DecodeNameConstraints(PLArenaPool *reqArena, 723 cert_DecodeNameConstraints(PLArenaPool *reqArena,
714 » » » const SECItem *encodedConstraints) 724 const SECItem *encodedConstraints)
715 { 725 {
716 CERTNameConstraints *constraints; 726 CERTNameConstraints *constraints;
717 SECStatus rv; 727 SECStatus rv;
718 SECItem* newEncodedConstraints; 728 SECItem *newEncodedConstraints;
719 729
720 if (!reqArena) { 730 if (!reqArena) {
721 PORT_SetError(SEC_ERROR_INVALID_ARGS); 731 PORT_SetError(SEC_ERROR_INVALID_ARGS);
722 return NULL; 732 return NULL;
723 } 733 }
724 PORT_Assert(encodedConstraints); 734 PORT_Assert(encodedConstraints);
725 newEncodedConstraints = SECITEM_ArenaDupItem(reqArena, encodedConstraints); 735 newEncodedConstraints = SECITEM_ArenaDupItem(reqArena, encodedConstraints);
726 736
727 /* TODO: mark arena */ 737 /* TODO: mark arena */
728 constraints = PORT_ArenaZNew(reqArena, CERTNameConstraints); 738 constraints = PORT_ArenaZNew(reqArena, CERTNameConstraints);
729 if (constraints == NULL) { 739 if (constraints == NULL) {
730 » goto loser; 740 goto loser;
731 } 741 }
732 rv = SEC_QuickDERDecodeItem(reqArena, constraints, 742 rv = SEC_QuickDERDecodeItem(reqArena, constraints,
733 CERTNameConstraintsTemplate, 743 CERTNameConstraintsTemplate,
734 newEncodedConstraints); 744 newEncodedConstraints);
735 if (rv != SECSuccess) { 745 if (rv != SECSuccess) {
736 » goto loser; 746 goto loser;
737 } 747 }
738 if (constraints->DERPermited != NULL && 748 if (constraints->DERPermited != NULL &&
739 constraints->DERPermited[0] != NULL) { 749 constraints->DERPermited[0] != NULL) {
740 » constraints->permited = 750 constraints->permited = cert_DecodeNameConstraintSubTree(
741 » cert_DecodeNameConstraintSubTree(reqArena, 751 reqArena, constraints->DERPermited, PR_TRUE);
742 constraints->DERPermited, 752 if (constraints->permited == NULL) {
743 PR_TRUE); 753 goto loser;
744 » if (constraints->permited == NULL) { 754 }
745 » goto loser;
746 » }
747 } 755 }
748 if (constraints->DERExcluded != NULL && 756 if (constraints->DERExcluded != NULL &&
749 constraints->DERExcluded[0] != NULL) { 757 constraints->DERExcluded[0] != NULL) {
750 » constraints->excluded = 758 constraints->excluded = cert_DecodeNameConstraintSubTree(
751 » cert_DecodeNameConstraintSubTree(reqArena, 759 reqArena, constraints->DERExcluded, PR_FALSE);
752 constraints->DERExcluded, 760 if (constraints->excluded == NULL) {
753 PR_FALSE); 761 goto loser;
754 » if (constraints->excluded == NULL) { 762 }
755 » goto loser;
756 » }
757 } 763 }
758 /* TODO: unmark arena */ 764 /* TODO: unmark arena */
759 return constraints; 765 return constraints;
760 loser: 766 loser:
761 /* TODO: release arena back to mark */ 767 /* TODO: release arena back to mark */
762 return NULL; 768 return NULL;
763 } 769 }
764 770
765 /* Copy a chain of one or more general names to a destination chain. 771 /* Copy a chain of one or more general names to a destination chain.
766 ** Caller has allocated at least the first destination GeneralName struct. 772 ** Caller has allocated at least the first destination GeneralName struct.
767 ** Both source and destination chains are circular doubly-linked lists. 773 ** Both source and destination chains are circular doubly-linked lists.
768 ** The first source struct is copied to the first destination struct. 774 ** The first source struct is copied to the first destination struct.
769 ** If the source chain has more than one member, and the destination chain 775 ** If the source chain has more than one member, and the destination chain
770 ** has only one member, then this function allocates new structs for all but 776 ** has only one member, then this function allocates new structs for all but
771 ** the first copy from the arena and links them into the destination list. 777 ** the first copy from the arena and links them into the destination list.
772 ** If the destination struct is part of a list with more than one member, 778 ** If the destination struct is part of a list with more than one member,
773 ** then this function traverses both the source and destination lists, 779 ** then this function traverses both the source and destination lists,
774 ** copying each source struct to the corresponding dest struct. 780 ** copying each source struct to the corresponding dest struct.
775 ** In that case, the destination list MUST contain at least as many 781 ** In that case, the destination list MUST contain at least as many
776 ** structs as the source list or some dest entries will be overwritten. 782 ** structs as the source list or some dest entries will be overwritten.
777 */ 783 */
778 SECStatus 784 SECStatus
779 CERT_CopyGeneralName(PLArenaPool *arena, 785 CERT_CopyGeneralName(PLArenaPool *arena, CERTGeneralName *dest,
780 » » CERTGeneralName *dest, 786 CERTGeneralName *src)
781 » » CERTGeneralName *src)
782 { 787 {
783 SECStatus rv; 788 SECStatus rv;
784 CERTGeneralName *destHead = dest; 789 CERTGeneralName *destHead = dest;
785 CERTGeneralName *srcHead = src; 790 CERTGeneralName *srcHead = src;
786 791
787 PORT_Assert(dest != NULL); 792 PORT_Assert(dest != NULL);
788 if (!dest) { 793 if (!dest) {
789 » PORT_SetError(SEC_ERROR_INVALID_ARGS); 794 PORT_SetError(SEC_ERROR_INVALID_ARGS);
790 return SECFailure; 795 return SECFailure;
791 } 796 }
792 /* TODO: mark arena */ 797 /* TODO: mark arena */
793 do { 798 do {
794 » rv = cert_CopyOneGeneralName(arena, dest, src); 799 rv = cert_CopyOneGeneralName(arena, dest, src);
795 » if (rv != SECSuccess) 800 if (rv != SECSuccess)
796 » goto loser; 801 goto loser;
797 » src = CERT_GetNextGeneralName(src); 802 src = CERT_GetNextGeneralName(src);
798 » /* if there is only one general name, we shouldn't do this */ 803 /* if there is only one general name, we shouldn't do this */
799 » if (src != srcHead) { 804 if (src != srcHead) {
800 » if (dest->l.next == &destHead->l) { 805 if (dest->l.next == &destHead->l) {
801 » » CERTGeneralName *temp; 806 CERTGeneralName *temp;
802 » » temp = CERT_NewGeneralName(arena, (CERTGeneralNameType)0); 807 temp = CERT_NewGeneralName(arena, (CERTGeneralNameType)0);
803 » » if (!temp) 808 if (!temp)
804 » » goto loser; 809 goto loser;
805 » » temp->l.next = &destHead->l; 810 temp->l.next = &destHead->l;
806 » » temp->l.prev = &dest->l; 811 temp->l.prev = &dest->l;
807 » » destHead->l.prev = &temp->l; 812 destHead->l.prev = &temp->l;
808 » » dest->l.next = &temp->l; 813 dest->l.next = &temp->l;
809 » » dest = temp; 814 dest = temp;
810 » } else { 815 } else {
811 » » dest = CERT_GetNextGeneralName(dest); 816 dest = CERT_GetNextGeneralName(dest);
812 » } 817 }
813 » } 818 }
814 } while (src != srcHead && rv == SECSuccess); 819 } while (src != srcHead && rv == SECSuccess);
815 /* TODO: unmark arena */ 820 /* TODO: unmark arena */
816 return rv; 821 return rv;
817 loser: 822 loser:
818 /* TODO: release back to mark */ 823 /* TODO: release back to mark */
819 return SECFailure; 824 return SECFailure;
820 } 825 }
821 826
822
823 CERTGeneralNameList * 827 CERTGeneralNameList *
824 CERT_DupGeneralNameList(CERTGeneralNameList *list) 828 CERT_DupGeneralNameList(CERTGeneralNameList *list)
825 { 829 {
826 if (list != NULL) { 830 if (list != NULL) {
827 » PZ_Lock(list->lock); 831 PZ_Lock(list->lock);
828 » list->refCount++; 832 list->refCount++;
829 » PZ_Unlock(list->lock); 833 PZ_Unlock(list->lock);
830 } 834 }
831 return list; 835 return list;
832 } 836 }
833 837
834 /* Allocate space and copy CERTNameConstraint from src to dest */ 838 /* Allocate space and copy CERTNameConstraint from src to dest */
835 CERTNameConstraint * 839 CERTNameConstraint *
836 CERT_CopyNameConstraint(PLArenaPool *arena, 840 CERT_CopyNameConstraint(PLArenaPool *arena, CERTNameConstraint *dest,
837 » » » CERTNameConstraint *dest, 841 CERTNameConstraint *src)
838 » » » CERTNameConstraint *src)
839 { 842 {
840 SECStatus rv; 843 SECStatus rv;
841 844
842 /* TODO: mark arena */ 845 /* TODO: mark arena */
843 if (dest == NULL) { 846 if (dest == NULL) {
844 » dest = PORT_ArenaZNew(arena, CERTNameConstraint); 847 dest = PORT_ArenaZNew(arena, CERTNameConstraint);
845 » if (!dest) 848 if (!dest)
846 » goto loser; 849 goto loser;
847 » /* mark that it is not linked */ 850 /* mark that it is not linked */
848 » dest->name.l.prev = dest->name.l.next = &(dest->name.l); 851 dest->name.l.prev = dest->name.l.next = &(dest->name.l);
849 } 852 }
850 rv = CERT_CopyGeneralName(arena, &dest->name, &src->name); 853 rv = CERT_CopyGeneralName(arena, &dest->name, &src->name);
851 if (rv != SECSuccess) { 854 if (rv != SECSuccess) {
852 » goto loser; 855 goto loser;
853 } 856 }
854 rv = SECITEM_CopyItem(arena, &dest->DERName, &src->DERName); 857 rv = SECITEM_CopyItem(arena, &dest->DERName, &src->DERName);
855 if (rv != SECSuccess) { 858 if (rv != SECSuccess) {
856 » goto loser; 859 goto loser;
857 } 860 }
858 rv = SECITEM_CopyItem(arena, &dest->min, &src->min); 861 rv = SECITEM_CopyItem(arena, &dest->min, &src->min);
859 if (rv != SECSuccess) { 862 if (rv != SECSuccess) {
860 » goto loser; 863 goto loser;
861 } 864 }
862 rv = SECITEM_CopyItem(arena, &dest->max, &src->max); 865 rv = SECITEM_CopyItem(arena, &dest->max, &src->max);
863 if (rv != SECSuccess) { 866 if (rv != SECSuccess) {
864 » goto loser; 867 goto loser;
865 } 868 }
866 dest->l.prev = dest->l.next = &dest->l; 869 dest->l.prev = dest->l.next = &dest->l;
867 /* TODO: unmark arena */ 870 /* TODO: unmark arena */
868 return dest; 871 return dest;
869 loser: 872 loser:
870 /* TODO: release arena to mark */ 873 /* TODO: release arena to mark */
871 return NULL; 874 return NULL;
872 } 875 }
873 876
874
875 CERTGeneralName * 877 CERTGeneralName *
876 cert_CombineNamesLists(CERTGeneralName *list1, CERTGeneralName *list2) 878 cert_CombineNamesLists(CERTGeneralName *list1, CERTGeneralName *list2)
877 { 879 {
878 PRCList *begin1; 880 PRCList *begin1;
879 PRCList *begin2; 881 PRCList *begin2;
880 PRCList *end1; 882 PRCList *end1;
881 PRCList *end2; 883 PRCList *end2;
882 884
883 if (list1 == NULL){ 885 if (list1 == NULL) {
884 » return list2; 886 return list2;
885 } else if (list2 == NULL) { 887 } else if (list2 == NULL) {
886 » return list1; 888 return list1;
887 } else { 889 } else {
888 » begin1 = &list1->l; 890 begin1 = &list1->l;
889 » begin2 = &list2->l; 891 begin2 = &list2->l;
890 » end1 = list1->l.prev; 892 end1 = list1->l.prev;
891 » end2 = list2->l.prev; 893 end2 = list2->l.prev;
892 » end1->next = begin2; 894 end1->next = begin2;
893 » end2->next = begin1; 895 end2->next = begin1;
894 » begin1->prev = end2; 896 begin1->prev = end2;
895 » begin2->prev = end1; 897 begin2->prev = end1;
896 » return list1; 898 return list1;
897 } 899 }
898 } 900 }
899 901
900
901 CERTNameConstraint * 902 CERTNameConstraint *
902 cert_CombineConstraintsLists(CERTNameConstraint *list1, CERTNameConstraint *list 2) 903 cert_CombineConstraintsLists(CERTNameConstraint *list1,
904 CERTNameConstraint *list2)
903 { 905 {
904 PRCList *begin1; 906 PRCList *begin1;
905 PRCList *begin2; 907 PRCList *begin2;
906 PRCList *end1; 908 PRCList *end1;
907 PRCList *end2; 909 PRCList *end2;
908 910
909 if (list1 == NULL){ 911 if (list1 == NULL) {
910 » return list2; 912 return list2;
911 } else if (list2 == NULL) { 913 } else if (list2 == NULL) {
912 » return list1; 914 return list1;
913 } else { 915 } else {
914 » begin1 = &list1->l; 916 begin1 = &list1->l;
915 » begin2 = &list2->l; 917 begin2 = &list2->l;
916 » end1 = list1->l.prev; 918 end1 = list1->l.prev;
917 » end2 = list2->l.prev; 919 end2 = list2->l.prev;
918 » end1->next = begin2; 920 end1->next = begin2;
919 » end2->next = begin1; 921 end2->next = begin1;
920 » begin1->prev = end2; 922 begin1->prev = end2;
921 » begin2->prev = end1; 923 begin2->prev = end1;
922 » return list1; 924 return list1;
923 } 925 }
924 } 926 }
925 927
926
927 /* Add a CERTNameConstraint to the CERTNameConstraint list */ 928 /* Add a CERTNameConstraint to the CERTNameConstraint list */
928 CERTNameConstraint * 929 CERTNameConstraint *
929 CERT_AddNameConstraint(CERTNameConstraint *list, 930 CERT_AddNameConstraint(CERTNameConstraint *list, CERTNameConstraint *constraint)
930 » » CERTNameConstraint *constraint)
931 { 931 {
932 PORT_Assert(constraint != NULL); 932 PORT_Assert(constraint != NULL);
933 constraint->l.next = constraint->l.prev = &constraint->l; 933 constraint->l.next = constraint->l.prev = &constraint->l;
934 list = cert_CombineConstraintsLists(list, constraint); 934 list = cert_CombineConstraintsLists(list, constraint);
935 return list; 935 return list;
936 } 936 }
937 937
938
939 SECStatus 938 SECStatus
940 CERT_GetNameConstraintByType (CERTNameConstraint *constraints, 939 CERT_GetNameConstraintByType(CERTNameConstraint *constraints,
941 » » » CERTGeneralNameType type, 940 CERTGeneralNameType type,
942 » » » CERTNameConstraint **returnList, 941 CERTNameConstraint **returnList,
943 » » » PLArenaPool *arena) 942 PLArenaPool *arena)
944 { 943 {
945 CERTNameConstraint *current = NULL; 944 CERTNameConstraint *current = NULL;
946 void *mark = NULL; 945 void *mark = NULL;
947 946
948 *returnList = NULL; 947 *returnList = NULL;
949 if (!constraints) 948 if (!constraints)
950 » return SECSuccess; 949 return SECSuccess;
951 950
952 mark = PORT_ArenaMark(arena); 951 mark = PORT_ArenaMark(arena);
953 952
954 current = constraints; 953 current = constraints;
955 do { 954 do {
956 » PORT_Assert(current->name.type); 955 PORT_Assert(current->name.type);
957 » if (current->name.type == type) { 956 if (current->name.type == type) {
958 » CERTNameConstraint *temp; 957 CERTNameConstraint *temp;
959 » temp = CERT_CopyNameConstraint(arena, NULL, current); 958 temp = CERT_CopyNameConstraint(arena, NULL, current);
960 » if (temp == NULL) 959 if (temp == NULL)
961 » » goto loser; 960 goto loser;
962 » *returnList = CERT_AddNameConstraint(*returnList, temp); 961 *returnList = CERT_AddNameConstraint(*returnList, temp);
963 » } 962 }
964 » current = CERT_GetNextNameConstraint(current); 963 current = CERT_GetNextNameConstraint(current);
965 } while (current != constraints); 964 } while (current != constraints);
966 PORT_ArenaUnmark(arena, mark); 965 PORT_ArenaUnmark(arena, mark);
967 return SECSuccess; 966 return SECSuccess;
968 967
969 loser: 968 loser:
970 PORT_ArenaRelease(arena, mark); 969 PORT_ArenaRelease(arena, mark);
971 return SECFailure; 970 return SECFailure;
972 } 971 }
973 972
974 void * 973 void *
975 CERT_GetGeneralNameByType (CERTGeneralName *genNames, 974 CERT_GetGeneralNameByType(CERTGeneralName *genNames, CERTGeneralNameType type,
976 » » » CERTGeneralNameType type, PRBool derFormat) 975 PRBool derFormat)
977 { 976 {
978 CERTGeneralName *current; 977 CERTGeneralName *current;
979 978
980 if (!genNames) 979 if (!genNames)
981 » return NULL; 980 return NULL;
982 current = genNames; 981 current = genNames;
983 982
984 do { 983 do {
985 » if (current->type == type) { 984 if (current->type == type) {
986 » switch (type) { 985 switch (type) {
987 » case certDNSName: 986 case certDNSName:
988 » case certEDIPartyName: 987 case certEDIPartyName:
989 » case certIPAddress: 988 case certIPAddress:
990 » case certRegisterID: 989 case certRegisterID:
991 » case certRFC822Name: 990 case certRFC822Name:
992 » case certX400Address: 991 case certX400Address:
993 » case certURI: 992 case certURI:
994 » » return (void *)&current->name.other; /* SECItem * */ 993 return (void *)&current->name.other; /* SECItem * */
995 994
996 » case certOtherName: 995 case certOtherName:
997 » » return (void *)&current->name.OthName; /* OthName * */ 996 return (void *)&current->name.OthName; /* OthName * */
998 997
999 » case certDirectoryName: 998 case certDirectoryName:
1000 » » return derFormat 999 return derFormat
1001 » » ? (void *)&current->derDirectoryName /* SECItem * */ 1000 ? (void *)&current
1002 » » : (void *)&current->name.directoryName; /* CERTName * */ 1001 ->derDirectoryName /* SECItem * */
1003 » } 1002 : (void *)&current->name
1004 » PORT_Assert(0); 1003 .directoryName; /* CERTName * */
1005 » return NULL; 1004 }
1006 » } 1005 PORT_Assert(0);
1007 » current = CERT_GetNextGeneralName(current); 1006 return NULL;
1007 }
1008 current = CERT_GetNextGeneralName(current);
1008 } while (current != genNames); 1009 } while (current != genNames);
1009 return NULL; 1010 return NULL;
1010 } 1011 }
1011 1012
1012 int 1013 int
1013 CERT_GetNamesLength(CERTGeneralName *names) 1014 CERT_GetNamesLength(CERTGeneralName *names)
1014 { 1015 {
1015 int length = 0; 1016 int length = 0;
1016 CERTGeneralName *first; 1017 CERTGeneralName *first;
1017 1018
1018 first = names; 1019 first = names;
1019 if (names != NULL) { 1020 if (names != NULL) {
1020 » do { 1021 do {
1021 » length++; 1022 length++;
1022 » names = CERT_GetNextGeneralName(names); 1023 names = CERT_GetNextGeneralName(names);
1023 » } while (names != first); 1024 } while (names != first);
1024 } 1025 }
1025 return length; 1026 return length;
1026 } 1027 }
1027 1028
1028 /* Creates new GeneralNames for any email addresses found in the 1029 /* Creates new GeneralNames for any email addresses found in the
1029 ** input DN, and links them onto the list for the DN. 1030 ** input DN, and links them onto the list for the DN.
1030 */ 1031 */
1031 SECStatus 1032 SECStatus
1032 cert_ExtractDNEmailAddrs(CERTGeneralName *name, PLArenaPool *arena) 1033 cert_ExtractDNEmailAddrs(CERTGeneralName *name, PLArenaPool *arena)
1033 { 1034 {
1034 CERTGeneralName *nameList = NULL; 1035 CERTGeneralName *nameList = NULL;
1035 const CERTRDN **nRDNs = (const CERTRDN **)(name->name.directoryName.rdns); 1036 const CERTRDN **nRDNs = (const CERTRDN **)(name->name.directoryName.rdns);
1036 SECStatus rv = SECSuccess; 1037 SECStatus rv = SECSuccess;
1037 1038
1038 PORT_Assert(name->type == certDirectoryName); 1039 PORT_Assert(name->type == certDirectoryName);
1039 if (name->type != certDirectoryName) { 1040 if (name->type != certDirectoryName) {
1040 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1041 PORT_SetError(SEC_ERROR_INVALID_ARGS);
1041 » return SECFailure; 1042 return SECFailure;
1042 } 1043 }
1043 /* TODO: mark arena */ 1044 /* TODO: mark arena */
1044 while (nRDNs && *nRDNs) { /* loop over RDNs */ 1045 while (nRDNs && *nRDNs) { /* loop over RDNs */
1045 » const CERTRDN *nRDN = *nRDNs++; 1046 const CERTRDN *nRDN = *nRDNs++;
1046 » CERTAVA **nAVAs = nRDN->avas; 1047 CERTAVA **nAVAs = nRDN->avas;
1047 » while (nAVAs && *nAVAs) { /* loop over AVAs */ 1048 while (nAVAs && *nAVAs) { /* loop over AVAs */
1048 » int tag; 1049 int tag;
1049 » CERTAVA *nAVA = *nAVAs++; 1050 CERTAVA *nAVA = *nAVAs++;
1050 » tag = CERT_GetAVATag(nAVA); 1051 tag = CERT_GetAVATag(nAVA);
1051 » if ( tag == SEC_OID_PKCS9_EMAIL_ADDRESS || 1052 if (tag == SEC_OID_PKCS9_EMAIL_ADDRESS ||
1052 » » tag == SEC_OID_RFC1274_MAIL) { /* email AVA */ 1053 tag == SEC_OID_RFC1274_MAIL) { /* email AVA */
1053 » » CERTGeneralName *newName = NULL; 1054 CERTGeneralName *newName = NULL;
1054 » » SECItem *avaValue = CERT_DecodeAVAValue(&nAVA->value); 1055 SECItem *avaValue = CERT_DecodeAVAValue(&nAVA->value);
1055 » » if (!avaValue) 1056 if (!avaValue)
1056 » » goto loser; 1057 goto loser;
1057 » » rv = SECFailure; 1058 rv = SECFailure;
1058 newName = CERT_NewGeneralName(arena, certRFC822Name); 1059 newName = CERT_NewGeneralName(arena, certRFC822Name);
1059 » » if (newName) { 1060 if (newName) {
1060 » » rv = SECITEM_CopyItem(arena, &newName->name.other, avaValue); 1061 rv =
1061 » » } 1062 SECITEM_CopyItem(arena, &newName->name.other, avaValue);
1062 » » SECITEM_FreeItem(avaValue, PR_TRUE); 1063 }
1063 » » if (rv != SECSuccess) 1064 SECITEM_FreeItem(avaValue, PR_TRUE);
1064 » » goto loser; 1065 if (rv != SECSuccess)
1065 » » nameList = cert_CombineNamesLists(nameList, newName); 1066 goto loser;
1066 » } /* handle one email AVA */ 1067 nameList = cert_CombineNamesLists(nameList, newName);
1067 » } /* loop over AVAs */ 1068 } /* handle one email AVA */
1068 } /* loop over RDNs */ 1069 } /* loop over AVAs */
1070 } /* loop over RDNs */
1069 /* combine new names with old one. */ 1071 /* combine new names with old one. */
1070 name = cert_CombineNamesLists(name, nameList); 1072 name = cert_CombineNamesLists(name, nameList);
1071 /* TODO: unmark arena */ 1073 /* TODO: unmark arena */
1072 return SECSuccess; 1074 return SECSuccess;
1073 1075
1074 loser: 1076 loser:
1075 /* TODO: release arena back to mark */ 1077 /* TODO: release arena back to mark */
1076 return SECFailure; 1078 return SECFailure;
1077 } 1079 }
1078 1080
1079 /* Extract all names except Subject Common Name from a cert 1081 /* Extract all names except Subject Common Name from a cert
1080 ** in preparation for a name constraints test. 1082 ** in preparation for a name constraints test.
1081 */ 1083 */
1082 CERTGeneralName * 1084 CERTGeneralName *
1083 CERT_GetCertificateNames(CERTCertificate *cert, PLArenaPool *arena) 1085 CERT_GetCertificateNames(CERTCertificate *cert, PLArenaPool *arena)
1084 { 1086 {
1085 return CERT_GetConstrainedCertificateNames(cert, arena, PR_FALSE); 1087 return CERT_GetConstrainedCertificateNames(cert, arena, PR_FALSE);
1086 } 1088 }
1087 1089
1088 /* This function is called by CERT_VerifyCertChain to extract all 1090 /* This function is called by CERT_VerifyCertChain to extract all
1089 ** names from a cert in preparation for a name constraints test. 1091 ** names from a cert in preparation for a name constraints test.
1090 */ 1092 */
1091 CERTGeneralName * 1093 CERTGeneralName *
1092 CERT_GetConstrainedCertificateNames(const CERTCertificate *cert, 1094 CERT_GetConstrainedCertificateNames(const CERTCertificate *cert,
1093 PLArenaPool *arena, 1095 PLArenaPool *arena,
1094 PRBool includeSubjectCommonName) 1096 PRBool includeSubjectCommonName)
1095 { 1097 {
1096 CERTGeneralName *DN; 1098 CERTGeneralName *DN;
1097 CERTGeneralName *SAN; 1099 CERTGeneralName *SAN;
1098 PRUint32 numDNSNames = 0; 1100 PRUint32 numDNSNames = 0;
1099 SECStatus rv; 1101 SECStatus rv;
1100 1102
1101 if (!arena) { 1103 if (!arena) {
1102 » PORT_SetError(SEC_ERROR_INVALID_ARGS); 1104 PORT_SetError(SEC_ERROR_INVALID_ARGS);
1103 » return NULL; 1105 return NULL;
1104 } 1106 }
1105 /* TODO: mark arena */ 1107 /* TODO: mark arena */
1106 DN = CERT_NewGeneralName(arena, certDirectoryName); 1108 DN = CERT_NewGeneralName(arena, certDirectoryName);
1107 if (DN == NULL) { 1109 if (DN == NULL) {
1108 » goto loser; 1110 goto loser;
1109 } 1111 }
1110 rv = CERT_CopyName(arena, &DN->name.directoryName, &cert->subject); 1112 rv = CERT_CopyName(arena, &DN->name.directoryName, &cert->subject);
1111 if (rv != SECSuccess) { 1113 if (rv != SECSuccess) {
1112 » goto loser; 1114 goto loser;
1113 } 1115 }
1114 rv = SECITEM_CopyItem(arena, &DN->derDirectoryName, &cert->derSubject); 1116 rv = SECITEM_CopyItem(arena, &DN->derDirectoryName, &cert->derSubject);
1115 if (rv != SECSuccess) { 1117 if (rv != SECSuccess) {
1116 » goto loser; 1118 goto loser;
1117 } 1119 }
1118 /* Extract email addresses from DN, construct CERTGeneralName structs 1120 /* Extract email addresses from DN, construct CERTGeneralName structs
1119 ** for them, add them to the name list 1121 ** for them, add them to the name list
1120 */ 1122 */
1121 rv = cert_ExtractDNEmailAddrs(DN, arena); 1123 rv = cert_ExtractDNEmailAddrs(DN, arena);
1122 if (rv != SECSuccess) 1124 if (rv != SECSuccess)
1123 goto loser; 1125 goto loser;
1124 1126
1125 /* Now extract any GeneralNames from the subject name names extension. */ 1127 /* Now extract any GeneralNames from the subject name names extension. */
1126 SAN = cert_GetSubjectAltNameList(cert, arena); 1128 SAN = cert_GetSubjectAltNameList(cert, arena);
1127 if (SAN) { 1129 if (SAN) {
1128 » numDNSNames = cert_CountDNSPatterns(SAN); 1130 numDNSNames = cert_CountDNSPatterns(SAN);
1129 » DN = cert_CombineNamesLists(DN, SAN); 1131 DN = cert_CombineNamesLists(DN, SAN);
1130 } 1132 }
1131 if (!numDNSNames && includeSubjectCommonName) { 1133 if (!numDNSNames && includeSubjectCommonName) {
1132 » char *cn = CERT_GetCommonName(&cert->subject); 1134 char *cn = CERT_GetCommonName(&cert->subject);
1133 » if (cn) { 1135 if (cn) {
1134 » CERTGeneralName *CN = CERT_NewGeneralName(arena, certDNSName); 1136 CERTGeneralName *CN = CERT_NewGeneralName(arena, certDNSName);
1135 » if (CN) { 1137 if (CN) {
1136 » » SECItem cnItem = {siBuffer, NULL, 0}; 1138 SECItem cnItem = { siBuffer, NULL, 0 };
1137 » » cnItem.data = (unsigned char *)cn; 1139 cnItem.data = (unsigned char *)cn;
1138 » » cnItem.len = strlen(cn); 1140 cnItem.len = strlen(cn);
1139 » » rv = SECITEM_CopyItem(arena, &CN->name.other, &cnItem); 1141 rv = SECITEM_CopyItem(arena, &CN->name.other, &cnItem);
1140 » » if (rv == SECSuccess) { 1142 if (rv == SECSuccess) {
1141 » » DN = cert_CombineNamesLists(DN, CN); 1143 DN = cert_CombineNamesLists(DN, CN);
1142 » } 1144 }
1143 » } 1145 }
1144 » PORT_Free(cn); 1146 PORT_Free(cn);
1145 » } 1147 }
1146 } 1148 }
1147 if (rv == SECSuccess) { 1149 if (rv == SECSuccess) {
1148 » /* TODO: unmark arena */ 1150 /* TODO: unmark arena */
1149 » return DN; 1151 return DN;
1150 } 1152 }
1151 loser: 1153 loser:
1152 /* TODO: release arena to mark */ 1154 /* TODO: release arena to mark */
1153 return NULL; 1155 return NULL;
1154 } 1156 }
1155 1157
1156 /* Returns SECSuccess if name matches constraint per RFC 3280 rules for 1158 /* Returns SECSuccess if name matches constraint per RFC 3280 rules for
1157 ** URI name constraints. SECFailure otherwise. 1159 ** URI name constraints. SECFailure otherwise.
1158 ** If the constraint begins with a dot, it is a domain name, otherwise 1160 ** If the constraint begins with a dot, it is a domain name, otherwise
1159 ** It is a host name. Examples: 1161 ** It is a host name. Examples:
1160 ** Constraint Name Result 1162 ** Constraint Name Result
1161 ** ------------ --------------- -------- 1163 ** ------------ --------------- --------
1162 ** foo.bar.com foo.bar.com matches 1164 ** foo.bar.com foo.bar.com matches
1163 ** foo.bar.com FoO.bAr.CoM matches 1165 ** foo.bar.com FoO.bAr.CoM matches
1164 ** foo.bar.com www.foo.bar.com no match 1166 ** foo.bar.com www.foo.bar.com no match
1165 ** foo.bar.com nofoo.bar.com no match 1167 ** foo.bar.com nofoo.bar.com no match
1166 ** .foo.bar.com www.foo.bar.com matches 1168 ** .foo.bar.com www.foo.bar.com matches
1167 ** .foo.bar.com nofoo.bar.com no match 1169 ** .foo.bar.com nofoo.bar.com no match
1168 ** .foo.bar.com foo.bar.com no match 1170 ** .foo.bar.com foo.bar.com no match
1169 ** .foo.bar.com www..foo.bar.com no match 1171 ** .foo.bar.com www..foo.bar.com no match
1170 */ 1172 */
1171 static SECStatus 1173 static SECStatus
1172 compareURIN2C(const SECItem *name, const SECItem *constraint) 1174 compareURIN2C(const SECItem *name, const SECItem *constraint)
1173 { 1175 {
1174 int offset; 1176 int offset;
1175 /* The spec is silent on intepreting zero-length constraints. 1177 /* The spec is silent on intepreting zero-length constraints.
1176 ** We interpret them as matching no URI names. 1178 ** We interpret them as matching no URI names.
1177 */ 1179 */
1178 if (!constraint->len) 1180 if (!constraint->len)
1179 return SECFailure; 1181 return SECFailure;
1180 if (constraint->data[0] != '.') { 1182 if (constraint->data[0] != '.') {
1181 » /* constraint is a host name. */ 1183 /* constraint is a host name. */
1182 » if (name->len != constraint->len || 1184 if (name->len != constraint->len ||
1183 » PL_strncasecmp((char *)name->data, 1185 PL_strncasecmp((char *)name->data, (char *)constraint->data,
1184 » » » (char *)constraint->data, constraint->len)) 1186 constraint->len))
1185 » return SECFailure; 1187 return SECFailure;
1186 » return SECSuccess; 1188 return SECSuccess;
1187 } 1189 }
1188 /* constraint is a domain name. */ 1190 /* constraint is a domain name. */
1189 if (name->len < constraint->len) 1191 if (name->len < constraint->len)
1190 return SECFailure; 1192 return SECFailure;
1191 offset = name->len - constraint->len; 1193 offset = name->len - constraint->len;
1192 if (PL_strncasecmp((char *)(name->data + offset), 1194 if (PL_strncasecmp((char *)(name->data + offset), (char *)constraint->data,
1193 » » (char *)constraint->data, constraint->len)) 1195 constraint->len))
1194 return SECFailure; 1196 return SECFailure;
1195 if (!offset || 1197 if (!offset ||
1196 (name->data[offset - 1] == '.') + (constraint->data[0] == '.') == 1) 1198 (name->data[offset - 1] == '.') + (constraint->data[0] == '.') == 1)
1197 » return SECSuccess; 1199 return SECSuccess;
1198 return SECFailure; 1200 return SECFailure;
1199 } 1201 }
1200 1202
1201 /* for DNSname constraints, RFC 3280 says, (section 4.2.1.11, page 38) 1203 /* for DNSname constraints, RFC 3280 says, (section 4.2.1.11, page 38)
1202 ** 1204 **
1203 ** DNS name restrictions are expressed as foo.bar.com. Any DNS name 1205 ** DNS name restrictions are expressed as foo.bar.com. Any DNS name
1204 ** that can be constructed by simply adding to the left hand side of the 1206 ** that can be constructed by simply adding to the left hand side of the
1205 ** name satisfies the name constraint. For example, www.foo.bar.com 1207 ** name satisfies the name constraint. For example, www.foo.bar.com
1206 ** would satisfy the constraint but foo1.bar.com would not. 1208 ** would satisfy the constraint but foo1.bar.com would not.
1207 ** 1209 **
1208 ** But NIST's PKITS test suite requires that the constraint be treated 1210 ** But NIST's PKITS test suite requires that the constraint be treated
1209 ** as a domain name, and requires that any name added to the left hand 1211 ** as a domain name, and requires that any name added to the left hand
1210 ** side end in a dot ".". Sensible, but not strictly following the RFC. 1212 ** side end in a dot ".". Sensible, but not strictly following the RFC.
1211 ** 1213 **
1212 ** Constraint Name RFC 3280 NIST PKITS 1214 ** Constraint Name RFC 3280 NIST PKITS
1213 ** ------------ --------------- -------- ---------- 1215 ** ------------ --------------- -------- ----------
1214 ** foo.bar.com foo.bar.com matches matches 1216 ** foo.bar.com foo.bar.com matches matches
1215 ** foo.bar.com FoO.bAr.CoM matches matches 1217 ** foo.bar.com FoO.bAr.CoM matches matches
1216 ** foo.bar.com www.foo.bar.com matches matches 1218 ** foo.bar.com www.foo.bar.com matches matches
1217 ** foo.bar.com nofoo.bar.com MATCHES NO MATCH 1219 ** foo.bar.com nofoo.bar.com MATCHES NO MATCH
1218 ** .foo.bar.com www.foo.bar.com matches matches? disallowed? 1220 ** .foo.bar.com www.foo.bar.com matches matches? disallowed?
1219 ** .foo.bar.com foo.bar.com no match no match 1221 ** .foo.bar.com foo.bar.com no match no match
1220 ** .foo.bar.com www..foo.bar.com matches probably not 1222 ** .foo.bar.com www..foo.bar.com matches probably not
1221 ** 1223 **
1222 ** We will try to conform to NIST's PKITS tests, and the unstated 1224 ** We will try to conform to NIST's PKITS tests, and the unstated
1223 ** rules they imply. 1225 ** rules they imply.
1224 */ 1226 */
1225 static SECStatus 1227 static SECStatus
1226 compareDNSN2C(const SECItem *name, const SECItem *constraint) 1228 compareDNSN2C(const SECItem *name, const SECItem *constraint)
1227 { 1229 {
1228 int offset; 1230 int offset;
1229 /* The spec is silent on intepreting zero-length constraints. 1231 /* The spec is silent on intepreting zero-length constraints.
1230 ** We interpret them as matching all DNSnames. 1232 ** We interpret them as matching all DNSnames.
1231 */ 1233 */
1232 if (!constraint->len) 1234 if (!constraint->len)
1233 return SECSuccess; 1235 return SECSuccess;
1234 if (name->len < constraint->len) 1236 if (name->len < constraint->len)
1235 return SECFailure; 1237 return SECFailure;
1236 offset = name->len - constraint->len; 1238 offset = name->len - constraint->len;
1237 if (PL_strncasecmp((char *)(name->data + offset), 1239 if (PL_strncasecmp((char *)(name->data + offset), (char *)constraint->data,
1238 » » (char *)constraint->data, constraint->len)) 1240 constraint->len))
1239 return SECFailure; 1241 return SECFailure;
1240 if (!offset || 1242 if (!offset ||
1241 (name->data[offset - 1] == '.') + (constraint->data[0] == '.') == 1) 1243 (name->data[offset - 1] == '.') + (constraint->data[0] == '.') == 1)
1242 » return SECSuccess; 1244 return SECSuccess;
1243 return SECFailure; 1245 return SECFailure;
1244 } 1246 }
1245 1247
1246 /* Returns SECSuccess if name matches constraint per RFC 3280 rules for 1248 /* Returns SECSuccess if name matches constraint per RFC 3280 rules for
1247 ** internet email addresses. SECFailure otherwise. 1249 ** internet email addresses. SECFailure otherwise.
1248 ** If constraint contains a '@' then the two strings much match exactly. 1250 ** If constraint contains a '@' then the two strings much match exactly.
1249 ** Else if constraint starts with a '.'. then it must match the right-most 1251 ** Else if constraint starts with a '.'. then it must match the right-most
1250 ** substring of the name, 1252 ** substring of the name,
1251 ** else constraint string must match entire name after the name's '@'. 1253 ** else constraint string must match entire name after the name's '@'.
1252 ** Empty constraint string matches all names. All comparisons case insensitive. 1254 ** Empty constraint string matches all names. All comparisons case insensitive.
1253 */ 1255 */
1254 static SECStatus 1256 static SECStatus
1255 compareRFC822N2C(const SECItem *name, const SECItem *constraint) 1257 compareRFC822N2C(const SECItem *name, const SECItem *constraint)
1256 { 1258 {
1257 int offset; 1259 int offset;
1258 if (!constraint->len) 1260 if (!constraint->len)
1259 return SECSuccess; 1261 return SECSuccess;
1260 if (name->len < constraint->len) 1262 if (name->len < constraint->len)
1261 return SECFailure; 1263 return SECFailure;
1262 if (constraint->len == 1 && constraint->data[0] == '.') 1264 if (constraint->len == 1 && constraint->data[0] == '.')
1263 return SECSuccess; 1265 return SECSuccess;
1264 for (offset = constraint->len - 1; offset >= 0; --offset) { 1266 for (offset = constraint->len - 1; offset >= 0; --offset) {
1265 » if (constraint->data[offset] == '@') { 1267 if (constraint->data[offset] == '@') {
1266 » return (name->len == constraint->len && 1268 return (name->len == constraint->len &&
1267 » !PL_strncasecmp((char *)name->data, 1269 !PL_strncasecmp((char *)name->data,
1268 » » » » (char *)constraint->data, constraint->len)) 1270 (char *)constraint->data, constraint->len))
1269 » » ? SECSuccess : SECFailure; 1271 ? SECSuccess
1270 » } 1272 : SECFailure;
1273 }
1271 } 1274 }
1272 offset = name->len - constraint->len; 1275 offset = name->len - constraint->len;
1273 if (PL_strncasecmp((char *)(name->data + offset), 1276 if (PL_strncasecmp((char *)(name->data + offset), (char *)constraint->data,
1274 » » (char *)constraint->data, constraint->len)) 1277 constraint->len))
1275 return SECFailure; 1278 return SECFailure;
1276 if (constraint->data[0] == '.') 1279 if (constraint->data[0] == '.')
1277 return SECSuccess; 1280 return SECSuccess;
1278 if (offset > 0 && name->data[offset - 1] == '@') 1281 if (offset > 0 && name->data[offset - 1] == '@')
1279 return SECSuccess; 1282 return SECSuccess;
1280 return SECFailure; 1283 return SECFailure;
1281 } 1284 }
1282 1285
1283 /* name contains either a 4 byte IPv4 address or a 16 byte IPv6 address. 1286 /* name contains either a 4 byte IPv4 address or a 16 byte IPv6 address.
1284 ** constraint contains an address of the same length, and a subnet mask 1287 ** constraint contains an address of the same length, and a subnet mask
1285 ** of the same length. Compare name's address to the constraint's 1288 ** of the same length. Compare name's address to the constraint's
1286 ** address, subject to the mask. 1289 ** address, subject to the mask.
1287 ** Return SECSuccess if they match, SECFailure if they don't. 1290 ** Return SECSuccess if they match, SECFailure if they don't.
1288 */ 1291 */
1289 static SECStatus 1292 static SECStatus
1290 compareIPaddrN2C(const SECItem *name, const SECItem *constraint) 1293 compareIPaddrN2C(const SECItem *name, const SECItem *constraint)
1291 { 1294 {
1292 int i; 1295 int i;
1293 if (name->len == 4 && constraint->len == 8) { /* ipv4 addr */ 1296 if (name->len == 4 && constraint->len == 8) { /* ipv4 addr */
1294 for (i = 0; i < 4; i++) { 1297 for (i = 0; i < 4; i++) {
1295 » if ((name->data[i] ^ constraint->data[i]) & constraint->data[i+4]) 1298 if ((name->data[i] ^ constraint->data[i]) & constraint->data[i + 4])
1296 » goto loser; 1299 goto loser;
1297 » } 1300 }
1298 » return SECSuccess; 1301 return SECSuccess;
1299 } 1302 }
1300 if (name->len == 16 && constraint->len == 32) { /* ipv6 addr */ 1303 if (name->len == 16 && constraint->len == 32) { /* ipv6 addr */
1301 for (i = 0; i < 16; i++) { 1304 for (i = 0; i < 16; i++) {
1302 » if ((name->data[i] ^ constraint->data[i]) & constraint->data[i+16]) 1305 if ((name->data[i] ^ constraint->data[i]) &
1303 » goto loser; 1306 constraint->data[i + 16])
1304 » } 1307 goto loser;
1305 » return SECSuccess; 1308 }
1309 return SECSuccess;
1306 } 1310 }
1307 loser: 1311 loser:
1308 return SECFailure; 1312 return SECFailure;
1309 } 1313 }
1310 1314
1311 /* start with a SECItem that points to a URI. Parse it lookingg for 1315 /* start with a SECItem that points to a URI. Parse it lookingg for
1312 ** a hostname. Modify item->data and item->len to define the hostname, 1316 ** a hostname. Modify item->data and item->len to define the hostname,
1313 ** but do not modify and data at item->data. 1317 ** but do not modify and data at item->data.
1314 ** If anything goes wrong, the contents of *item are undefined. 1318 ** If anything goes wrong, the contents of *item are undefined.
1315 */ 1319 */
1316 static SECStatus 1320 static SECStatus
1317 parseUriHostname(SECItem * item) 1321 parseUriHostname(SECItem *item)
1318 { 1322 {
1319 int i; 1323 int i;
1320 PRBool found = PR_FALSE; 1324 PRBool found = PR_FALSE;
1321 for (i = 0; (unsigned)(i+2) < item->len; ++i) { 1325 for (i = 0; (unsigned)(i + 2) < item->len; ++i) {
1322 » if (item->data[i ] == ':' && 1326 if (item->data[i] == ':' && item->data[i + 1] == '/' &&
1323 » item->data[i+1] == '/' && 1327 item->data[i + 2] == '/') {
1324 » item->data[i+2] == '/') { 1328 i += 3;
1325 » i += 3; 1329 item->data += i;
1326 » item->data += i; 1330 item->len -= i;
1327 » item->len -= i; 1331 found = PR_TRUE;
1328 » found = PR_TRUE; 1332 break;
1329 » break; 1333 }
1330 » }
1331 } 1334 }
1332 if (!found) 1335 if (!found)
1333 return SECFailure; 1336 return SECFailure;
1334 /* now look for a '/', which is an upper bound in the end of the name */ 1337 /* now look for a '/', which is an upper bound in the end of the name */
1335 for (i = 0; (unsigned)i < item->len; ++i) { 1338 for (i = 0; (unsigned)i < item->len; ++i) {
1336 » if (item->data[i] == '/') { 1339 if (item->data[i] == '/') {
1337 » item->len = i; 1340 item->len = i;
1338 » break; 1341 break;
1339 » } 1342 }
1340 } 1343 }
1341 /* now look for a ':', which marks the end of the name */ 1344 /* now look for a ':', which marks the end of the name */
1342 for (i = item->len; --i >= 0; ) { 1345 for (i = item->len; --i >= 0;) {
1343 if (item->data[i] == ':') { 1346 if (item->data[i] == ':') {
1344 » item->len = i; 1347 item->len = i;
1345 » break; 1348 break;
1346 » } 1349 }
1347 } 1350 }
1348 /* now look for an '@', which marks the beginning of the hostname */ 1351 /* now look for an '@', which marks the beginning of the hostname */
1349 for (i = 0; (unsigned)i < item->len; ++i) { 1352 for (i = 0; (unsigned)i < item->len; ++i) {
1350 » if (item->data[i] == '@') { 1353 if (item->data[i] == '@') {
1351 » ++i; 1354 ++i;
1352 » item->data += i; 1355 item->data += i;
1353 » item->len -= i; 1356 item->len -= i;
1354 » break; 1357 break;
1355 » } 1358 }
1356 } 1359 }
1357 return item->len ? SECSuccess : SECFailure; 1360 return item->len ? SECSuccess : SECFailure;
1358 } 1361 }
1359 1362
1360 /* This function takes one name, and a list of constraints. 1363 /* This function takes one name, and a list of constraints.
1361 ** It searches the constraints looking for a match. 1364 ** It searches the constraints looking for a match.
1362 ** It returns SECSuccess if the name satisfies the constraints, i.e., 1365 ** It returns SECSuccess if the name satisfies the constraints, i.e.,
1363 ** if excluded, then the name does not match any constraint, 1366 ** if excluded, then the name does not match any constraint,
1364 ** if permitted, then the name matches at least one constraint. 1367 ** if permitted, then the name matches at least one constraint.
1365 ** It returns SECFailure if the name fails to satisfy the constraints, 1368 ** It returns SECFailure if the name fails to satisfy the constraints,
1366 ** or if some code fails (e.g. out of memory, or invalid constraint) 1369 ** or if some code fails (e.g. out of memory, or invalid constraint)
1367 */ 1370 */
1368 SECStatus 1371 SECStatus
1369 cert_CompareNameWithConstraints(const CERTGeneralName *name, 1372 cert_CompareNameWithConstraints(const CERTGeneralName *name,
1370 » » » » const CERTNameConstraint *constraints, 1373 const CERTNameConstraint *constraints,
1371 » » » » PRBool excluded) 1374 PRBool excluded)
1372 { 1375 {
1373 SECStatus rv = SECSuccess; 1376 SECStatus rv = SECSuccess;
1374 SECStatus matched = SECFailure; 1377 SECStatus matched = SECFailure;
1375 const CERTNameConstraint *current; 1378 const CERTNameConstraint *current;
1376 1379
1377 PORT_Assert(constraints); /* caller should not call with NULL */ 1380 PORT_Assert(constraints); /* caller should not call with NULL */
1378 if (!constraints) { 1381 if (!constraints) {
1379 » PORT_SetError(SEC_ERROR_INVALID_ARGS); 1382 PORT_SetError(SEC_ERROR_INVALID_ARGS);
1380 return SECFailure; 1383 return SECFailure;
1381 } 1384 }
1382 1385
1383 current = constraints; 1386 current = constraints;
1384 do { 1387 do {
1385 » rv = SECSuccess; 1388 rv = SECSuccess;
1386 » matched = SECFailure; 1389 matched = SECFailure;
1387 » PORT_Assert(name->type == current->name.type); 1390 PORT_Assert(name->type == current->name.type);
1388 » switch (name->type) { 1391 switch (name->type) {
1389 1392
1390 » case certDNSName: 1393 case certDNSName:
1391 » matched = compareDNSN2C(&name->name.other, 1394 matched =
1392 » &current->name.name.other); 1395 compareDNSN2C(&name->name.other, &current->name.name.other);
1393 » break; 1396 break;
1394 1397
1395 » case certRFC822Name: 1398 case certRFC822Name:
1396 » matched = compareRFC822N2C(&name->name.other, 1399 matched = compareRFC822N2C(&name->name.other,
1397 » &current->name.name.other); 1400 &current->name.name.other);
1398 » break; 1401 break;
1399 1402
1400 » case certURI: 1403 case certURI: {
1401 » { 1404 /* make a modifiable copy of the URI SECItem. */
1402 » » /* make a modifiable copy of the URI SECItem. */ 1405 SECItem uri = name->name.other;
1403 » » SECItem uri = name->name.other; 1406 /* find the hostname in the URI */
1404 » » /* find the hostname in the URI */ 1407 rv = parseUriHostname(&uri);
1405 » » rv = parseUriHostname(&uri); 1408 if (rv == SECSuccess) {
1406 » » if (rv == SECSuccess) { 1409 /* does our hostname meet the constraint? */
1407 » » /* does our hostname meet the constraint? */ 1410 matched = compareURIN2C(&uri, &current->name.name.other);
1408 » » matched = compareURIN2C(&uri, &current->name.name.other); 1411 }
1409 » » } 1412 } break;
1410 » }
1411 » break;
1412 1413
1413 » case certDirectoryName: 1414 case certDirectoryName:
1414 » /* Determine if the constraint directory name is a "prefix" 1415 /* Determine if the constraint directory name is a "prefix"
1415 » ** for the directory name being tested. 1416 ** for the directory name being tested.
1416 » */ 1417 */
1417 » { 1418 {
1418 » /* status defaults to SECEqual, so that a constraint with 1419 /* status defaults to SECEqual, so that a constraint with
1419 » ** no AVAs will be a wildcard, matching all directory names. 1420 ** no AVAs will be a wildcard, matching all directory names.
1420 » */ 1421 */
1421 » SECComparison status = SECEqual; 1422 SECComparison status = SECEqual;
1422 » const CERTRDN **cRDNs = 1423 const CERTRDN **cRDNs =
1423 » » (const CERTRDN **)current->name.name.directoryName.rdns; 1424 (const CERTRDN **)current->name.name.directoryName.rdns;
1424 » const CERTRDN **nRDNs = 1425 const CERTRDN **nRDNs =
1425 » » (const CERTRDN **)name->name.directoryName.rdns; 1426 (const CERTRDN **)name->name.directoryName.rdns;
1426 » while (cRDNs && *cRDNs && nRDNs && *nRDNs) { 1427 while (cRDNs && *cRDNs && nRDNs && *nRDNs) {
1427 » » /* loop over name RDNs and constraint RDNs in lock step */ 1428 /* loop over name RDNs and constraint RDNs in lock step
1428 » » const CERTRDN *cRDN = *cRDNs++; 1429 */
1429 » » const CERTRDN *nRDN = *nRDNs++; 1430 const CERTRDN *cRDN = *cRDNs++;
1430 » » CERTAVA **cAVAs = cRDN->avas; 1431 const CERTRDN *nRDN = *nRDNs++;
1431 » » while (cAVAs && *cAVAs) { /* loop over constraint AVAs */ 1432 CERTAVA **cAVAs = cRDN->avas;
1432 » » CERTAVA *cAVA = *cAVAs++; 1433 while (cAVAs &&
1433 » » CERTAVA **nAVAs = nRDN->avas; 1434 *cAVAs) { /* loop over constraint AVAs */
1434 » » while (nAVAs && *nAVAs) { /* loop over name AVAs */ 1435 CERTAVA *cAVA = *cAVAs++;
1435 » » » CERTAVA *nAVA = *nAVAs++; 1436 CERTAVA **nAVAs = nRDN->avas;
1436 » » » status = CERT_CompareAVA(cAVA, nAVA); 1437 while (nAVAs && *nAVAs) { /* loop over name AVAs */
1437 » » » if (status == SECEqual) 1438 CERTAVA *nAVA = *nAVAs++;
1438 » » » break; 1439 status = CERT_CompareAVA(cAVA, nAVA);
1439 » » } /* loop over name AVAs */ 1440 if (status == SECEqual)
1440 » » if (status != SECEqual) 1441 break;
1441 » » » break; 1442 } /* loop over name AVAs */
1442 » » } /* loop over constraint AVAs */ 1443 if (status != SECEqual)
1443 » » if (status != SECEqual) 1444 break;
1444 » » break; 1445 } /* loop over constraint AVAs */
1445 » } /* loop over name RDNs and constraint RDNs */ 1446 if (status != SECEqual)
1446 » matched = (status == SECEqual) ? SECSuccess : SECFailure; 1447 break;
1447 » break; 1448 } /* loop over name RDNs and constraint RDNs */
1448 » } 1449 matched = (status == SECEqual) ? SECSuccess : SECFailure;
1450 break;
1451 }
1449 1452
1450 » case certIPAddress:» /* type 8 */ 1453 case certIPAddress: /* type 8 */
1451 » matched = compareIPaddrN2C(&name->name.other, 1454 matched = compareIPaddrN2C(&name->name.other,
1452 » &current->name.name.other); 1455 &current->name.name.other);
1453 » break; 1456 break;
1454 1457
1455 » /* NSS does not know how to compare these "Other" type names with 1458 /* NSS does not know how to compare these "Other" type names with
1456 » ** their respective constraints. But it does know how to tell 1459 ** their respective constraints. But it does know how to tell
1457 » ** if the constraint applies to the type of name (by comparing 1460 ** if the constraint applies to the type of name (by comparing
1458 » ** the constraint OID to the name OID). NSS makes no use of "Other" 1461 ** the constraint OID to the name OID). NSS makes no use of "Other"
1459 » ** type names at all, so NSS errs on the side of leniency for these 1462 ** type names at all, so NSS errs on the side of leniency for these
1460 » ** types, provided that their OIDs match. So, when an "Other" 1463 ** types, provided that their OIDs match. So, when an "Other"
1461 » ** name constraint appears in an excluded subtree, it never causes 1464 ** name constraint appears in an excluded subtree, it never causes
1462 » ** a name to fail. When an "Other" name constraint appears in a 1465 ** a name to fail. When an "Other" name constraint appears in a
1463 » ** permitted subtree, AND the constraint's OID matches the name's 1466 ** permitted subtree, AND the constraint's OID matches the name's
1464 » ** OID, then name is treated as if it matches the constraint. 1467 ** OID, then name is treated as if it matches the constraint.
1465 » */ 1468 */
1466 » case certOtherName:» /* type 1 */ 1469 case certOtherName: /* type 1 */
1467 » matched = (!excluded && 1470 matched =
1468 » » name->type == current->name.type && 1471 (!excluded && name->type == current->name.type &&
1469 » » SECITEM_ItemsAreEqual(&name->name.OthName.oid, 1472 SECITEM_ItemsAreEqual(&name->name.OthName.oid,
1470 » » » » » &current->name.name.OthName.oid)) 1473 &current->name.name.OthName.oid))
1471 » » ? SECSuccess : SECFailure; 1474 ? SECSuccess
1472 » break; 1475 : SECFailure;
1476 break;
1473 1477
1474 » /* NSS does not know how to compare these types of names with their 1478 /* NSS does not know how to compare these types of names with their
1475 » ** respective constraints. But NSS makes no use of these types of 1479 ** respective constraints. But NSS makes no use of these types of
1476 » ** names at all, so it errs on the side of leniency for these types. 1480 ** names at all, so it errs on the side of leniency for these types.
1477 » ** Constraints for these types of names never cause the name to 1481 ** Constraints for these types of names never cause the name to
1478 » ** fail the constraints test. NSS behaves as if the name matched 1482 ** fail the constraints test. NSS behaves as if the name matched
1479 » ** for permitted constraints, and did not match for excluded ones. 1483 ** for permitted constraints, and did not match for excluded ones.
1480 » */ 1484 */
1481 » case certX400Address:» /* type 4 */ 1485 case certX400Address: /* type 4 */
1482 » case certEDIPartyName: /* type 6 */ 1486 case certEDIPartyName: /* type 6 */
1483 » case certRegisterID:» /* type 9 */ 1487 case certRegisterID: /* type 9 */
1484 » matched = excluded ? SECFailure : SECSuccess; 1488 matched = excluded ? SECFailure : SECSuccess;
1485 » break; 1489 break;
1486 1490
1487 » default: /* non-standard types are not supported */ 1491 default: /* non-standard types are not supported */
1488 » rv = SECFailure; 1492 rv = SECFailure;
1489 » break; 1493 break;
1490 » } 1494 }
1491 » if (matched == SECSuccess || rv != SECSuccess) 1495 if (matched == SECSuccess || rv != SECSuccess)
1492 » break; 1496 break;
1493 » current = CERT_GetNextNameConstraint((CERTNameConstraint*)current); 1497 current = CERT_GetNextNameConstraint((CERTNameConstraint *)current);
1494 } while (current != constraints); 1498 } while (current != constraints);
1495 if (rv == SECSuccess) { 1499 if (rv == SECSuccess) {
1496 if (matched == SECSuccess) 1500 if (matched == SECSuccess)
1497 » rv = excluded ? SECFailure : SECSuccess; 1501 rv = excluded ? SECFailure : SECSuccess;
1498 » else 1502 else
1499 » rv = excluded ? SECSuccess : SECFailure; 1503 rv = excluded ? SECSuccess : SECFailure;
1500 » return rv; 1504 return rv;
1501 } 1505 }
1502 1506
1503 return SECFailure; 1507 return SECFailure;
1504 } 1508 }
1505 1509
1506 /* Add and link a CERTGeneralName to a CERTNameConstraint list. Most 1510 /* Add and link a CERTGeneralName to a CERTNameConstraint list. Most
1507 ** likely the CERTNameConstraint passed in is either the permitted 1511 ** likely the CERTNameConstraint passed in is either the permitted
1508 ** list or the excluded list of a CERTNameConstraints. 1512 ** list or the excluded list of a CERTNameConstraints.
1509 */ 1513 */
1510 SECStatus 1514 SECStatus
1511 CERT_AddNameConstraintByGeneralName(PLArenaPool *arena, 1515 CERT_AddNameConstraintByGeneralName(PLArenaPool *arena,
1512 CERTNameConstraint **constraints, 1516 CERTNameConstraint **constraints,
1513 CERTGeneralName *name) 1517 CERTGeneralName *name)
1514 { 1518 {
1515 SECStatus rv; 1519 SECStatus rv;
1516 CERTNameConstraint *current = NULL; 1520 CERTNameConstraint *current = NULL;
1517 CERTNameConstraint *first = *constraints; 1521 CERTNameConstraint *first = *constraints;
1518 void *mark = NULL; 1522 void *mark = NULL;
1519 1523
1520 mark = PORT_ArenaMark(arena); 1524 mark = PORT_ArenaMark(arena);
1521 1525
1522 current = PORT_ArenaZNew(arena, CERTNameConstraint); 1526 current = PORT_ArenaZNew(arena, CERTNameConstraint);
1523 if (current == NULL) { 1527 if (current == NULL) {
1524 rv = SECFailure; 1528 rv = SECFailure;
1525 goto done; 1529 goto done;
1526 } 1530 }
1527 1531
1528 rv = cert_CopyOneGeneralName(arena, &current->name, name); 1532 rv = cert_CopyOneGeneralName(arena, &current->name, name);
1529 if (rv != SECSuccess) { 1533 if (rv != SECSuccess) {
1530 goto done; 1534 goto done;
1531 } 1535 }
1532 1536
1533 current->name.l.prev = current->name.l.next = &(current->name.l); 1537 current->name.l.prev = current->name.l.next = &(current->name.l);
1534 1538
1535 if (first == NULL) { 1539 if (first == NULL) {
1536 *constraints = current; 1540 *constraints = current;
1537 PR_INIT_CLIST(&current->l); 1541 PR_INIT_CLIST(&current->l);
1538 } else { 1542 } else {
1539 PR_INSERT_BEFORE(&current->l, &first->l); 1543 PR_INSERT_BEFORE(&current->l, &first->l);
1540 } 1544 }
1541 1545
1542 done: 1546 done:
1543 if (rv == SECFailure) { 1547 if (rv == SECFailure) {
1544 PORT_ArenaRelease(arena, mark); 1548 PORT_ArenaRelease(arena, mark);
(...skipping 17 matching lines...) Expand all
1562 * 1566 *
1563 * Entities subject to name constraints are identified by subject name 1567 * Entities subject to name constraints are identified by subject name
1564 * so that we can cover all certificates for that entity, including, e.g., 1568 * so that we can cover all certificates for that entity, including, e.g.,
1565 * cross-certificates. We use subject rather than public key because 1569 * cross-certificates. We use subject rather than public key because
1566 * calling methods often have easy access to that field (vs., say, a key ID), 1570 * calling methods often have easy access to that field (vs., say, a key ID),
1567 * and in practice, subject names and public keys are usually in one-to-one 1571 * and in practice, subject names and public keys are usually in one-to-one
1568 * correspondence anyway. 1572 * correspondence anyway.
1569 * 1573 *
1570 */ 1574 */
1571 1575
1572 #define STRING_TO_SECITEM(str) \ 1576 #define STRING_TO_SECITEM(str) \
1573 { siBuffer, (unsigned char*) str, sizeof(str) - 1 } 1577 { \
1578 siBuffer, (unsigned char *)str, sizeof(str) - 1 \
1579 }
1574 1580
1575 #define NAME_CONSTRAINTS_ENTRY(CA) \ 1581 #define NAME_CONSTRAINTS_ENTRY(CA) \
1576 { \ 1582 { \
1577 STRING_TO_SECITEM(CA ## _SUBJECT_DN), \ 1583 STRING_TO_SECITEM(CA##_SUBJECT_DN), \
1578 STRING_TO_SECITEM(CA ## _NAME_CONSTRAINTS) \ 1584 STRING_TO_SECITEM(CA##_NAME_CONSTRAINTS) \
1579 } 1585 }
1580 1586
1581 /* Agence Nationale de la Securite des Systemes d'Information (ANSSI) */ 1587 /* Agence Nationale de la Securite des Systemes d'Information (ANSSI) */
1582 1588
1583 #define ANSSI_SUBJECT_DN \ 1589 /* clang-format off */
1584 "\x30\x81\x85" \
1585 "\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02" "FR" /* C */ \
1586 "\x31\x0F\x30\x0D\x06\x03\x55\x04\x08\x13\x06" "France" /* ST */ \
1587 "\x31\x0E\x30\x0C\x06\x03\x55\x04\x07\x13\x05" "Paris" /* L */ \
1588 "\x31\x10\x30\x0E\x06\x03\x55\x04\x0A\x13\x07" "PM/SGDN" /* O */ \
1589 "\x31\x0E\x30\x0C\x06\x03\x55\x04\x0B\x13\x05" "DCSSI" /* OU */ \
1590 "\x31\x0E\x30\x0C\x06\x03\x55\x04\x03\x13\x05" "IGC/A" /* CN */ \
1591 "\x31\x23\x30\x21\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x01" \
1592 "\x16\x14" "igca@sgdn.pm.gouv.fr" /* emailAddress */ \
1593 1590
1594 #define ANSSI_NAME_CONSTRAINTS \ 1591 #define ANSSI_SUBJECT_DN \
1595 "\x30\x5D\xA0\x5B" \ 1592 "\x30\x81\x85" \
1596 "\x30\x05\x82\x03" ".fr" \ 1593 "\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02" "FR" /* C */ \
1597 "\x30\x05\x82\x03" ".gp" \ 1594 "\x31\x0F\x30\x0D\x06\x03\x55\x04\x08\x13\x06" "France" /* ST */ \
1598 "\x30\x05\x82\x03" ".gf" \ 1595 "\x31\x0E\x30\x0C\x06\x03\x55\x04\x07\x13\x05" "Paris" /* L */ \
1599 "\x30\x05\x82\x03" ".mq" \ 1596 "\x31\x10\x30\x0E\x06\x03\x55\x04\x0A\x13\x07" "PM/SGDN" /* O */ \
1600 "\x30\x05\x82\x03" ".re" \ 1597 "\x31\x0E\x30\x0C\x06\x03\x55\x04\x0B\x13\x05" "DCSSI" /* OU */ \
1601 "\x30\x05\x82\x03" ".yt" \ 1598 "\x31\x0E\x30\x0C\x06\x03\x55\x04\x03\x13\x05" "IGC/A" /* CN */ \
1602 "\x30\x05\x82\x03" ".pm" \ 1599 "\x31\x23\x30\x21\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x01" \
1603 "\x30\x05\x82\x03" ".bl" \ 1600 "\x16\x14" "igca@sgdn.pm.gouv.fr" /* emailAddress */ \
1604 "\x30\x05\x82\x03" ".mf" \
1605 "\x30\x05\x82\x03" ".wf" \
1606 "\x30\x05\x82\x03" ".pf" \
1607 "\x30\x05\x82\x03" ".nc" \
1608 "\x30\x05\x82\x03" ".tf" \
1609 1601
1610 static const SECItem builtInNameConstraints[][2] = { 1602 #define ANSSI_NAME_CONSTRAINTS \
1611 NAME_CONSTRAINTS_ENTRY(ANSSI) 1603 "\x30\x5D\xA0\x5B" \
1612 }; 1604 "\x30\x05\x82\x03" ".fr" \
1605 "\x30\x05\x82\x03" ".gp" \
1606 "\x30\x05\x82\x03" ".gf" \
1607 "\x30\x05\x82\x03" ".mq" \
1608 "\x30\x05\x82\x03" ".re" \
1609 "\x30\x05\x82\x03" ".yt" \
1610 "\x30\x05\x82\x03" ".pm" \
1611 "\x30\x05\x82\x03" ".bl" \
1612 "\x30\x05\x82\x03" ".mf" \
1613 "\x30\x05\x82\x03" ".wf" \
1614 "\x30\x05\x82\x03" ".pf" \
1615 "\x30\x05\x82\x03" ".nc" \
1616 "\x30\x05\x82\x03" ".tf"
1617
1618 /* clang-format on */
1619
1620 static const SECItem builtInNameConstraints[][2] = { NAME_CONSTRAINTS_ENTRY(
1621 ANSSI) };
1613 1622
1614 SECStatus 1623 SECStatus
1615 CERT_GetImposedNameConstraints(const SECItem *derSubject, 1624 CERT_GetImposedNameConstraints(const SECItem *derSubject, SECItem *extensions)
1616 SECItem *extensions)
1617 { 1625 {
1618 size_t i; 1626 size_t i;
1619 1627
1620 if (!extensions) { 1628 if (!extensions) {
1621 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1629 PORT_SetError(SEC_ERROR_INVALID_ARGS);
1622 return SECFailure; 1630 return SECFailure;
1623 } 1631 }
1624 1632
1625 for (i = 0; i < PR_ARRAY_SIZE(builtInNameConstraints); ++i) { 1633 for (i = 0; i < PR_ARRAY_SIZE(builtInNameConstraints); ++i) {
1626 if (SECITEM_ItemsAreEqual(derSubject, &builtInNameConstraints[i][0])) { 1634 if (SECITEM_ItemsAreEqual(derSubject, &builtInNameConstraints[i][0])) {
1627 return SECITEM_CopyItem(NULL, 1635 return SECITEM_CopyItem(NULL, extensions,
1628 extensions,
1629 &builtInNameConstraints[i][1]); 1636 &builtInNameConstraints[i][1]);
1630 } 1637 }
1631 } 1638 }
1632 1639
1633 PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND); 1640 PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND);
1634 return SECFailure; 1641 return SECFailure;
1635 } 1642 }
1636 1643
1637 /* 1644 /*
1638 * Extract the name constraints extension from the CA cert. 1645 * Extract the name constraints extension from the CA cert.
1639 * If the certificate contains no name constraints extension, but 1646 * If the certificate contains no name constraints extension, but
1640 * CERT_GetImposedNameConstraints returns a name constraints extension 1647 * CERT_GetImposedNameConstraints returns a name constraints extension
1641 * for the subject of the certificate, then that extension will be returned. 1648 * for the subject of the certificate, then that extension will be returned.
1642 */ 1649 */
1643 SECStatus 1650 SECStatus
1644 CERT_FindNameConstraintsExten(PLArenaPool *arena, 1651 CERT_FindNameConstraintsExten(PLArenaPool *arena, CERTCertificate *cert,
1645 CERTCertificate *cert,
1646 CERTNameConstraints **constraints) 1652 CERTNameConstraints **constraints)
1647 { 1653 {
1648 SECStatus rv = SECSuccess; 1654 SECStatus rv = SECSuccess;
1649 SECItem constraintsExtension; 1655 SECItem constraintsExtension;
1650 void *mark = NULL; 1656 void *mark = NULL;
1651 1657
1652 *constraints = NULL; 1658 *constraints = NULL;
1653 1659
1654 rv = CERT_FindCertExtension(cert, SEC_OID_X509_NAME_CONSTRAINTS, 1660 rv = CERT_FindCertExtension(cert, SEC_OID_X509_NAME_CONSTRAINTS,
1655 &constraintsExtension); 1661 &constraintsExtension);
1656 if (rv != SECSuccess) { 1662 if (rv != SECSuccess) {
1657 if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND) { 1663 if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND) {
1658 return rv; 1664 return rv;
1659 } 1665 }
1660 rv = CERT_GetImposedNameConstraints(&cert->derSubject, 1666 rv = CERT_GetImposedNameConstraints(&cert->derSubject,
1661 &constraintsExtension); 1667 &constraintsExtension);
1662 if (rv != SECSuccess) { 1668 if (rv != SECSuccess) {
1663 if (PORT_GetError() == SEC_ERROR_EXTENSION_NOT_FOUND) { 1669 if (PORT_GetError() == SEC_ERROR_EXTENSION_NOT_FOUND) {
1664 return SECSuccess; 1670 return SECSuccess;
1665 } 1671 }
1666 return rv; 1672 return rv;
1667 } 1673 }
1668 } 1674 }
1669 1675
1670 mark = PORT_ArenaMark(arena); 1676 mark = PORT_ArenaMark(arena);
1671 1677
1672 *constraints = cert_DecodeNameConstraints(arena, &constraintsExtension); 1678 *constraints = cert_DecodeNameConstraints(arena, &constraintsExtension);
1673 if (*constraints == NULL) { /* decode failed */ 1679 if (*constraints == NULL) { /* decode failed */
1674 rv = SECFailure; 1680 rv = SECFailure;
1675 } 1681 }
1676 PORT_Free (constraintsExtension.data); 1682 PORT_Free(constraintsExtension.data);
1677 1683
1678 if (rv == SECFailure) { 1684 if (rv == SECFailure) {
1679 PORT_ArenaRelease(arena, mark); 1685 PORT_ArenaRelease(arena, mark);
1680 } else { 1686 } else {
1681 PORT_ArenaUnmark(arena, mark); 1687 PORT_ArenaUnmark(arena, mark);
1682 } 1688 }
1683 1689
1684 return rv; 1690 return rv;
1685 } 1691 }
1686 1692
1687 /* Verify name against all the constraints relevant to that type of 1693 /* Verify name against all the constraints relevant to that type of
1688 ** the name. 1694 ** the name.
1689 */ 1695 */
1690 SECStatus 1696 SECStatus
1691 CERT_CheckNameSpace(PLArenaPool *arena, 1697 CERT_CheckNameSpace(PLArenaPool *arena, const CERTNameConstraints *constraints,
1692 const CERTNameConstraints *constraints, 1698 const CERTGeneralName *currentName)
1693 const CERTGeneralName *currentName)
1694 { 1699 {
1695 CERTNameConstraint *matchingConstraints; 1700 CERTNameConstraint *matchingConstraints;
1696 SECStatus rv = SECSuccess; 1701 SECStatus rv = SECSuccess;
1697 1702
1698 if (constraints->excluded != NULL) { 1703 if (constraints->excluded != NULL) {
1699 rv = CERT_GetNameConstraintByType(constraints->excluded, 1704 rv = CERT_GetNameConstraintByType(constraints->excluded,
1700 currentName->type, 1705 currentName->type,
1701 &matchingConstraints, arena); 1706 &matchingConstraints, arena);
1702 if (rv == SECSuccess && matchingConstraints != NULL) { 1707 if (rv == SECSuccess && matchingConstraints != NULL) {
1703 rv = cert_CompareNameWithConstraints(currentName, 1708 rv = cert_CompareNameWithConstraints(currentName,
1704 matchingConstraints, 1709 matchingConstraints, PR_TRUE);
1705 PR_TRUE);
1706 } 1710 }
1707 if (rv != SECSuccess) { 1711 if (rv != SECSuccess) {
1708 return(rv); 1712 return (rv);
1709 }
1710 }
1711
1712 if (constraints->permited != NULL) {
1713 rv = CERT_GetNameConstraintByType(constraints->permited,
1714 currentName->type,
1715 &matchingConstraints, arena);
1716 if (rv == SECSuccess && matchingConstraints != NULL) {
1717 rv = cert_CompareNameWithConstraints(currentName,
1718 matchingConstraints,
1719 PR_FALSE);
1720 }
1721 if (rv != SECSuccess) {
1722 return(rv);
1723 } 1713 }
1724 } 1714 }
1725 1715
1726 return(SECSuccess); 1716 if (constraints->permited != NULL) {
1717 rv = CERT_GetNameConstraintByType(constraints->permited,
1718 currentName->type,
1719 &matchingConstraints, arena);
1720 if (rv == SECSuccess && matchingConstraints != NULL) {
1721 rv = cert_CompareNameWithConstraints(currentName,
1722 matchingConstraints, PR_FALSE);
1723 }
1724 if (rv != SECSuccess) {
1725 return (rv);
1726 }
1727 }
1728
1729 return (SECSuccess);
1727 } 1730 }
1728 1731
1729 /* Extract the name constraints extension from the CA cert. 1732 /* Extract the name constraints extension from the CA cert.
1730 ** Test each and every name in namesList against all the constraints 1733 ** Test each and every name in namesList against all the constraints
1731 ** relevant to that type of name. 1734 ** relevant to that type of name.
1732 ** Returns NULL in pBadCert for success, if all names are acceptable. 1735 ** Returns NULL in pBadCert for success, if all names are acceptable.
1733 ** If some name is not acceptable, returns a pointer to the cert that 1736 ** If some name is not acceptable, returns a pointer to the cert that
1734 ** contained that name. 1737 ** contained that name.
1735 */ 1738 */
1736 SECStatus 1739 SECStatus
1737 CERT_CompareNameSpace(CERTCertificate *cert, 1740 CERT_CompareNameSpace(CERTCertificate *cert, CERTGeneralName *namesList,
1738 » » CERTGeneralName *namesList, 1741 CERTCertificate **certsList, PLArenaPool *reqArena,
1739 » » CERTCertificate **certsList, 1742 CERTCertificate **pBadCert)
1740 » » PLArenaPool *reqArena,
1741 » » CERTCertificate **pBadCert)
1742 { 1743 {
1743 SECStatus rv = SECSuccess; 1744 SECStatus rv = SECSuccess;
1744 CERTNameConstraints *constraints; 1745 CERTNameConstraints *constraints;
1745 CERTGeneralName *currentName; 1746 CERTGeneralName *currentName;
1746 int count = 0; 1747 int count = 0;
1747 CERTCertificate *badCert = NULL; 1748 CERTCertificate *badCert = NULL;
1748 1749
1749 /* If no names to check, then no names can be bad. */ 1750 /* If no names to check, then no names can be bad. */
1750 if (!namesList) 1751 if (!namesList)
1751 » goto done; 1752 goto done;
1752 rv = CERT_FindNameConstraintsExten(reqArena, cert, &constraints); 1753 rv = CERT_FindNameConstraintsExten(reqArena, cert, &constraints);
1753 if (rv != SECSuccess) { 1754 if (rv != SECSuccess) {
1754 » count = -1; 1755 count = -1;
1755 » goto done; 1756 goto done;
1756 } 1757 }
1757 1758
1758 currentName = namesList; 1759 currentName = namesList;
1759 do { 1760 do {
1760 » if (constraints){ 1761 if (constraints) {
1761 » rv = CERT_CheckNameSpace(reqArena, constraints, currentName); 1762 rv = CERT_CheckNameSpace(reqArena, constraints, currentName);
1762 » if (rv != SECSuccess) { 1763 if (rv != SECSuccess) {
1763 » » break; 1764 break;
1764 » } 1765 }
1765 » } 1766 }
1766 » currentName = CERT_GetNextGeneralName(currentName); 1767 currentName = CERT_GetNextGeneralName(currentName);
1767 » count ++; 1768 count++;
1768 } while (currentName != namesList); 1769 } while (currentName != namesList);
1769 1770
1770 done: 1771 done:
1771 if (rv != SECSuccess) { 1772 if (rv != SECSuccess) {
1772 » badCert = (count >= 0) ? certsList[count] : cert; 1773 badCert = (count >= 0) ? certsList[count] : cert;
1773 } 1774 }
1774 if (pBadCert) 1775 if (pBadCert)
1775 » *pBadCert = badCert; 1776 *pBadCert = badCert;
1776 1777
1777 return rv; 1778 return rv;
1778 } 1779 }
1779 1780
1780 #if 0 1781 #if 0
1781 /* not exported from shared libs, not used. Turn on if we ever need it. */ 1782 /* not exported from shared libs, not used. Turn on if we ever need it. */
1782 SECStatus 1783 SECStatus
1783 CERT_CompareGeneralName(CERTGeneralName *a, CERTGeneralName *b) 1784 CERT_CompareGeneralName(CERTGeneralName *a, CERTGeneralName *b)
1784 { 1785 {
1785 CERTGeneralName *currentA; 1786 CERTGeneralName *currentA;
1786 CERTGeneralName *currentB; 1787 CERTGeneralName *currentB;
1787 PRBool found; 1788 PRBool found;
1788 1789
1789 currentA = a; 1790 currentA = a;
1790 currentB = b; 1791 currentB = b;
1791 if (a != NULL) { 1792 if (a != NULL) {
1792 » do { 1793 » do {
1793 if (currentB == NULL) { 1794 if (currentB == NULL) {
1794 return SECFailure; 1795 return SECFailure;
1795 } 1796 }
1796 currentB = CERT_GetNextGeneralName(currentB); 1797 currentB = CERT_GetNextGeneralName(currentB);
1797 currentA = CERT_GetNextGeneralName(currentA); 1798 currentA = CERT_GetNextGeneralName(currentA);
1798 } while (currentA != a); 1799 } while (currentA != a);
1799 } 1800 }
1800 if (currentB != b) { 1801 if (currentB != b) {
1801 return SECFailure; 1802 return SECFailure;
1802 } 1803 }
1803 currentA = a; 1804 currentA = a;
1804 do { 1805 do {
1805 currentB = b; 1806 currentB = b;
1806 found = PR_FALSE; 1807 found = PR_FALSE;
1807 do { 1808 do {
1808 if (currentB->type == currentA->type) { 1809 if (currentB->type == currentA->type) {
1809 switch (currentB->type) { 1810 switch (currentB->type) {
1810 case certDNSName: 1811 case certDNSName:
1811 case certEDIPartyName: 1812 case certEDIPartyName:
1812 case certIPAddress: 1813 case certIPAddress:
1813 case certRegisterID: 1814 case certRegisterID:
1814 case certRFC822Name: 1815 case certRFC822Name:
1815 case certX400Address: 1816 case certX400Address:
1816 case certURI: 1817 case certURI:
1817 if (SECITEM_CompareItem(&currentA->name.other, 1818 if (SECITEM_CompareItem(&currentA->name.other,
1818 » » » » » &currentB->name.other) 1819 » » » » » &currentB->name.other)
1819 == SECEqual) { 1820 == SECEqual) {
1820 found = PR_TRUE; 1821 found = PR_TRUE;
1821 } 1822 }
1822 break; 1823 break;
1823 case certOtherName: 1824 case certOtherName:
1824 if (SECITEM_CompareItem(&currentA->name.OthName.oid, 1825 if (SECITEM_CompareItem(&currentA->name.OthName.oid,
1825 » » » » » &currentB->name.OthName.oid) 1826 » » » » » &currentB->name.OthName.oid)
1826 == SECEqual && 1827 == SECEqual &&
1827 SECITEM_CompareItem(&currentA->name.OthName.name, 1828 SECITEM_CompareItem(&currentA->name.OthName.name,
1828 &currentB->name.OthName.name) 1829 &currentB->name.OthName.name)
1829 == SECEqual) { 1830 == SECEqual) {
1830 found = PR_TRUE; 1831 found = PR_TRUE;
1831 } 1832 }
1832 break; 1833 break;
1833 case certDirectoryName: 1834 case certDirectoryName:
1834 if (CERT_CompareName(&currentA->name.directoryName, 1835 if (CERT_CompareName(&currentA->name.directoryName,
1835 &currentB->name.directoryName) 1836 &currentB->name.directoryName)
1836 == SECEqual) { 1837 == SECEqual) {
1837 found = PR_TRUE; 1838 found = PR_TRUE;
1838 } 1839 }
1839 } 1840 }
1840 » » 1841
1841 } 1842 }
1842 currentB = CERT_GetNextGeneralName(currentB); 1843 currentB = CERT_GetNextGeneralName(currentB);
1843 } while (currentB != b && found != PR_TRUE); 1844 } while (currentB != b && found != PR_TRUE);
1844 if (found != PR_TRUE) { 1845 if (found != PR_TRUE) {
1845 return SECFailure; 1846 return SECFailure;
1846 } 1847 }
1847 currentA = CERT_GetNextGeneralName(currentA); 1848 currentA = CERT_GetNextGeneralName(currentA);
1848 } while (currentA != a); 1849 } while (currentA != a);
1849 return SECSuccess; 1850 return SECSuccess;
1850 } 1851 }
(...skipping 22 matching lines...) Expand all
1873 #if 0 1874 #if 0
1874 /* This function is not exported from NSS shared libraries, and is not 1875 /* This function is not exported from NSS shared libraries, and is not
1875 ** used inside of NSS. 1876 ** used inside of NSS.
1876 ** XXX it doesn't check for failed allocations. :-( 1877 ** XXX it doesn't check for failed allocations. :-(
1877 */ 1878 */
1878 void * 1879 void *
1879 CERT_GetGeneralNameFromListByType(CERTGeneralNameList *list, 1880 CERT_GetGeneralNameFromListByType(CERTGeneralNameList *list,
1880 CERTGeneralNameType type, 1881 CERTGeneralNameType type,
1881 PLArenaPool *arena) 1882 PLArenaPool *arena)
1882 { 1883 {
1883 CERTName *name = NULL; 1884 CERTName *name = NULL;
1884 SECItem *item = NULL; 1885 SECItem *item = NULL;
1885 OtherName *other = NULL; 1886 OtherName *other = NULL;
1886 OtherName *tmpOther = NULL; 1887 OtherName *tmpOther = NULL;
1887 void *data; 1888 void *data;
1888 1889
1889 PZ_Lock(list->lock); 1890 PZ_Lock(list->lock);
1890 data = CERT_GetGeneralNameByType(list->name, type, PR_FALSE); 1891 data = CERT_GetGeneralNameByType(list->name, type, PR_FALSE);
1891 if (data != NULL) { 1892 if (data != NULL) {
1892 switch (type) { 1893 switch (type) {
1893 case certDNSName: 1894 case certDNSName:
1894 case certEDIPartyName: 1895 case certEDIPartyName:
1895 case certIPAddress: 1896 case certIPAddress:
1896 case certRegisterID: 1897 case certRegisterID:
1897 case certRFC822Name: 1898 case certRFC822Name:
1898 case certX400Address: 1899 case certX400Address:
1899 case certURI: 1900 case certURI:
1900 if (arena != NULL) { 1901 if (arena != NULL) {
1901 item = PORT_ArenaNew(arena, SECItem); 1902 item = PORT_ArenaNew(arena, SECItem);
1902 if (item != NULL) { 1903 if (item != NULL) {
1903 XXX SECITEM_CopyItem(arena, item, (SECItem *) data); 1904 XXX SECITEM_CopyItem(arena, item, (SECItem *) data);
1904 } 1905 }
1905 » } else { 1906 » } else {
1906 item = SECITEM_DupItem((SECItem *) data); 1907 item = SECITEM_DupItem((SECItem *) data);
1907 } 1908 }
1908 PZ_Unlock(list->lock); 1909 PZ_Unlock(list->lock);
1909 return item; 1910 return item;
1910 case certOtherName: 1911 case certOtherName:
1911 other = (OtherName *) data; 1912 other = (OtherName *) data;
1912 if (arena != NULL) { 1913 if (arena != NULL) {
1913 tmpOther = PORT_ArenaNew(arena, OtherName); 1914 tmpOther = PORT_ArenaNew(arena, OtherName);
1914 } else { 1915 } else {
1915 tmpOther = PORT_New(OtherName); 1916 tmpOther = PORT_New(OtherName);
(...skipping 20 matching lines...) Expand all
1936 } 1937 }
1937 #endif 1938 #endif
1938 1939
1939 #if 0 1940 #if 0
1940 /* This function is not exported from NSS shared libraries, and is not 1941 /* This function is not exported from NSS shared libraries, and is not
1941 ** used inside of NSS. 1942 ** used inside of NSS.
1942 ** XXX it should NOT be a void function, since it does allocations 1943 ** XXX it should NOT be a void function, since it does allocations
1943 ** that can fail. 1944 ** that can fail.
1944 */ 1945 */
1945 void 1946 void
1946 CERT_AddGeneralNameToList(CERTGeneralNameList *list, 1947 CERT_AddGeneralNameToList(CERTGeneralNameList *list,
1947 CERTGeneralNameType type, 1948 CERTGeneralNameType type,
1948 void *data, SECItem *oid) 1949 void *data, SECItem *oid)
1949 { 1950 {
1950 CERTGeneralName *name; 1951 CERTGeneralName *name;
1951 1952
1952 if (list != NULL && data != NULL) { 1953 if (list != NULL && data != NULL) {
1953 PZ_Lock(list->lock); 1954 PZ_Lock(list->lock);
1954 name = CERT_NewGeneralName(list->arena, type); 1955 name = CERT_NewGeneralName(list->arena, type);
1955 if (!name) 1956 if (!name)
1956 goto done; 1957 goto done;
(...skipping 19 matching lines...) Expand all
1976 break; 1977 break;
1977 } 1978 }
1978 list->name = cert_CombineNamesLists(list->name, name); 1979 list->name = cert_CombineNamesLists(list->name, name);
1979 list->len++; 1980 list->len++;
1980 done: 1981 done:
1981 PZ_Unlock(list->lock); 1982 PZ_Unlock(list->lock);
1982 } 1983 }
1983 return; 1984 return;
1984 } 1985 }
1985 #endif 1986 #endif
OLDNEW
« no previous file with comments | « nss/lib/certdb/genname.h ('k') | nss/lib/certdb/polcyxtn.c » ('j') | nss/lib/util/secoid.c » ('J')

Powered by Google App Engine
This is Rietveld 408576698