OLD | NEW |
1 /* This Source Code Form is subject to the terms of the Mozilla Public | 1 /* This Source Code Form is subject to the terms of the Mozilla Public |
2 * License, v. 2.0. If a copy of the MPL was not distributed with this | 2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
4 | 4 |
5 #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 *)¤t->name.other; /* SECItem * */ | 993 return (void *)¤t->name.other; /* SECItem * */ |
995 | 994 |
996 » case certOtherName: | 995 case certOtherName: |
997 » » return (void *)¤t->name.OthName; /* OthName * */ | 996 return (void *)¤t->name.OthName; /* OthName * */ |
998 | 997 |
999 » case certDirectoryName: | 998 case certDirectoryName: |
1000 » » return derFormat | 999 return derFormat |
1001 » » ? (void *)¤t->derDirectoryName /* SECItem * */ | 1000 ? (void *)¤t |
1002 » » : (void *)¤t->name.directoryName; /* CERTName * */ | 1001 ->derDirectoryName /* SECItem * */ |
1003 » } | 1002 : (void *)¤t->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 » ¤t->name.name.other); | 1395 compareDNSN2C(&name->name.other, ¤t->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 » ¤t->name.name.other); | 1400 ¤t->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, ¤t->name.name.other); |
1408 » » matched = compareURIN2C(&uri, ¤t->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 » ¤t->name.name.other); | 1455 ¤t->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 » » » » » ¤t->name.name.OthName.oid)) | 1473 ¤t->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, ¤t->name, name); | 1532 rv = cert_CopyOneGeneralName(arena, ¤t->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(¤t->l); | 1541 PR_INIT_CLIST(¤t->l); |
1538 } else { | 1542 } else { |
1539 PR_INSERT_BEFORE(¤t->l, &first->l); | 1543 PR_INSERT_BEFORE(¤t->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 Loading... |
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(¤tA->name.other, | 1818 if (SECITEM_CompareItem(¤tA->name.other, |
1818 » » » » » ¤tB->name.other) | 1819 » » » » » ¤tB->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(¤tA->name.OthName.oid, | 1825 if (SECITEM_CompareItem(¤tA->name.OthName.oid, |
1825 » » » » » ¤tB->name.OthName.oid) | 1826 » » » » » ¤tB->name.OthName.oid) |
1826 == SECEqual && | 1827 == SECEqual && |
1827 SECITEM_CompareItem(¤tA->name.OthName.name, | 1828 SECITEM_CompareItem(¤tA->name.OthName.name, |
1828 ¤tB->name.OthName.name) | 1829 ¤tB->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(¤tA->name.directoryName, | 1835 if (CERT_CompareName(¤tA->name.directoryName, |
1835 ¤tB->name.directoryName) | 1836 ¤tB->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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |