respcmn.c (11844B)
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(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 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 94 crmf_create_prtime(SECItem *src, PRTime **dest) 95 { 96 *dest = PORT_ZNew(PRTime); 97 return DER_DecodeTimeChoice(*dest, src); 98 } 99 100 CRMFCertExtension * 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 * 123 cmmf_encode_certificate(CERTCertificate *inCert) 124 { 125 return SEC_ASN1EncodeItem(NULL, NULL, inCert, 126 SEC_ASN1_GET(SEC_SignedCertificateTemplate)); 127 } 128 129 CERTCertList * 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 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 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 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 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 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 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 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 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 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 * 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 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 }