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 "cert.h" | 5 #include "cert.h" |
6 #include "certt.h" | 6 #include "certt.h" |
7 #include "secder.h" | 7 #include "secder.h" |
8 #include "key.h" | 8 #include "key.h" |
9 #include "secitem.h" | 9 #include "secitem.h" |
10 #include "secasn1.h" | 10 #include "secasn1.h" |
11 #include "secerr.h" | 11 #include "secerr.h" |
12 | 12 |
13 SEC_ASN1_MKSUB(SEC_AnyTemplate) | 13 SEC_ASN1_MKSUB(SEC_AnyTemplate) |
14 | 14 |
15 const SEC_ASN1Template CERT_AttributeTemplate[] = { | 15 const SEC_ASN1Template CERT_AttributeTemplate[] = { |
16 { SEC_ASN1_SEQUENCE, | 16 { SEC_ASN1_SEQUENCE, |
17 » 0, NULL, sizeof(CERTAttribute) }, | 17 0, NULL, sizeof(CERTAttribute) }, |
18 { SEC_ASN1_OBJECT_ID, offsetof(CERTAttribute, attrType) }, | 18 { SEC_ASN1_OBJECT_ID, offsetof(CERTAttribute, attrType) }, |
19 { SEC_ASN1_SET_OF | SEC_ASN1_XTRN, offsetof(CERTAttribute, attrValue), | 19 { SEC_ASN1_SET_OF | SEC_ASN1_XTRN, offsetof(CERTAttribute, attrValue), |
20 » SEC_ASN1_SUB(SEC_AnyTemplate) }, | 20 SEC_ASN1_SUB(SEC_AnyTemplate) }, |
21 { 0 } | 21 { 0 } |
22 }; | 22 }; |
23 | 23 |
24 const SEC_ASN1Template CERT_SetOfAttributeTemplate[] = { | 24 const SEC_ASN1Template CERT_SetOfAttributeTemplate[] = { |
25 { SEC_ASN1_SET_OF, 0, CERT_AttributeTemplate }, | 25 { SEC_ASN1_SET_OF, 0, CERT_AttributeTemplate }, |
26 }; | 26 }; |
27 | 27 |
28 const SEC_ASN1Template CERT_CertificateRequestTemplate[] = { | 28 const SEC_ASN1Template CERT_CertificateRequestTemplate[] = { |
29 { SEC_ASN1_SEQUENCE, | 29 { SEC_ASN1_SEQUENCE, |
30 » 0, NULL, sizeof(CERTCertificateRequest) }, | 30 0, NULL, sizeof(CERTCertificateRequest) }, |
31 { SEC_ASN1_INTEGER, | 31 { SEC_ASN1_INTEGER, |
32 » offsetof(CERTCertificateRequest,version) }, | 32 offsetof(CERTCertificateRequest, version) }, |
33 { SEC_ASN1_INLINE, | 33 { SEC_ASN1_INLINE, |
34 » offsetof(CERTCertificateRequest,subject), | 34 offsetof(CERTCertificateRequest, subject), |
35 » CERT_NameTemplate }, | 35 CERT_NameTemplate }, |
36 { SEC_ASN1_INLINE, | 36 { SEC_ASN1_INLINE, |
37 » offsetof(CERTCertificateRequest,subjectPublicKeyInfo), | 37 offsetof(CERTCertificateRequest, subjectPublicKeyInfo), |
38 » CERT_SubjectPublicKeyInfoTemplate }, | 38 CERT_SubjectPublicKeyInfoTemplate }, |
39 { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, | 39 { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, |
40 » offsetof(CERTCertificateRequest,attributes), | 40 offsetof(CERTCertificateRequest, attributes), |
41 » CERT_SetOfAttributeTemplate }, | 41 CERT_SetOfAttributeTemplate }, |
42 { 0 } | 42 { 0 } |
43 }; | 43 }; |
44 | 44 |
45 SEC_ASN1_CHOOSER_IMPLEMENT(CERT_CertificateRequestTemplate) | 45 SEC_ASN1_CHOOSER_IMPLEMENT(CERT_CertificateRequestTemplate) |
46 | 46 |
47 CERTCertificate * | 47 CERTCertificate * |
48 CERT_CreateCertificate(unsigned long serialNumber, | 48 CERT_CreateCertificate(unsigned long serialNumber, |
49 » » CERTName *issuer, | 49 CERTName *issuer, |
50 » » CERTValidity *validity, | 50 CERTValidity *validity, |
51 » » CERTCertificateRequest *req) | 51 CERTCertificateRequest *req) |
52 { | 52 { |
53 CERTCertificate *c; | 53 CERTCertificate *c; |
54 int rv; | 54 int rv; |
55 PLArenaPool *arena; | 55 PLArenaPool *arena; |
56 | 56 |
57 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 57 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
58 | 58 |
59 if ( !arena ) { | 59 if (!arena) { |
60 » return(0); | 60 return (0); |
61 } | 61 } |
62 | 62 |
63 c = (CERTCertificate *)PORT_ArenaZAlloc(arena, sizeof(CERTCertificate)); | 63 c = (CERTCertificate *)PORT_ArenaZAlloc(arena, sizeof(CERTCertificate)); |
64 | 64 |
65 if (!c) { | 65 if (!c) { |
66 » PORT_FreeArena(arena, PR_FALSE); | 66 PORT_FreeArena(arena, PR_FALSE); |
67 » return 0; | 67 return 0; |
68 } | 68 } |
69 | 69 |
70 c->referenceCount = 1; | 70 c->referenceCount = 1; |
71 c->arena = arena; | 71 c->arena = arena; |
72 | 72 |
73 /* | 73 /* |
74 * Default is a plain version 1. | 74 * Default is a plain version 1. |
75 * If extensions are added, it will get changed as appropriate. | 75 * If extensions are added, it will get changed as appropriate. |
76 */ | 76 */ |
77 rv = DER_SetUInteger(arena, &c->version, SEC_CERTIFICATE_VERSION_1); | 77 rv = DER_SetUInteger(arena, &c->version, SEC_CERTIFICATE_VERSION_1); |
78 if (rv) goto loser; | 78 if (rv) |
| 79 goto loser; |
79 | 80 |
80 rv = DER_SetUInteger(arena, &c->serialNumber, serialNumber); | 81 rv = DER_SetUInteger(arena, &c->serialNumber, serialNumber); |
81 if (rv) goto loser; | 82 if (rv) |
| 83 goto loser; |
82 | 84 |
83 rv = CERT_CopyName(arena, &c->issuer, issuer); | 85 rv = CERT_CopyName(arena, &c->issuer, issuer); |
84 if (rv) goto loser; | 86 if (rv) |
| 87 goto loser; |
85 | 88 |
86 rv = CERT_CopyValidity(arena, &c->validity, validity); | 89 rv = CERT_CopyValidity(arena, &c->validity, validity); |
87 if (rv) goto loser; | 90 if (rv) |
| 91 goto loser; |
88 | 92 |
89 rv = CERT_CopyName(arena, &c->subject, &req->subject); | 93 rv = CERT_CopyName(arena, &c->subject, &req->subject); |
90 if (rv) goto loser; | 94 if (rv) |
| 95 goto loser; |
91 rv = SECKEY_CopySubjectPublicKeyInfo(arena, &c->subjectPublicKeyInfo, | 96 rv = SECKEY_CopySubjectPublicKeyInfo(arena, &c->subjectPublicKeyInfo, |
92 » » » » » &req->subjectPublicKeyInfo); | 97 &req->subjectPublicKeyInfo); |
93 if (rv) goto loser; | 98 if (rv) |
| 99 goto loser; |
94 | 100 |
95 return c; | 101 return c; |
96 | 102 |
97 loser: | 103 loser: |
98 CERT_DestroyCertificate(c); | 104 CERT_DestroyCertificate(c); |
99 return 0; | 105 return 0; |
100 } | 106 } |
101 | 107 |
102 /************************************************************************/ | 108 /************************************************************************/ |
103 /* It's clear from the comments that the original author of this | 109 /* It's clear from the comments that the original author of this |
104 * function expected the template for certificate requests to treat | 110 * function expected the template for certificate requests to treat |
105 * the attributes as a SET OF ANY. This function expected to be | 111 * the attributes as a SET OF ANY. This function expected to be |
106 * passed an array of SECItems each of which contained an already encoded | 112 * passed an array of SECItems each of which contained an already encoded |
107 * Attribute. But the cert request template does not treat the | 113 * Attribute. But the cert request template does not treat the |
108 * Attributes as a SET OF ANY, and AFAIK never has. Instead the template | 114 * Attributes as a SET OF ANY, and AFAIK never has. Instead the template |
109 * encodes attributes as a SET OF xxxxxxx. That is, it expects to encode | 115 * encodes attributes as a SET OF xxxxxxx. That is, it expects to encode |
110 * each of the Attributes, not have them pre-encoded. Consequently an | 116 * each of the Attributes, not have them pre-encoded. Consequently an |
111 * array of SECItems containing encoded Attributes is of no value to this | 117 * array of SECItems containing encoded Attributes is of no value to this |
112 * function. But we cannot change the signature of this public function. | 118 * function. But we cannot change the signature of this public function. |
113 * It must continue to take SECItems. | 119 * It must continue to take SECItems. |
114 * | 120 * |
115 * I have recoded this function so that each SECItem contains an | 121 * I have recoded this function so that each SECItem contains an |
116 * encoded cert extension. The encoded cert extensions form the list for the | 122 * encoded cert extension. The encoded cert extensions form the list for the |
117 * single attribute of the cert request. In this implementation there is at most | 123 * single attribute of the cert request. In this implementation there is at most |
118 * one attribute and it is always of type SEC_OID_PKCS9_EXTENSION_REQUEST. | 124 * one attribute and it is always of type SEC_OID_PKCS9_EXTENSION_REQUEST. |
119 */ | 125 */ |
120 | 126 |
121 CERTCertificateRequest * | 127 CERTCertificateRequest * |
122 CERT_CreateCertificateRequest(CERTName *subject, | 128 CERT_CreateCertificateRequest(CERTName *subject, |
123 » » » CERTSubjectPublicKeyInfo *spki, | 129 CERTSubjectPublicKeyInfo *spki, |
124 » » » SECItem **attributes) | 130 SECItem **attributes) |
125 { | 131 { |
126 CERTCertificateRequest *certreq; | 132 CERTCertificateRequest *certreq; |
127 PLArenaPool *arena; | 133 PLArenaPool *arena; |
128 CERTAttribute * attribute; | 134 CERTAttribute *attribute; |
129 SECOidData * oidData; | 135 SECOidData *oidData; |
130 SECStatus rv; | 136 SECStatus rv; |
131 int i = 0; | 137 int i = 0; |
132 | 138 |
133 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 139 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
134 if ( arena == NULL ) { | 140 if (arena == NULL) { |
135 » return NULL; | 141 return NULL; |
136 } | 142 } |
137 | 143 |
138 certreq = PORT_ArenaZNew(arena, CERTCertificateRequest); | 144 certreq = PORT_ArenaZNew(arena, CERTCertificateRequest); |
139 if (!certreq) { | 145 if (!certreq) { |
140 » PORT_FreeArena(arena, PR_FALSE); | 146 PORT_FreeArena(arena, PR_FALSE); |
141 » return NULL; | 147 return NULL; |
142 } | 148 } |
143 /* below here it is safe to goto loser */ | 149 /* below here it is safe to goto loser */ |
144 | 150 |
145 certreq->arena = arena; | 151 certreq->arena = arena; |
146 | 152 |
147 rv = DER_SetUInteger(arena, &certreq->version, | 153 rv = DER_SetUInteger(arena, &certreq->version, |
148 » » » SEC_CERTIFICATE_REQUEST_VERSION); | 154 SEC_CERTIFICATE_REQUEST_VERSION); |
149 if (rv != SECSuccess) | 155 if (rv != SECSuccess) |
150 » goto loser; | 156 goto loser; |
151 | 157 |
152 rv = CERT_CopyName(arena, &certreq->subject, subject); | 158 rv = CERT_CopyName(arena, &certreq->subject, subject); |
153 if (rv != SECSuccess) | 159 if (rv != SECSuccess) |
154 » goto loser; | 160 goto loser; |
155 | 161 |
156 rv = SECKEY_CopySubjectPublicKeyInfo(arena, | 162 rv = SECKEY_CopySubjectPublicKeyInfo(arena, |
157 » » » » &certreq->subjectPublicKeyInfo, | 163 &certreq->subjectPublicKeyInfo, |
158 » » » » spki); | 164 spki); |
159 if (rv != SECSuccess) | 165 if (rv != SECSuccess) |
160 » goto loser; | 166 goto loser; |
161 | 167 |
162 certreq->attributes = PORT_ArenaZNewArray(arena, CERTAttribute*, 2); | 168 certreq->attributes = PORT_ArenaZNewArray(arena, CERTAttribute *, 2); |
163 if(!certreq->attributes) | 169 if (!certreq->attributes) |
164 » goto loser; | 170 goto loser; |
165 | 171 |
166 /* Copy over attribute information */ | 172 /* Copy over attribute information */ |
167 if (!attributes || !attributes[0]) { | 173 if (!attributes || !attributes[0]) { |
168 » /* | 174 /* |
169 ** Invent empty attribute information. According to the | 175 ** Invent empty attribute information. According to the |
170 ** pkcs#10 spec, attributes has this ASN.1 type: | 176 ** pkcs#10 spec, attributes has this ASN.1 type: |
171 ** | 177 ** |
172 ** attributes [0] IMPLICIT Attributes | 178 ** attributes [0] IMPLICIT Attributes |
173 » ** | 179 » ** |
174 ** Which means, we should create a NULL terminated list | 180 ** Which means, we should create a NULL terminated list |
175 ** with the first entry being NULL; | 181 ** with the first entry being NULL; |
176 */ | 182 */ |
177 » certreq->attributes[0] = NULL; | 183 certreq->attributes[0] = NULL; |
178 » return certreq; | 184 return certreq; |
179 }» | 185 } |
180 | 186 |
181 /* allocate space for attributes */ | 187 /* allocate space for attributes */ |
182 attribute = PORT_ArenaZNew(arena, CERTAttribute); | 188 attribute = PORT_ArenaZNew(arena, CERTAttribute); |
183 if (!attribute) | 189 if (!attribute) |
184 » goto loser; | 190 goto loser; |
185 | 191 |
186 oidData = SECOID_FindOIDByTag( SEC_OID_PKCS9_EXTENSION_REQUEST ); | 192 oidData = SECOID_FindOIDByTag(SEC_OID_PKCS9_EXTENSION_REQUEST); |
187 PORT_Assert(oidData); | 193 PORT_Assert(oidData); |
188 if (!oidData) | 194 if (!oidData) |
189 » goto loser; | 195 goto loser; |
190 rv = SECITEM_CopyItem(arena, &attribute->attrType, &oidData->oid); | 196 rv = SECITEM_CopyItem(arena, &attribute->attrType, &oidData->oid); |
191 if (rv != SECSuccess) | 197 if (rv != SECSuccess) |
192 » goto loser; | 198 goto loser; |
193 | 199 |
194 for (i = 0; attributes[i] != NULL ; i++) | 200 for (i = 0; attributes[i] != NULL; i++) |
195 » ; | 201 ; |
196 attribute->attrValue = PORT_ArenaZNewArray(arena, SECItem *, i+1); | 202 attribute->attrValue = PORT_ArenaZNewArray(arena, SECItem *, i + 1); |
197 if (!attribute->attrValue) | 203 if (!attribute->attrValue) |
198 » goto loser; | 204 goto loser; |
199 | 205 |
200 /* copy attributes */ | 206 /* copy attributes */ |
201 for (i = 0; attributes[i]; i++) { | 207 for (i = 0; attributes[i]; i++) { |
202 » /* | 208 /* |
203 ** Attributes are a SetOf Attribute which implies | 209 ** Attributes are a SetOf Attribute which implies |
204 ** lexigraphical ordering. It is assumes that the | 210 ** lexigraphical ordering. It is assumes that the |
205 ** attributes are passed in sorted. If we need to | 211 ** attributes are passed in sorted. If we need to |
206 ** add functionality to sort them, there is an | 212 ** add functionality to sort them, there is an |
207 ** example in the PKCS 7 code. | 213 ** example in the PKCS 7 code. |
208 */ | 214 */ |
209 » attribute->attrValue[i] = SECITEM_ArenaDupItem(arena, attributes[i]); | 215 attribute->attrValue[i] = SECITEM_ArenaDupItem(arena, attributes[i]); |
210 » if(!attribute->attrValue[i]) | 216 if (!attribute->attrValue[i]) |
211 » goto loser; | 217 goto loser; |
212 } | 218 } |
213 | 219 |
214 certreq->attributes[0] = attribute; | 220 certreq->attributes[0] = attribute; |
215 | 221 |
216 return certreq; | 222 return certreq; |
217 | 223 |
218 loser: | 224 loser: |
219 CERT_DestroyCertificateRequest(certreq); | 225 CERT_DestroyCertificateRequest(certreq); |
220 return NULL; | 226 return NULL; |
221 } | 227 } |
222 | 228 |
223 void | 229 void |
224 CERT_DestroyCertificateRequest(CERTCertificateRequest *req) | 230 CERT_DestroyCertificateRequest(CERTCertificateRequest *req) |
225 { | 231 { |
226 if (req && req->arena) { | 232 if (req && req->arena) { |
227 » PORT_FreeArena(req->arena, PR_FALSE); | 233 PORT_FreeArena(req->arena, PR_FALSE); |
228 } | 234 } |
229 return; | 235 return; |
230 } | 236 } |
231 | 237 |
232 static void | 238 static void |
233 setCRExt(void *o, CERTCertExtension **exts) | 239 setCRExt(void *o, CERTCertExtension **exts) |
234 { | 240 { |
235 ((CERTCertificateRequest *)o)->attributes = (struct CERTAttributeStr **)exts
; | 241 ((CERTCertificateRequest *)o)->attributes = (struct CERTAttributeStr **)exts
; |
236 } | 242 } |
237 | 243 |
238 /* | 244 /* |
239 ** Set up to start gathering cert extensions for a cert request. | 245 ** Set up to start gathering cert extensions for a cert request. |
240 ** The list is created as CertExtensions and converted to an | 246 ** The list is created as CertExtensions and converted to an |
241 ** attribute list by CERT_FinishCRAttributes(). | 247 ** attribute list by CERT_FinishCRAttributes(). |
242 */ | 248 */ |
243 extern void *cert_StartExtensions(void *owner, PLArenaPool *ownerArena, | 249 extern void *cert_StartExtensions(void *owner, PLArenaPool *ownerArena, |
244 void (*setExts)(void *object, CERTCertExtension **exts)); | 250 void (*setExts)(void *object, CERTCertExtensio
n **exts)); |
245 void * | 251 void * |
246 CERT_StartCertificateRequestAttributes(CERTCertificateRequest *req) | 252 CERT_StartCertificateRequestAttributes(CERTCertificateRequest *req) |
247 { | 253 { |
248 return (cert_StartExtensions ((void *)req, req->arena, setCRExt)); | 254 return (cert_StartExtensions((void *)req, req->arena, setCRExt)); |
249 } | 255 } |
250 | 256 |
251 /* | 257 /* |
252 ** At entry req->attributes actually contains an list of cert extensions-- | 258 ** At entry req->attributes actually contains an list of cert extensions-- |
253 ** req-attributes is overloaded until the list is DER encoded (the first | 259 ** req-attributes is overloaded until the list is DER encoded (the first |
254 ** ...EncodeItem() below). | 260 ** ...EncodeItem() below). |
255 ** We turn this into an attribute list by encapsulating it | 261 ** We turn this into an attribute list by encapsulating it |
256 ** in a PKCS 10 Attribute structure | 262 ** in a PKCS 10 Attribute structure |
257 */ | 263 */ |
258 SECStatus | 264 SECStatus |
259 CERT_FinishCertificateRequestAttributes(CERTCertificateRequest *req) | 265 CERT_FinishCertificateRequestAttributes(CERTCertificateRequest *req) |
260 { SECItem *extlist; | 266 { |
| 267 SECItem *extlist; |
261 SECOidData *oidrec; | 268 SECOidData *oidrec; |
262 CERTAttribute *attribute; | 269 CERTAttribute *attribute; |
263 | 270 |
264 if (!req || !req->arena) { | 271 if (!req || !req->arena) { |
265 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 272 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
266 return SECFailure; | 273 return SECFailure; |
267 } | 274 } |
268 if (req->attributes == NULL || req->attributes[0] == NULL) | 275 if (req->attributes == NULL || req->attributes[0] == NULL) |
269 return SECSuccess; | 276 return SECSuccess; |
270 | 277 |
271 extlist = SEC_ASN1EncodeItem(req->arena, NULL, &req->attributes, | 278 extlist = SEC_ASN1EncodeItem(req->arena, NULL, &req->attributes, |
272 SEC_ASN1_GET(CERT_SequenceOfCertExtensionTemplate)); | 279 SEC_ASN1_GET(CERT_SequenceOfCertExtensionTempla
te)); |
273 if (extlist == NULL) | 280 if (extlist == NULL) |
274 return(SECFailure); | 281 return (SECFailure); |
275 | 282 |
276 oidrec = SECOID_FindOIDByTag(SEC_OID_PKCS9_EXTENSION_REQUEST); | 283 oidrec = SECOID_FindOIDByTag(SEC_OID_PKCS9_EXTENSION_REQUEST); |
277 if (oidrec == NULL) | 284 if (oidrec == NULL) |
278 » return SECFailure; | 285 return SECFailure; |
279 | 286 |
280 /* now change the list of cert extensions into a list of attributes | 287 /* now change the list of cert extensions into a list of attributes |
281 */ | 288 */ |
282 req->attributes = PORT_ArenaZNewArray(req->arena, CERTAttribute*, 2); | 289 req->attributes = PORT_ArenaZNewArray(req->arena, CERTAttribute *, 2); |
283 | 290 |
284 attribute = PORT_ArenaZNew(req->arena, CERTAttribute); | 291 attribute = PORT_ArenaZNew(req->arena, CERTAttribute); |
285 | 292 |
286 if (req->attributes == NULL || attribute == NULL || | 293 if (req->attributes == NULL || attribute == NULL || |
287 SECITEM_CopyItem(req->arena, &attribute->attrType, &oidrec->oid) != 0) { | 294 SECITEM_CopyItem(req->arena, &attribute->attrType, &oidrec->oid) != 0) { |
288 PORT_SetError(SEC_ERROR_NO_MEMORY); | 295 PORT_SetError(SEC_ERROR_NO_MEMORY); |
289 » return SECFailure; | 296 return SECFailure; |
290 } | 297 } |
291 attribute->attrValue = PORT_ArenaZNewArray(req->arena, SECItem*, 2); | 298 attribute->attrValue = PORT_ArenaZNewArray(req->arena, SECItem *, 2); |
292 | 299 |
293 if (attribute->attrValue == NULL) | 300 if (attribute->attrValue == NULL) |
294 return SECFailure; | 301 return SECFailure; |
295 | 302 |
296 attribute->attrValue[0] = extlist; | 303 attribute->attrValue[0] = extlist; |
297 attribute->attrValue[1] = NULL; | 304 attribute->attrValue[1] = NULL; |
298 req->attributes[0] = attribute; | 305 req->attributes[0] = attribute; |
299 req->attributes[1] = NULL; | 306 req->attributes[1] = NULL; |
300 | 307 |
301 return SECSuccess; | 308 return SECSuccess; |
302 } | 309 } |
303 | 310 |
304 SECStatus | 311 SECStatus |
305 CERT_GetCertificateRequestExtensions(CERTCertificateRequest *req, | 312 CERT_GetCertificateRequestExtensions(CERTCertificateRequest *req, |
306 CERTCertExtension ***exts) | 313 CERTCertExtension ***exts) |
307 { | 314 { |
308 if (req == NULL || exts == NULL) { | 315 if (req == NULL || exts == NULL) { |
309 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 316 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
310 return SECFailure; | |
311 } | |
312 | |
313 if (req->attributes == NULL || *req->attributes == NULL) | |
314 return SECSuccess; | |
315 | |
316 if ((*req->attributes)->attrValue == NULL) { | |
317 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | |
318 return SECFailure; | 317 return SECFailure; |
319 } | 318 } |
320 | 319 |
321 return(SEC_ASN1DecodeItem(req->arena, exts, | 320 if (req->attributes == NULL || *req->attributes == NULL) |
322 SEC_ASN1_GET(CERT_SequenceOfCertExtensionTemplate), | 321 return SECSuccess; |
323 (*req->attributes)->attrValue[0])); | 322 |
| 323 if ((*req->attributes)->attrValue == NULL) { |
| 324 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 325 return SECFailure; |
| 326 } |
| 327 |
| 328 return (SEC_ASN1DecodeItem(req->arena, exts, |
| 329 SEC_ASN1_GET(CERT_SequenceOfCertExtensionTemplate
), |
| 330 (*req->attributes)->attrValue[0])); |
324 } | 331 } |
OLD | NEW |