OLD | NEW |
1 /* -*- Mode: C; tab-width: 8 -*-*/ | 1 /* -*- Mode: C; tab-width: 8 -*-*/ |
2 /* This Source Code Form is subject to the terms of the Mozilla Public | 2 /* This Source Code Form is subject to the terms of the Mozilla Public |
3 * License, v. 2.0. If a copy of the MPL was not distributed with this | 3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
5 | 5 |
6 #include "crmf.h" | 6 #include "crmf.h" |
7 #include "crmfi.h" | 7 #include "crmfi.h" |
8 #include "keyhi.h" | 8 #include "keyhi.h" |
9 #include "secder.h" | 9 #include "secder.h" |
10 | 10 |
11 /* | 11 /* |
12 * Macro that returns PR_TRUE if the pointer is not NULL. | 12 * Macro that returns PR_TRUE if the pointer is not NULL. |
13 * If the pointer is NULL, then the macro will return PR_FALSE. | 13 * If the pointer is NULL, then the macro will return PR_FALSE. |
14 */ | 14 */ |
15 #define IS_NOT_NULL(ptr) ((ptr) == NULL) ? PR_FALSE : PR_TRUE | 15 #define IS_NOT_NULL(ptr) ((ptr) == NULL) ? PR_FALSE : PR_TRUE |
16 | 16 |
17 const unsigned char hexTrue = 0xff; | 17 const unsigned char hexTrue = 0xff; |
18 const unsigned char hexFalse = 0x00; | 18 const unsigned char hexFalse = 0x00; |
19 | 19 |
20 | 20 SECStatus crmf_encode_integer(PLArenaPool *poolp, SECItem *dest, long value) { |
21 SECStatus | 21 SECItem *dummy; |
22 crmf_encode_integer(PLArenaPool *poolp, SECItem *dest, long value) | 22 |
23 { | 23 dummy = SEC_ASN1EncodeInteger(poolp, dest, value); |
24 SECItem *dummy; | 24 PORT_Assert(dummy == dest); |
25 | 25 if (dummy == NULL) { |
26 dummy = SEC_ASN1EncodeInteger(poolp, dest, value); | 26 return SECFailure; |
27 PORT_Assert (dummy == dest); | 27 } |
28 if (dummy == NULL) { | 28 return SECSuccess; |
29 return SECFailure; | 29 } |
30 } | 30 |
31 return SECSuccess; | 31 SECStatus crmf_encode_unsigned_integer(PLArenaPool *poolp, SECItem *dest, |
32 } | 32 unsigned long value) { |
33 | 33 SECItem *dummy; |
34 SECStatus | 34 |
35 crmf_encode_unsigned_integer(PLArenaPool *poolp, SECItem *dest, | 35 dummy = SEC_ASN1EncodeUnsignedInteger(poolp, dest, value); |
36 unsigned long value) | 36 PORT_Assert(dummy == dest); |
37 { | 37 if (dummy != dest) { |
38 SECItem *dummy; | 38 return SECFailure; |
39 | 39 } |
40 dummy = SEC_ASN1EncodeUnsignedInteger(poolp, dest, value); | 40 return SECSuccess; |
41 PORT_Assert (dummy == dest); | 41 } |
42 if (dummy != dest) { | 42 |
43 return SECFailure; | 43 static SECStatus crmf_copy_secitem(PLArenaPool *poolp, SECItem *dest, |
44 } | 44 SECItem *src) { |
45 return SECSuccess; | 45 return SECITEM_CopyItem(poolp, dest, src); |
46 } | 46 } |
47 | 47 |
48 static SECStatus | 48 PRBool CRMF_DoesRequestHaveField(CRMFCertRequest *inCertReq, |
49 crmf_copy_secitem (PLArenaPool *poolp, SECItem *dest, SECItem *src) | 49 CRMFCertTemplateField inField) { |
50 { | 50 |
51 return SECITEM_CopyItem (poolp, dest, src); | 51 PORT_Assert(inCertReq != NULL); |
52 } | 52 if (inCertReq == NULL) { |
53 | 53 return PR_FALSE; |
54 PRBool | 54 } |
55 CRMF_DoesRequestHaveField (CRMFCertRequest *inCertReq,· | 55 switch (inField) { |
56 » » » CRMFCertTemplateField inField) | |
57 { | |
58 ·· | |
59 PORT_Assert(inCertReq != NULL); | |
60 if (inCertReq == NULL) { | |
61 return PR_FALSE; | |
62 } | |
63 switch (inField) { | |
64 case crmfVersion: | 56 case crmfVersion: |
65 return inCertReq->certTemplate.version.data != NULL; | 57 return inCertReq->certTemplate.version.data != NULL; |
66 case crmfSerialNumber: | 58 case crmfSerialNumber: |
67 return inCertReq->certTemplate.serialNumber.data != NULL; | 59 return inCertReq->certTemplate.serialNumber.data != NULL; |
68 case crmfSigningAlg: | 60 case crmfSigningAlg: |
69 return inCertReq->certTemplate.signingAlg != NULL; | 61 return inCertReq->certTemplate.signingAlg != NULL; |
70 case crmfIssuer: | 62 case crmfIssuer: |
71 return inCertReq->certTemplate.issuer != NULL; | 63 return inCertReq->certTemplate.issuer != NULL; |
72 case crmfValidity: | 64 case crmfValidity: |
73 return inCertReq->certTemplate.validity != NULL; | 65 return inCertReq->certTemplate.validity != NULL; |
74 case crmfSubject: | 66 case crmfSubject: |
75 return inCertReq->certTemplate.subject != NULL; | 67 return inCertReq->certTemplate.subject != NULL; |
76 case crmfPublicKey: | 68 case crmfPublicKey: |
77 return inCertReq->certTemplate.publicKey != NULL; | 69 return inCertReq->certTemplate.publicKey != NULL; |
78 case crmfIssuerUID: | 70 case crmfIssuerUID: |
79 return inCertReq->certTemplate.issuerUID.data != NULL; | 71 return inCertReq->certTemplate.issuerUID.data != NULL; |
80 case crmfSubjectUID: | 72 case crmfSubjectUID: |
81 return inCertReq->certTemplate.subjectUID.data != NULL; | 73 return inCertReq->certTemplate.subjectUID.data != NULL; |
82 case crmfExtension: | 74 case crmfExtension: |
83 return CRMF_CertRequestGetNumberOfExtensions(inCertReq) != 0; | 75 return CRMF_CertRequestGetNumberOfExtensions(inCertReq) != 0; |
84 } | 76 } |
85 return PR_FALSE; | 77 return PR_FALSE; |
86 } | 78 } |
87 | 79 |
88 CRMFCertRequest * | 80 CRMFCertRequest *CRMF_CreateCertRequest(PRUint32 inRequestID) { |
89 CRMF_CreateCertRequest (PRUint32 inRequestID) | 81 PLArenaPool *poolp; |
90 { | 82 CRMFCertRequest *certReq; |
91 PLArenaPool *poolp; | 83 SECStatus rv; |
92 CRMFCertRequest *certReq; | 84 |
93 SECStatus rv; | 85 poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE); |
94 ···· | 86 if (poolp == NULL) { |
95 poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE); | 87 goto loser; |
96 if (poolp == NULL) { | 88 } |
97 goto loser; | 89 |
98 } | 90 certReq = PORT_ArenaZNew(poolp, CRMFCertRequest); |
99 ···· | 91 if (certReq == NULL) { |
100 certReq=PORT_ArenaZNew(poolp,CRMFCertRequest); | 92 goto loser; |
101 if (certReq == NULL) { | 93 } |
102 goto loser; | 94 |
103 } | 95 certReq->poolp = poolp; |
104 | 96 certReq->requestID = inRequestID; |
105 certReq->poolp = poolp; | 97 |
106 certReq->requestID = inRequestID; | 98 rv = crmf_encode_unsigned_integer(poolp, &(certReq->certReqId), inRequestID); |
107 ···· | 99 if (rv != SECSuccess) { |
108 rv = crmf_encode_unsigned_integer(poolp, &(certReq->certReqId), | 100 goto loser; |
109 inRequestID); | 101 } |
110 if (rv != SECSuccess) { | 102 |
111 goto loser; | 103 return certReq; |
112 } | 104 loser: |
113 | 105 if (poolp) { |
114 return certReq; | 106 PORT_FreeArena(poolp, PR_FALSE); |
115 loser: | 107 } |
116 if (poolp) { | 108 return NULL; |
117 PORT_FreeArena(poolp, PR_FALSE); | 109 } |
118 } | 110 |
119 return NULL; | 111 SECStatus CRMF_DestroyCertRequest(CRMFCertRequest *inCertReq) { |
120 } | 112 PORT_Assert(inCertReq != NULL); |
121 | 113 if (inCertReq != NULL) { |
122 SECStatus | 114 if (inCertReq->certTemplate.extensions) { |
123 CRMF_DestroyCertRequest(CRMFCertRequest *inCertReq) | 115 PORT_Free(inCertReq->certTemplate.extensions); |
124 { | 116 } |
125 PORT_Assert(inCertReq != NULL); | 117 if (inCertReq->controls) { |
126 if (inCertReq != NULL) { | 118 /* Right now we don't support EnveloppedData option, |
127 if (inCertReq->certTemplate.extensions) { | 119 * so we won't go through and delete each occurrence of |
128 » PORT_Free(inCertReq->certTemplate.extensions); | 120 * an EnveloppedData in the control. |
129 » } | 121 */ |
130 » if (inCertReq->controls) { | 122 PORT_Free(inCertReq->controls); |
131 » /* Right now we don't support EnveloppedData option, | 123 } |
132 » * so we won't go through and delete each occurrence of· | 124 if (inCertReq->poolp) { |
133 » * an EnveloppedData in the control. | 125 PORT_FreeArena(inCertReq->poolp, PR_TRUE); |
134 » */ | 126 } |
135 » PORT_Free(inCertReq->controls); | 127 } |
136 » } | 128 return SECSuccess; |
137 » if (inCertReq->poolp) { | 129 } |
138 » PORT_FreeArena(inCertReq->poolp, PR_TRUE); | 130 |
139 » } | 131 static SECStatus crmf_template_add_version(PLArenaPool *poolp, SECItem *dest, |
140 } | 132 long version) { |
141 return SECSuccess; | 133 return (crmf_encode_integer(poolp, dest, version)); |
142 } | 134 } |
143 | 135 |
144 static SECStatus | 136 static SECStatus crmf_template_add_serialnumber(PLArenaPool *poolp, |
145 crmf_template_add_version(PLArenaPool *poolp, SECItem *dest, long version) | 137 SECItem *dest, long serial) { |
146 { | 138 return (crmf_encode_integer(poolp, dest, serial)); |
147 return (crmf_encode_integer(poolp, dest, version)); | 139 } |
148 } | 140 |
149 | 141 SECStatus crmf_template_copy_secalg(PLArenaPool *poolp, SECAlgorithmID **dest, |
150 static SECStatus | 142 SECAlgorithmID *src) { |
151 crmf_template_add_serialnumber(PLArenaPool *poolp, SECItem *dest, long serial) | 143 SECStatus rv; |
152 { | 144 void *mark = NULL; |
153 return (crmf_encode_integer(poolp, dest, serial)); | 145 SECAlgorithmID *mySecAlg; |
154 } | 146 |
155 | 147 if (!poolp) { |
156 SECStatus | 148 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
157 crmf_template_copy_secalg (PLArenaPool *poolp, SECAlgorithmID **dest, | |
158 » » » SECAlgorithmID* src) | |
159 { | |
160 SECStatus rv; | |
161 void *mark = NULL; | |
162 SECAlgorithmID *mySecAlg; | |
163 | |
164 if (!poolp) { | |
165 PORT_SetError(SEC_ERROR_INVALID_ARGS); | |
166 return SECFailure; | |
167 } | |
168 | |
169 mark = PORT_ArenaMark(poolp); | |
170 *dest = mySecAlg = PORT_ArenaZNew(poolp, SECAlgorithmID); | |
171 if (mySecAlg == NULL) { | |
172 goto loser; | |
173 } | |
174 rv = SECOID_CopyAlgorithmID(poolp, mySecAlg, src); | |
175 if (rv != SECSuccess) { | |
176 goto loser; | |
177 } | |
178 if (mark) { | |
179 PORT_ArenaUnmark(poolp, mark); | |
180 } | |
181 return SECSuccess; | |
182 | |
183 loser: | |
184 *dest = NULL; | |
185 if (mark) { | |
186 PORT_ArenaRelease(poolp, mark); | |
187 } | |
188 return SECFailure; | 149 return SECFailure; |
189 } | 150 } |
190 | 151 |
191 SECStatus | 152 mark = PORT_ArenaMark(poolp); |
192 crmf_copy_cert_name(PLArenaPool *poolp, CERTName **dest, | 153 *dest = mySecAlg = PORT_ArenaZNew(poolp, SECAlgorithmID); |
193 » » CERTName *src) | 154 if (mySecAlg == NULL) { |
194 { | 155 goto loser; |
195 CERTName *newName; | 156 } |
196 SECStatus rv; | 157 rv = SECOID_CopyAlgorithmID(poolp, mySecAlg, src); |
197 void *mark; | 158 if (rv != SECSuccess) { |
198 | 159 goto loser; |
199 mark = PORT_ArenaMark(poolp); | 160 } |
200 *dest = newName = PORT_ArenaZNew(poolp, CERTName); | 161 if (mark) { |
201 if (newName == NULL) { | 162 PORT_ArenaUnmark(poolp, mark); |
202 goto loser; | 163 } |
203 } | 164 return SECSuccess; |
204 | 165 |
205 rv = CERT_CopyName(poolp, newName, src); | 166 loser: |
| 167 *dest = NULL; |
| 168 if (mark) { |
| 169 PORT_ArenaRelease(poolp, mark); |
| 170 } |
| 171 return SECFailure; |
| 172 } |
| 173 |
| 174 SECStatus crmf_copy_cert_name(PLArenaPool *poolp, CERTName **dest, |
| 175 CERTName *src) { |
| 176 CERTName *newName; |
| 177 SECStatus rv; |
| 178 void *mark; |
| 179 |
| 180 mark = PORT_ArenaMark(poolp); |
| 181 *dest = newName = PORT_ArenaZNew(poolp, CERTName); |
| 182 if (newName == NULL) { |
| 183 goto loser; |
| 184 } |
| 185 |
| 186 rv = CERT_CopyName(poolp, newName, src); |
| 187 if (rv != SECSuccess) { |
| 188 goto loser; |
| 189 } |
| 190 PORT_ArenaUnmark(poolp, mark); |
| 191 return SECSuccess; |
| 192 loser: |
| 193 PORT_ArenaRelease(poolp, mark); |
| 194 *dest = NULL; |
| 195 return SECFailure; |
| 196 } |
| 197 |
| 198 static SECStatus crmf_template_add_issuer(PLArenaPool *poolp, CERTName **dest, |
| 199 CERTName *issuerName) { |
| 200 return crmf_copy_cert_name(poolp, dest, issuerName); |
| 201 } |
| 202 |
| 203 static SECStatus crmf_template_add_validity(PLArenaPool *poolp, |
| 204 CRMFOptionalValidity **dest, |
| 205 CRMFValidityCreationInfo *info) { |
| 206 SECStatus rv; |
| 207 void *mark; |
| 208 CRMFOptionalValidity *myValidity; |
| 209 |
| 210 /*First off, let's make sure at least one of the two fields is present*/ |
| 211 if (!info || (!info->notBefore && !info->notAfter)) { |
| 212 return SECFailure; |
| 213 } |
| 214 mark = PORT_ArenaMark(poolp); |
| 215 *dest = myValidity = PORT_ArenaZNew(poolp, CRMFOptionalValidity); |
| 216 if (myValidity == NULL) { |
| 217 goto loser; |
| 218 } |
| 219 |
| 220 if (info->notBefore) { |
| 221 rv = DER_EncodeTimeChoice(poolp, &myValidity->notBefore, *info->notBefore); |
206 if (rv != SECSuccess) { | 222 if (rv != SECSuccess) { |
207 goto loser; | 223 goto loser; |
208 } | 224 } |
209 PORT_ArenaUnmark(poolp, mark); | 225 } |
210 return SECSuccess; | 226 if (info->notAfter) { |
211 loser: | 227 rv = DER_EncodeTimeChoice(poolp, &myValidity->notAfter, *info->notAfter); |
212 PORT_ArenaRelease(poolp, mark); | |
213 *dest = NULL; | |
214 return SECFailure; | |
215 } | |
216 | |
217 static SECStatus | |
218 crmf_template_add_issuer (PLArenaPool *poolp, CERTName **dest, | |
219 » » » CERTName* issuerName) | |
220 { | |
221 return crmf_copy_cert_name(poolp, dest, issuerName); | |
222 } | |
223 | |
224 | |
225 static SECStatus | |
226 crmf_template_add_validity (PLArenaPool *poolp, CRMFOptionalValidity **dest, | |
227 » » » CRMFValidityCreationInfo *info) | |
228 { | |
229 SECStatus rv; | |
230 void *mark;· | |
231 CRMFOptionalValidity *myValidity; | |
232 | |
233 /*First off, let's make sure at least one of the two fields is present*/ | |
234 if (!info || (!info->notBefore && !info->notAfter)) { | |
235 return SECFailure; | |
236 } | |
237 mark = PORT_ArenaMark (poolp); | |
238 *dest = myValidity = PORT_ArenaZNew(poolp, CRMFOptionalValidity); | |
239 if (myValidity == NULL) { | |
240 goto loser; | |
241 } | |
242 | |
243 if (info->notBefore) { | |
244 rv = DER_EncodeTimeChoice (poolp, &myValidity->notBefore,· | |
245 » » » » *info->notBefore); | |
246 » if (rv != SECSuccess) { | |
247 » goto loser; | |
248 » } | |
249 } | |
250 if (info->notAfter) { | |
251 rv = DER_EncodeTimeChoice (poolp, &myValidity->notAfter, | |
252 » » » » *info->notAfter); | |
253 » if (rv != SECSuccess) { | |
254 » goto loser; | |
255 » } | |
256 } | |
257 PORT_ArenaUnmark(poolp, mark); | |
258 return SECSuccess; | |
259 loser: | |
260 PORT_ArenaRelease(poolp, mark); | |
261 *dest = NULL; | |
262 return SECFailure; | |
263 } | |
264 | |
265 static SECStatus | |
266 crmf_template_add_subject (PLArenaPool *poolp, CERTName **dest, | |
267 » » » CERTName *subject) | |
268 { | |
269 return crmf_copy_cert_name(poolp, dest, subject); | |
270 } | |
271 | |
272 SECStatus | |
273 crmf_template_add_public_key(PLArenaPool *poolp, | |
274 » » » CERTSubjectPublicKeyInfo **dest, | |
275 » » » CERTSubjectPublicKeyInfo *pubKey) | |
276 { | |
277 CERTSubjectPublicKeyInfo *spki; | |
278 SECStatus rv; | |
279 | |
280 *dest = spki = (poolp == NULL) ? | |
281 PORT_ZNew(CERTSubjectPublicKeyInfo) : | |
282 PORT_ArenaZNew (poolp, CERTSubjectPublicKeyInfo); | |
283 if (spki == NULL) { | |
284 goto loser; | |
285 } | |
286 rv = SECKEY_CopySubjectPublicKeyInfo (poolp, spki, pubKey); | |
287 if (rv != SECSuccess) { | 228 if (rv != SECSuccess) { |
288 goto loser; | 229 goto loser; |
289 } | 230 } |
290 return SECSuccess; | 231 } |
291 loser: | 232 PORT_ArenaUnmark(poolp, mark); |
292 if (poolp == NULL && spki != NULL) { | 233 return SECSuccess; |
293 SECKEY_DestroySubjectPublicKeyInfo(spki); | 234 loser: |
294 } | 235 PORT_ArenaRelease(poolp, mark); |
295 *dest = NULL; | 236 *dest = NULL; |
296 return SECFailure; | 237 return SECFailure; |
297 } | 238 } |
298 | 239 |
299 static SECStatus | 240 static SECStatus crmf_template_add_subject(PLArenaPool *poolp, CERTName **dest, |
300 crmf_copy_bitstring (PLArenaPool *poolp, SECItem *dest, const SECItem *src) | 241 CERTName *subject) { |
301 { | 242 return crmf_copy_cert_name(poolp, dest, subject); |
302 SECStatus rv; | 243 } |
303 SECItem byteSrc; | 244 |
304 ···· | 245 SECStatus crmf_template_add_public_key(PLArenaPool *poolp, |
305 byteSrc = *src; | 246 CERTSubjectPublicKeyInfo **dest, |
306 byteSrc.len = CRMF_BITS_TO_BYTES(byteSrc.len); | 247 CERTSubjectPublicKeyInfo *pubKey) { |
307 rv = crmf_copy_secitem(poolp, dest, &byteSrc); | 248 CERTSubjectPublicKeyInfo *spki; |
308 dest->len = src->len; | 249 SECStatus rv; |
309 return rv; | 250 |
310 } | 251 *dest = spki = (poolp == NULL) |
311 | 252 ? PORT_ZNew(CERTSubjectPublicKeyInfo) |
312 static SECStatus | 253 : PORT_ArenaZNew(poolp, CERTSubjectPublicKeyInfo); |
313 crmf_template_add_issuer_uid(PLArenaPool *poolp, SECItem *dest, | 254 if (spki == NULL) { |
314 » » » const SECItem *issuerUID) | 255 goto loser; |
315 { | 256 } |
316 return crmf_copy_bitstring (poolp, dest, issuerUID); | 257 rv = SECKEY_CopySubjectPublicKeyInfo(poolp, spki, pubKey); |
317 } | 258 if (rv != SECSuccess) { |
318 | 259 goto loser; |
319 static SECStatus | 260 } |
320 crmf_template_add_subject_uid(PLArenaPool *poolp, SECItem *dest, | 261 return SECSuccess; |
321 » » » const SECItem *subjectUID) | 262 loser: |
322 { | 263 if (poolp == NULL && spki != NULL) { |
323 return crmf_copy_bitstring (poolp, dest, subjectUID); | 264 SECKEY_DestroySubjectPublicKeyInfo(spki); |
324 } | 265 } |
325 | 266 *dest = NULL; |
326 static void | 267 return SECFailure; |
327 crmf_zeroize_new_extensions (CRMFCertExtension **extensions, | 268 } |
328 » » » int numToZeroize)· | 269 |
329 { | 270 static SECStatus crmf_copy_bitstring(PLArenaPool *poolp, SECItem *dest, |
330 PORT_Memset((void*)extensions, 0, sizeof(CERTCertExtension*)*numToZeroize); | 271 const SECItem *src) { |
| 272 SECStatus rv; |
| 273 SECItem byteSrc; |
| 274 |
| 275 byteSrc = *src; |
| 276 byteSrc.len = CRMF_BITS_TO_BYTES(byteSrc.len); |
| 277 rv = crmf_copy_secitem(poolp, dest, &byteSrc); |
| 278 dest->len = src->len; |
| 279 return rv; |
| 280 } |
| 281 |
| 282 static SECStatus crmf_template_add_issuer_uid(PLArenaPool *poolp, SECItem *dest, |
| 283 const SECItem *issuerUID) { |
| 284 return crmf_copy_bitstring(poolp, dest, issuerUID); |
| 285 } |
| 286 |
| 287 static SECStatus crmf_template_add_subject_uid(PLArenaPool *poolp, |
| 288 SECItem *dest, |
| 289 const SECItem *subjectUID) { |
| 290 return crmf_copy_bitstring(poolp, dest, subjectUID); |
| 291 } |
| 292 |
| 293 static void crmf_zeroize_new_extensions(CRMFCertExtension **extensions, |
| 294 int numToZeroize) { |
| 295 PORT_Memset((void *)extensions, 0, |
| 296 sizeof(CERTCertExtension *) * numToZeroize); |
331 } | 297 } |
332 | 298 |
333 /* | 299 /* |
334 * The strategy for adding templates will differ from all the other | 300 * The strategy for adding templates will differ from all the other |
335 * attributes in the template. First, we want to allow the client | 301 * attributes in the template. First, we want to allow the client |
336 * of this API to set extensions more than just once. So we will | 302 * of this API to set extensions more than just once. So we will |
337 * need the ability grow the array of extensions. Since arenas don't | 303 * need the ability grow the array of extensions. Since arenas don't |
338 * give us the realloc function, we'll use the generic PORT_* functions | 304 * give us the realloc function, we'll use the generic PORT_* functions |
339 * to allocate the array of pointers *ONLY*. Then we will allocate each | 305 * to allocate the array of pointers *ONLY*. Then we will allocate each |
340 * individual extension from the arena that comes along with the certReq | 306 * individual extension from the arena that comes along with the certReq |
341 * structure that owns this template. | 307 * structure that owns this template. |
342 */ | 308 */ |
343 static SECStatus | 309 static SECStatus crmf_template_add_extensions( |
344 crmf_template_add_extensions(PLArenaPool *poolp, CRMFCertTemplate *inTemplate, | 310 PLArenaPool *poolp, CRMFCertTemplate *inTemplate, |
345 » » » CRMFCertExtCreationInfo *extensions) | 311 CRMFCertExtCreationInfo *extensions) { |
346 { | 312 void *mark; |
347 void *mark; | 313 int newSize, oldSize, i; |
348 int newSize, oldSize, i; | 314 SECStatus rv; |
349 SECStatus rv; | 315 CRMFCertExtension **extArray; |
350 CRMFCertExtension **extArray; | 316 CRMFCertExtension *newExt, *currExt; |
351 CRMFCertExtension *newExt, *currExt; | 317 |
352 | 318 mark = PORT_ArenaMark(poolp); |
353 mark = PORT_ArenaMark(poolp); | 319 if (inTemplate->extensions == NULL) { |
354 if (inTemplate->extensions == NULL) { | 320 newSize = extensions->numExtensions; |
355 newSize = extensions->numExtensions; | 321 extArray = PORT_ZNewArray(CRMFCertExtension *, newSize + 1); |
356 extArray = PORT_ZNewArray(CRMFCertExtension*,newSize+1); | 322 } else { |
357 } else { | 323 newSize = inTemplate->numExtensions + extensions->numExtensions; |
358 newSize = inTemplate->numExtensions + extensions->numExtensions; | 324 extArray = PORT_Realloc(inTemplate->extensions, |
359 extArray = PORT_Realloc(inTemplate->extensions,· | 325 sizeof(CRMFCertExtension *) * (newSize + 1)); |
360 » » » » sizeof(CRMFCertExtension*)*(newSize+1)); | 326 } |
361 } | 327 if (extArray == NULL) { |
362 if (extArray == NULL) { | 328 goto loser; |
363 goto loser; | 329 } |
364 } | 330 oldSize = inTemplate->numExtensions; |
365 oldSize = inTemplate->numExtensions; | 331 inTemplate->extensions = extArray; |
366 inTemplate->extensions = extArray; | 332 inTemplate->numExtensions = newSize; |
367 inTemplate->numExtensions = newSize; | 333 for (i = oldSize; i < newSize; i++) { |
368 for (i=oldSize; i < newSize; i++) { | 334 newExt = PORT_ArenaZNew(poolp, CRMFCertExtension); |
369 newExt = PORT_ArenaZNew(poolp, CRMFCertExtension); | 335 if (newExt == NULL) { |
370 » if (newExt == NULL) { | 336 goto loser2; |
371 » goto loser2; | 337 } |
372 » } | 338 currExt = extensions->extensions[i - oldSize]; |
373 » currExt = extensions->extensions[i-oldSize]; | 339 rv = crmf_copy_secitem(poolp, &(newExt->id), &(currExt->id)); |
374 » rv = crmf_copy_secitem(poolp, &(newExt->id), &(currExt->id)); | 340 if (rv != SECSuccess) { |
375 » if (rv != SECSuccess) { | 341 goto loser2; |
376 » goto loser2; | 342 } |
377 » } | 343 rv = crmf_copy_secitem(poolp, &(newExt->critical), &(currExt->critical)); |
378 » rv = crmf_copy_secitem(poolp, &(newExt->critical), | 344 if (rv != SECSuccess) { |
379 » » » &(currExt->critical)); | 345 goto loser2; |
380 » if (rv != SECSuccess) { | 346 } |
381 » goto loser2; | 347 rv = crmf_copy_secitem(poolp, &(newExt->value), &(currExt->value)); |
382 » } | 348 if (rv != SECSuccess) { |
383 » rv = crmf_copy_secitem(poolp, &(newExt->value), &(currExt->value)); | 349 goto loser2; |
384 » if (rv != SECSuccess) { | 350 } |
385 » goto loser2; | 351 extArray[i] = newExt; |
386 » } | 352 } |
387 » extArray[i] = newExt; | 353 extArray[newSize] = NULL; |
388 } | 354 PORT_ArenaUnmark(poolp, mark); |
389 extArray[newSize] = NULL; | 355 return SECSuccess; |
390 PORT_ArenaUnmark(poolp, mark); | 356 loser2: |
391 return SECSuccess; | 357 crmf_zeroize_new_extensions(&(inTemplate->extensions[oldSize]), |
392 loser2: | 358 extensions->numExtensions); |
393 crmf_zeroize_new_extensions (&(inTemplate->extensions[oldSize]), | 359 inTemplate->numExtensions = oldSize; |
394 » » » » extensions->numExtensions); | 360 loser: |
395 inTemplate->numExtensions = oldSize; | 361 PORT_ArenaRelease(poolp, mark); |
396 loser: | 362 return SECFailure; |
397 PORT_ArenaRelease(poolp, mark); | 363 } |
| 364 |
| 365 SECStatus CRMF_CertRequestSetTemplateField( |
| 366 CRMFCertRequest *inCertReq, CRMFCertTemplateField inTemplateField, |
| 367 void *data) { |
| 368 CRMFCertTemplate *certTemplate; |
| 369 PLArenaPool *poolp; |
| 370 SECStatus rv = SECFailure; |
| 371 void *mark; |
| 372 |
| 373 if (inCertReq == NULL) { |
398 return SECFailure; | 374 return SECFailure; |
399 } | 375 } |
400 | 376 |
401 SECStatus | 377 certTemplate = &(inCertReq->certTemplate); |
402 CRMF_CertRequestSetTemplateField(CRMFCertRequest *inCertReq,· | 378 |
403 » » » » CRMFCertTemplateField inTemplateField, | 379 poolp = inCertReq->poolp; |
404 » » » » void *data) | 380 mark = PORT_ArenaMark(poolp); |
405 { | 381 switch (inTemplateField) { |
406 CRMFCertTemplate *certTemplate; | |
407 PLArenaPool *poolp; | |
408 SECStatus rv = SECFailure; | |
409 void *mark; | |
410 ···· | |
411 | |
412 if (inCertReq == NULL) { | |
413 return SECFailure; | |
414 } | |
415 | |
416 certTemplate = &(inCertReq->certTemplate); | |
417 | |
418 poolp = inCertReq->poolp; | |
419 mark = PORT_ArenaMark(poolp); | |
420 switch (inTemplateField) { | |
421 case crmfVersion: | 382 case crmfVersion: |
422 rv = crmf_template_add_version(poolp,&(certTemplate->version),· | 383 rv = crmf_template_add_version(poolp, &(certTemplate->version), |
423 » » » » *(long*)data); | 384 *(long *)data); |
424 break; | 385 break; |
425 case crmfSerialNumber: | 386 case crmfSerialNumber: |
426 rv = crmf_template_add_serialnumber(poolp, | 387 rv = crmf_template_add_serialnumber(poolp, &(certTemplate->serialNumber), |
427 » » » » » &(certTemplate->serialNumber), | 388 *(long *)data); |
428 » » » » » *(long*)data); | |
429 break; | 389 break; |
430 case crmfSigningAlg: | 390 case crmfSigningAlg: |
431 rv = crmf_template_copy_secalg (poolp, &(certTemplate->signingAlg), | 391 rv = crmf_template_copy_secalg(poolp, &(certTemplate->signingAlg), |
432 » » » » (SECAlgorithmID*)data); | 392 (SECAlgorithmID *)data); |
433 break; | 393 break; |
434 case crmfIssuer: | 394 case crmfIssuer: |
435 rv = crmf_template_add_issuer (poolp, &(certTemplate->issuer),· | 395 rv = crmf_template_add_issuer(poolp, &(certTemplate->issuer), |
436 » » » » (CERTName*)data); | 396 (CERTName *)data); |
437 break; | 397 break; |
438 case crmfValidity: | 398 case crmfValidity: |
439 rv = crmf_template_add_validity (poolp, &(certTemplate->validity), | 399 rv = crmf_template_add_validity(poolp, &(certTemplate->validity), |
440 » » » » (CRMFValidityCreationInfo*)data); | 400 (CRMFValidityCreationInfo *)data); |
441 break; | 401 break; |
442 case crmfSubject: | 402 case crmfSubject: |
443 rv = crmf_template_add_subject (poolp, &(certTemplate->subject), | 403 rv = crmf_template_add_subject(poolp, &(certTemplate->subject), |
444 » » » » (CERTName*)data); | 404 (CERTName *)data); |
445 break; | 405 break; |
446 case crmfPublicKey: | 406 case crmfPublicKey: |
447 rv = crmf_template_add_public_key(poolp, &(certTemplate->publicKey), | 407 rv = crmf_template_add_public_key(poolp, &(certTemplate->publicKey), |
448 » » » » » (CERTSubjectPublicKeyInfo*)data); | 408 (CERTSubjectPublicKeyInfo *)data); |
449 break; | 409 break; |
450 case crmfIssuerUID: | 410 case crmfIssuerUID: |
451 rv = crmf_template_add_issuer_uid(poolp, &(certTemplate->issuerUID), | 411 rv = crmf_template_add_issuer_uid(poolp, &(certTemplate->issuerUID), |
452 » » » » » (SECItem*)data); | 412 (SECItem *)data); |
453 break; | 413 break; |
454 case crmfSubjectUID: | 414 case crmfSubjectUID: |
455 rv = crmf_template_add_subject_uid(poolp, &(certTemplate->subjectUID), | 415 rv = crmf_template_add_subject_uid(poolp, &(certTemplate->subjectUID), |
456 » » » » » (SECItem*)data); | 416 (SECItem *)data); |
457 break; | 417 break; |
458 case crmfExtension: | 418 case crmfExtension: |
459 rv = crmf_template_add_extensions(poolp, certTemplate,· | 419 rv = crmf_template_add_extensions(poolp, certTemplate, |
460 » » » » » (CRMFCertExtCreationInfo*)data); | 420 (CRMFCertExtCreationInfo *)data); |
461 break; | 421 break; |
462 } | 422 } |
463 if (rv != SECSuccess) { | 423 if (rv != SECSuccess) { |
464 PORT_ArenaRelease(poolp, mark); | 424 PORT_ArenaRelease(poolp, mark); |
465 } else { | 425 } else { |
466 PORT_ArenaUnmark(poolp, mark); | 426 PORT_ArenaUnmark(poolp, mark); |
467 } | 427 } |
468 return rv; | 428 return rv; |
469 } | 429 } |
470 | 430 |
471 SECStatus | 431 SECStatus CRMF_CertReqMsgSetCertRequest(CRMFCertReqMsg *inCertReqMsg, |
472 CRMF_CertReqMsgSetCertRequest (CRMFCertReqMsg *inCertReqMsg,· | 432 CRMFCertRequest *inCertReq) { |
473 » » » CRMFCertRequest *inCertReq) | 433 PORT_Assert(inCertReqMsg != NULL && inCertReq != NULL); |
474 { | 434 if (inCertReqMsg == NULL || inCertReq == NULL) { |
475 PORT_Assert (inCertReqMsg != NULL && inCertReq != NULL); | 435 return SECFailure; |
476 if (inCertReqMsg == NULL || inCertReq == NULL) { | 436 } |
477 return SECFailure; | 437 inCertReqMsg->certReq = |
478 } | 438 crmf_copy_cert_request(inCertReqMsg->poolp, inCertReq); |
479 inCertReqMsg->certReq = crmf_copy_cert_request(inCertReqMsg->poolp, | 439 return (inCertReqMsg->certReq == NULL) ? SECFailure : SECSuccess; |
480 » » » » » » inCertReq); | 440 } |
481 return (inCertReqMsg->certReq == NULL) ? SECFailure : SECSuccess; | 441 |
482 } | 442 CRMFCertReqMsg *CRMF_CreateCertReqMsg(void) { |
483 | 443 PLArenaPool *poolp; |
484 CRMFCertReqMsg* | 444 CRMFCertReqMsg *reqMsg; |
485 CRMF_CreateCertReqMsg(void) | 445 |
486 { | 446 poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE); |
487 PLArenaPool *poolp; | 447 if (poolp == NULL) { |
488 CRMFCertReqMsg *reqMsg; | 448 goto loser; |
489 | 449 } |
490 poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE); | 450 reqMsg = PORT_ArenaZNew(poolp, CRMFCertReqMsg); |
491 if (poolp == NULL) { | 451 if (reqMsg == NULL) { |
492 goto loser; | 452 goto loser; |
493 } | 453 } |
494 reqMsg = PORT_ArenaZNew(poolp, CRMFCertReqMsg); | 454 reqMsg->poolp = poolp; |
495 if (reqMsg == NULL) { | 455 return reqMsg; |
496 goto loser; | 456 |
497 } | 457 loser: |
498 reqMsg->poolp = poolp; | 458 if (poolp) { |
499 return reqMsg; | 459 PORT_FreeArena(poolp, PR_FALSE); |
500 ···· | 460 } |
501 loser: | 461 return NULL; |
502 if (poolp) { | 462 } |
503 PORT_FreeArena(poolp, PR_FALSE); | 463 |
504 } | 464 SECStatus CRMF_DestroyCertReqMsg(CRMFCertReqMsg *inCertReqMsg) { |
505 return NULL; | 465 PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->poolp != NULL); |
506 } | 466 if (!inCertReqMsg->isDecoded) { |
507 | 467 if (inCertReqMsg->certReq->certTemplate.extensions != NULL) { |
508 SECStatus | 468 PORT_Free(inCertReqMsg->certReq->certTemplate.extensions); |
509 CRMF_DestroyCertReqMsg(CRMFCertReqMsg *inCertReqMsg) | 469 } |
510 { | 470 if (inCertReqMsg->certReq->controls != NULL) { |
511 PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->poolp != NULL); | 471 PORT_Free(inCertReqMsg->certReq->controls); |
512 if (!inCertReqMsg->isDecoded) { | 472 } |
513 if (inCertReqMsg->certReq->certTemplate.extensions != NULL) { | 473 } |
514 » PORT_Free(inCertReqMsg->certReq->certTemplate.extensions); | 474 PORT_FreeArena(inCertReqMsg->poolp, PR_TRUE); |
515 » } | 475 return SECSuccess; |
516 » if (inCertReqMsg->certReq->controls != NULL) { | 476 } |
517 » PORT_Free(inCertReqMsg->certReq->controls); | 477 |
518 » } | 478 CRMFCertExtension *crmf_create_cert_extension(PLArenaPool *poolp, SECOidTag id, |
519 } | 479 PRBool isCritical, |
520 PORT_FreeArena(inCertReqMsg->poolp, PR_TRUE); | 480 SECItem *data) { |
521 return SECSuccess; | 481 CRMFCertExtension *newExt; |
522 } | 482 SECOidData *oidData; |
523 | 483 SECStatus rv; |
524 CRMFCertExtension* | 484 |
525 crmf_create_cert_extension(PLArenaPool *poolp, | 485 newExt = (poolp == NULL) ? PORT_ZNew(CRMFCertExtension) |
526 » » » SECOidTag id, | 486 : PORT_ArenaZNew(poolp, CRMFCertExtension); |
527 » » » PRBool isCritical, | 487 if (newExt == NULL) { |
528 » » » SECItem *data) | 488 goto loser; |
529 { | 489 } |
530 CRMFCertExtension *newExt; | 490 oidData = SECOID_FindOIDByTag(id); |
531 SECOidData *oidData; | 491 if (oidData == NULL || |
532 SECStatus rv; | 492 oidData->supportedExtension != SUPPORTED_CERT_EXTENSION) { |
533 | 493 goto loser; |
534 newExt = (poolp == NULL) ? PORT_ZNew(CRMFCertExtension) : | 494 } |
535 PORT_ArenaZNew(poolp, CRMFCertExtension); | 495 |
536 if (newExt == NULL) { | 496 rv = SECITEM_CopyItem(poolp, &(newExt->id), &(oidData->oid)); |
537 goto loser; | 497 if (rv != SECSuccess) { |
538 } | 498 goto loser; |
539 oidData = SECOID_FindOIDByTag(id); | 499 } |
540 if (oidData == NULL ||· | 500 |
541 » oidData->supportedExtension != SUPPORTED_CERT_EXTENSION) { | 501 rv = SECITEM_CopyItem(poolp, &(newExt->value), data); |
542 goto loser; | 502 if (rv != SECSuccess) { |
543 } | 503 goto loser; |
544 | 504 } |
545 rv = SECITEM_CopyItem(poolp, &(newExt->id), &(oidData->oid)); | 505 |
546 if (rv != SECSuccess) { | 506 if (isCritical) { |
547 goto loser; | 507 newExt->critical.data = |
548 } | 508 (poolp == NULL) ? PORT_New(unsigned char) : PORT_ArenaNew( |
549 | 509 poolp, unsigned char); |
550 rv = SECITEM_CopyItem(poolp, &(newExt->value), data); | 510 if (newExt->critical.data == NULL) { |
551 if (rv != SECSuccess) { | 511 goto loser; |
552 goto loser; | 512 } |
553 } | 513 newExt->critical.data[0] = hexTrue; |
554 | 514 newExt->critical.len = 1; |
555 if (isCritical) { | 515 } |
556 newExt->critical.data = (poolp == NULL) ? | 516 return newExt; |
557 » PORT_New(unsigned char) : | 517 loser: |
558 » PORT_ArenaNew(poolp, unsigned char); | 518 if (newExt != NULL && poolp == NULL) { |
559 » if (newExt->critical.data == NULL) { | 519 CRMF_DestroyCertExtension(newExt); |
560 » goto loser; | 520 } |
561 » } | 521 return NULL; |
562 » newExt->critical.data[0] = hexTrue; | 522 } |
563 » newExt->critical.len = 1; | 523 |
564 } | 524 CRMFCertExtension *CRMF_CreateCertExtension(SECOidTag id, PRBool isCritical, |
565 return newExt; | 525 SECItem *data) { |
566 loser: | 526 return crmf_create_cert_extension(NULL, id, isCritical, data); |
567 if (newExt != NULL && poolp == NULL) { | 527 } |
568 CRMF_DestroyCertExtension(newExt); | 528 |
569 } | 529 static SECStatus crmf_destroy_cert_extension(CRMFCertExtension *inExtension, |
570 return NULL; | 530 PRBool freeit) { |
571 } | 531 if (inExtension != NULL) { |
572 | 532 SECITEM_FreeItem(&(inExtension->id), PR_FALSE); |
573 CRMFCertExtension * | 533 SECITEM_FreeItem(&(inExtension->value), PR_FALSE); |
574 CRMF_CreateCertExtension(SECOidTag id, | 534 SECITEM_FreeItem(&(inExtension->critical), PR_FALSE); |
575 » » » PRBool isCritical, | 535 if (freeit) { |
576 » » » SECItem *data) | 536 PORT_Free(inExtension); |
577 { | 537 } |
578 return crmf_create_cert_extension(NULL, id, isCritical, data); | 538 } |
579 } | 539 return SECSuccess; |
580 | 540 } |
581 static SECStatus | 541 |
582 crmf_destroy_cert_extension(CRMFCertExtension *inExtension, PRBool freeit) | 542 SECStatus CRMF_DestroyCertExtension(CRMFCertExtension *inExtension) { |
583 { | 543 return crmf_destroy_cert_extension(inExtension, PR_TRUE); |
584 if (inExtension != NULL) { | 544 } |
585 SECITEM_FreeItem (&(inExtension->id), PR_FALSE); | 545 |
586 » SECITEM_FreeItem (&(inExtension->value), PR_FALSE); | 546 SECStatus CRMF_DestroyCertReqMessages(CRMFCertReqMessages *inCertReqMsgs) { |
587 » SECITEM_FreeItem (&(inExtension->critical), PR_FALSE); | 547 PORT_Assert(inCertReqMsgs != NULL); |
588 » if (freeit) { | 548 if (inCertReqMsgs != NULL) { |
589 » PORT_Free(inExtension); | 549 PORT_FreeArena(inCertReqMsgs->poolp, PR_TRUE); |
590 » } | 550 } |
591 } | 551 return SECSuccess; |
592 return SECSuccess; | 552 } |
593 } | 553 |
594 | 554 static PRBool crmf_item_has_data(SECItem *item) { |
595 SECStatus | 555 if (item != NULL && item->data != NULL) { |
596 CRMF_DestroyCertExtension(CRMFCertExtension *inExtension) | 556 return PR_TRUE; |
597 { | 557 } |
598 return crmf_destroy_cert_extension(inExtension, PR_TRUE); | 558 return PR_FALSE; |
599 } | 559 } |
600 | 560 |
601 SECStatus | 561 PRBool CRMF_CertRequestIsFieldPresent(CRMFCertRequest *inCertReq, |
602 CRMF_DestroyCertReqMessages(CRMFCertReqMessages *inCertReqMsgs) | 562 CRMFCertTemplateField inTemplateField) { |
603 { | 563 PRBool retVal; |
604 PORT_Assert (inCertReqMsgs != NULL); | 564 CRMFCertTemplate *certTemplate; |
605 if (inCertReqMsgs != NULL) { | 565 |
606 PORT_FreeArena(inCertReqMsgs->poolp, PR_TRUE); | 566 PORT_Assert(inCertReq != NULL); |
607 } | 567 if (inCertReq == NULL) { |
608 return SECSuccess; | 568 /* This is probably some kind of error, but this is |
609 } | 569 * the safest return value for this function. |
610 | 570 */ |
611 static PRBool | |
612 crmf_item_has_data(SECItem *item) | |
613 { | |
614 if (item != NULL && item->data != NULL) { | |
615 return PR_TRUE; | |
616 } | |
617 return PR_FALSE; | 571 return PR_FALSE; |
618 } | 572 } |
619 | 573 certTemplate = &inCertReq->certTemplate; |
620 PRBool | 574 switch (inTemplateField) { |
621 CRMF_CertRequestIsFieldPresent(CRMFCertRequest *inCertReq, | |
622 » » » CRMFCertTemplateField inTemplateField) | |
623 { | |
624 PRBool retVal; | |
625 CRMFCertTemplate *certTemplate; | |
626 | |
627 PORT_Assert(inCertReq != NULL); | |
628 if (inCertReq == NULL) { | |
629 /* This is probably some kind of error, but this is· | |
630 » * the safest return value for this function. | |
631 » */ | |
632 return PR_FALSE; | |
633 } | |
634 certTemplate = &inCertReq->certTemplate; | |
635 switch (inTemplateField) { | |
636 case crmfVersion: | 575 case crmfVersion: |
637 retVal = crmf_item_has_data(&certTemplate->version); | 576 retVal = crmf_item_has_data(&certTemplate->version); |
638 break; | 577 break; |
639 case crmfSerialNumber: | 578 case crmfSerialNumber: |
640 retVal = crmf_item_has_data(&certTemplate->serialNumber); | 579 retVal = crmf_item_has_data(&certTemplate->serialNumber); |
641 break; | 580 break; |
642 case crmfSigningAlg: | 581 case crmfSigningAlg: |
643 retVal = IS_NOT_NULL(certTemplate->signingAlg); | 582 retVal = IS_NOT_NULL(certTemplate->signingAlg); |
644 break; | 583 break; |
645 case crmfIssuer: | 584 case crmfIssuer: |
(...skipping 12 matching lines...) Expand all Loading... |
658 retVal = crmf_item_has_data(&certTemplate->issuerUID); | 597 retVal = crmf_item_has_data(&certTemplate->issuerUID); |
659 break; | 598 break; |
660 case crmfSubjectUID: | 599 case crmfSubjectUID: |
661 retVal = crmf_item_has_data(&certTemplate->subjectUID); | 600 retVal = crmf_item_has_data(&certTemplate->subjectUID); |
662 break; | 601 break; |
663 case crmfExtension: | 602 case crmfExtension: |
664 retVal = IS_NOT_NULL(certTemplate->extensions); | 603 retVal = IS_NOT_NULL(certTemplate->extensions); |
665 break; | 604 break; |
666 default: | 605 default: |
667 retVal = PR_FALSE; | 606 retVal = PR_FALSE; |
668 } | 607 } |
669 return retVal; | 608 return retVal; |
670 } | 609 } |
OLD | NEW |