security/nss/lib/crmf/crmfreq.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 * Macro that returns PR_TRUE if the pointer is not NULL.
michael@0 13 * If the pointer is NULL, then the macro will return PR_FALSE.
michael@0 14 */
michael@0 15 #define IS_NOT_NULL(ptr) ((ptr) == NULL) ? PR_FALSE : PR_TRUE
michael@0 16
michael@0 17 const unsigned char hexTrue = 0xff;
michael@0 18 const unsigned char hexFalse = 0x00;
michael@0 19
michael@0 20
michael@0 21 SECStatus
michael@0 22 crmf_encode_integer(PLArenaPool *poolp, SECItem *dest, long value)
michael@0 23 {
michael@0 24 SECItem *dummy;
michael@0 25
michael@0 26 dummy = SEC_ASN1EncodeInteger(poolp, dest, value);
michael@0 27 PORT_Assert (dummy == dest);
michael@0 28 if (dummy == NULL) {
michael@0 29 return SECFailure;
michael@0 30 }
michael@0 31 return SECSuccess;
michael@0 32 }
michael@0 33
michael@0 34 SECStatus
michael@0 35 crmf_encode_unsigned_integer(PLArenaPool *poolp, SECItem *dest,
michael@0 36 unsigned long value)
michael@0 37 {
michael@0 38 SECItem *dummy;
michael@0 39
michael@0 40 dummy = SEC_ASN1EncodeUnsignedInteger(poolp, dest, value);
michael@0 41 PORT_Assert (dummy == dest);
michael@0 42 if (dummy != dest) {
michael@0 43 return SECFailure;
michael@0 44 }
michael@0 45 return SECSuccess;
michael@0 46 }
michael@0 47
michael@0 48 static SECStatus
michael@0 49 crmf_copy_secitem (PLArenaPool *poolp, SECItem *dest, SECItem *src)
michael@0 50 {
michael@0 51 return SECITEM_CopyItem (poolp, dest, src);
michael@0 52 }
michael@0 53
michael@0 54 PRBool
michael@0 55 CRMF_DoesRequestHaveField (CRMFCertRequest *inCertReq,
michael@0 56 CRMFCertTemplateField inField)
michael@0 57 {
michael@0 58
michael@0 59 PORT_Assert(inCertReq != NULL);
michael@0 60 if (inCertReq == NULL) {
michael@0 61 return PR_FALSE;
michael@0 62 }
michael@0 63 switch (inField) {
michael@0 64 case crmfVersion:
michael@0 65 return inCertReq->certTemplate.version.data != NULL;
michael@0 66 case crmfSerialNumber:
michael@0 67 return inCertReq->certTemplate.serialNumber.data != NULL;
michael@0 68 case crmfSigningAlg:
michael@0 69 return inCertReq->certTemplate.signingAlg != NULL;
michael@0 70 case crmfIssuer:
michael@0 71 return inCertReq->certTemplate.issuer != NULL;
michael@0 72 case crmfValidity:
michael@0 73 return inCertReq->certTemplate.validity != NULL;
michael@0 74 case crmfSubject:
michael@0 75 return inCertReq->certTemplate.subject != NULL;
michael@0 76 case crmfPublicKey:
michael@0 77 return inCertReq->certTemplate.publicKey != NULL;
michael@0 78 case crmfIssuerUID:
michael@0 79 return inCertReq->certTemplate.issuerUID.data != NULL;
michael@0 80 case crmfSubjectUID:
michael@0 81 return inCertReq->certTemplate.subjectUID.data != NULL;
michael@0 82 case crmfExtension:
michael@0 83 return CRMF_CertRequestGetNumberOfExtensions(inCertReq) != 0;
michael@0 84 }
michael@0 85 return PR_FALSE;
michael@0 86 }
michael@0 87
michael@0 88 CRMFCertRequest *
michael@0 89 CRMF_CreateCertRequest (PRUint32 inRequestID)
michael@0 90 {
michael@0 91 PLArenaPool *poolp;
michael@0 92 CRMFCertRequest *certReq;
michael@0 93 SECStatus rv;
michael@0 94
michael@0 95 poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
michael@0 96 if (poolp == NULL) {
michael@0 97 goto loser;
michael@0 98 }
michael@0 99
michael@0 100 certReq=PORT_ArenaZNew(poolp,CRMFCertRequest);
michael@0 101 if (certReq == NULL) {
michael@0 102 goto loser;
michael@0 103 }
michael@0 104
michael@0 105 certReq->poolp = poolp;
michael@0 106 certReq->requestID = inRequestID;
michael@0 107
michael@0 108 rv = crmf_encode_unsigned_integer(poolp, &(certReq->certReqId),
michael@0 109 inRequestID);
michael@0 110 if (rv != SECSuccess) {
michael@0 111 goto loser;
michael@0 112 }
michael@0 113
michael@0 114 return certReq;
michael@0 115 loser:
michael@0 116 if (poolp) {
michael@0 117 PORT_FreeArena(poolp, PR_FALSE);
michael@0 118 }
michael@0 119 return NULL;
michael@0 120 }
michael@0 121
michael@0 122 SECStatus
michael@0 123 CRMF_DestroyCertRequest(CRMFCertRequest *inCertReq)
michael@0 124 {
michael@0 125 PORT_Assert(inCertReq != NULL);
michael@0 126 if (inCertReq != NULL) {
michael@0 127 if (inCertReq->certTemplate.extensions) {
michael@0 128 PORT_Free(inCertReq->certTemplate.extensions);
michael@0 129 }
michael@0 130 if (inCertReq->controls) {
michael@0 131 /* Right now we don't support EnveloppedData option,
michael@0 132 * so we won't go through and delete each occurrence of
michael@0 133 * an EnveloppedData in the control.
michael@0 134 */
michael@0 135 PORT_Free(inCertReq->controls);
michael@0 136 }
michael@0 137 if (inCertReq->poolp) {
michael@0 138 PORT_FreeArena(inCertReq->poolp, PR_TRUE);
michael@0 139 }
michael@0 140 }
michael@0 141 return SECSuccess;
michael@0 142 }
michael@0 143
michael@0 144 static SECStatus
michael@0 145 crmf_template_add_version(PLArenaPool *poolp, SECItem *dest, long version)
michael@0 146 {
michael@0 147 return (crmf_encode_integer(poolp, dest, version));
michael@0 148 }
michael@0 149
michael@0 150 static SECStatus
michael@0 151 crmf_template_add_serialnumber(PLArenaPool *poolp, SECItem *dest, long serial)
michael@0 152 {
michael@0 153 return (crmf_encode_integer(poolp, dest, serial));
michael@0 154 }
michael@0 155
michael@0 156 SECStatus
michael@0 157 crmf_template_copy_secalg (PLArenaPool *poolp, SECAlgorithmID **dest,
michael@0 158 SECAlgorithmID* src)
michael@0 159 {
michael@0 160 SECStatus rv;
michael@0 161 void *mark = NULL;
michael@0 162 SECAlgorithmID *mySecAlg;
michael@0 163
michael@0 164 if (!poolp) {
michael@0 165 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 166 return SECFailure;
michael@0 167 }
michael@0 168
michael@0 169 mark = PORT_ArenaMark(poolp);
michael@0 170 *dest = mySecAlg = PORT_ArenaZNew(poolp, SECAlgorithmID);
michael@0 171 if (mySecAlg == NULL) {
michael@0 172 goto loser;
michael@0 173 }
michael@0 174 rv = SECOID_CopyAlgorithmID(poolp, mySecAlg, src);
michael@0 175 if (rv != SECSuccess) {
michael@0 176 goto loser;
michael@0 177 }
michael@0 178 if (mark) {
michael@0 179 PORT_ArenaUnmark(poolp, mark);
michael@0 180 }
michael@0 181 return SECSuccess;
michael@0 182
michael@0 183 loser:
michael@0 184 *dest = NULL;
michael@0 185 if (mark) {
michael@0 186 PORT_ArenaRelease(poolp, mark);
michael@0 187 }
michael@0 188 return SECFailure;
michael@0 189 }
michael@0 190
michael@0 191 SECStatus
michael@0 192 crmf_copy_cert_name(PLArenaPool *poolp, CERTName **dest,
michael@0 193 CERTName *src)
michael@0 194 {
michael@0 195 CERTName *newName;
michael@0 196 SECStatus rv;
michael@0 197 void *mark;
michael@0 198
michael@0 199 mark = PORT_ArenaMark(poolp);
michael@0 200 *dest = newName = PORT_ArenaZNew(poolp, CERTName);
michael@0 201 if (newName == NULL) {
michael@0 202 goto loser;
michael@0 203 }
michael@0 204
michael@0 205 rv = CERT_CopyName(poolp, newName, src);
michael@0 206 if (rv != SECSuccess) {
michael@0 207 goto loser;
michael@0 208 }
michael@0 209 PORT_ArenaUnmark(poolp, mark);
michael@0 210 return SECSuccess;
michael@0 211 loser:
michael@0 212 PORT_ArenaRelease(poolp, mark);
michael@0 213 *dest = NULL;
michael@0 214 return SECFailure;
michael@0 215 }
michael@0 216
michael@0 217 static SECStatus
michael@0 218 crmf_template_add_issuer (PLArenaPool *poolp, CERTName **dest,
michael@0 219 CERTName* issuerName)
michael@0 220 {
michael@0 221 return crmf_copy_cert_name(poolp, dest, issuerName);
michael@0 222 }
michael@0 223
michael@0 224
michael@0 225 static SECStatus
michael@0 226 crmf_template_add_validity (PLArenaPool *poolp, CRMFOptionalValidity **dest,
michael@0 227 CRMFValidityCreationInfo *info)
michael@0 228 {
michael@0 229 SECStatus rv;
michael@0 230 void *mark;
michael@0 231 CRMFOptionalValidity *myValidity;
michael@0 232
michael@0 233 /*First off, let's make sure at least one of the two fields is present*/
michael@0 234 if (!info || (!info->notBefore && !info->notAfter)) {
michael@0 235 return SECFailure;
michael@0 236 }
michael@0 237 mark = PORT_ArenaMark (poolp);
michael@0 238 *dest = myValidity = PORT_ArenaZNew(poolp, CRMFOptionalValidity);
michael@0 239 if (myValidity == NULL) {
michael@0 240 goto loser;
michael@0 241 }
michael@0 242
michael@0 243 if (info->notBefore) {
michael@0 244 rv = DER_EncodeTimeChoice (poolp, &myValidity->notBefore,
michael@0 245 *info->notBefore);
michael@0 246 if (rv != SECSuccess) {
michael@0 247 goto loser;
michael@0 248 }
michael@0 249 }
michael@0 250 if (info->notAfter) {
michael@0 251 rv = DER_EncodeTimeChoice (poolp, &myValidity->notAfter,
michael@0 252 *info->notAfter);
michael@0 253 if (rv != SECSuccess) {
michael@0 254 goto loser;
michael@0 255 }
michael@0 256 }
michael@0 257 PORT_ArenaUnmark(poolp, mark);
michael@0 258 return SECSuccess;
michael@0 259 loser:
michael@0 260 PORT_ArenaRelease(poolp, mark);
michael@0 261 *dest = NULL;
michael@0 262 return SECFailure;
michael@0 263 }
michael@0 264
michael@0 265 static SECStatus
michael@0 266 crmf_template_add_subject (PLArenaPool *poolp, CERTName **dest,
michael@0 267 CERTName *subject)
michael@0 268 {
michael@0 269 return crmf_copy_cert_name(poolp, dest, subject);
michael@0 270 }
michael@0 271
michael@0 272 SECStatus
michael@0 273 crmf_template_add_public_key(PLArenaPool *poolp,
michael@0 274 CERTSubjectPublicKeyInfo **dest,
michael@0 275 CERTSubjectPublicKeyInfo *pubKey)
michael@0 276 {
michael@0 277 CERTSubjectPublicKeyInfo *spki;
michael@0 278 SECStatus rv;
michael@0 279
michael@0 280 *dest = spki = (poolp == NULL) ?
michael@0 281 PORT_ZNew(CERTSubjectPublicKeyInfo) :
michael@0 282 PORT_ArenaZNew (poolp, CERTSubjectPublicKeyInfo);
michael@0 283 if (spki == NULL) {
michael@0 284 goto loser;
michael@0 285 }
michael@0 286 rv = SECKEY_CopySubjectPublicKeyInfo (poolp, spki, pubKey);
michael@0 287 if (rv != SECSuccess) {
michael@0 288 goto loser;
michael@0 289 }
michael@0 290 return SECSuccess;
michael@0 291 loser:
michael@0 292 if (poolp == NULL && spki != NULL) {
michael@0 293 SECKEY_DestroySubjectPublicKeyInfo(spki);
michael@0 294 }
michael@0 295 *dest = NULL;
michael@0 296 return SECFailure;
michael@0 297 }
michael@0 298
michael@0 299 static SECStatus
michael@0 300 crmf_copy_bitstring (PLArenaPool *poolp, SECItem *dest, const SECItem *src)
michael@0 301 {
michael@0 302 SECStatus rv;
michael@0 303 SECItem byteSrc;
michael@0 304
michael@0 305 byteSrc = *src;
michael@0 306 byteSrc.len = CRMF_BITS_TO_BYTES(byteSrc.len);
michael@0 307 rv = crmf_copy_secitem(poolp, dest, &byteSrc);
michael@0 308 dest->len = src->len;
michael@0 309 return rv;
michael@0 310 }
michael@0 311
michael@0 312 static SECStatus
michael@0 313 crmf_template_add_issuer_uid(PLArenaPool *poolp, SECItem *dest,
michael@0 314 const SECItem *issuerUID)
michael@0 315 {
michael@0 316 return crmf_copy_bitstring (poolp, dest, issuerUID);
michael@0 317 }
michael@0 318
michael@0 319 static SECStatus
michael@0 320 crmf_template_add_subject_uid(PLArenaPool *poolp, SECItem *dest,
michael@0 321 const SECItem *subjectUID)
michael@0 322 {
michael@0 323 return crmf_copy_bitstring (poolp, dest, subjectUID);
michael@0 324 }
michael@0 325
michael@0 326 static void
michael@0 327 crmf_zeroize_new_extensions (CRMFCertExtension **extensions,
michael@0 328 int numToZeroize)
michael@0 329 {
michael@0 330 PORT_Memset((void*)extensions, 0, sizeof(CERTCertExtension*)*numToZeroize);
michael@0 331 }
michael@0 332
michael@0 333 /*
michael@0 334 * The strategy for adding templates will differ from all the other
michael@0 335 * attributes in the template. First, we want to allow the client
michael@0 336 * of this API to set extensions more than just once. So we will
michael@0 337 * need the ability grow the array of extensions. Since arenas don't
michael@0 338 * give us the realloc function, we'll use the generic PORT_* functions
michael@0 339 * to allocate the array of pointers *ONLY*. Then we will allocate each
michael@0 340 * individual extension from the arena that comes along with the certReq
michael@0 341 * structure that owns this template.
michael@0 342 */
michael@0 343 static SECStatus
michael@0 344 crmf_template_add_extensions(PLArenaPool *poolp, CRMFCertTemplate *inTemplate,
michael@0 345 CRMFCertExtCreationInfo *extensions)
michael@0 346 {
michael@0 347 void *mark;
michael@0 348 int newSize, oldSize, i;
michael@0 349 SECStatus rv;
michael@0 350 CRMFCertExtension **extArray;
michael@0 351 CRMFCertExtension *newExt, *currExt;
michael@0 352
michael@0 353 mark = PORT_ArenaMark(poolp);
michael@0 354 if (inTemplate->extensions == NULL) {
michael@0 355 newSize = extensions->numExtensions;
michael@0 356 extArray = PORT_ZNewArray(CRMFCertExtension*,newSize+1);
michael@0 357 } else {
michael@0 358 newSize = inTemplate->numExtensions + extensions->numExtensions;
michael@0 359 extArray = PORT_Realloc(inTemplate->extensions,
michael@0 360 sizeof(CRMFCertExtension*)*(newSize+1));
michael@0 361 }
michael@0 362 if (extArray == NULL) {
michael@0 363 goto loser;
michael@0 364 }
michael@0 365 oldSize = inTemplate->numExtensions;
michael@0 366 inTemplate->extensions = extArray;
michael@0 367 inTemplate->numExtensions = newSize;
michael@0 368 for (i=oldSize; i < newSize; i++) {
michael@0 369 newExt = PORT_ArenaZNew(poolp, CRMFCertExtension);
michael@0 370 if (newExt == NULL) {
michael@0 371 goto loser2;
michael@0 372 }
michael@0 373 currExt = extensions->extensions[i-oldSize];
michael@0 374 rv = crmf_copy_secitem(poolp, &(newExt->id), &(currExt->id));
michael@0 375 if (rv != SECSuccess) {
michael@0 376 goto loser2;
michael@0 377 }
michael@0 378 rv = crmf_copy_secitem(poolp, &(newExt->critical),
michael@0 379 &(currExt->critical));
michael@0 380 if (rv != SECSuccess) {
michael@0 381 goto loser2;
michael@0 382 }
michael@0 383 rv = crmf_copy_secitem(poolp, &(newExt->value), &(currExt->value));
michael@0 384 if (rv != SECSuccess) {
michael@0 385 goto loser2;
michael@0 386 }
michael@0 387 extArray[i] = newExt;
michael@0 388 }
michael@0 389 extArray[newSize] = NULL;
michael@0 390 PORT_ArenaUnmark(poolp, mark);
michael@0 391 return SECSuccess;
michael@0 392 loser2:
michael@0 393 crmf_zeroize_new_extensions (&(inTemplate->extensions[oldSize]),
michael@0 394 extensions->numExtensions);
michael@0 395 inTemplate->numExtensions = oldSize;
michael@0 396 loser:
michael@0 397 PORT_ArenaRelease(poolp, mark);
michael@0 398 return SECFailure;
michael@0 399 }
michael@0 400
michael@0 401 SECStatus
michael@0 402 CRMF_CertRequestSetTemplateField(CRMFCertRequest *inCertReq,
michael@0 403 CRMFCertTemplateField inTemplateField,
michael@0 404 void *data)
michael@0 405 {
michael@0 406 CRMFCertTemplate *certTemplate;
michael@0 407 PLArenaPool *poolp;
michael@0 408 SECStatus rv = SECFailure;
michael@0 409 void *mark;
michael@0 410
michael@0 411
michael@0 412 if (inCertReq == NULL) {
michael@0 413 return SECFailure;
michael@0 414 }
michael@0 415
michael@0 416 certTemplate = &(inCertReq->certTemplate);
michael@0 417
michael@0 418 poolp = inCertReq->poolp;
michael@0 419 mark = PORT_ArenaMark(poolp);
michael@0 420 switch (inTemplateField) {
michael@0 421 case crmfVersion:
michael@0 422 rv = crmf_template_add_version(poolp,&(certTemplate->version),
michael@0 423 *(long*)data);
michael@0 424 break;
michael@0 425 case crmfSerialNumber:
michael@0 426 rv = crmf_template_add_serialnumber(poolp,
michael@0 427 &(certTemplate->serialNumber),
michael@0 428 *(long*)data);
michael@0 429 break;
michael@0 430 case crmfSigningAlg:
michael@0 431 rv = crmf_template_copy_secalg (poolp, &(certTemplate->signingAlg),
michael@0 432 (SECAlgorithmID*)data);
michael@0 433 break;
michael@0 434 case crmfIssuer:
michael@0 435 rv = crmf_template_add_issuer (poolp, &(certTemplate->issuer),
michael@0 436 (CERTName*)data);
michael@0 437 break;
michael@0 438 case crmfValidity:
michael@0 439 rv = crmf_template_add_validity (poolp, &(certTemplate->validity),
michael@0 440 (CRMFValidityCreationInfo*)data);
michael@0 441 break;
michael@0 442 case crmfSubject:
michael@0 443 rv = crmf_template_add_subject (poolp, &(certTemplate->subject),
michael@0 444 (CERTName*)data);
michael@0 445 break;
michael@0 446 case crmfPublicKey:
michael@0 447 rv = crmf_template_add_public_key(poolp, &(certTemplate->publicKey),
michael@0 448 (CERTSubjectPublicKeyInfo*)data);
michael@0 449 break;
michael@0 450 case crmfIssuerUID:
michael@0 451 rv = crmf_template_add_issuer_uid(poolp, &(certTemplate->issuerUID),
michael@0 452 (SECItem*)data);
michael@0 453 break;
michael@0 454 case crmfSubjectUID:
michael@0 455 rv = crmf_template_add_subject_uid(poolp, &(certTemplate->subjectUID),
michael@0 456 (SECItem*)data);
michael@0 457 break;
michael@0 458 case crmfExtension:
michael@0 459 rv = crmf_template_add_extensions(poolp, certTemplate,
michael@0 460 (CRMFCertExtCreationInfo*)data);
michael@0 461 break;
michael@0 462 }
michael@0 463 if (rv != SECSuccess) {
michael@0 464 PORT_ArenaRelease(poolp, mark);
michael@0 465 } else {
michael@0 466 PORT_ArenaUnmark(poolp, mark);
michael@0 467 }
michael@0 468 return rv;
michael@0 469 }
michael@0 470
michael@0 471 SECStatus
michael@0 472 CRMF_CertReqMsgSetCertRequest (CRMFCertReqMsg *inCertReqMsg,
michael@0 473 CRMFCertRequest *inCertReq)
michael@0 474 {
michael@0 475 PORT_Assert (inCertReqMsg != NULL && inCertReq != NULL);
michael@0 476 if (inCertReqMsg == NULL || inCertReq == NULL) {
michael@0 477 return SECFailure;
michael@0 478 }
michael@0 479 inCertReqMsg->certReq = crmf_copy_cert_request(inCertReqMsg->poolp,
michael@0 480 inCertReq);
michael@0 481 return (inCertReqMsg->certReq == NULL) ? SECFailure : SECSuccess;
michael@0 482 }
michael@0 483
michael@0 484 CRMFCertReqMsg*
michael@0 485 CRMF_CreateCertReqMsg(void)
michael@0 486 {
michael@0 487 PLArenaPool *poolp;
michael@0 488 CRMFCertReqMsg *reqMsg;
michael@0 489
michael@0 490 poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
michael@0 491 if (poolp == NULL) {
michael@0 492 goto loser;
michael@0 493 }
michael@0 494 reqMsg = PORT_ArenaZNew(poolp, CRMFCertReqMsg);
michael@0 495 if (reqMsg == NULL) {
michael@0 496 goto loser;
michael@0 497 }
michael@0 498 reqMsg->poolp = poolp;
michael@0 499 return reqMsg;
michael@0 500
michael@0 501 loser:
michael@0 502 if (poolp) {
michael@0 503 PORT_FreeArena(poolp, PR_FALSE);
michael@0 504 }
michael@0 505 return NULL;
michael@0 506 }
michael@0 507
michael@0 508 SECStatus
michael@0 509 CRMF_DestroyCertReqMsg(CRMFCertReqMsg *inCertReqMsg)
michael@0 510 {
michael@0 511 PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->poolp != NULL);
michael@0 512 if (!inCertReqMsg->isDecoded) {
michael@0 513 if (inCertReqMsg->certReq->certTemplate.extensions != NULL) {
michael@0 514 PORT_Free(inCertReqMsg->certReq->certTemplate.extensions);
michael@0 515 }
michael@0 516 if (inCertReqMsg->certReq->controls != NULL) {
michael@0 517 PORT_Free(inCertReqMsg->certReq->controls);
michael@0 518 }
michael@0 519 }
michael@0 520 PORT_FreeArena(inCertReqMsg->poolp, PR_TRUE);
michael@0 521 return SECSuccess;
michael@0 522 }
michael@0 523
michael@0 524 CRMFCertExtension*
michael@0 525 crmf_create_cert_extension(PLArenaPool *poolp,
michael@0 526 SECOidTag id,
michael@0 527 PRBool isCritical,
michael@0 528 SECItem *data)
michael@0 529 {
michael@0 530 CRMFCertExtension *newExt;
michael@0 531 SECOidData *oidData;
michael@0 532 SECStatus rv;
michael@0 533
michael@0 534 newExt = (poolp == NULL) ? PORT_ZNew(CRMFCertExtension) :
michael@0 535 PORT_ArenaZNew(poolp, CRMFCertExtension);
michael@0 536 if (newExt == NULL) {
michael@0 537 goto loser;
michael@0 538 }
michael@0 539 oidData = SECOID_FindOIDByTag(id);
michael@0 540 if (oidData == NULL ||
michael@0 541 oidData->supportedExtension != SUPPORTED_CERT_EXTENSION) {
michael@0 542 goto loser;
michael@0 543 }
michael@0 544
michael@0 545 rv = SECITEM_CopyItem(poolp, &(newExt->id), &(oidData->oid));
michael@0 546 if (rv != SECSuccess) {
michael@0 547 goto loser;
michael@0 548 }
michael@0 549
michael@0 550 rv = SECITEM_CopyItem(poolp, &(newExt->value), data);
michael@0 551 if (rv != SECSuccess) {
michael@0 552 goto loser;
michael@0 553 }
michael@0 554
michael@0 555 if (isCritical) {
michael@0 556 newExt->critical.data = (poolp == NULL) ?
michael@0 557 PORT_New(unsigned char) :
michael@0 558 PORT_ArenaNew(poolp, unsigned char);
michael@0 559 if (newExt->critical.data == NULL) {
michael@0 560 goto loser;
michael@0 561 }
michael@0 562 newExt->critical.data[0] = hexTrue;
michael@0 563 newExt->critical.len = 1;
michael@0 564 }
michael@0 565 return newExt;
michael@0 566 loser:
michael@0 567 if (newExt != NULL && poolp == NULL) {
michael@0 568 CRMF_DestroyCertExtension(newExt);
michael@0 569 }
michael@0 570 return NULL;
michael@0 571 }
michael@0 572
michael@0 573 CRMFCertExtension *
michael@0 574 CRMF_CreateCertExtension(SECOidTag id,
michael@0 575 PRBool isCritical,
michael@0 576 SECItem *data)
michael@0 577 {
michael@0 578 return crmf_create_cert_extension(NULL, id, isCritical, data);
michael@0 579 }
michael@0 580
michael@0 581 static SECStatus
michael@0 582 crmf_destroy_cert_extension(CRMFCertExtension *inExtension, PRBool freeit)
michael@0 583 {
michael@0 584 if (inExtension != NULL) {
michael@0 585 SECITEM_FreeItem (&(inExtension->id), PR_FALSE);
michael@0 586 SECITEM_FreeItem (&(inExtension->value), PR_FALSE);
michael@0 587 SECITEM_FreeItem (&(inExtension->critical), PR_FALSE);
michael@0 588 if (freeit) {
michael@0 589 PORT_Free(inExtension);
michael@0 590 }
michael@0 591 }
michael@0 592 return SECSuccess;
michael@0 593 }
michael@0 594
michael@0 595 SECStatus
michael@0 596 CRMF_DestroyCertExtension(CRMFCertExtension *inExtension)
michael@0 597 {
michael@0 598 return crmf_destroy_cert_extension(inExtension, PR_TRUE);
michael@0 599 }
michael@0 600
michael@0 601 SECStatus
michael@0 602 CRMF_DestroyCertReqMessages(CRMFCertReqMessages *inCertReqMsgs)
michael@0 603 {
michael@0 604 PORT_Assert (inCertReqMsgs != NULL);
michael@0 605 if (inCertReqMsgs != NULL) {
michael@0 606 PORT_FreeArena(inCertReqMsgs->poolp, PR_TRUE);
michael@0 607 }
michael@0 608 return SECSuccess;
michael@0 609 }
michael@0 610
michael@0 611 static PRBool
michael@0 612 crmf_item_has_data(SECItem *item)
michael@0 613 {
michael@0 614 if (item != NULL && item->data != NULL) {
michael@0 615 return PR_TRUE;
michael@0 616 }
michael@0 617 return PR_FALSE;
michael@0 618 }
michael@0 619
michael@0 620 PRBool
michael@0 621 CRMF_CertRequestIsFieldPresent(CRMFCertRequest *inCertReq,
michael@0 622 CRMFCertTemplateField inTemplateField)
michael@0 623 {
michael@0 624 PRBool retVal;
michael@0 625 CRMFCertTemplate *certTemplate;
michael@0 626
michael@0 627 PORT_Assert(inCertReq != NULL);
michael@0 628 if (inCertReq == NULL) {
michael@0 629 /* This is probably some kind of error, but this is
michael@0 630 * the safest return value for this function.
michael@0 631 */
michael@0 632 return PR_FALSE;
michael@0 633 }
michael@0 634 certTemplate = &inCertReq->certTemplate;
michael@0 635 switch (inTemplateField) {
michael@0 636 case crmfVersion:
michael@0 637 retVal = crmf_item_has_data(&certTemplate->version);
michael@0 638 break;
michael@0 639 case crmfSerialNumber:
michael@0 640 retVal = crmf_item_has_data(&certTemplate->serialNumber);
michael@0 641 break;
michael@0 642 case crmfSigningAlg:
michael@0 643 retVal = IS_NOT_NULL(certTemplate->signingAlg);
michael@0 644 break;
michael@0 645 case crmfIssuer:
michael@0 646 retVal = IS_NOT_NULL(certTemplate->issuer);
michael@0 647 break;
michael@0 648 case crmfValidity:
michael@0 649 retVal = IS_NOT_NULL(certTemplate->validity);
michael@0 650 break;
michael@0 651 case crmfSubject:
michael@0 652 retVal = IS_NOT_NULL(certTemplate->subject);
michael@0 653 break;
michael@0 654 case crmfPublicKey:
michael@0 655 retVal = IS_NOT_NULL(certTemplate->publicKey);
michael@0 656 break;
michael@0 657 case crmfIssuerUID:
michael@0 658 retVal = crmf_item_has_data(&certTemplate->issuerUID);
michael@0 659 break;
michael@0 660 case crmfSubjectUID:
michael@0 661 retVal = crmf_item_has_data(&certTemplate->subjectUID);
michael@0 662 break;
michael@0 663 case crmfExtension:
michael@0 664 retVal = IS_NOT_NULL(certTemplate->extensions);
michael@0 665 break;
michael@0 666 default:
michael@0 667 retVal = PR_FALSE;
michael@0 668 }
michael@0 669 return retVal;
michael@0 670 }

mercurial