security/nss/lib/crmf/crmfget.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial