crmfget.c (12435B)
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 "crmf.h" 7 #include "crmfi.h" 8 #include "keyhi.h" 9 #include "secder.h" 10 11 CRMFPOPChoice 12 CRMF_CertReqMsgGetPOPType(CRMFCertReqMsg *inCertReqMsg) 13 { 14 PORT_Assert(inCertReqMsg != NULL); 15 if (inCertReqMsg != NULL && inCertReqMsg->pop != NULL) { 16 return inCertReqMsg->pop->popUsed; 17 } 18 return crmfNoPOPChoice; 19 } 20 21 static SECStatus 22 crmf_destroy_validity(CRMFOptionalValidity *inValidity, PRBool freeit) 23 { 24 if (inValidity != NULL) { 25 if (inValidity->notBefore.data != NULL) { 26 PORT_Free(inValidity->notBefore.data); 27 } 28 if (inValidity->notAfter.data != NULL) { 29 PORT_Free(inValidity->notAfter.data); 30 } 31 if (freeit) { 32 PORT_Free(inValidity); 33 } 34 } 35 return SECSuccess; 36 } 37 38 static SECStatus 39 crmf_copy_cert_request_validity(PLArenaPool *poolp, 40 CRMFOptionalValidity **destValidity, 41 CRMFOptionalValidity *srcValidity) 42 { 43 CRMFOptionalValidity *myValidity = NULL; 44 SECStatus rv; 45 46 *destValidity = myValidity = (poolp == NULL) ? PORT_ZNew(CRMFOptionalValidity) 47 : PORT_ArenaZNew(poolp, CRMFOptionalValidity); 48 if (myValidity == NULL) { 49 goto loser; 50 } 51 if (srcValidity->notBefore.data != NULL) { 52 rv = SECITEM_CopyItem(poolp, &myValidity->notBefore, 53 &srcValidity->notBefore); 54 if (rv != SECSuccess) { 55 goto loser; 56 } 57 } 58 if (srcValidity->notAfter.data != NULL) { 59 rv = SECITEM_CopyItem(poolp, &myValidity->notAfter, 60 &srcValidity->notAfter); 61 if (rv != SECSuccess) { 62 goto loser; 63 } 64 } 65 return SECSuccess; 66 loser: 67 if (myValidity != NULL && poolp == NULL) { 68 crmf_destroy_validity(myValidity, PR_TRUE); 69 } 70 return SECFailure; 71 } 72 73 static SECStatus 74 crmf_copy_extensions(PLArenaPool *poolp, 75 CRMFCertTemplate *destTemplate, 76 CRMFCertExtension **srcExt) 77 { 78 int numExt = 0, i; 79 CRMFCertExtension **myExtArray = NULL; 80 81 while (srcExt[numExt] != NULL) { 82 numExt++; 83 } 84 if (numExt == 0) { 85 /*No extensions to copy.*/ 86 destTemplate->extensions = NULL; 87 destTemplate->numExtensions = 0; 88 return SECSuccess; 89 } 90 destTemplate->extensions = myExtArray = 91 PORT_NewArray(CRMFCertExtension *, numExt + 1); 92 if (myExtArray == NULL) { 93 goto loser; 94 } 95 96 for (i = 0; i < numExt; i++) { 97 myExtArray[i] = crmf_copy_cert_extension(poolp, srcExt[i]); 98 if (myExtArray[i] == NULL) { 99 goto loser; 100 } 101 } 102 destTemplate->numExtensions = numExt; 103 myExtArray[numExt] = NULL; 104 return SECSuccess; 105 loser: 106 if (myExtArray != NULL) { 107 if (poolp == NULL) { 108 for (i = 0; myExtArray[i] != NULL; i++) { 109 CRMF_DestroyCertExtension(myExtArray[i]); 110 } 111 } 112 PORT_Free(myExtArray); 113 } 114 destTemplate->extensions = NULL; 115 destTemplate->numExtensions = 0; 116 return SECFailure; 117 } 118 119 static SECStatus 120 crmf_copy_cert_request_template(PLArenaPool *poolp, 121 CRMFCertTemplate *destTemplate, 122 CRMFCertTemplate *srcTemplate) 123 { 124 SECStatus rv; 125 126 if (srcTemplate->version.data != NULL) { 127 rv = SECITEM_CopyItem(poolp, &destTemplate->version, 128 &srcTemplate->version); 129 if (rv != SECSuccess) { 130 goto loser; 131 } 132 } 133 if (srcTemplate->serialNumber.data != NULL) { 134 rv = SECITEM_CopyItem(poolp, &destTemplate->serialNumber, 135 &srcTemplate->serialNumber); 136 if (rv != SECSuccess) { 137 goto loser; 138 } 139 } 140 if (srcTemplate->signingAlg != NULL) { 141 rv = crmf_template_copy_secalg(poolp, &destTemplate->signingAlg, 142 srcTemplate->signingAlg); 143 if (rv != SECSuccess) { 144 goto loser; 145 } 146 } 147 if (srcTemplate->issuer != NULL) { 148 rv = crmf_copy_cert_name(poolp, &destTemplate->issuer, 149 srcTemplate->issuer); 150 if (rv != SECSuccess) { 151 goto loser; 152 } 153 } 154 if (srcTemplate->validity != NULL) { 155 rv = crmf_copy_cert_request_validity(poolp, &destTemplate->validity, 156 srcTemplate->validity); 157 if (rv != SECSuccess) { 158 goto loser; 159 } 160 } 161 if (srcTemplate->subject != NULL) { 162 rv = crmf_copy_cert_name(poolp, &destTemplate->subject, 163 srcTemplate->subject); 164 if (rv != SECSuccess) { 165 goto loser; 166 } 167 } 168 if (srcTemplate->publicKey != NULL) { 169 rv = crmf_template_add_public_key(poolp, &destTemplate->publicKey, 170 srcTemplate->publicKey); 171 if (rv != SECSuccess) { 172 goto loser; 173 } 174 } 175 if (srcTemplate->issuerUID.data != NULL) { 176 rv = crmf_make_bitstring_copy(poolp, &destTemplate->issuerUID, 177 &srcTemplate->issuerUID); 178 if (rv != SECSuccess) { 179 goto loser; 180 } 181 } 182 if (srcTemplate->subjectUID.data != NULL) { 183 rv = crmf_make_bitstring_copy(poolp, &destTemplate->subjectUID, 184 &srcTemplate->subjectUID); 185 if (rv != SECSuccess) { 186 goto loser; 187 } 188 } 189 if (srcTemplate->extensions != NULL) { 190 rv = crmf_copy_extensions(poolp, destTemplate, 191 srcTemplate->extensions); 192 if (rv != SECSuccess) { 193 goto loser; 194 } 195 } 196 return SECSuccess; 197 loser: 198 return SECFailure; 199 } 200 201 static CRMFControl * 202 crmf_copy_control(PLArenaPool *poolp, CRMFControl *srcControl) 203 { 204 CRMFControl *newControl; 205 SECStatus rv; 206 207 newControl = (poolp == NULL) ? PORT_ZNew(CRMFControl) : PORT_ArenaZNew(poolp, CRMFControl); 208 if (newControl == NULL) { 209 goto loser; 210 } 211 newControl->tag = srcControl->tag; 212 rv = SECITEM_CopyItem(poolp, &newControl->derTag, &srcControl->derTag); 213 if (rv != SECSuccess) { 214 goto loser; 215 } 216 rv = SECITEM_CopyItem(poolp, &newControl->derValue, &srcControl->derValue); 217 if (rv != SECSuccess) { 218 goto loser; 219 } 220 /* We only handle PKIArchiveOptions Control right now. But if in 221 * the future, more controls that are part of the union are added, 222 * then they need to be handled here as well. 223 */ 224 switch (newControl->tag) { 225 case SEC_OID_PKIX_REGCTRL_PKI_ARCH_OPTIONS: 226 rv = crmf_copy_pkiarchiveoptions(poolp, 227 &newControl->value.archiveOptions, 228 &srcControl->value.archiveOptions); 229 break; 230 default: 231 rv = SECSuccess; 232 } 233 if (rv != SECSuccess) { 234 goto loser; 235 } 236 return newControl; 237 238 loser: 239 if (poolp == NULL && newControl != NULL) { 240 CRMF_DestroyControl(newControl); 241 } 242 return NULL; 243 } 244 245 static SECStatus 246 crmf_copy_cert_request_controls(PLArenaPool *poolp, 247 CRMFCertRequest *destReq, 248 CRMFCertRequest *srcReq) 249 { 250 int numControls, i; 251 CRMFControl **myControls = NULL; 252 253 numControls = CRMF_CertRequestGetNumControls(srcReq); 254 if (numControls == 0) { 255 /* No Controls To Copy*/ 256 return SECSuccess; 257 } 258 myControls = destReq->controls = PORT_NewArray(CRMFControl *, 259 numControls + 1); 260 if (myControls == NULL) { 261 goto loser; 262 } 263 for (i = 0; i < numControls; i++) { 264 myControls[i] = crmf_copy_control(poolp, srcReq->controls[i]); 265 if (myControls[i] == NULL) { 266 goto loser; 267 } 268 } 269 myControls[numControls] = NULL; 270 return SECSuccess; 271 loser: 272 if (myControls != NULL) { 273 if (poolp == NULL) { 274 for (i = 0; myControls[i] != NULL; i++) { 275 CRMF_DestroyControl(myControls[i]); 276 } 277 } 278 PORT_Free(myControls); 279 } 280 return SECFailure; 281 } 282 283 CRMFCertRequest * 284 crmf_copy_cert_request(PLArenaPool *poolp, CRMFCertRequest *srcReq) 285 { 286 CRMFCertRequest *newReq = NULL; 287 SECStatus rv; 288 289 if (srcReq == NULL) { 290 return NULL; 291 } 292 newReq = (poolp == NULL) ? PORT_ZNew(CRMFCertRequest) : PORT_ArenaZNew(poolp, CRMFCertRequest); 293 if (newReq == NULL) { 294 goto loser; 295 } 296 rv = SECITEM_CopyItem(poolp, &newReq->certReqId, &srcReq->certReqId); 297 if (rv != SECSuccess) { 298 goto loser; 299 } 300 rv = crmf_copy_cert_request_template(poolp, &newReq->certTemplate, 301 &srcReq->certTemplate); 302 if (rv != SECSuccess) { 303 goto loser; 304 } 305 rv = crmf_copy_cert_request_controls(poolp, newReq, srcReq); 306 if (rv != SECSuccess) { 307 goto loser; 308 } 309 return newReq; 310 loser: 311 if (newReq != NULL && poolp == NULL) { 312 CRMF_DestroyCertRequest(newReq); 313 PORT_Free(newReq); 314 } 315 return NULL; 316 } 317 318 SECStatus 319 CRMF_DestroyGetValidity(CRMFGetValidity *inValidity) 320 { 321 PORT_Assert(inValidity != NULL); 322 if (inValidity != NULL) { 323 if (inValidity->notAfter) { 324 PORT_Free(inValidity->notAfter); 325 inValidity->notAfter = NULL; 326 } 327 if (inValidity->notBefore) { 328 PORT_Free(inValidity->notBefore); 329 inValidity->notBefore = NULL; 330 } 331 } 332 return SECSuccess; 333 } 334 335 SECStatus 336 crmf_make_bitstring_copy(PLArenaPool *arena, SECItem *dest, SECItem *src) 337 { 338 int origLenBits; 339 int bytesToCopy; 340 SECStatus rv; 341 342 origLenBits = src->len; 343 bytesToCopy = CRMF_BITS_TO_BYTES(origLenBits); 344 src->len = bytesToCopy; 345 rv = SECITEM_CopyItem(arena, dest, src); 346 src->len = origLenBits; 347 if (rv != SECSuccess) { 348 return rv; 349 } 350 dest->len = origLenBits; 351 return SECSuccess; 352 } 353 354 int 355 CRMF_CertRequestGetNumberOfExtensions(CRMFCertRequest *inCertReq) 356 { 357 CRMFCertTemplate *certTemplate; 358 int count = 0; 359 360 certTemplate = &inCertReq->certTemplate; 361 if (certTemplate->extensions) { 362 while (certTemplate->extensions[count] != NULL) 363 count++; 364 } 365 return count; 366 } 367 368 SECOidTag 369 CRMF_CertExtensionGetOidTag(CRMFCertExtension *inExtension) 370 { 371 PORT_Assert(inExtension != NULL); 372 if (inExtension == NULL) { 373 return SEC_OID_UNKNOWN; 374 } 375 return SECOID_FindOIDTag(&inExtension->id); 376 } 377 378 PRBool 379 CRMF_CertExtensionGetIsCritical(CRMFCertExtension *inExt) 380 { 381 PORT_Assert(inExt != NULL); 382 if (inExt == NULL) { 383 return PR_FALSE; 384 } 385 return inExt->critical.data != NULL; 386 } 387 388 SECItem * 389 CRMF_CertExtensionGetValue(CRMFCertExtension *inExtension) 390 { 391 PORT_Assert(inExtension != NULL); 392 if (inExtension == NULL) { 393 return NULL; 394 } 395 396 return SECITEM_DupItem(&inExtension->value); 397 } 398 399 SECStatus 400 CRMF_DestroyPOPOSigningKey(CRMFPOPOSigningKey *inKey) 401 { 402 PORT_Assert(inKey != NULL); 403 if (inKey != NULL) { 404 if (inKey->derInput.data != NULL) { 405 SECITEM_FreeItem(&inKey->derInput, PR_FALSE); 406 } 407 if (inKey->algorithmIdentifier != NULL) { 408 SECOID_DestroyAlgorithmID(inKey->algorithmIdentifier, PR_TRUE); 409 } 410 if (inKey->signature.data != NULL) { 411 SECITEM_FreeItem(&inKey->signature, PR_FALSE); 412 } 413 PORT_Free(inKey); 414 } 415 return SECSuccess; 416 } 417 418 SECStatus 419 CRMF_DestroyPOPOPrivKey(CRMFPOPOPrivKey *inPrivKey) 420 { 421 PORT_Assert(inPrivKey != NULL); 422 if (inPrivKey != NULL) { 423 SECITEM_FreeItem(&inPrivKey->message.thisMessage, PR_FALSE); 424 PORT_Free(inPrivKey); 425 } 426 return SECSuccess; 427 } 428 429 int 430 CRMF_CertRequestGetNumControls(CRMFCertRequest *inCertReq) 431 { 432 int count = 0; 433 434 PORT_Assert(inCertReq != NULL); 435 if (inCertReq == NULL) { 436 return 0; 437 } 438 if (inCertReq->controls) { 439 while (inCertReq->controls[count] != NULL) 440 count++; 441 } 442 return count; 443 }