| 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 |