|
1 /* -*- Mode: C; tab-width: 8 -*-*/ |
|
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 |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #include "cmmf.h" |
|
7 #include "cmmfi.h" |
|
8 #include "secitem.h" |
|
9 #include "secder.h" |
|
10 |
|
11 SECStatus |
|
12 cmmf_DestroyPKIStatusInfo (CMMFPKIStatusInfo *info, PRBool freeit) |
|
13 { |
|
14 if (info->status.data != NULL) { |
|
15 PORT_Free(info->status.data); |
|
16 info->status.data = NULL; |
|
17 } |
|
18 if (info->statusString.data != NULL) { |
|
19 PORT_Free(info->statusString.data); |
|
20 info->statusString.data = NULL; |
|
21 } |
|
22 if (info->failInfo.data != NULL) { |
|
23 PORT_Free(info->failInfo.data); |
|
24 info->failInfo.data = NULL; |
|
25 } |
|
26 if (freeit) { |
|
27 PORT_Free(info); |
|
28 } |
|
29 return SECSuccess; |
|
30 } |
|
31 |
|
32 SECStatus |
|
33 CMMF_DestroyCertResponse(CMMFCertResponse *inCertResp) |
|
34 { |
|
35 PORT_Assert(inCertResp != NULL); |
|
36 if (inCertResp != NULL) { |
|
37 if (inCertResp->certReqId.data != NULL) { |
|
38 PORT_Free(inCertResp->certReqId.data); |
|
39 } |
|
40 cmmf_DestroyPKIStatusInfo(&inCertResp->status, PR_FALSE); |
|
41 if (inCertResp->certifiedKeyPair != NULL) { |
|
42 CMMF_DestroyCertifiedKeyPair(inCertResp->certifiedKeyPair); |
|
43 } |
|
44 PORT_Free(inCertResp); |
|
45 } |
|
46 return SECSuccess; |
|
47 } |
|
48 |
|
49 SECStatus |
|
50 CMMF_DestroyCertRepContent(CMMFCertRepContent *inCertRepContent) |
|
51 { |
|
52 PORT_Assert(inCertRepContent != NULL); |
|
53 if (inCertRepContent != NULL) { |
|
54 CMMFCertResponse **pResponse = inCertRepContent->response; |
|
55 if (pResponse != NULL) { |
|
56 for (; *pResponse != NULL; pResponse++) { |
|
57 CMMFCertifiedKeyPair *certKeyPair = (*pResponse)->certifiedKeyPair; |
|
58 /* XXX Why not call CMMF_DestroyCertifiedKeyPair or |
|
59 ** XXX cmmf_DestroyCertOrEncCert ? |
|
60 */ |
|
61 if (certKeyPair != NULL && |
|
62 certKeyPair->certOrEncCert.choice == cmmfCertificate && |
|
63 certKeyPair->certOrEncCert.cert.certificate != NULL) { |
|
64 CERT_DestroyCertificate |
|
65 (certKeyPair->certOrEncCert.cert.certificate); |
|
66 certKeyPair->certOrEncCert.cert.certificate = NULL; |
|
67 } |
|
68 } |
|
69 } |
|
70 if (inCertRepContent->caPubs) { |
|
71 CERTCertificate **caPubs = inCertRepContent->caPubs; |
|
72 for (; *caPubs; ++caPubs) { |
|
73 CERT_DestroyCertificate(*caPubs); |
|
74 *caPubs = NULL; |
|
75 } |
|
76 } |
|
77 if (inCertRepContent->poolp != NULL) { |
|
78 PORT_FreeArena(inCertRepContent->poolp, PR_TRUE); |
|
79 } |
|
80 } |
|
81 return SECSuccess; |
|
82 } |
|
83 |
|
84 SECStatus |
|
85 CMMF_DestroyPOPODecKeyChallContent(CMMFPOPODecKeyChallContent *inDecKeyCont) |
|
86 { |
|
87 PORT_Assert(inDecKeyCont != NULL); |
|
88 if (inDecKeyCont != NULL && inDecKeyCont->poolp) { |
|
89 PORT_FreeArena(inDecKeyCont->poolp, PR_FALSE); |
|
90 } |
|
91 return SECSuccess; |
|
92 } |
|
93 |
|
94 SECStatus |
|
95 crmf_create_prtime(SECItem *src, PRTime **dest) |
|
96 { |
|
97 *dest = PORT_ZNew(PRTime); |
|
98 return DER_DecodeTimeChoice(*dest, src); |
|
99 } |
|
100 |
|
101 CRMFCertExtension* |
|
102 crmf_copy_cert_extension(PLArenaPool *poolp, CRMFCertExtension *inExtension) |
|
103 { |
|
104 PRBool isCritical; |
|
105 SECOidTag id; |
|
106 SECItem *data; |
|
107 CRMFCertExtension *newExt; |
|
108 |
|
109 PORT_Assert(inExtension != NULL); |
|
110 if (inExtension == NULL) { |
|
111 return NULL; |
|
112 } |
|
113 id = CRMF_CertExtensionGetOidTag(inExtension); |
|
114 isCritical = CRMF_CertExtensionGetIsCritical(inExtension); |
|
115 data = CRMF_CertExtensionGetValue(inExtension); |
|
116 newExt = crmf_create_cert_extension(poolp, id, |
|
117 isCritical, |
|
118 data); |
|
119 SECITEM_FreeItem(data, PR_TRUE); |
|
120 return newExt; |
|
121 } |
|
122 |
|
123 static SECItem* |
|
124 cmmf_encode_certificate(CERTCertificate *inCert) |
|
125 { |
|
126 return SEC_ASN1EncodeItem(NULL, NULL, inCert, |
|
127 SEC_ASN1_GET(SEC_SignedCertificateTemplate)); |
|
128 } |
|
129 |
|
130 CERTCertList* |
|
131 cmmf_MakeCertList(CERTCertificate **inCerts) |
|
132 { |
|
133 CERTCertList *certList; |
|
134 CERTCertificate *currCert; |
|
135 SECItem *derCert, *freeCert = NULL; |
|
136 SECStatus rv; |
|
137 int i; |
|
138 |
|
139 certList = CERT_NewCertList(); |
|
140 if (certList == NULL) { |
|
141 return NULL; |
|
142 } |
|
143 for (i=0; inCerts[i] != NULL; i++) { |
|
144 derCert = &inCerts[i]->derCert; |
|
145 if (derCert->data == NULL) { |
|
146 derCert = freeCert = cmmf_encode_certificate(inCerts[i]); |
|
147 } |
|
148 currCert=CERT_NewTempCertificate(CERT_GetDefaultCertDB(), |
|
149 derCert, NULL, PR_FALSE, PR_TRUE); |
|
150 if (freeCert != NULL) { |
|
151 SECITEM_FreeItem(freeCert, PR_TRUE); |
|
152 freeCert = NULL; |
|
153 } |
|
154 if (currCert == NULL) { |
|
155 goto loser; |
|
156 } |
|
157 rv = CERT_AddCertToListTail(certList, currCert); |
|
158 if (rv != SECSuccess) { |
|
159 goto loser; |
|
160 } |
|
161 } |
|
162 return certList; |
|
163 loser: |
|
164 CERT_DestroyCertList(certList); |
|
165 return NULL; |
|
166 } |
|
167 |
|
168 CMMFPKIStatus |
|
169 cmmf_PKIStatusInfoGetStatus(CMMFPKIStatusInfo *inStatus) |
|
170 { |
|
171 long derVal; |
|
172 |
|
173 derVal = DER_GetInteger(&inStatus->status); |
|
174 if (derVal == -1 || derVal < cmmfGranted || derVal >= cmmfNumPKIStatus) { |
|
175 return cmmfNoPKIStatus; |
|
176 } |
|
177 return (CMMFPKIStatus)derVal; |
|
178 } |
|
179 |
|
180 int |
|
181 CMMF_CertRepContentGetNumResponses(CMMFCertRepContent *inCertRepContent) |
|
182 { |
|
183 int numResponses = 0; |
|
184 PORT_Assert (inCertRepContent != NULL); |
|
185 if (inCertRepContent != NULL && inCertRepContent->response != NULL) { |
|
186 while (inCertRepContent->response[numResponses] != NULL) { |
|
187 numResponses++; |
|
188 } |
|
189 } |
|
190 return numResponses; |
|
191 } |
|
192 |
|
193 |
|
194 SECStatus |
|
195 cmmf_DestroyCertOrEncCert(CMMFCertOrEncCert *certOrEncCert, PRBool freeit) |
|
196 { |
|
197 switch (certOrEncCert->choice) { |
|
198 case cmmfCertificate: |
|
199 CERT_DestroyCertificate(certOrEncCert->cert.certificate); |
|
200 certOrEncCert->cert.certificate = NULL; |
|
201 break; |
|
202 case cmmfEncryptedCert: |
|
203 crmf_destroy_encrypted_value(certOrEncCert->cert.encryptedCert, |
|
204 PR_TRUE); |
|
205 certOrEncCert->cert.encryptedCert = NULL; |
|
206 break; |
|
207 default: |
|
208 break; |
|
209 } |
|
210 if (freeit) { |
|
211 PORT_Free(certOrEncCert); |
|
212 } |
|
213 return SECSuccess; |
|
214 } |
|
215 |
|
216 SECStatus |
|
217 cmmf_copy_secitem (PLArenaPool *poolp, SECItem *dest, SECItem *src) |
|
218 { |
|
219 SECStatus rv; |
|
220 |
|
221 if (src->data != NULL) { |
|
222 rv = SECITEM_CopyItem(poolp, dest, src); |
|
223 } else { |
|
224 dest->data = NULL; |
|
225 dest->len = 0; |
|
226 rv = SECSuccess; |
|
227 } |
|
228 return rv; |
|
229 } |
|
230 |
|
231 SECStatus |
|
232 CMMF_DestroyCertifiedKeyPair(CMMFCertifiedKeyPair *inCertKeyPair) |
|
233 { |
|
234 PORT_Assert(inCertKeyPair != NULL); |
|
235 if (inCertKeyPair != NULL) { |
|
236 cmmf_DestroyCertOrEncCert(&inCertKeyPair->certOrEncCert, PR_FALSE); |
|
237 if (inCertKeyPair->privateKey) { |
|
238 crmf_destroy_encrypted_value(inCertKeyPair->privateKey, PR_TRUE); |
|
239 } |
|
240 if (inCertKeyPair->derPublicationInfo.data) { |
|
241 PORT_Free(inCertKeyPair->derPublicationInfo.data); |
|
242 } |
|
243 PORT_Free(inCertKeyPair); |
|
244 } |
|
245 return SECSuccess; |
|
246 } |
|
247 |
|
248 SECStatus |
|
249 cmmf_CopyCertResponse(PLArenaPool *poolp, |
|
250 CMMFCertResponse *dest, |
|
251 CMMFCertResponse *src) |
|
252 { |
|
253 SECStatus rv; |
|
254 |
|
255 if (src->certReqId.data != NULL) { |
|
256 rv = SECITEM_CopyItem(poolp, &dest->certReqId, &src->certReqId); |
|
257 if (rv != SECSuccess) { |
|
258 return rv; |
|
259 } |
|
260 } |
|
261 rv = cmmf_CopyPKIStatusInfo(poolp, &dest->status, &src->status); |
|
262 if (rv != SECSuccess) { |
|
263 return rv; |
|
264 } |
|
265 if (src->certifiedKeyPair != NULL) { |
|
266 CMMFCertifiedKeyPair *destKeyPair; |
|
267 |
|
268 destKeyPair = (poolp == NULL) ? PORT_ZNew(CMMFCertifiedKeyPair) : |
|
269 PORT_ArenaZNew(poolp, CMMFCertifiedKeyPair); |
|
270 if (!destKeyPair) { |
|
271 return SECFailure; |
|
272 } |
|
273 rv = cmmf_CopyCertifiedKeyPair(poolp, destKeyPair, |
|
274 src->certifiedKeyPair); |
|
275 if (rv != SECSuccess) { |
|
276 if (!poolp) { |
|
277 CMMF_DestroyCertifiedKeyPair(destKeyPair); |
|
278 } |
|
279 return rv; |
|
280 } |
|
281 dest->certifiedKeyPair = destKeyPair; |
|
282 } |
|
283 return SECSuccess; |
|
284 } |
|
285 |
|
286 static SECStatus |
|
287 cmmf_CopyCertOrEncCert(PLArenaPool *poolp, CMMFCertOrEncCert *dest, |
|
288 CMMFCertOrEncCert *src) |
|
289 { |
|
290 SECStatus rv = SECSuccess; |
|
291 CRMFEncryptedValue *encVal; |
|
292 |
|
293 dest->choice = src->choice; |
|
294 rv = cmmf_copy_secitem(poolp, &dest->derValue, &src->derValue); |
|
295 switch (src->choice) { |
|
296 case cmmfCertificate: |
|
297 dest->cert.certificate = CERT_DupCertificate(src->cert.certificate); |
|
298 break; |
|
299 case cmmfEncryptedCert: |
|
300 encVal = (poolp == NULL) ? PORT_ZNew(CRMFEncryptedValue) : |
|
301 PORT_ArenaZNew(poolp, CRMFEncryptedValue); |
|
302 if (encVal == NULL) { |
|
303 return SECFailure; |
|
304 } |
|
305 rv = crmf_copy_encryptedvalue(poolp, src->cert.encryptedCert, encVal); |
|
306 if (rv != SECSuccess) { |
|
307 if (!poolp) { |
|
308 crmf_destroy_encrypted_value(encVal, PR_TRUE); |
|
309 } |
|
310 return rv; |
|
311 } |
|
312 dest->cert.encryptedCert = encVal; |
|
313 break; |
|
314 default: |
|
315 rv = SECFailure; |
|
316 } |
|
317 return rv; |
|
318 } |
|
319 |
|
320 SECStatus |
|
321 cmmf_CopyCertifiedKeyPair(PLArenaPool *poolp, CMMFCertifiedKeyPair *dest, |
|
322 CMMFCertifiedKeyPair *src) |
|
323 { |
|
324 SECStatus rv; |
|
325 |
|
326 rv = cmmf_CopyCertOrEncCert(poolp, &dest->certOrEncCert, |
|
327 &src->certOrEncCert); |
|
328 if (rv != SECSuccess) { |
|
329 return rv; |
|
330 } |
|
331 |
|
332 if (src->privateKey != NULL) { |
|
333 CRMFEncryptedValue *encVal; |
|
334 |
|
335 encVal = (poolp == NULL) ? PORT_ZNew(CRMFEncryptedValue) : |
|
336 PORT_ArenaZNew(poolp, CRMFEncryptedValue); |
|
337 if (encVal == NULL) { |
|
338 return SECFailure; |
|
339 } |
|
340 rv = crmf_copy_encryptedvalue(poolp, src->privateKey, |
|
341 encVal); |
|
342 if (rv != SECSuccess) { |
|
343 if (!poolp) { |
|
344 crmf_destroy_encrypted_value(encVal, PR_TRUE); |
|
345 } |
|
346 return rv; |
|
347 } |
|
348 dest->privateKey = encVal; |
|
349 } |
|
350 rv = cmmf_copy_secitem(poolp, &dest->derPublicationInfo, |
|
351 &src->derPublicationInfo); |
|
352 return rv; |
|
353 } |
|
354 |
|
355 SECStatus |
|
356 cmmf_CopyPKIStatusInfo(PLArenaPool *poolp, CMMFPKIStatusInfo *dest, |
|
357 CMMFPKIStatusInfo *src) |
|
358 { |
|
359 SECStatus rv; |
|
360 |
|
361 rv = cmmf_copy_secitem (poolp, &dest->status, &src->status); |
|
362 if (rv != SECSuccess) { |
|
363 return rv; |
|
364 } |
|
365 rv = cmmf_copy_secitem (poolp, &dest->statusString, &src->statusString); |
|
366 if (rv != SECSuccess) { |
|
367 return rv; |
|
368 } |
|
369 rv = cmmf_copy_secitem (poolp, &dest->failInfo, &src->failInfo); |
|
370 return rv; |
|
371 } |
|
372 |
|
373 CERTCertificate* |
|
374 cmmf_CertOrEncCertGetCertificate(CMMFCertOrEncCert *certOrEncCert, |
|
375 CERTCertDBHandle *certdb) |
|
376 { |
|
377 if (certOrEncCert->choice != cmmfCertificate || |
|
378 certOrEncCert->cert.certificate == NULL) { |
|
379 return NULL; |
|
380 } |
|
381 return CERT_NewTempCertificate(certdb, |
|
382 &certOrEncCert->cert.certificate->derCert, |
|
383 NULL, PR_FALSE, PR_TRUE); |
|
384 } |
|
385 |
|
386 SECStatus |
|
387 cmmf_PKIStatusInfoSetStatus(CMMFPKIStatusInfo *statusInfo, |
|
388 PLArenaPool *poolp, |
|
389 CMMFPKIStatus inStatus) |
|
390 { |
|
391 SECItem *dummy; |
|
392 |
|
393 if (inStatus <cmmfGranted || inStatus >= cmmfNumPKIStatus) { |
|
394 return SECFailure; |
|
395 } |
|
396 |
|
397 dummy = SEC_ASN1EncodeInteger(poolp, &statusInfo->status, inStatus); |
|
398 PORT_Assert(dummy == &statusInfo->status); |
|
399 if (dummy != &statusInfo->status) { |
|
400 SECITEM_FreeItem(dummy, PR_TRUE); |
|
401 return SECFailure; |
|
402 } |
|
403 return SECSuccess; |
|
404 } |
|
405 |
|
406 |