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