1 /* 2 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 /* 6 * Copyright (c) 1995-1999 Intel Corporation. All rights reserved. 7 */ 8 9 #pragma ident "%Z%%M% %I% %E% SMI" 10 11 #include <strings.h> 12 #include <kmftypes.h> 13 #include <ber_der.h> 14 #include <kmfapi.h> 15 #include <kmfapiP.h> 16 17 #include <stdio.h> 18 19 #define DSA_RAW_SIG_LEN 40 20 21 static uint8_t OID_ExtensionRequest[] = { OID_PKCS_9, 14 }; 22 const KMF_OID extension_request_oid = {OID_PKCS_9_LENGTH + 1, 23 OID_ExtensionRequest}; 24 25 static KMF_RETURN 26 encode_algoid(BerElement *asn1, KMF_X509_ALGORITHM_IDENTIFIER *algoid) 27 { 28 KMF_RETURN ret = KMF_OK; 29 30 if (kmfber_printf(asn1, "{D", &algoid->algorithm) == -1) { 31 ret = KMF_ERR_BAD_CERT_FORMAT; 32 } 33 if (algoid->parameters.Data == NULL || 34 algoid->parameters.Length == 0) { 35 if (kmfber_printf(asn1, "n}") == -1) 36 return (KMF_ERR_BAD_CERT_FORMAT); 37 } else { 38 /* 39 * The algorithm data can be anything, so we just write it 40 * straight into the buffer. It is already DER encoded. 41 */ 42 (void) kmfber_write(asn1, (char *)algoid->parameters.Data, 43 algoid->parameters.Length, 0); 44 if (kmfber_printf(asn1, "}") == -1) { 45 ret = KMF_ERR_BAD_CERT_FORMAT; 46 } 47 } 48 49 return (ret); 50 } 51 52 static void 53 free_data(KMF_DATA *data) 54 { 55 if (data == NULL || data->Data == NULL) 56 return; 57 58 free(data->Data); 59 data->Data = NULL; 60 data->Length = 0; 61 } 62 63 static void 64 free_algoid(KMF_X509_ALGORITHM_IDENTIFIER *algoid) 65 { 66 free_data(&algoid->algorithm); 67 free_data(&algoid->parameters); 68 } 69 70 static void 71 free_decoded_spki(KMF_X509_SPKI *spki) 72 { 73 if (spki != NULL) { 74 free_algoid(&spki->algorithm); 75 free_data(&spki->subjectPublicKey); 76 } 77 } 78 79 static void 80 free_rdn_data(KMF_X509_NAME *name) 81 { 82 KMF_X509_RDN *newrdn = NULL; 83 KMF_X509_TYPE_VALUE_PAIR *av = NULL; 84 int i, j; 85 86 if (name && name->numberOfRDNs) { 87 for (i = 0; i < name->numberOfRDNs; i++) { 88 newrdn = &name->RelativeDistinguishedName[i]; 89 for (j = 0; j < newrdn->numberOfPairs; j++) { 90 av = &newrdn->AttributeTypeAndValue[j]; 91 free_data(&av->type); 92 free_data(&av->value); 93 } 94 free(newrdn->AttributeTypeAndValue); 95 } 96 free(name->RelativeDistinguishedName); 97 name->numberOfRDNs = 0; 98 name->RelativeDistinguishedName = NULL; 99 } 100 } 101 102 static void 103 free_validity(KMF_X509_VALIDITY *validity) 104 { 105 free_data(&validity->notBefore.time); 106 free_data(&validity->notAfter.time); 107 } 108 109 static void 110 free_one_extension(KMF_X509_EXTENSION *exptr) 111 { 112 free_data(&exptr->extnId); 113 free_data(&exptr->BERvalue); 114 115 if (exptr->value.tagAndValue) { 116 free_data(&exptr->value.tagAndValue->value); 117 free(exptr->value.tagAndValue); 118 } 119 } 120 121 static void 122 free_extensions(KMF_X509_EXTENSIONS *extns) 123 { 124 int i; 125 KMF_X509_EXTENSION *exptr; 126 127 if (extns && extns->numberOfExtensions > 0) { 128 for (i = 0; i < extns->numberOfExtensions; i++) { 129 exptr = &extns->extensions[i]; 130 free_one_extension(exptr); 131 } 132 free(extns->extensions); 133 extns->numberOfExtensions = 0; 134 extns->extensions = NULL; 135 } 136 } 137 138 static void 139 free_tbscsr(KMF_TBS_CSR *tbscsr) 140 { 141 if (tbscsr) { 142 free_data(&tbscsr->version); 143 144 free_rdn_data(&tbscsr->subject); 145 146 free_decoded_spki(&tbscsr->subjectPublicKeyInfo); 147 148 free_extensions(&tbscsr->extensions); 149 } 150 } 151 152 153 static void 154 free_bigint(KMF_BIGINT *bn) 155 { 156 if (bn != NULL && bn->val != NULL) { 157 free(bn->val); 158 bn->val = NULL; 159 bn->len = 0; 160 } 161 } 162 163 static void 164 free_tbscert(KMF_X509_TBS_CERT *tbscert) 165 { 166 if (tbscert) { 167 free_data(&tbscert->version); 168 free_bigint(&tbscert->serialNumber); 169 free_algoid(&tbscert->signature); 170 171 free_rdn_data(&tbscert->issuer); 172 free_rdn_data(&tbscert->subject); 173 174 free_validity(&tbscert->validity); 175 176 free_data(&tbscert->issuerUniqueIdentifier); 177 free_data(&tbscert->subjectUniqueIdentifier); 178 free_decoded_spki(&tbscert->subjectPublicKeyInfo); 179 free_extensions(&tbscert->extensions); 180 181 free_data(&tbscert->issuerUniqueIdentifier); 182 free_data(&tbscert->subjectUniqueIdentifier); 183 } 184 } 185 186 static void 187 free_decoded_cert(KMF_X509_CERTIFICATE *certptr) 188 { 189 if (!certptr) 190 return; 191 192 free_tbscert(&certptr->certificate); 193 194 free_algoid(&certptr->signature.algorithmIdentifier); 195 free_data(&certptr->signature.encrypted); 196 } 197 198 static KMF_RETURN 199 get_algoid(BerElement *asn1, KMF_X509_ALGORITHM_IDENTIFIER *algoid) 200 { 201 KMF_RETURN ret = KMF_OK; 202 ber_tag_t tag, newtag; 203 ber_len_t size; 204 BerValue AlgOID = {NULL, 0}; 205 206 tag = kmfber_next_element(asn1, &size, NULL); 207 if (tag != BER_CONSTRUCTED_SEQUENCE) 208 return (KMF_ERR_BAD_CERT_FORMAT); 209 210 if ((tag = kmfber_scanf(asn1, "{Dt", &AlgOID, &newtag)) == -1) { 211 return (KMF_ERR_BAD_CERT_FORMAT); 212 } 213 algoid->algorithm.Data = (uchar_t *)AlgOID.bv_val; 214 algoid->algorithm.Length = AlgOID.bv_len; 215 216 if (newtag == BER_NULL) { 217 (void) kmfber_scanf(asn1, "n}"); 218 algoid->parameters.Data = NULL; 219 algoid->parameters.Length = 0; 220 } else { 221 /* Peek at the tag and length bytes */ 222 if ((kmfber_scanf(asn1, "tl", &tag, &size)) == -1) { 223 ret = KMF_ERR_BAD_CERT_FORMAT; 224 goto cleanup; 225 } 226 227 /* 228 * We need to read the tag and the length bytes too, 229 * so adjust the size. 230 */ 231 size += kmfber_calc_taglen(tag) + kmfber_calc_lenlen(size); 232 algoid->parameters.Data = malloc(size); 233 if (algoid->parameters.Data == NULL) { 234 ret = KMF_ERR_MEMORY; 235 goto cleanup; 236 } 237 /* read the raw data into the Algoritm params area. */ 238 if (kmfber_read(asn1, (char *)algoid->parameters.Data, 239 size) == -1) { 240 ret = KMF_ERR_BAD_CERT_FORMAT; 241 goto cleanup; 242 } 243 algoid->parameters.Length = size; 244 if ((tag = kmfber_scanf(asn1, "}")) == -1) { 245 ret = KMF_ERR_BAD_CERT_FORMAT; 246 } 247 } 248 cleanup: 249 if (ret != KMF_OK) { 250 free_algoid(algoid); 251 } 252 253 return (ret); 254 } 255 256 static KMF_RETURN 257 CopyData(KMF_DATA *src, KMF_DATA *dst) 258 { 259 if (src && dst && src->Data != NULL && src->Length > 0) { 260 dst->Length = src->Length; 261 dst->Data = malloc(sizeof (dst->Length)); 262 if (dst->Data == NULL) 263 return (KMF_ERR_MEMORY); 264 (void) memcpy(dst->Data, src->Data, src->Length); 265 } 266 return (KMF_OK); 267 } 268 269 static KMF_RETURN 270 encode_spki(BerElement *asn1, KMF_X509_SPKI *spki) 271 { 272 KMF_RETURN ret = KMF_OK; 273 274 if (kmfber_printf(asn1, "{") == -1) 275 return (KMF_ERR_BAD_CERT_FORMAT); 276 277 if ((ret = encode_algoid(asn1, &spki->algorithm)) != KMF_OK) 278 return (ret); 279 280 if (kmfber_printf(asn1, "B}", spki->subjectPublicKey.Data, 281 spki->subjectPublicKey.Length * 8) == -1) 282 return (KMF_ERR_BAD_CERT_FORMAT); 283 284 return (ret); 285 } 286 287 KMF_RETURN 288 DerEncodeSPKI(KMF_X509_SPKI *spki, KMF_DATA *EncodedSPKI) 289 { 290 KMF_RETURN ret = KMF_OK; 291 BerElement *asn1; 292 BerValue *result; 293 294 if (spki == NULL || EncodedSPKI == NULL) 295 return (KMF_ERR_BAD_PARAMETER); 296 297 if ((asn1 = kmfder_alloc()) == NULL) 298 return (KMF_ERR_MEMORY); 299 300 if ((ret = encode_spki(asn1, spki)) != KMF_OK) { 301 return (ret); 302 } 303 304 if (kmfber_flatten(asn1, &result) == -1) { 305 kmfber_free(asn1, 1); 306 return (KMF_ERR_ENCODING); 307 } 308 309 EncodedSPKI->Data = (uchar_t *)result->bv_val; 310 EncodedSPKI->Length = result->bv_len; 311 312 free(result); 313 kmfber_free(asn1, 1); 314 return (KMF_OK); 315 } 316 317 static KMF_RETURN 318 get_spki(BerElement *asn1, KMF_X509_SPKI *spki) 319 { 320 KMF_RETURN ret = KMF_OK; 321 char *bitstr = NULL; 322 ber_len_t size; 323 324 if (kmfber_scanf(asn1, "{") == -1) 325 return (KMF_ERR_BAD_CERT_FORMAT); 326 327 if ((ret = get_algoid(asn1, &spki->algorithm)) != KMF_OK) 328 return (ret); 329 330 if (kmfber_scanf(asn1, "B}", &bitstr, &size) == BER_BIT_STRING) { 331 spki->subjectPublicKey.Data = (uchar_t *)bitstr; 332 spki->subjectPublicKey.Length = size / 8; 333 } else { 334 ret = KMF_ERR_BAD_CERT_FORMAT; 335 goto cleanup; 336 } 337 cleanup: 338 if (ret != KMF_OK) { 339 if (bitstr != NULL) 340 free(bitstr); 341 spki->subjectPublicKey.Data = NULL; 342 spki->subjectPublicKey.Length = 0; 343 344 free_algoid(&spki->algorithm); 345 } 346 return (ret); 347 } 348 349 KMF_RETURN 350 DerEncodeDSASignature(KMF_DATA *rawdata, KMF_DATA *signature) 351 { 352 BerElement *asn1; 353 BerValue *buf; 354 int n; 355 356 if (rawdata == NULL || signature == NULL) 357 return (KMF_ERR_BAD_PARAMETER); 358 359 if (rawdata->Data == NULL || rawdata->Length != DSA_RAW_SIG_LEN) 360 return (KMF_ERR_BAD_PARAMETER); 361 362 asn1 = kmfder_alloc(); 363 if (asn1 == NULL) 364 return (KMF_ERR_MEMORY); 365 366 /* 367 * The DSA signature is the concatenation of 2 SHA-1 hashed 368 * bignum values. 369 */ 370 n = DSA_RAW_SIG_LEN/2; 371 if (kmfber_printf(asn1, "{II}", 372 rawdata->Data, n, 373 &rawdata->Data[n], n) == -1) { 374 kmfber_free(asn1, 1); 375 return (KMF_ERR_MEMORY); 376 } 377 378 if (kmfber_flatten(asn1, &buf) == -1) { 379 kmfber_free(asn1, 1); 380 return (KMF_ERR_ENCODING); 381 } 382 383 signature->Data = (uchar_t *)buf->bv_val; 384 signature->Length = buf->bv_len; 385 386 kmfber_free(asn1, 1); 387 free(buf); 388 389 return (KMF_OK); 390 } 391 392 KMF_RETURN 393 DerDecodeDSASignature(KMF_DATA *encoded, KMF_DATA *signature) 394 { 395 KMF_RETURN ret = KMF_OK; 396 BerElement *asn1 = NULL; 397 BerValue buf, *R = NULL, *S = NULL; 398 399 buf.bv_val = (char *)encoded->Data; 400 buf.bv_len = encoded->Length; 401 402 if (encoded == NULL || encoded->Data == NULL || 403 signature == NULL) 404 return (KMF_ERR_BAD_PARAMETER); 405 406 signature->Data = NULL; 407 signature->Length = 0; 408 409 if ((asn1 = kmfder_init(&buf)) == NULL) 410 return (KMF_ERR_MEMORY); 411 412 if (kmfber_scanf(asn1, "{II}", &R, &S) == -1) { 413 ret = KMF_ERR_BAD_PARAMETER; 414 goto cleanup; 415 } 416 signature->Length = R->bv_len + S->bv_len; 417 signature->Data = malloc(signature->Length); 418 if (signature->Data == NULL) { 419 ret = KMF_ERR_MEMORY; 420 goto cleanup; 421 } 422 (void) memcpy(signature->Data, R->bv_val, R->bv_len); 423 (void) memcpy(&signature->Data[R->bv_len], S->bv_val, S->bv_len); 424 425 cleanup: 426 if (R && R->bv_val) 427 free(R->bv_val); 428 if (S && S->bv_val) 429 free(S->bv_val); 430 431 if (S) free(S); 432 if (R) free(R); 433 434 if (asn1) kmfber_free(asn1, 1); 435 436 return (ret); 437 } 438 439 KMF_RETURN 440 DerDecodeSPKI(KMF_DATA *EncodedSPKI, KMF_X509_SPKI *spki) 441 { 442 KMF_RETURN ret = KMF_OK; 443 BerElement *asn1; 444 BerValue bv; 445 446 if (EncodedSPKI == NULL || EncodedSPKI->Data == NULL || 447 spki == NULL) 448 return (KMF_ERR_BAD_PARAMETER); 449 450 (void) memset(spki, 0, sizeof (KMF_X509_SPKI)); 451 452 bv.bv_val = (char *)EncodedSPKI->Data; 453 bv.bv_len = EncodedSPKI->Length; 454 455 if ((asn1 = kmfder_init(&bv)) == NULL) 456 return (KMF_ERR_MEMORY); 457 458 ret = get_spki(asn1, spki); 459 460 cleanup: 461 if (ret != KMF_OK) { 462 free_decoded_spki(spki); 463 } 464 kmfber_free(asn1, 1); 465 466 return (ret); 467 } 468 469 KMF_RETURN 470 CopySPKI(KMF_X509_SPKI *src, 471 KMF_X509_SPKI **dest) 472 { 473 KMF_RETURN ret = KMF_OK; 474 KMF_X509_SPKI *newspki; 475 476 *dest = NULL; 477 478 newspki = malloc(sizeof (KMF_X509_SPKI)); 479 if (newspki == NULL) 480 return (KMF_ERR_MEMORY); 481 (void) memset(newspki, 0, sizeof (KMF_X509_SPKI)); 482 483 ret = CopyData(&src->algorithm.algorithm, 484 &newspki->algorithm.algorithm); 485 if (ret != KMF_OK) 486 goto cleanup; 487 488 ret = CopyData(&src->algorithm.parameters, 489 &newspki->algorithm.parameters); 490 if (ret != KMF_OK) 491 goto cleanup; 492 493 ret = CopyData(&src->subjectPublicKey, 494 &newspki->subjectPublicKey); 495 if (ret != KMF_OK) 496 goto cleanup; 497 498 *dest = newspki; 499 cleanup: 500 if (ret != KMF_OK) { 501 if (newspki) 502 free_decoded_spki(newspki); 503 } 504 return (ret); 505 } 506 507 static KMF_RETURN 508 encode_validity(BerElement *asn1, KMF_X509_VALIDITY *validity) 509 { 510 int ret; 511 512 ret = kmfber_printf(asn1, "{tsts}", 513 validity->notBefore.timeType, 514 validity->notBefore.time.Data, 515 validity->notAfter.timeType, 516 validity->notAfter.time.Data); 517 518 if (ret == -1) 519 return (KMF_ERR_BAD_CERT_FORMAT); 520 521 return (KMF_OK); 522 } 523 524 static KMF_RETURN 525 get_validity(BerElement *asn1, KMF_X509_VALIDITY *validity) 526 { 527 KMF_RETURN ret = KMF_OK; 528 int tag; 529 int t1, t2; 530 ber_len_t size; 531 char *t1str, *t2str; 532 533 (void) memset(validity, 0, sizeof (KMF_X509_VALIDITY)); 534 535 tag = kmfber_next_element(asn1, &size, NULL); 536 if (tag != BER_CONSTRUCTED_SEQUENCE) { 537 return (KMF_ERR_BAD_CERT_FORMAT); 538 } 539 540 if (kmfber_scanf(asn1, "{tata}", &t1, &t1str, &t2, &t2str) == -1) { 541 return (KMF_ERR_BAD_CERT_FORMAT); 542 } 543 544 validity->notBefore.timeType = t1; 545 validity->notBefore.time.Data = (uchar_t *)t1str; 546 validity->notBefore.time.Length = strlen(t1str); 547 548 validity->notAfter.timeType = t2; 549 validity->notAfter.time.Data = (uchar_t *)t2str; 550 validity->notAfter.time.Length = strlen(t2str); 551 552 return (ret); 553 } 554 555 KMF_RETURN 556 AddRDN(KMF_X509_NAME *name, KMF_X509_RDN *newrdn) 557 { 558 KMF_RETURN ret = KMF_OK; 559 KMF_X509_RDN *rdnslot = NULL; 560 561 /* Add new RDN record to existing list */ 562 name->numberOfRDNs++; 563 name->RelativeDistinguishedName = 564 realloc(name->RelativeDistinguishedName, 565 name->numberOfRDNs * sizeof (KMF_X509_RDN)); 566 567 if (name->RelativeDistinguishedName == NULL) { 568 ret = KMF_ERR_MEMORY; 569 goto cleanup; 570 } 571 rdnslot = &name->RelativeDistinguishedName[name->numberOfRDNs-1]; 572 573 if (newrdn) { 574 (void) memcpy(rdnslot, newrdn, sizeof (KMF_X509_RDN)); 575 } else { 576 rdnslot->numberOfPairs = 0; 577 rdnslot->AttributeTypeAndValue = NULL; 578 } 579 580 cleanup: 581 /* No cleanup needed here */ 582 return (ret); 583 } 584 585 static KMF_RETURN 586 encode_rdn(BerElement *asn1, KMF_X509_NAME *name) 587 { 588 KMF_RETURN ret = KMF_OK; 589 KMF_X509_TYPE_VALUE_PAIR *attrtvpair = NULL; 590 int i; 591 KMF_X509_RDN *rdn; 592 593 if (kmfber_printf(asn1, "{") == -1) { 594 ret = KMF_ERR_MEMORY; 595 goto cleanup; 596 } 597 598 for (i = 0; i < name->numberOfRDNs; i++) { 599 if (kmfber_printf(asn1, "[") == -1) { 600 ret = KMF_ERR_MEMORY; 601 goto cleanup; 602 } 603 rdn = &name->RelativeDistinguishedName[i]; 604 attrtvpair = rdn->AttributeTypeAndValue; 605 606 if (rdn->numberOfPairs > 0) { 607 if (kmfber_printf(asn1, "{Dto}", 608 &attrtvpair->type, 609 attrtvpair->valueType, 610 attrtvpair->value.Data, 611 attrtvpair->value.Length) == -1) { 612 ret = KMF_ERR_MEMORY; 613 goto cleanup; 614 } 615 } 616 if (kmfber_printf(asn1, "]") == -1) { 617 ret = KMF_ERR_MEMORY; 618 goto cleanup; 619 } 620 } 621 622 if (kmfber_printf(asn1, "}") == -1) { 623 ret = KMF_ERR_MEMORY; 624 goto cleanup; 625 } 626 627 cleanup: 628 /* No cleanup needed here */ 629 630 return (ret); 631 } 632 633 634 KMF_RETURN 635 CopyRDN(KMF_X509_NAME *srcname, KMF_X509_NAME **destname) 636 { 637 KMF_RETURN ret = KMF_OK; 638 KMF_X509_NAME *newname = NULL; 639 KMF_X509_RDN *rdn, *dstrdn; 640 KMF_X509_TYPE_VALUE_PAIR *av = NULL; 641 KMF_X509_TYPE_VALUE_PAIR *srcav = NULL; 642 KMF_X509_TYPE_VALUE_PAIR *dstav = NULL; 643 int i, j; 644 645 newname = malloc(sizeof (KMF_X509_NAME)); 646 if (newname == NULL) 647 return (KMF_ERR_MEMORY); 648 (void) memset(newname, 0, sizeof (KMF_X509_NAME)); 649 650 newname->numberOfRDNs = srcname->numberOfRDNs; 651 newname->RelativeDistinguishedName = malloc(newname->numberOfRDNs * 652 sizeof (KMF_X509_RDN)); 653 if (newname->RelativeDistinguishedName == NULL) { 654 free(newname); 655 return (KMF_ERR_MEMORY); 656 } 657 /* Copy each RDN in the list */ 658 for (i = 0; i < newname->numberOfRDNs; i++) { 659 rdn = &srcname->RelativeDistinguishedName[i]; 660 661 dstrdn = &newname->RelativeDistinguishedName[i]; 662 (void) memset(dstrdn, 0, sizeof (KMF_X509_RDN)); 663 664 dstrdn->numberOfPairs = rdn->numberOfPairs; 665 if (dstrdn->numberOfPairs > 0) { 666 av = malloc(dstrdn->numberOfPairs * 667 sizeof (KMF_X509_TYPE_VALUE_PAIR)); 668 if (av == NULL) { 669 ret = KMF_ERR_MEMORY; 670 goto cleanup; 671 } 672 (void) memset(av, 0, dstrdn->numberOfPairs * 673 sizeof (KMF_X509_TYPE_VALUE_PAIR)); 674 675 dstrdn->AttributeTypeAndValue = av; 676 if (av == NULL) { 677 ret = KMF_ERR_MEMORY; 678 goto cleanup; 679 } 680 /* Copy each A/V pair in the list */ 681 for (j = 0; j < dstrdn->numberOfPairs; j++) { 682 srcav = &rdn->AttributeTypeAndValue[j]; 683 dstav = &dstrdn->AttributeTypeAndValue[j]; 684 if ((ret = CopyData(&srcav->type, 685 &dstav->type)) != KMF_OK) 686 goto cleanup; 687 dstav->valueType = srcav->valueType; 688 if ((ret = CopyData(&srcav->value, 689 &dstav->value)) != KMF_OK) 690 goto cleanup; 691 } 692 } else { 693 dstrdn->AttributeTypeAndValue = NULL; 694 } 695 } 696 *destname = newname; 697 698 cleanup: 699 if (ret != KMF_OK) { 700 if (newname) 701 free_rdn_data(newname); 702 703 free(newname); 704 *destname = NULL; 705 } 706 return (ret); 707 } 708 709 #define VALID_DIRECTORYSTRING_TAG(t) ( \ 710 (t == BER_UTF8_STRING) || \ 711 (t == BER_PRINTABLE_STRING) || \ 712 (t == BER_IA5STRING) || \ 713 (t == BER_T61STRING) || \ 714 (t == BER_BMP_STRING) || \ 715 (t == BER_UNIVERSAL_STRING)) 716 717 static KMF_RETURN 718 get_rdn(BerElement *asn1, KMF_X509_NAME *name) 719 { 720 KMF_RETURN ret = KMF_OK; 721 ber_len_t size; 722 char *end; 723 int tag; 724 BerValue AttrOID; 725 char *AttrValue = NULL; 726 KMF_X509_TYPE_VALUE_PAIR *newpair = NULL; 727 KMF_X509_RDN newrdn; 728 729 /* 730 * AttributeType ::= OBJECT IDENTIFIER 731 * AttributeValue ::= ANY 732 * 733 * AttributeTypeAndValue ::= SEQUENCE { 734 * type AttributeType, 735 * value AttributeValue } 736 * 737 * Name ::= CHOICE { -- only one possibility for now -- 738 * rdnSequence RDNSequence } 739 * 740 * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName 741 * 742 * DistinguishedName ::= RDNSequence 743 * 744 * RelativeDistinguishedName ::= 745 * SET SIZE (1 .. MAX) OF AttributeTypeAndValue 746 * 747 */ 748 749 name->numberOfRDNs = 0; 750 name->RelativeDistinguishedName = NULL; 751 752 /* Get the beginning of the RDN Set and a ptr to the end */ 753 tag = kmfber_first_element(asn1, &size, &end); 754 if (tag != BER_CONSTRUCTED_SET) { 755 goto cleanup; 756 } 757 758 /* Walk through the individual SET items until the "end" is reached */ 759 while ((tag = kmfber_next_element(asn1, &size, end)) == 760 BER_CONSTRUCTED_SET) { 761 /* Skip over the SET tag */ 762 if (kmfber_scanf(asn1, "T", &tag) == -1) { 763 ret = KMF_ERR_BAD_CERT_FORMAT; 764 break; 765 } 766 767 /* An "empty" set member means we tack on an empty node */ 768 if (size == 0) { 769 if ((ret = AddRDN(name, NULL)) != KMF_OK) 770 goto cleanup; 771 continue; 772 } 773 774 /* Attr OID and peek at the next tag and field length */ 775 if (kmfber_scanf(asn1, "{Dtl", &AttrOID, &tag, &size) == -1) { 776 ret = KMF_ERR_BAD_CERT_FORMAT; 777 break; 778 } 779 780 if (!(VALID_DIRECTORYSTRING_TAG(tag))) { 781 ret = KMF_ERR_BAD_CERT_FORMAT; 782 break; 783 } 784 785 if (kmfber_scanf(asn1, "a}]", &AttrValue) == -1) { 786 ret = KMF_ERR_BAD_CERT_FORMAT; 787 break; 788 } 789 790 /* Allocate a new name/value pair record */ 791 newpair = malloc(sizeof (KMF_X509_TYPE_VALUE_PAIR)); 792 if (newpair == NULL) { 793 ret = KMF_ERR_MEMORY; 794 break; 795 } 796 (void) memset(newpair, 0, sizeof (KMF_X509_TYPE_VALUE_PAIR)); 797 newpair->type.Data = (uchar_t *)AttrOID.bv_val; 798 newpair->type.Length = AttrOID.bv_len; 799 newpair->valueType = tag; /* what kind of string is it? */ 800 newpair->value.Data = (uchar_t *)AttrValue; 801 newpair->value.Length = strlen(AttrValue); 802 803 (void) memset(&newrdn, 0, sizeof (KMF_X509_RDN)); 804 newrdn.numberOfPairs = 1; 805 newrdn.AttributeTypeAndValue = newpair; 806 807 if ((ret = AddRDN(name, &newrdn)) != KMF_OK) 808 break; 809 } 810 811 cleanup: 812 if (ret != KMF_OK) { 813 free_rdn_data(name); 814 } 815 return (ret); 816 } 817 818 static KMF_RETURN 819 set_der_integer(KMF_DATA *data, int value) 820 { 821 if (data == NULL) 822 return (KMF_ERR_BAD_PARAMETER); 823 824 data->Data = malloc(sizeof (int)); 825 if (data->Data == NULL) 826 return (KMF_ERR_MEMORY); 827 828 data->Length = sizeof (int); 829 (void) memcpy((void *)data->Data, (const void *)&value, sizeof (int)); 830 831 return (KMF_OK); 832 } 833 834 static KMF_RETURN 835 set_bigint(KMF_BIGINT *data, KMF_BIGINT *bigint) 836 { 837 if (data == NULL || bigint == NULL) 838 return (KMF_ERR_BAD_PARAMETER); 839 840 data->val = malloc(bigint->len); 841 if (data->val == NULL) 842 return (KMF_ERR_MEMORY); 843 844 data->len = bigint->len; 845 (void) memcpy((void *)data->val, (const void *)bigint->val, 846 bigint->len); 847 848 return (KMF_OK); 849 } 850 851 static KMF_RETURN 852 encode_uniqueid(BerElement *asn1, int tag, KMF_DATA *id) 853 { 854 KMF_RETURN ret = KMF_OK; 855 uint32_t len; 856 857 len = kmfber_calc_taglen(BER_BIT_STRING) + 858 kmfber_calc_lenlen(id->Length * 8) + id->Length; 859 if (kmfber_printf(asn1, "TlB", tag, len, 860 id->Data, id->Length * 8) == -1) 861 return (KMF_ERR_BAD_CERT_FORMAT); 862 863 return (ret); 864 } 865 866 static KMF_RETURN 867 encode_extension_list(BerElement *asn1, KMF_X509_EXTENSIONS *extns) 868 { 869 KMF_RETURN ret = KMF_OK; 870 int i; 871 872 for (i = 0; i < extns->numberOfExtensions; i++) { 873 BerValue v; 874 v.bv_val = (char *)extns->extensions[i].extnId.Data; 875 v.bv_len = extns->extensions[i].extnId.Length; 876 877 if (kmfber_printf(asn1, "{D", &v) == -1) { 878 ret = KMF_ERR_ENCODING; 879 goto cleanup; 880 } 881 882 if (extns->extensions[i].critical) { 883 if (kmfber_printf(asn1, "b", 884 extns->extensions[i].critical) == -1) { 885 ret = KMF_ERR_ENCODING; 886 goto cleanup; 887 } 888 } 889 890 if (kmfber_printf(asn1, "o}", 891 extns->extensions[i].BERvalue.Data, 892 extns->extensions[i].BERvalue.Length) == -1) { 893 ret = KMF_ERR_ENCODING; 894 goto cleanup; 895 } 896 } 897 cleanup: 898 return (ret); 899 } 900 901 static KMF_RETURN 902 encode_extensions(BerElement *asn1, KMF_X509_EXTENSIONS *extns) 903 { 904 KMF_RETURN ret = KMF_OK; 905 BerElement *extn = NULL; 906 BerValue *extnvalue = NULL; 907 908 extn = kmfder_alloc(); 909 if (extn == NULL) 910 return (KMF_ERR_MEMORY); 911 912 if (kmfber_printf(extn, "{") == -1) { 913 ret = KMF_ERR_ENCODING; 914 goto cleanup; 915 } 916 917 ret = encode_extension_list(extn, extns); 918 919 if (kmfber_printf(extn, "}") == -1) { 920 ret = KMF_ERR_ENCODING; 921 goto cleanup; 922 } 923 924 if (kmfber_flatten(extn, &extnvalue) == -1) { 925 ret = KMF_ERR_MEMORY; 926 goto cleanup; 927 } 928 929 if (kmfber_printf(asn1, "Tl", 0xA3, extnvalue->bv_len) == -1) { 930 ret = KMF_ERR_BAD_CERT_FORMAT; 931 goto cleanup; 932 } 933 934 if (kmfber_write(asn1, extnvalue->bv_val, extnvalue->bv_len, 0) == -1) { 935 ret = KMF_ERR_BAD_CERT_FORMAT; 936 goto cleanup; 937 } 938 939 cleanup: 940 kmfber_free(extn, 1); 941 if (extnvalue != NULL) 942 kmfber_bvfree(extnvalue); 943 944 return (ret); 945 } 946 947 static KMF_RETURN 948 get_one_extension(BerElement *asn1, KMF_X509_EXTENSION **retex, char *end) 949 { 950 KMF_RETURN ret = KMF_OK; 951 ber_len_t size; 952 int critical, tag; 953 KMF_X509_EXTENSION *ex = NULL; 954 BerValue extOID; 955 BerValue extValue; 956 BerElement *extnber = NULL; 957 958 if (kmfber_scanf(asn1, "T", &tag) == -1) { 959 ret = KMF_ERR_BAD_CERT_FORMAT; 960 goto cleanup; 961 } 962 963 tag = kmfber_next_element(asn1, &size, end); 964 if (tag != BER_OBJECT_IDENTIFIER) { 965 ret = KMF_ERR_BAD_CERT_FORMAT; 966 goto cleanup; 967 } 968 if (kmfber_scanf(asn1, "D", &extOID) == -1) { 969 ret = KMF_ERR_BAD_CERT_FORMAT; 970 goto cleanup; 971 } 972 973 tag = kmfber_next_element(asn1, &size, end); 974 if (tag != BER_BOOLEAN) { 975 critical = 0; 976 if (tag != BER_OCTET_STRING) 977 goto cleanup; 978 } else { 979 if (kmfber_scanf(asn1, "b", &critical) == -1) 980 goto cleanup; 981 } 982 983 tag = kmfber_next_element(asn1, &size, end); 984 if (tag != BER_OCTET_STRING) { 985 ret = KMF_ERR_BAD_CERT_FORMAT; 986 goto cleanup; 987 } 988 if (kmfber_scanf(asn1, "o", &extValue) == -1) { 989 ret = KMF_ERR_BAD_CERT_FORMAT; 990 goto cleanup; 991 } 992 993 /* allocate a new Extension record */ 994 ex = malloc(sizeof (KMF_X509_EXTENSION)); 995 if (ex == NULL) { 996 ret = KMF_ERR_MEMORY; 997 goto cleanup; 998 } 999 (void) memset(ex, 0, sizeof (ex)); 1000 1001 ex->extnId.Data = (uchar_t *)extOID.bv_val; 1002 ex->extnId.Length = extOID.bv_len; 1003 ex->critical = critical; 1004 ex->format = KMF_X509_DATAFORMAT_ENCODED; 1005 ex->BERvalue.Data = (uchar_t *)extValue.bv_val; 1006 ex->BERvalue.Length = extValue.bv_len; 1007 1008 /* Tag and value is a little tricky */ 1009 ex->value.tagAndValue = malloc(sizeof (KMF_X509EXT_TAGandVALUE)); 1010 if (ex->value.tagAndValue == NULL) { 1011 ret = KMF_ERR_MEMORY; 1012 goto cleanup; 1013 } 1014 (void) memset(ex->value.tagAndValue, 0, 1015 sizeof (KMF_X509EXT_TAGandVALUE)); 1016 1017 /* Parse the Extension value field */ 1018 extnber = kmfder_init(&extValue); 1019 if (extnber == NULL) { 1020 ret = KMF_ERR_MEMORY; 1021 goto cleanup; 1022 } 1023 1024 /* Get the tag and length of the extension field */ 1025 if (kmfber_scanf(extnber, "tl", &tag, &size) == -1) { 1026 ret = KMF_ERR_BAD_CERT_FORMAT; 1027 goto cleanup; 1028 } 1029 1030 if (kmfber_scanf(extnber, "T", &tag) == -1) { 1031 ret = KMF_ERR_BAD_CERT_FORMAT; 1032 goto cleanup; 1033 } 1034 1035 ex->value.tagAndValue->value.Data = malloc(size); 1036 ex->value.tagAndValue->value.Length = size; 1037 size = kmfber_read(extnber, 1038 (char *)ex->value.tagAndValue->value.Data, size); 1039 if (size != ex->value.tagAndValue->value.Length) { 1040 ret = KMF_ERR_BAD_CERT_FORMAT; 1041 goto cleanup; 1042 } 1043 kmfber_free(extnber, 1); 1044 ex->value.tagAndValue->type = tag; 1045 1046 *retex = ex; 1047 cleanup: 1048 if (ret != KMF_OK) { 1049 if (ex != NULL) 1050 free_one_extension(ex); 1051 } 1052 1053 return (ret); 1054 } 1055 1056 static KMF_RETURN 1057 get_extensions(BerElement *asn1, KMF_X509_EXTENSIONS *extns) 1058 { 1059 KMF_RETURN ret = KMF_OK; 1060 ber_len_t size; 1061 char *end = NULL; 1062 KMF_X509_EXTENSION *ex = NULL; 1063 1064 /* 1065 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension 1066 * 1067 * Extension ::= SEQUENCE { 1068 * extnID OBJECT IDENTIFIER, 1069 * critical BOOLEAN DEFAULT FALSE, 1070 * extnValue OCTET STRING } 1071 * 1072 * { {{D}Bo}, ... } 1073 */ 1074 if (kmfber_first_element(asn1, &size, &end) != 1075 BER_CONSTRUCTED_SEQUENCE) 1076 return (KMF_ERR_BAD_CERT_FORMAT); 1077 1078 while (kmfber_next_element(asn1, &size, end) == 1079 BER_CONSTRUCTED_SEQUENCE) { 1080 ret = get_one_extension(asn1, &ex, end); 1081 if (ret != KMF_OK) 1082 goto cleanup; 1083 1084 extns->numberOfExtensions++; 1085 extns->extensions = realloc(extns->extensions, 1086 extns->numberOfExtensions * 1087 sizeof (KMF_X509_EXTENSION)); 1088 if (extns->extensions == NULL) { 1089 ret = KMF_ERR_MEMORY; 1090 break; 1091 } 1092 1093 extns->extensions[extns->numberOfExtensions-1] = *ex; 1094 free(ex); 1095 } 1096 1097 cleanup: 1098 if (ret != KMF_OK) 1099 free_extensions(extns); 1100 1101 return (ret); 1102 } 1103 1104 KMF_RETURN 1105 decode_tbscert_data(BerElement *asn1, 1106 KMF_X509_TBS_CERT **signed_cert_ptr_ptr) 1107 { 1108 KMF_RETURN ret = KMF_OK; 1109 KMF_X509_TBS_CERT *tbscert = NULL; 1110 int tag, version; 1111 struct berval *bvserno = NULL; 1112 KMF_BIGINT serno; 1113 1114 if (kmfber_scanf(asn1, "{t", &tag) == -1) { 1115 ret = KMF_ERR_BAD_CERT_FORMAT; 1116 goto cleanup; 1117 } 1118 1119 /* Version number is optional */ 1120 if (tag == 0xA0) { 1121 if (kmfber_scanf(asn1, "Ti", &tag, &version) == -1) { 1122 ret = KMF_ERR_BAD_CERT_FORMAT; 1123 goto cleanup; 1124 } 1125 } else { 1126 version = 0; /* DEFAULT v1 (0) */ 1127 } 1128 1129 /* Now get the serial number, it is not optional */ 1130 if (kmfber_scanf(asn1, "I", &bvserno) == -1) { 1131 ret = KMF_ERR_BAD_CERT_FORMAT; 1132 goto cleanup; 1133 } else { 1134 serno.val = (uchar_t *)bvserno->bv_val; 1135 serno.len = bvserno->bv_len; 1136 } 1137 1138 tbscert = malloc(sizeof (KMF_X509_TBS_CERT)); 1139 if (!tbscert) { 1140 ret = KMF_ERR_MEMORY; 1141 goto cleanup; 1142 } 1143 1144 (void) memset(tbscert, 0, sizeof (KMF_X509_TBS_CERT)); 1145 1146 if ((ret = set_der_integer(&tbscert->version, version)) != KMF_OK) 1147 goto cleanup; 1148 1149 if ((ret = set_bigint(&tbscert->serialNumber, &serno)) != KMF_OK) 1150 goto cleanup; 1151 1152 if ((ret = get_algoid(asn1, &tbscert->signature)) != KMF_OK) 1153 goto cleanup; 1154 1155 if ((ret = get_rdn(asn1, &tbscert->issuer)) != KMF_OK) 1156 goto cleanup; 1157 1158 if ((ret = get_validity(asn1, &tbscert->validity)) != KMF_OK) 1159 goto cleanup; 1160 1161 if ((ret = get_rdn(asn1, &tbscert->subject)) != KMF_OK) 1162 goto cleanup; 1163 1164 if ((ret = get_spki(asn1, &tbscert->subjectPublicKeyInfo)) != KMF_OK) 1165 goto cleanup; 1166 1167 /* Check for the optional fields */ 1168 tbscert->extensions.numberOfExtensions = 0; 1169 tbscert->extensions.extensions = NULL; 1170 1171 while ((kmfber_scanf(asn1, "t", &tag)) != -1 && 1172 (tag == 0xA1 || tag == 0xA2 || tag == 0xA3)) { 1173 char *optfield; 1174 ber_len_t len; 1175 1176 /* consume the tag and length */ 1177 (void) kmfber_scanf(asn1, "T", &tag); 1178 switch (tag) { 1179 case 0xA1: 1180 if (kmfber_scanf(asn1, "B", &optfield, &len) != 1181 BER_BIT_STRING) { 1182 ret = KMF_ERR_BAD_CERT_FORMAT; 1183 goto cleanup; 1184 } 1185 tbscert->issuerUniqueIdentifier.Data = 1186 (uchar_t *)optfield; 1187 tbscert->issuerUniqueIdentifier.Length = 1188 len / 8; 1189 break; 1190 case 0xA2: 1191 if (kmfber_scanf(asn1, "B", &optfield, &len) != 1192 BER_BIT_STRING) { 1193 ret = KMF_ERR_BAD_CERT_FORMAT; 1194 goto cleanup; 1195 } 1196 tbscert->subjectUniqueIdentifier.Data = 1197 (uchar_t *)optfield; 1198 tbscert->subjectUniqueIdentifier.Length = 1199 len / 8; 1200 break; 1201 case 0xA3: 1202 ret = get_extensions(asn1, &tbscert->extensions); 1203 break; 1204 } 1205 } 1206 1207 *signed_cert_ptr_ptr = tbscert; 1208 1209 cleanup: 1210 if (bvserno != NULL) { 1211 free(bvserno->bv_val); 1212 free(bvserno); 1213 } 1214 if (ret != KMF_OK) { 1215 if (tbscert) { 1216 free_tbscert(tbscert); 1217 free(tbscert); 1218 } 1219 *signed_cert_ptr_ptr = NULL; 1220 } 1221 return (ret); 1222 } 1223 1224 KMF_RETURN 1225 DerDecodeTbsCertificate(const KMF_DATA *Value, 1226 KMF_X509_TBS_CERT **tbscert) 1227 { 1228 KMF_RETURN ret = KMF_OK; 1229 BerElement *asn1 = NULL; 1230 BerValue rawcert; 1231 KMF_X509_TBS_CERT *newcert = NULL; 1232 1233 if (!tbscert || !Value || !Value->Data || !Value->Length) 1234 return (KMF_ERR_BAD_PARAMETER); 1235 1236 rawcert.bv_val = (char *)Value->Data; 1237 rawcert.bv_len = Value->Length; 1238 1239 if ((asn1 = kmfder_init(&rawcert)) == NULL) 1240 return (KMF_ERR_MEMORY); 1241 1242 ret = decode_tbscert_data(asn1, &newcert); 1243 if (ret != KMF_OK) 1244 goto cleanup; 1245 1246 *tbscert = newcert; 1247 1248 cleanup: 1249 if (ret != KMF_OK) { 1250 if (newcert) 1251 free_tbscert(newcert); 1252 *tbscert = NULL; 1253 } 1254 kmfber_free(asn1, 1); 1255 1256 return (ret); 1257 } 1258 1259 /* 1260 * Name: DerDecodeSignedCertificate 1261 * 1262 * Description: 1263 * DER decodes the encoded X509 certificate 1264 * 1265 * Parameters: 1266 * Value (input): DER encoded object that shd be decoded 1267 * 1268 * signed_cert_ptr_ptr (output) : Decoded KMF_X509_CERTIFICATE object 1269 */ 1270 KMF_RETURN 1271 DerDecodeSignedCertificate(const KMF_DATA *Value, 1272 KMF_X509_CERTIFICATE **signed_cert_ptr_ptr) 1273 { 1274 KMF_RETURN ret = KMF_OK; 1275 BerElement *asn1 = NULL; 1276 BerValue rawcert; 1277 ber_tag_t tag; 1278 ber_len_t size; 1279 char *end = NULL; 1280 char *signature; 1281 KMF_X509_TBS_CERT *tbscert = NULL; 1282 KMF_X509_CERTIFICATE *certptr = NULL; 1283 1284 if (!signed_cert_ptr_ptr || !Value || !Value->Data || !Value->Length) 1285 return (KMF_ERR_BAD_PARAMETER); 1286 1287 rawcert.bv_val = (char *)Value->Data; 1288 rawcert.bv_len = Value->Length; 1289 1290 if ((asn1 = kmfder_init(&rawcert)) == NULL) 1291 return (KMF_ERR_MEMORY); 1292 1293 if (kmfber_first_element(asn1, &size, &end) != 1294 BER_CONSTRUCTED_SEQUENCE) { 1295 ret = KMF_ERR_BAD_CERT_FORMAT; 1296 goto cleanup; 1297 } 1298 1299 certptr = malloc(sizeof (KMF_X509_CERTIFICATE)); 1300 if (certptr == NULL) { 1301 ret = KMF_ERR_MEMORY; 1302 goto cleanup; 1303 } 1304 (void) memset(certptr, 0, sizeof (KMF_X509_CERTIFICATE)); 1305 1306 ret = decode_tbscert_data(asn1, &tbscert); 1307 if (ret != KMF_OK) 1308 goto cleanup; 1309 1310 certptr->certificate = *tbscert; 1311 free(tbscert); 1312 tbscert = NULL; 1313 1314 /* 1315 * The signature data my not be present yet. 1316 */ 1317 if ((ret = get_algoid(asn1, 1318 &certptr->signature.algorithmIdentifier)) == KMF_OK) { 1319 1320 /* Check to see if the cert has a signature yet */ 1321 if (kmfber_next_element(asn1, &size, end) == BER_BIT_STRING) { 1322 /* Finally, get the encrypted signature BITSTRING */ 1323 if (kmfber_scanf(asn1, "tl", &tag, &size) == -1) { 1324 ret = KMF_ERR_BAD_CERT_FORMAT; 1325 goto cleanup; 1326 } 1327 if (tag != BER_BIT_STRING) { 1328 ret = KMF_ERR_BAD_CERT_FORMAT; 1329 goto cleanup; 1330 } 1331 if (kmfber_scanf(asn1, "B}", &signature, &size) == -1) { 1332 ret = KMF_ERR_BAD_CERT_FORMAT; 1333 goto cleanup; 1334 } 1335 certptr->signature.encrypted.Data = 1336 (uchar_t *)signature; 1337 certptr->signature.encrypted.Length = size / 8; 1338 } else { 1339 certptr->signature.encrypted.Data = NULL; 1340 certptr->signature.encrypted.Length = 0; 1341 } 1342 } else { 1343 (void) memset(&certptr->signature, 0, 1344 sizeof (certptr->signature)); 1345 ret = KMF_OK; 1346 } 1347 1348 *signed_cert_ptr_ptr = certptr; 1349 cleanup: 1350 if (ret != KMF_OK) { 1351 if (certptr) { 1352 free_decoded_cert(certptr); 1353 free(certptr); 1354 } 1355 1356 *signed_cert_ptr_ptr = NULL; 1357 } 1358 if (asn1) 1359 kmfber_free(asn1, 1); 1360 1361 return (ret); 1362 1363 } 1364 1365 KMF_RETURN 1366 DerDecodeExtension(KMF_DATA *Data, KMF_X509_EXTENSION **extn) 1367 { 1368 KMF_RETURN ret = KMF_OK; 1369 BerElement *asn1 = NULL; 1370 BerValue bv; 1371 1372 bv.bv_val = (char *)Data->Data; 1373 bv.bv_len = Data->Length; 1374 1375 asn1 = kmfder_init(&bv); 1376 if (asn1 == NULL) 1377 return (KMF_ERR_MEMORY); 1378 1379 ret = get_one_extension(asn1, extn, NULL); 1380 1381 cleanup: 1382 if (ret != KMF_OK) { 1383 if (*extn != NULL) { 1384 free(*extn); 1385 } 1386 *extn = NULL; 1387 } 1388 1389 kmfber_free(asn1, 1); 1390 return (ret); 1391 } 1392 1393 KMF_RETURN 1394 DerDecodeName(KMF_DATA *encodedname, KMF_X509_NAME *name) 1395 { 1396 KMF_RETURN ret = KMF_OK; 1397 BerElement *asn1 = NULL; 1398 BerValue bv; 1399 1400 bv.bv_val = (char *)encodedname->Data; 1401 bv.bv_len = encodedname->Length; 1402 1403 asn1 = kmfder_init(&bv); 1404 if (asn1 == NULL) 1405 return (KMF_ERR_MEMORY); 1406 1407 (void) memset((void *)name, 0, sizeof (KMF_X509_NAME)); 1408 1409 if ((ret = get_rdn(asn1, name)) != KMF_OK) 1410 goto cleanup; 1411 1412 cleanup: 1413 if (asn1) 1414 kmfber_free(asn1, 1); 1415 return (ret); 1416 } 1417 1418 KMF_RETURN 1419 DerEncodeName(KMF_X509_NAME *name, KMF_DATA *encodedname) 1420 { 1421 KMF_RETURN ret = KMF_OK; 1422 BerElement *asn1 = NULL; 1423 BerValue *bv = NULL; 1424 1425 asn1 = kmfder_alloc(); 1426 if (asn1 == NULL) 1427 return (KMF_ERR_MEMORY); 1428 1429 if ((ret = encode_rdn(asn1, name)) != KMF_OK) 1430 goto cleanup; 1431 1432 if (kmfber_flatten(asn1, &bv) == -1) { 1433 ret = KMF_ERR_BAD_CERT_FORMAT; 1434 goto cleanup; 1435 } 1436 1437 encodedname->Data = (uchar_t *)bv->bv_val; 1438 encodedname->Length = bv->bv_len; 1439 1440 cleanup: 1441 if (bv) 1442 free(bv); 1443 1444 if (asn1) 1445 kmfber_free(asn1, 1); 1446 1447 return (ret); 1448 } 1449 1450 static KMF_RETURN 1451 encode_tbs_cert(BerElement *asn1, KMF_X509_TBS_CERT *tbscert) 1452 { 1453 KMF_RETURN ret = KMF_OK; 1454 uint32_t version; 1455 1456 /* version should be 4 bytes or less */ 1457 if (tbscert->version.Length > sizeof (int)) 1458 return (KMF_ERR_BAD_CERT_FORMAT); 1459 1460 (void) memcpy(&version, tbscert->version.Data, 1461 tbscert->version.Length); 1462 1463 /* Start the sequence and add the version */ 1464 if (kmfber_printf(asn1, "{Tli", 0xA0, 3, version) == -1) { 1465 ret = KMF_ERR_BAD_CERT_FORMAT; 1466 goto cleanup; 1467 } 1468 /* Write the serial number */ 1469 if (kmfber_printf(asn1, "I", 1470 (char *)tbscert->serialNumber.val, 1471 (size_t)tbscert->serialNumber.len) == -1) { 1472 ret = KMF_ERR_BAD_CERT_FORMAT; 1473 goto cleanup; 1474 } 1475 1476 if ((ret = encode_algoid(asn1, &tbscert->signature)) != KMF_OK) 1477 goto cleanup; 1478 1479 /* Encode the Issuer RDN */ 1480 if ((ret = encode_rdn(asn1, &tbscert->issuer)) != KMF_OK) 1481 goto cleanup; 1482 1483 /* Encode the Validity fields */ 1484 if ((ret = encode_validity(asn1, &tbscert->validity)) != KMF_OK) 1485 goto cleanup; 1486 1487 /* Encode the Subject RDN */ 1488 if ((ret = encode_rdn(asn1, &tbscert->subject)) != KMF_OK) 1489 goto cleanup; 1490 1491 /* Encode the Subject Public Key Info */ 1492 if ((ret = encode_spki(asn1, &tbscert->subjectPublicKeyInfo)) != KMF_OK) 1493 goto cleanup; 1494 1495 /* Optional field: issuer Unique ID */ 1496 if (tbscert->issuerUniqueIdentifier.Length > 0) { 1497 if ((ret = encode_uniqueid(asn1, 0xA1, 1498 &tbscert->issuerUniqueIdentifier)) != KMF_OK) 1499 goto cleanup; 1500 } 1501 1502 /* Optional field: Subject Unique ID */ 1503 if (tbscert->subjectUniqueIdentifier.Length > 0) { 1504 if ((ret = encode_uniqueid(asn1, 0xA2, 1505 &tbscert->subjectUniqueIdentifier)) != KMF_OK) 1506 goto cleanup; 1507 } 1508 1509 /* Optional field: Certificate Extensions */ 1510 if (tbscert->extensions.numberOfExtensions > 0) { 1511 if ((ret = encode_extensions(asn1, 1512 &tbscert->extensions)) != KMF_OK) 1513 goto cleanup; 1514 } 1515 1516 /* Close out the TBSCert sequence */ 1517 if (kmfber_printf(asn1, "}") == -1) { 1518 ret = KMF_ERR_BAD_CERT_FORMAT; 1519 goto cleanup; 1520 } 1521 1522 cleanup: 1523 /* 1524 * Memory cleanup is done in the caller or in the individual 1525 * encoding routines. 1526 */ 1527 1528 return (ret); 1529 } 1530 1531 KMF_RETURN 1532 DerEncodeTbsCertificate(KMF_X509_TBS_CERT *tbs_cert_ptr, 1533 KMF_DATA *enc_tbs_cert_ptr) 1534 { 1535 KMF_RETURN ret; 1536 BerElement *asn1 = NULL; 1537 BerValue *tbsdata = NULL; 1538 1539 asn1 = kmfder_alloc(); 1540 if (asn1 == NULL) 1541 return (KMF_ERR_MEMORY); 1542 1543 enc_tbs_cert_ptr->Data = NULL; 1544 enc_tbs_cert_ptr->Length = 0; 1545 1546 ret = encode_tbs_cert(asn1, tbs_cert_ptr); 1547 if (ret != KMF_OK) 1548 goto cleanup; 1549 1550 if (kmfber_flatten(asn1, &tbsdata) == -1) { 1551 ret = KMF_ERR_MEMORY; 1552 goto cleanup; 1553 } 1554 1555 enc_tbs_cert_ptr->Data = (uchar_t *)tbsdata->bv_val; 1556 enc_tbs_cert_ptr->Length = tbsdata->bv_len; 1557 1558 cleanup: 1559 if (ret != KMF_OK) 1560 free_data(enc_tbs_cert_ptr); 1561 1562 if (asn1 != NULL) 1563 kmfber_free(asn1, 1); 1564 1565 if (tbsdata) 1566 free(tbsdata); 1567 1568 return (ret); 1569 } 1570 1571 KMF_RETURN 1572 DerEncodeSignedCertificate(KMF_X509_CERTIFICATE *signed_cert_ptr, 1573 KMF_DATA *encodedcert) 1574 { 1575 KMF_RETURN ret = KMF_OK; 1576 KMF_X509_TBS_CERT *tbscert = NULL; 1577 KMF_X509_SIGNATURE *signature = NULL; 1578 BerElement *asn1 = NULL; 1579 BerValue *tbsdata = NULL; 1580 1581 if (signed_cert_ptr == NULL || encodedcert == NULL) 1582 return (KMF_ERR_BAD_PARAMETER); 1583 1584 encodedcert->Data = NULL; 1585 encodedcert->Length = 0; 1586 1587 tbscert = &signed_cert_ptr->certificate; 1588 signature = &signed_cert_ptr->signature; 1589 1590 asn1 = kmfder_alloc(); 1591 if (asn1 == NULL) 1592 return (KMF_ERR_MEMORY); 1593 1594 /* Start outer X509 Certificate SEQUENCE */ 1595 if (kmfber_printf(asn1, "{") == -1) { 1596 ret = KMF_ERR_BAD_CERT_FORMAT; 1597 goto cleanup; 1598 } 1599 1600 if ((ret = encode_tbs_cert(asn1, tbscert)) != KMF_OK) { 1601 ret = KMF_ERR_BAD_CERT_FORMAT; 1602 goto cleanup; 1603 } 1604 1605 /* Add the Algorithm & Signature Sequence */ 1606 if ((ret = encode_algoid(asn1, 1607 &signature->algorithmIdentifier)) != KMF_OK) 1608 goto cleanup; 1609 1610 if (signature->encrypted.Length > 0) { 1611 if (kmfber_printf(asn1, "B", signature->encrypted.Data, 1612 signature->encrypted.Length * 8) == -1) { 1613 ret = KMF_ERR_BAD_CERT_FORMAT; 1614 goto cleanup; 1615 } 1616 } 1617 1618 if (kmfber_printf(asn1, "}") == -1) { 1619 ret = KMF_ERR_BAD_CERT_FORMAT; 1620 goto cleanup; 1621 } 1622 1623 if (kmfber_flatten(asn1, &tbsdata) == -1) { 1624 ret = KMF_ERR_MEMORY; 1625 goto cleanup; 1626 } 1627 1628 encodedcert->Data = (uchar_t *)tbsdata->bv_val; 1629 encodedcert->Length = tbsdata->bv_len; 1630 1631 cleanup: 1632 if (ret != KMF_OK) 1633 free_data(encodedcert); 1634 1635 if (tbsdata) 1636 free(tbsdata); 1637 1638 if (asn1) 1639 kmfber_free(asn1, 1); 1640 1641 return (ret); 1642 } 1643 1644 KMF_RETURN 1645 ExtractX509CertParts(KMF_DATA *x509cert, KMF_DATA *tbscert, 1646 KMF_DATA *signature) 1647 { 1648 KMF_RETURN ret = KMF_OK; 1649 BerElement *der = NULL; 1650 BerValue x509; 1651 ber_tag_t tag; 1652 ber_len_t size; 1653 1654 if (tbscert == NULL || x509cert == NULL) 1655 return (KMF_ERR_BAD_PARAMETER); 1656 1657 x509.bv_val = (char *)x509cert->Data; 1658 x509.bv_len = x509cert->Length; 1659 1660 der = kmfder_init(&x509); 1661 if (der == NULL) 1662 return (KMF_ERR_MEMORY); 1663 1664 /* Skip over the overall Sequence tag to get at the TBS Cert data */ 1665 if (kmfber_scanf(der, "Tl", &tag, &size) == -1) { 1666 ret = KMF_ERR_BAD_CERT_FORMAT; 1667 goto cleanup; 1668 } 1669 if (tag != BER_CONSTRUCTED_SEQUENCE) { 1670 ret = KMF_ERR_BAD_CERT_FORMAT; 1671 goto cleanup; 1672 } 1673 1674 /* 1675 * Since we are extracting a copy of the ENCODED bytes, we 1676 * must make sure to also include the bytes for the tag and 1677 * the length fields for the CONSTRUCTED SEQUENCE (TBSCert). 1678 */ 1679 size += kmfber_calc_taglen(tag) + kmfber_calc_lenlen(size); 1680 1681 tbscert->Data = malloc(size); 1682 if (tbscert->Data == NULL) { 1683 ret = KMF_ERR_MEMORY; 1684 goto cleanup; 1685 } 1686 tbscert->Length = size; 1687 1688 /* The der data ptr is now set to the start of the TBS cert sequence */ 1689 size = kmfber_read(der, (char *)tbscert->Data, tbscert->Length); 1690 if (size != tbscert->Length) { 1691 ret = KMF_ERR_BAD_CERT_FORMAT; 1692 goto cleanup; 1693 } 1694 1695 if (signature != NULL) { 1696 KMF_X509_ALGORITHM_IDENTIFIER algoid; 1697 if ((ret = get_algoid(der, &algoid)) != KMF_OK) 1698 goto cleanup; 1699 free_algoid(&algoid); 1700 1701 if (kmfber_scanf(der, "tl", &tag, &size) != BER_BIT_STRING) { 1702 ret = KMF_ERR_BAD_CERT_FORMAT; 1703 goto cleanup; 1704 } 1705 /* Now get the signature data */ 1706 if (kmfber_scanf(der, "B", (char **)&signature->Data, 1707 (ber_len_t *)&signature->Length) == -1) { 1708 ret = KMF_ERR_BAD_CERT_FORMAT; 1709 goto cleanup; 1710 } 1711 /* convert bitstring length to bytes */ 1712 signature->Length = signature->Length / 8; 1713 } 1714 1715 cleanup: 1716 if (der) 1717 kmfber_free(der, 1); 1718 1719 if (ret != KMF_OK) 1720 free_data(tbscert); 1721 1722 return (ret); 1723 } 1724 1725 /* 1726 * Name: GetKeyFromSpki 1727 * 1728 * Description: 1729 * This function parses the KMF_X509_SPKI into its 1730 * key and parameter components based on the key generation algorithm. 1731 * NOTE: Currently, it only checks for the RSA and DSA algorithms. 1732 * The RSA algorithm is equivalent to the default behavior. 1733 * All other algorithms will default to the parameters = NULL and the 1734 * key data equal to whatever is in the CSSM_KEY structure for the key 1735 * 1736 * Parameters: 1737 * AlgId (input) : Algorithm identifier 1738 * SpkiPtr (input): SPKI structure that contains the key 1739 * key_ptr(output): The output key 1740 * 1741 */ 1742 KMF_RETURN 1743 GetKeyFromSpki(KMF_ALGORITHM_INDEX AlgId, 1744 KMF_X509_SPKI *SpkiPtr, 1745 KMF_DATA **key_ptr) 1746 { 1747 KMF_RETURN ret = KMF_OK; 1748 BerElement *asn1; 1749 BerValue *encodedkey = NULL; 1750 1751 if (!key_ptr || !SpkiPtr) { 1752 return (KMF_ERR_BAD_PARAMETER); 1753 } 1754 *key_ptr = NULL; 1755 1756 switch (AlgId) { 1757 case KMF_ALGID_DSA: 1758 asn1 = kmfder_alloc(); 1759 if (asn1 == NULL) { 1760 return (KMF_ERR_MEMORY); 1761 } 1762 1763 if ((ret = encode_spki(asn1, SpkiPtr)) != KMF_OK) { 1764 ret = KMF_ERR_MEMORY; 1765 goto cleanup; 1766 } 1767 1768 if (kmfber_flatten(asn1, &encodedkey) == -1) { 1769 ret = KMF_ERR_MEMORY; 1770 goto cleanup; 1771 } 1772 1773 *key_ptr = malloc(sizeof (KMF_DATA)); 1774 1775 if (!*key_ptr) { 1776 ret = KMF_ERR_MEMORY; 1777 goto cleanup; 1778 } 1779 1780 (*key_ptr)->Length = encodedkey->bv_len; 1781 (*key_ptr)->Data = (uchar_t *)encodedkey->bv_val; 1782 cleanup: 1783 kmfber_free(asn1, 1); 1784 if (encodedkey) 1785 free(encodedkey); 1786 break; 1787 default: /* RSA */ 1788 *key_ptr = malloc(sizeof (KMF_DATA)); 1789 1790 if (!*key_ptr) { 1791 return (KMF_ERR_MEMORY); 1792 } 1793 (*key_ptr)->Length = SpkiPtr->subjectPublicKey.Length; 1794 (*key_ptr)->Data = malloc((*key_ptr)->Length); 1795 1796 if (!(*key_ptr)->Data) { 1797 free(*key_ptr); 1798 *key_ptr = NULL; 1799 return (KMF_ERR_MEMORY); 1800 } 1801 (void) memcpy((*key_ptr)->Data, 1802 SpkiPtr->subjectPublicKey.Data, 1803 (*key_ptr)->Length); 1804 return (ret); 1805 } 1806 return (ret); 1807 } 1808 1809 static KMF_RETURN 1810 decode_csr_extensions(BerElement *asn1, KMF_X509_EXTENSIONS *extns) 1811 { 1812 KMF_RETURN ret = KMF_OK; 1813 BerValue oid; 1814 1815 if (kmfber_scanf(asn1, "{D", &oid) == -1) { 1816 return (KMF_ERR_UNKNOWN_CSR_ATTRIBUTE); 1817 } 1818 1819 /* We only understand extension requests in a CSR */ 1820 if (memcmp(oid.bv_val, extension_request_oid.Data, 1821 oid.bv_len) != 0) { 1822 return (KMF_ERR_UNKNOWN_CSR_ATTRIBUTE); 1823 } 1824 1825 if (kmfber_scanf(asn1, "[") == -1) { 1826 return (KMF_ERR_ENCODING); 1827 } 1828 ret = get_extensions(asn1, extns); 1829 1830 1831 return (ret); 1832 } 1833 1834 static KMF_RETURN 1835 decode_tbscsr_data(BerElement *asn1, 1836 KMF_TBS_CSR **signed_csr_ptr_ptr) 1837 { 1838 KMF_RETURN ret = KMF_OK; 1839 KMF_TBS_CSR *tbscsr = NULL; 1840 char *end = NULL; 1841 uint32_t version; 1842 ber_tag_t tag; 1843 ber_len_t size; 1844 1845 /* Now get the version number, it is not optional */ 1846 if (kmfber_scanf(asn1, "{i", &version) == -1) { 1847 ret = KMF_ERR_BAD_CERT_FORMAT; 1848 goto cleanup; 1849 } 1850 1851 tbscsr = malloc(sizeof (KMF_TBS_CSR)); 1852 if (!tbscsr) { 1853 ret = KMF_ERR_MEMORY; 1854 goto cleanup; 1855 } 1856 1857 (void) memset(tbscsr, 0, sizeof (KMF_TBS_CSR)); 1858 1859 if ((ret = set_der_integer(&tbscsr->version, version)) != KMF_OK) 1860 goto cleanup; 1861 1862 if ((ret = get_rdn(asn1, &tbscsr->subject)) != KMF_OK) 1863 goto cleanup; 1864 1865 if ((ret = get_spki(asn1, &tbscsr->subjectPublicKeyInfo)) != KMF_OK) 1866 goto cleanup; 1867 1868 /* Check for the optional fields (attributes) */ 1869 if (kmfber_next_element(asn1, &size, end) == 0xA0) { 1870 if (kmfber_scanf(asn1, "Tl", &tag, &size) == -1) { 1871 ret = KMF_ERR_ENCODING; 1872 goto cleanup; 1873 } 1874 1875 ret = decode_csr_extensions(asn1, &tbscsr->extensions); 1876 } 1877 if (ret == KMF_OK) 1878 *signed_csr_ptr_ptr = tbscsr; 1879 1880 cleanup: 1881 if (ret != KMF_OK) { 1882 if (tbscsr) { 1883 free_tbscsr(tbscsr); 1884 free(tbscsr); 1885 } 1886 *signed_csr_ptr_ptr = NULL; 1887 } 1888 return (ret); 1889 } 1890 1891 KMF_RETURN 1892 DerDecodeTbsCsr(const KMF_DATA *Value, 1893 KMF_TBS_CSR **tbscsr) 1894 { 1895 KMF_RETURN ret = KMF_OK; 1896 BerElement *asn1 = NULL; 1897 BerValue rawcsr; 1898 KMF_TBS_CSR *newcsr = NULL; 1899 1900 if (!tbscsr || !Value || !Value->Data || !Value->Length) 1901 return (KMF_ERR_BAD_PARAMETER); 1902 1903 rawcsr.bv_val = (char *)Value->Data; 1904 rawcsr.bv_len = Value->Length; 1905 1906 if ((asn1 = kmfder_init(&rawcsr)) == NULL) 1907 return (KMF_ERR_MEMORY); 1908 1909 ret = decode_tbscsr_data(asn1, &newcsr); 1910 if (ret != KMF_OK) 1911 goto cleanup; 1912 1913 *tbscsr = newcsr; 1914 1915 cleanup: 1916 if (ret != KMF_OK) { 1917 if (newcsr) 1918 free_tbscsr(newcsr); 1919 *tbscsr = NULL; 1920 } 1921 kmfber_free(asn1, 1); 1922 1923 return (ret); 1924 } 1925 1926 KMF_RETURN 1927 DerDecodeSignedCsr(const KMF_DATA *Value, 1928 KMF_CSR_DATA **signed_csr_ptr_ptr) 1929 { 1930 KMF_RETURN ret = KMF_OK; 1931 BerElement *asn1 = NULL; 1932 BerValue rawcsr; 1933 int tag; 1934 ber_len_t size; 1935 char *end = NULL; 1936 char *signature; 1937 KMF_TBS_CSR *tbscsr = NULL; 1938 KMF_CSR_DATA *csrptr = NULL; 1939 1940 if (!signed_csr_ptr_ptr || !Value || !Value->Data || !Value->Length) 1941 return (KMF_ERR_BAD_PARAMETER); 1942 1943 rawcsr.bv_val = (char *)Value->Data; 1944 rawcsr.bv_len = Value->Length; 1945 1946 if ((asn1 = kmfder_init(&rawcsr)) == NULL) 1947 return (KMF_ERR_MEMORY); 1948 1949 if (kmfber_first_element(asn1, &size, &end) != 1950 BER_CONSTRUCTED_SEQUENCE) { 1951 ret = KMF_ERR_BAD_CERT_FORMAT; 1952 goto cleanup; 1953 } 1954 1955 csrptr = malloc(sizeof (KMF_CSR_DATA)); 1956 if (csrptr == NULL) { 1957 ret = KMF_ERR_MEMORY; 1958 goto cleanup; 1959 } 1960 (void) memset(csrptr, 0, sizeof (KMF_CSR_DATA)); 1961 1962 ret = decode_tbscsr_data(asn1, &tbscsr); 1963 if (ret != KMF_OK) 1964 goto cleanup; 1965 1966 csrptr->csr = *tbscsr; 1967 free(tbscsr); 1968 tbscsr = NULL; 1969 1970 if ((ret = get_algoid(asn1, 1971 &csrptr->signature.algorithmIdentifier)) != KMF_OK) 1972 goto cleanup; 1973 1974 /* Check to see if the cert has a signature yet */ 1975 if (kmfber_next_element(asn1, &size, end) == BER_BIT_STRING) { 1976 /* Finally, get the encrypted signature BITSTRING */ 1977 if (kmfber_scanf(asn1, "tl", &tag, &size) == -1) { 1978 ret = KMF_ERR_BAD_CERT_FORMAT; 1979 goto cleanup; 1980 } 1981 if (tag != BER_BIT_STRING) { 1982 ret = KMF_ERR_BAD_CERT_FORMAT; 1983 goto cleanup; 1984 } 1985 if (kmfber_scanf(asn1, "B}", &signature, &size) == -1) { 1986 ret = KMF_ERR_BAD_CERT_FORMAT; 1987 goto cleanup; 1988 } 1989 csrptr->signature.encrypted.Data = (uchar_t *)signature; 1990 csrptr->signature.encrypted.Length = size / 8; 1991 } else { 1992 csrptr->signature.encrypted.Data = NULL; 1993 csrptr->signature.encrypted.Length = 0; 1994 } 1995 1996 *signed_csr_ptr_ptr = csrptr; 1997 cleanup: 1998 if (ret != KMF_OK) { 1999 free_tbscsr(&csrptr->csr); 2000 free_algoid(&csrptr->signature.algorithmIdentifier); 2001 if (csrptr->signature.encrypted.Data) 2002 free(csrptr->signature.encrypted.Data); 2003 2004 if (csrptr) 2005 free(csrptr); 2006 2007 *signed_csr_ptr_ptr = NULL; 2008 } 2009 if (asn1) 2010 kmfber_free(asn1, 1); 2011 2012 return (ret); 2013 2014 } 2015 2016 static KMF_RETURN 2017 encode_csr_extensions(BerElement *asn1, KMF_TBS_CSR *tbscsr) 2018 { 2019 KMF_RETURN ret = KMF_OK; 2020 int attlen = 0; 2021 BerElement *extnasn1 = NULL; 2022 BerValue *extnvalue = NULL; 2023 2024 /* Optional field: CSR attributes and extensions */ 2025 if (tbscsr->extensions.numberOfExtensions > 0) { 2026 if (kmfber_printf(asn1, "T", 0xA0) == -1) { 2027 ret = KMF_ERR_ENCODING; 2028 goto cleanup; 2029 } 2030 } else { 2031 /* No extensions or attributes to encode */ 2032 return (KMF_OK); 2033 } 2034 2035 /* 2036 * attributes [0] Attributes 2037 * Attributes := SET OF Attribute 2038 * Attribute := SEQUENCE { 2039 * { ATTRIBUTE ID 2040 * values SET SIZE(1..MAX) of ATTRIBUTE 2041 * } 2042 * 2043 * Ex: { ExtensionRequest OID [ { {extn1 } , {extn2 } } ] } 2044 */ 2045 2046 /* 2047 * Encode any extensions and add to the attributes section. 2048 */ 2049 if (tbscsr->extensions.numberOfExtensions > 0) { 2050 extnasn1 = kmfder_alloc(); 2051 if (extnasn1 == NULL) { 2052 ret = KMF_ERR_MEMORY; 2053 goto cleanup; 2054 } 2055 2056 if (kmfber_printf(extnasn1, "{D[{", 2057 &extension_request_oid) == -1) { 2058 ret = KMF_ERR_ENCODING; 2059 goto cleanup_1; 2060 } 2061 2062 if ((ret = encode_extension_list(extnasn1, 2063 &tbscsr->extensions)) != KMF_OK) { 2064 goto cleanup_1; 2065 } 2066 2067 if (kmfber_printf(extnasn1, "}]}") == -1) { 2068 ret = KMF_ERR_ENCODING; 2069 goto cleanup_1; 2070 } 2071 2072 if (kmfber_flatten(extnasn1, &extnvalue) == -1) { 2073 ret = KMF_ERR_MEMORY; 2074 goto cleanup_1; 2075 } 2076 cleanup_1: 2077 kmfber_free(extnasn1, 1); 2078 2079 if (ret == KMF_OK) 2080 /* Add 2 bytes to cover the tag and the length */ 2081 attlen = extnvalue->bv_len; 2082 } 2083 if (ret != KMF_OK) 2084 goto cleanup; 2085 2086 if (kmfber_printf(asn1, "l", attlen) == -1) { 2087 ret = KMF_ERR_ENCODING; 2088 goto cleanup; 2089 } 2090 2091 /* Write the actual encoded extensions */ 2092 if (extnvalue != NULL && extnvalue->bv_val != NULL) { 2093 if (kmfber_write(asn1, extnvalue->bv_val, 2094 extnvalue->bv_len, 0) == -1) { 2095 ret = KMF_ERR_ENCODING; 2096 goto cleanup; 2097 } 2098 } 2099 2100 cleanup: 2101 /* 2102 * Memory cleanup is done in the caller or in the individual 2103 * encoding routines. 2104 */ 2105 if (extnvalue) { 2106 if (extnvalue->bv_val) 2107 free(extnvalue->bv_val); 2108 free(extnvalue); 2109 } 2110 2111 return (ret); 2112 } 2113 2114 static KMF_RETURN 2115 encode_tbs_csr(BerElement *asn1, KMF_TBS_CSR *tbscsr) 2116 { 2117 KMF_RETURN ret = KMF_OK; 2118 uint32_t version; 2119 2120 /* Start the version */ 2121 (void) memcpy(&version, tbscsr->version.Data, 2122 tbscsr->version.Length); 2123 2124 if (kmfber_printf(asn1, "{i", version) == -1) { 2125 ret = KMF_ERR_BAD_CERT_FORMAT; 2126 goto cleanup; 2127 } 2128 2129 /* Encode the Subject RDN */ 2130 if ((ret = encode_rdn(asn1, &tbscsr->subject)) != KMF_OK) 2131 goto cleanup; 2132 2133 /* Encode the Subject Public Key Info */ 2134 if ((ret = encode_spki(asn1, &tbscsr->subjectPublicKeyInfo)) != KMF_OK) 2135 goto cleanup; 2136 2137 2138 if ((ret = encode_csr_extensions(asn1, tbscsr)) != KMF_OK) 2139 goto cleanup; 2140 2141 /* Close out the TBSCert sequence */ 2142 if (kmfber_printf(asn1, "}") == -1) { 2143 ret = KMF_ERR_BAD_CERT_FORMAT; 2144 goto cleanup; 2145 } 2146 2147 cleanup: 2148 return (ret); 2149 } 2150 2151 KMF_RETURN 2152 DerEncodeDSAPrivateKey(KMF_DATA *encodedkey, KMF_RAW_DSA_KEY *dsa) 2153 { 2154 KMF_RETURN rv = KMF_OK; 2155 BerElement *asn1 = NULL; 2156 BerValue *dsadata = NULL; 2157 2158 asn1 = kmfder_alloc(); 2159 if (asn1 == NULL) 2160 return (KMF_ERR_MEMORY); 2161 2162 if (kmfber_printf(asn1, "I", 2163 dsa->value.val, dsa->value.len) == -1) { 2164 rv = KMF_ERR_MEMORY; 2165 goto cleanup; 2166 } 2167 2168 if (kmfber_flatten(asn1, &dsadata) == -1) { 2169 rv = KMF_ERR_MEMORY; 2170 goto cleanup; 2171 } 2172 2173 encodedkey->Data = (uchar_t *)dsadata->bv_val; 2174 encodedkey->Length = dsadata->bv_len; 2175 2176 free(dsadata); 2177 cleanup: 2178 kmfber_free(asn1, 1); 2179 return (rv); 2180 } 2181 2182 KMF_RETURN 2183 DerEncodeRSAPrivateKey(KMF_DATA *encodedkey, KMF_RAW_RSA_KEY *rsa) 2184 { 2185 KMF_RETURN rv = KMF_OK; 2186 BerElement *asn1 = NULL; 2187 uchar_t ver = 0; 2188 BerValue *rsadata = NULL; 2189 2190 asn1 = kmfder_alloc(); 2191 if (asn1 == NULL) 2192 return (KMF_ERR_MEMORY); 2193 2194 if (kmfber_printf(asn1, "{IIIIIIIII}", 2195 &ver, 1, 2196 rsa->mod.val, rsa->mod.len, 2197 rsa->pubexp.val, rsa->pubexp.len, 2198 rsa->priexp.val, rsa->priexp.len, 2199 rsa->prime1.val, rsa->prime1.len, 2200 rsa->prime2.val, rsa->prime2.len, 2201 rsa->exp1.val, rsa->exp1.len, 2202 rsa->exp2.val, rsa->exp2.len, 2203 rsa->coef.val, rsa->coef.len) == -1) 2204 goto cleanup; 2205 2206 if (kmfber_flatten(asn1, &rsadata) == -1) { 2207 rv = KMF_ERR_MEMORY; 2208 goto cleanup; 2209 } 2210 2211 encodedkey->Data = (uchar_t *)rsadata->bv_val; 2212 encodedkey->Length = rsadata->bv_len; 2213 2214 free(rsadata); 2215 cleanup: 2216 kmfber_free(asn1, 1); 2217 return (rv); 2218 } 2219 2220 2221 KMF_RETURN 2222 DerEncodeTbsCsr(KMF_TBS_CSR *tbs_csr_ptr, 2223 KMF_DATA *enc_tbs_csr_ptr) 2224 { 2225 KMF_RETURN ret; 2226 BerValue *tbsdata = NULL; 2227 BerElement *asn1 = NULL; 2228 2229 asn1 = kmfder_alloc(); 2230 2231 enc_tbs_csr_ptr->Data = NULL; 2232 enc_tbs_csr_ptr->Length = 0; 2233 2234 if (asn1 == NULL) 2235 return (KMF_ERR_MEMORY); 2236 2237 ret = encode_tbs_csr(asn1, tbs_csr_ptr); 2238 if (ret != KMF_OK) 2239 goto cleanup; 2240 2241 if (kmfber_flatten(asn1, &tbsdata) == -1) { 2242 ret = KMF_ERR_MEMORY; 2243 goto cleanup; 2244 } 2245 2246 enc_tbs_csr_ptr->Data = (uchar_t *)tbsdata->bv_val; 2247 enc_tbs_csr_ptr->Length = tbsdata->bv_len; 2248 2249 cleanup: 2250 if (ret != KMF_OK) 2251 free_data(enc_tbs_csr_ptr); 2252 2253 if (asn1 != NULL) 2254 kmfber_free(asn1, 1); 2255 2256 if (tbsdata) 2257 free(tbsdata); 2258 2259 return (ret); 2260 } 2261 2262 KMF_RETURN 2263 DerEncodeSignedCsr(KMF_CSR_DATA *signed_csr_ptr, 2264 KMF_DATA *encodedcsr) 2265 { 2266 KMF_RETURN ret = KMF_OK; 2267 KMF_TBS_CSR *tbscsr = NULL; 2268 KMF_X509_SIGNATURE *signature = NULL; 2269 BerElement *asn1 = NULL; 2270 BerValue *tbsdata = NULL; 2271 2272 if (signed_csr_ptr == NULL) 2273 return (KMF_ERR_BAD_PARAMETER); 2274 2275 tbscsr = &signed_csr_ptr->csr; 2276 signature = &signed_csr_ptr->signature; 2277 2278 asn1 = kmfder_alloc(); 2279 if (asn1 == NULL) 2280 return (KMF_ERR_MEMORY); 2281 2282 /* Start outer CSR SEQUENCE */ 2283 if (kmfber_printf(asn1, "{") == -1) { 2284 ret = KMF_ERR_BAD_CERT_FORMAT; 2285 goto cleanup; 2286 } 2287 2288 ret = encode_tbs_csr(asn1, tbscsr); 2289 2290 /* Add the Algorithm & Signature Sequence */ 2291 if ((ret = encode_algoid(asn1, 2292 &signature->algorithmIdentifier)) != KMF_OK) 2293 goto cleanup; 2294 2295 if (signature->encrypted.Length > 0) { 2296 if (kmfber_printf(asn1, "B", signature->encrypted.Data, 2297 signature->encrypted.Length * 8) == -1) { 2298 ret = KMF_ERR_BAD_CERT_FORMAT; 2299 goto cleanup; 2300 } 2301 } 2302 2303 if (kmfber_printf(asn1, "}") == -1) { 2304 ret = KMF_ERR_BAD_CERT_FORMAT; 2305 goto cleanup; 2306 } 2307 2308 if (kmfber_flatten(asn1, &tbsdata) == -1) { 2309 ret = KMF_ERR_MEMORY; 2310 goto cleanup; 2311 } 2312 2313 encodedcsr->Data = (uchar_t *)tbsdata->bv_val; 2314 encodedcsr->Length = tbsdata->bv_len; 2315 2316 cleanup: 2317 if (ret != KMF_OK) { 2318 free_data(encodedcsr); 2319 } 2320 2321 if (tbsdata) 2322 free(tbsdata); 2323 2324 if (asn1) 2325 kmfber_free(asn1, 1); 2326 return (ret); 2327 } 2328 2329 KMF_RETURN 2330 ExtractSPKIData( 2331 const KMF_X509_SPKI *pKey, 2332 KMF_ALGORITHM_INDEX AlgorithmId, 2333 KMF_DATA *pKeyParts, 2334 uint32_t *uNumKeyParts) 2335 { 2336 KMF_RETURN ret = KMF_OK; 2337 BerElement *asn1 = NULL; 2338 BerValue *P, *Q, *G, *Mod, *Exp, *PubKey; 2339 BerValue PubKeyParams, PubKeyData; 2340 2341 if (pKeyParts == NULL || uNumKeyParts == NULL || pKey == NULL) 2342 return (KMF_ERR_BAD_PARAMETER); 2343 2344 switch (AlgorithmId) { 2345 case KMF_ALGID_DSA: 2346 case KMF_ALGID_SHA1WithDSA: 2347 /* First, get the parameters from the algorithm definition */ 2348 PubKeyParams.bv_val = (char *)pKey->algorithm.parameters.Data; 2349 PubKeyParams.bv_len = pKey->algorithm.parameters.Length; 2350 if ((asn1 = kmfder_init(&PubKeyParams)) == NULL) 2351 return (KMF_ERR_MEMORY); 2352 2353 if (kmfber_scanf(asn1, "{III}", &P, &Q, &G) == -1) { 2354 kmfber_free(asn1, 1); 2355 return (KMF_ERR_BAD_KEY_FORMAT); 2356 } 2357 pKeyParts[KMF_DSA_PRIME].Data = (uchar_t *)P->bv_val; 2358 pKeyParts[KMF_DSA_PRIME].Length = P->bv_len; 2359 pKeyParts[KMF_DSA_SUB_PRIME].Data = (uchar_t *)Q->bv_val; 2360 pKeyParts[KMF_DSA_SUB_PRIME].Length = Q->bv_len; 2361 pKeyParts[KMF_DSA_BASE].Data = (uchar_t *)G->bv_val; 2362 pKeyParts[KMF_DSA_BASE].Length = G->bv_len; 2363 2364 free(P); 2365 free(Q); 2366 free(G); 2367 kmfber_free(asn1, 1); 2368 2369 /* Get the PubKey data */ 2370 PubKeyData.bv_val = (char *)pKey->subjectPublicKey.Data; 2371 PubKeyData.bv_len = pKey->subjectPublicKey.Length; 2372 if ((asn1 = kmfder_init(&PubKeyData)) == NULL) { 2373 ret = KMF_ERR_MEMORY; 2374 goto cleanup; 2375 } 2376 PubKey = NULL; 2377 if (kmfber_scanf(asn1, "I", &PubKey) == -1) { 2378 ret = KMF_ERR_BAD_KEY_FORMAT; 2379 goto cleanup; 2380 } 2381 pKeyParts[KMF_DSA_PUBLIC_VALUE].Data = 2382 (uchar_t *)PubKey->bv_val; 2383 pKeyParts[KMF_DSA_PUBLIC_VALUE].Length = PubKey->bv_len; 2384 2385 free(PubKey); 2386 2387 *uNumKeyParts = KMF_NUMBER_DSA_PUBLIC_KEY_PARTS; 2388 break; 2389 2390 case KMF_ALGID_RSA: 2391 case KMF_ALGID_MD2WithRSA: 2392 case KMF_ALGID_MD5WithRSA: 2393 case KMF_ALGID_SHA1WithRSA: 2394 PubKeyData.bv_val = (char *)pKey->subjectPublicKey.Data; 2395 PubKeyData.bv_len = pKey->subjectPublicKey.Length; 2396 if ((asn1 = kmfder_init(&PubKeyData)) == NULL) { 2397 ret = KMF_ERR_MEMORY; 2398 goto cleanup; 2399 } 2400 if (kmfber_scanf(asn1, "{II}", &Mod, &Exp) == -1) { 2401 ret = KMF_ERR_BAD_KEY_FORMAT; 2402 goto cleanup; 2403 } 2404 pKeyParts[KMF_RSA_MODULUS].Data = (uchar_t *)Mod->bv_val; 2405 pKeyParts[KMF_RSA_MODULUS].Length = Mod->bv_len; 2406 pKeyParts[KMF_RSA_PUBLIC_EXPONENT].Data = 2407 (uchar_t *)Exp->bv_val; 2408 pKeyParts[KMF_RSA_PUBLIC_EXPONENT].Length = Exp->bv_len; 2409 *uNumKeyParts = KMF_NUMBER_RSA_PUBLIC_KEY_PARTS; 2410 2411 free(Mod); 2412 free(Exp); 2413 break; 2414 default: 2415 return (KMF_ERR_BAD_PARAMETER); 2416 } 2417 cleanup: 2418 if (ret != KMF_OK) { 2419 int i; 2420 for (i = 0; i < *uNumKeyParts; i++) 2421 free_data(&pKeyParts[i]); 2422 } 2423 if (asn1 != NULL) { 2424 kmfber_free(asn1, 1); 2425 } 2426 2427 return (ret); 2428 } 2429