1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 * 21 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 22 */ 23 24 #include <stdio.h> 25 #include <link.h> 26 #include <fcntl.h> 27 #include <ctype.h> 28 #include <sys/param.h> 29 #include <sys/types.h> 30 #include <sys/stat.h> 31 #include <errno.h> 32 #include <sys/socket.h> 33 #include <netinet/in.h> 34 #include <arpa/inet.h> 35 #include <ber_der.h> 36 #include <kmfapiP.h> 37 #include <libgen.h> 38 #include <cryptoutil.h> 39 40 KMF_RETURN 41 copy_data(KMF_DATA *dst, KMF_DATA *src) 42 { 43 KMF_RETURN ret = KMF_OK; 44 45 if (dst == NULL || src == NULL) 46 return (KMF_ERR_BAD_PARAMETER); 47 48 if (src->Length == 0) { 49 dst->Length = 0; 50 dst->Data = NULL; 51 src->Data = NULL; 52 return (ret); 53 } 54 55 dst->Data = malloc(src->Length); 56 if (dst->Data == NULL) 57 return (KMF_ERR_MEMORY); 58 59 dst->Length = src->Length; 60 (void) memcpy(dst->Data, src->Data, src->Length); 61 62 return (ret); 63 } 64 65 KMF_RETURN 66 copy_extension_data(KMF_X509_EXTENSION *dstext, 67 KMF_X509_EXTENSION *srcext) 68 { 69 KMF_RETURN ret = KMF_OK; 70 71 if (dstext == NULL || srcext == NULL) 72 return (KMF_ERR_BAD_PARAMETER); 73 74 (void) memset(dstext, 0, sizeof (KMF_X509_EXTENSION)); 75 76 ret = copy_data(&dstext->extnId, &srcext->extnId); 77 if (ret != KMF_OK) 78 goto cleanup; 79 80 dstext->extnId.Length = srcext->extnId.Length; 81 dstext->critical = srcext->critical; 82 dstext->format = srcext->format; 83 84 ret = copy_data(&dstext->BERvalue, &srcext->BERvalue); 85 if (ret != KMF_OK) 86 goto cleanup; 87 88 dstext->value.tagAndValue = malloc(sizeof (KMF_X509EXT_TAGandVALUE)); 89 if (dstext->value.tagAndValue == NULL) { 90 ret = KMF_ERR_MEMORY; 91 goto cleanup; 92 } 93 (void) memset(dstext->value.tagAndValue, 0, 94 sizeof (KMF_X509EXT_TAGandVALUE)); 95 96 ret = copy_data(&dstext->value.tagAndValue->value, 97 &srcext->value.tagAndValue->value); 98 if (ret != KMF_OK) 99 goto cleanup; 100 101 dstext->value.tagAndValue->type = srcext->value.tagAndValue->type; 102 103 cleanup: 104 if (ret != KMF_OK) { 105 if (dstext->extnId.Data != NULL) 106 kmf_free_data(&dstext->extnId); 107 108 if (dstext->BERvalue.Data != NULL) 109 kmf_free_data(&dstext->BERvalue); 110 111 if (dstext->value.tagAndValue->value.Data == NULL) 112 kmf_free_data(&dstext->value.tagAndValue->value); 113 } 114 115 return (ret); 116 } 117 118 /* 119 * Given a block of DER encoded X.509 certificate data and 120 * an OID for the desired extension, this routine will 121 * parse the cert data and return the data associated with 122 * the extension if it is found. 123 * 124 * RETURNS: 125 * KMF_OK - if extension found and copied OK. 126 * KMF_ERR_EXTENSION_NOT_FOUND - extension not found. 127 * parsing and memory allocation errors are also possible. 128 */ 129 KMF_RETURN 130 kmf_get_cert_extn(const KMF_DATA *certdata, 131 KMF_OID *extoid, KMF_X509_EXTENSION *extdata) 132 { 133 KMF_RETURN ret = KMF_OK; 134 KMF_X509_CERTIFICATE *cert = NULL; 135 KMF_X509_EXTENSION *eptr = NULL; 136 int i, found = 0; 137 138 if (certdata == NULL || extoid == NULL || extdata == NULL) 139 return (KMF_ERR_BAD_PARAMETER); 140 141 ret = DerDecodeSignedCertificate(certdata, &cert); 142 if (ret != KMF_OK) 143 return (ret); 144 145 if (cert->certificate.extensions.numberOfExtensions == 0) { 146 goto end; 147 } 148 149 (void) memset((void *)extdata, 0, sizeof (KMF_X509_EXTENSION)); 150 for (i = 0; !found && 151 i < cert->certificate.extensions.numberOfExtensions; 152 i++) { 153 eptr = &cert->certificate.extensions.extensions[i]; 154 if (IsEqualOid(extoid, &eptr->extnId)) { 155 ret = copy_extension_data(extdata, eptr); 156 found++; 157 } 158 } 159 end: 160 if (!found) 161 ret = KMF_ERR_EXTENSION_NOT_FOUND; 162 163 if (cert != NULL) { 164 kmf_free_signed_cert(cert); 165 free(cert); 166 } 167 168 return (ret); 169 } 170 171 /* 172 * Given a block of DER encoded X.509 certificate data and 173 * a "crit/non-crit/all" flag, search the extensions and 174 * return the OIDs for critical, non-critical or all extensions. 175 * 176 * RETURNS: 177 * KMF_OK - if extension found and copied OK. 178 * parsing and memory allocation errors are also possible. 179 * 180 * OIDlist - array of KMF_OID records, allocated 181 * by this function. 182 * NumOIDs - number of critical extensions found. 183 */ 184 KMF_RETURN 185 kmf_get_cert_extns(const KMF_DATA *certdata, KMF_FLAG_CERT_EXTN flag, 186 KMF_X509_EXTENSION **extlist, int *nextns) 187 { 188 KMF_RETURN ret = KMF_OK; 189 KMF_X509_CERTIFICATE *cert; 190 KMF_X509_EXTENSION *eptr, *elist; 191 int i; 192 193 if (certdata == NULL || extlist == NULL || nextns == NULL) 194 return (KMF_ERR_BAD_PARAMETER); 195 196 if (flag < KMF_ALL_EXTNS || flag > KMF_NONCRITICAL_EXTNS) 197 return (KMF_ERR_BAD_PARAMETER); 198 199 *nextns = 0; 200 *extlist = elist = NULL; 201 ret = DerDecodeSignedCertificate(certdata, &cert); 202 if (ret != KMF_OK) 203 return (ret); 204 205 if (cert->certificate.extensions.numberOfExtensions == 0) 206 return (KMF_ERR_EXTENSION_NOT_FOUND); 207 208 for (i = 0; i < cert->certificate.extensions.numberOfExtensions; 209 i++) { 210 eptr = &cert->certificate.extensions.extensions[i]; 211 212 if (flag == KMF_CRITICAL_EXTNS && eptr->critical == 0) 213 continue; 214 else if (flag == KMF_NONCRITICAL_EXTNS && eptr->critical != 0) 215 continue; 216 217 (*nextns)++; 218 elist = realloc(elist, sizeof (KMF_X509_EXTENSION) * 219 (*nextns)); 220 if (elist == NULL) { 221 ret = KMF_ERR_MEMORY; 222 goto end; 223 } 224 225 ret = copy_extension_data(&elist[(*nextns) - 1], eptr); 226 if (ret != KMF_OK) 227 goto end; 228 } 229 230 end: 231 kmf_free_signed_cert(cert); 232 free(cert); 233 if (ret != KMF_OK) { 234 if (elist != NULL) { 235 free(elist); 236 elist = NULL; 237 } 238 *nextns = 0; 239 } 240 241 /* 242 * If the flag is not all, then it is possible that we did not find 243 * any critical or non_critical extensions. When that happened, 244 * return KMF_ERR_EXTENSION_NOT_FOUND. 245 */ 246 if (flag != KMF_ALL_EXTNS && ret == KMF_OK && *nextns == 0) 247 ret = KMF_ERR_EXTENSION_NOT_FOUND; 248 249 *extlist = elist; 250 return (ret); 251 } 252 253 /* 254 * If the given certificate data (X.509 DER encoded data) 255 * contains the Key Usage extension, parse that 256 * data and return it in the KMF_X509EXT_BASICCONSTRAINTS 257 * record. 258 * 259 * RETURNS: 260 * KMF_OK - success 261 * KMF_ERR_BAD_PARAMETER - input data was bad. 262 * KMF_ERR_EXTENSION_NOT_FOUND - extension not found. 263 */ 264 KMF_RETURN 265 kmf_get_cert_ku(const KMF_DATA *certdata, 266 KMF_X509EXT_KEY_USAGE *keyusage) 267 { 268 KMF_RETURN ret = KMF_OK; 269 KMF_X509_EXTENSION extn; 270 271 if (certdata == NULL || keyusage == NULL) 272 return (KMF_ERR_BAD_PARAMETER); 273 274 (void) memset(&extn, 0, sizeof (extn)); 275 /* 276 * Check standard KeyUsage bits 277 */ 278 ret = kmf_get_cert_extn(certdata, (KMF_OID *)&KMFOID_KeyUsage, &extn); 279 280 if (ret != KMF_OK) { 281 goto end; 282 } 283 keyusage->critical = (extn.critical != 0); 284 if (extn.value.tagAndValue->value.Length > 1) { 285 keyusage->KeyUsageBits = 286 extn.value.tagAndValue->value.Data[1] << 8; 287 } else { 288 keyusage->KeyUsageBits = extn.value.tagAndValue->value.Data[0]; 289 } 290 end: 291 kmf_free_extn(&extn); 292 return (ret); 293 } 294 295 KMF_BOOL 296 is_eku_present(KMF_X509EXT_EKU *ekuptr, KMF_OID *ekuoid) 297 { 298 int i; 299 300 if (ekuptr == NULL || ekuoid == NULL) 301 return (0); 302 303 for (i = 0; i < ekuptr->nEKUs; i++) 304 if (IsEqualOid(&ekuptr->keyPurposeIdList[i], ekuoid)) 305 return (1); 306 307 return (0); 308 } 309 310 KMF_RETURN 311 parse_eku_data(const KMF_DATA *asn1data, KMF_X509EXT_EKU *ekuptr) 312 { 313 KMF_RETURN ret = KMF_OK; 314 BerElement *asn1 = NULL; 315 BerValue exdata; 316 KMF_OID oid; 317 char *end = NULL; 318 ber_len_t size; 319 320 /* 321 * Decode the ASN.1 data for the extension. 322 */ 323 exdata.bv_val = (char *)asn1data->Data; 324 exdata.bv_len = asn1data->Length; 325 326 if ((asn1 = kmfder_init(&exdata)) == NULL) { 327 ret = KMF_ERR_MEMORY; 328 goto end; 329 } 330 331 /* 332 * certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation 333 */ 334 if (kmfber_first_element(asn1, &size, &end) != BER_OBJECT_IDENTIFIER) { 335 ret = KMF_ERR_BAD_CERT_FORMAT; 336 goto end; 337 } 338 339 /* 340 * Count the number of EKU OIDs and store in 341 * the array. 342 */ 343 while (kmfber_next_element(asn1, &size, end) == 344 BER_OBJECT_IDENTIFIER) { 345 346 /* Skip over the CONSTRUCTED SET tag */ 347 if (kmfber_scanf(asn1, "D", &oid) == KMFBER_DEFAULT) { 348 ret = KMF_ERR_BAD_CERT_FORMAT; 349 goto end; 350 } 351 ekuptr->nEKUs++; 352 ekuptr->keyPurposeIdList = realloc(ekuptr->keyPurposeIdList, 353 ekuptr->nEKUs * sizeof (KMF_OID)); 354 if (ekuptr->keyPurposeIdList == NULL) { 355 ret = KMF_ERR_MEMORY; 356 goto end; 357 } 358 ekuptr->keyPurposeIdList[ekuptr->nEKUs - 1] = oid; 359 } 360 361 end: 362 if (asn1 != NULL) 363 kmfber_free(asn1, 1); 364 365 if (ret != KMF_OK) { 366 if (ekuptr->keyPurposeIdList != NULL) { 367 free_keyidlist(ekuptr->keyPurposeIdList, ekuptr->nEKUs); 368 ekuptr->keyPurposeIdList = NULL; 369 ekuptr->critical = 0; 370 } 371 } 372 373 return (ret); 374 } 375 376 KMF_RETURN 377 kmf_get_cert_eku(const KMF_DATA *certdata, 378 KMF_X509EXT_EKU *ekuptr) 379 { 380 KMF_RETURN ret = KMF_OK; 381 KMF_X509_EXTENSION extn; 382 383 if (certdata == NULL || ekuptr == NULL) 384 return (KMF_ERR_BAD_PARAMETER); 385 386 (void) memset(&extn, 0, sizeof (KMF_X509_EXTENSION)); 387 388 ekuptr->nEKUs = 0; 389 ekuptr->keyPurposeIdList = NULL; 390 ekuptr->critical = 0; 391 392 ret = kmf_get_cert_extn(certdata, 393 (KMF_OID *)&KMFOID_ExtendedKeyUsage, &extn); 394 395 if (ret != KMF_OK) { 396 goto end; 397 } 398 399 ret = parse_eku_data(&extn.BERvalue, ekuptr); 400 401 end: 402 kmf_free_extn(&extn); 403 404 return (ret); 405 } 406 407 /* 408 * If the given certificate data (X.509 DER encoded data) 409 * contains the Basic Constraints extension, parse that 410 * data and return it in the KMF_X509EXT_BASICCONSTRAINTS 411 * record. 412 * 413 * RETURNS: 414 * KMF_OK - success 415 * KMF_ERR_BAD_PARAMETER - input data was bad. 416 * KMF_ERR_EXTENSION_NOT_FOUND - extension not found. 417 */ 418 KMF_RETURN 419 kmf_get_cert_basic_constraint(const KMF_DATA *certdata, 420 KMF_BOOL *critical, KMF_X509EXT_BASICCONSTRAINTS *constraint) 421 { 422 KMF_RETURN ret = KMF_OK; 423 KMF_X509_EXTENSION extn; 424 BerElement *asn1 = NULL; 425 BerValue exdata; 426 ber_len_t size; 427 char *end = NULL; 428 int tag; 429 430 if (certdata == NULL || constraint == NULL || critical == NULL) 431 return (KMF_ERR_BAD_PARAMETER); 432 433 (void) memset(&extn, 0, sizeof (KMF_X509_EXTENSION)); 434 ret = kmf_get_cert_extn(certdata, 435 (KMF_OID *)&KMFOID_BasicConstraints, &extn); 436 437 if (ret != KMF_OK) { 438 goto end; 439 } 440 441 *critical = (extn.critical != 0); 442 443 exdata.bv_val = (char *)extn.value.tagAndValue->value.Data; 444 exdata.bv_len = extn.value.tagAndValue->value.Length; 445 446 if ((asn1 = kmfder_init(&exdata)) == NULL) { 447 ret = KMF_ERR_MEMORY; 448 goto end; 449 } 450 451 if (kmfber_scanf(asn1, "b", &constraint->cA) == KMFBER_DEFAULT) { 452 ret = KMF_ERR_BAD_CERT_FORMAT; 453 goto end; 454 } 455 constraint->pathLenConstraintPresent = KMF_FALSE; 456 457 tag = kmfber_next_element(asn1, &size, end); 458 if (tag == BER_INTEGER) { 459 if (kmfber_scanf(asn1, "i", 460 &constraint->pathLenConstraint) == KMFBER_DEFAULT) { 461 ret = KMF_ERR_BAD_CERT_FORMAT; 462 goto end; 463 } 464 constraint->pathLenConstraintPresent = KMF_TRUE; 465 } 466 end: 467 kmf_free_extn(&extn); 468 if (asn1 != NULL) 469 kmfber_free(asn1, 1); 470 471 return (ret); 472 } 473 474 static KMF_X509EXT_POLICYQUALIFIERINFO * 475 get_pqinfo(BerElement *asn1) 476 { 477 KMF_X509EXT_POLICYQUALIFIERINFO *pqinfo = NULL; 478 KMF_RETURN ret = KMF_OK; 479 int tag; 480 ber_len_t size; 481 char *end = NULL; 482 483 /* 484 * Policy Qualifiers may be a list of sequences. 485 * 486 * PolicyInformation ::= SEQUENCE { 487 * policyIdentifier CertPolicyId, 488 * policyQualifiers SEQUENCE SIZE (1..MAX) OF 489 * PolicyQualifierInfo OPTIONAL 490 * } 491 * 492 * PolicyQualifierInfo ::= SEQUENCE { 493 * policyQualifierId PolicyQualifierId, 494 * qualifier ANY DEFINED BY policyQualifierId 495 * } 496 */ 497 498 499 /* 500 * We already got the CertPolicyId, we just need to 501 * find all of the policyQualifiers in the set. 502 * 503 * Mark the first element of the SEQUENCE and reset the end ptr 504 * so the ber/der code knows when to stop looking. 505 */ 506 if ((tag = kmfber_first_element(asn1, &size, &end)) != 507 BER_CONSTRUCTED_SEQUENCE) { 508 ret = KMF_ERR_BAD_CERT_FORMAT; 509 goto end; 510 } 511 /* We found a sequence, loop until done */ 512 while ((tag = kmfber_next_element(asn1, &size, end)) == 513 BER_CONSTRUCTED_SEQUENCE) { 514 515 /* Skip over the CONSTRUCTED SET tag */ 516 if (kmfber_scanf(asn1, "T", &tag) == KMFBER_DEFAULT) { 517 ret = KMF_ERR_BAD_CERT_FORMAT; 518 goto end; 519 } 520 /* 521 * Allocate memory for the Policy Qualifier Info 522 */ 523 pqinfo = malloc(sizeof (KMF_X509EXT_POLICYQUALIFIERINFO)); 524 if (pqinfo == NULL) { 525 ret = KMF_ERR_MEMORY; 526 goto end; 527 } 528 (void) memset((void *)pqinfo, 0, 529 sizeof (KMF_X509EXT_POLICYQUALIFIERINFO)); 530 /* 531 * Read the PolicyQualifier OID 532 */ 533 if (kmfber_scanf(asn1, "D", 534 &pqinfo->policyQualifierId) == KMFBER_DEFAULT) { 535 ret = KMF_ERR_BAD_CERT_FORMAT; 536 goto end; 537 } 538 /* 539 * The OID of the policyQualifierId determines what 540 * sort of data comes next. 541 */ 542 if (IsEqualOid(&pqinfo->policyQualifierId, 543 (KMF_OID *)&KMFOID_PKIX_PQ_CPSuri)) { 544 /* 545 * CPS uri must be an IA5STRING 546 */ 547 if (kmfber_scanf(asn1, "tl", &tag, &size) == 548 KMFBER_DEFAULT || tag != BER_IA5STRING || 549 size == 0) { 550 ret = KMF_ERR_BAD_CERT_FORMAT; 551 goto end; 552 } 553 if ((pqinfo->value.Data = malloc(size)) == NULL) { 554 ret = KMF_ERR_MEMORY; 555 goto end; 556 } 557 if (kmfber_scanf(asn1, "s", pqinfo->value.Data, 558 &pqinfo->value.Length) == KMFBER_DEFAULT) { 559 ret = KMF_ERR_BAD_CERT_FORMAT; 560 goto end; 561 } 562 } else if (IsEqualOid(&pqinfo->policyQualifierId, 563 (KMF_OID *)&KMFOID_PKIX_PQ_Unotice)) { 564 if (kmfber_scanf(asn1, "tl", &tag, &size) == 565 KMFBER_DEFAULT || 566 tag != BER_CONSTRUCTED_SEQUENCE) { 567 ret = KMF_ERR_BAD_CERT_FORMAT; 568 goto end; 569 } 570 /* 571 * For now, just copy the while UserNotice ASN.1 572 * blob into the pqinfo data record. 573 * TBD - parse it into individual fields. 574 */ 575 if ((pqinfo->value.Data = malloc(size)) == NULL) { 576 ret = KMF_ERR_MEMORY; 577 goto end; 578 } 579 if (kmfber_scanf(asn1, "s", pqinfo->value.Data, 580 &pqinfo->value.Length) == KMFBER_DEFAULT) { 581 ret = KMF_ERR_BAD_CERT_FORMAT; 582 goto end; 583 } 584 } else { 585 ret = KMF_ERR_BAD_CERT_FORMAT; 586 goto end; 587 } 588 } 589 end: 590 if (ret != KMF_OK) { 591 if (pqinfo != NULL) { 592 kmf_free_data(&pqinfo->value); 593 kmf_free_data(&pqinfo->policyQualifierId); 594 free(pqinfo); 595 pqinfo = NULL; 596 } 597 } 598 return (pqinfo); 599 } 600 601 /* 602 * If the given certificate data (X.509 DER encoded data) 603 * contains the Certificate Policies extension, parse that 604 * data and return it in the KMF_X509EXT_CERT_POLICIES 605 * record. 606 * 607 * RETURNS: 608 * KMF_OK - success 609 * KMF_ERR_BAD_PARAMETER - input data was bad. 610 * KMF_ERR_EXTENSION_NOT_FOUND - extension not found. 611 * parsing and memory allocation errors are also possible. 612 */ 613 KMF_RETURN 614 kmf_get_cert_policies(const KMF_DATA *certdata, 615 KMF_BOOL *critical, KMF_X509EXT_CERT_POLICIES *extptr) 616 { 617 KMF_RETURN ret = KMF_OK; 618 KMF_X509_EXTENSION extn; 619 KMF_X509EXT_POLICYINFO *pinfo; 620 KMF_X509EXT_POLICYQUALIFIERINFO *pqinfo; 621 BerElement *asn1 = NULL; 622 BerValue exdata; 623 ber_len_t size; 624 char *end = NULL; 625 int tag; 626 627 if (certdata == NULL || critical == NULL || extptr == NULL) 628 return (KMF_ERR_BAD_PARAMETER); 629 630 (void) memset(&extn, 0, sizeof (extn)); 631 ret = kmf_get_cert_extn(certdata, 632 (KMF_OID *)&KMFOID_CertificatePolicies, &extn); 633 634 if (ret != KMF_OK) { 635 goto end; 636 } 637 638 *critical = (extn.critical != 0); 639 640 /* 641 * Decode the ASN.1 data for the extension. 642 */ 643 exdata.bv_val = (char *)extn.BERvalue.Data; 644 exdata.bv_len = extn.BERvalue.Length; 645 646 (void) memset((void *)extptr, 0, sizeof (KMF_X509EXT_CERT_POLICIES)); 647 648 if ((asn1 = kmfder_init(&exdata)) == NULL) { 649 ret = KMF_ERR_MEMORY; 650 goto end; 651 } 652 653 /* 654 * certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation 655 */ 656 if ((tag = kmfber_first_element(asn1, &size, &end)) != 657 BER_CONSTRUCTED_SEQUENCE) { 658 ret = KMF_ERR_BAD_CERT_FORMAT; 659 goto end; 660 } 661 662 /* 663 * Collect all of the PolicyInformation SEQUENCES 664 * 665 * PolicyInformation ::= SEQUENCE { 666 * policyIdentifier CertPolicyId, 667 * policyQualifiers SEQUENCE SIZE (1..MAX) OF 668 * PolicyQualifierInfo OPTIONAL 669 * } 670 * 671 * Loop over the SEQUENCES of PolicyInfo 672 */ 673 while ((tag = kmfber_next_element(asn1, &size, end)) == 674 BER_CONSTRUCTED_SEQUENCE) { 675 676 /* Skip over the CONSTRUCTED SET tag */ 677 if (kmfber_scanf(asn1, "T", &tag) == KMFBER_DEFAULT) { 678 ret = KMF_ERR_BAD_CERT_FORMAT; 679 goto end; 680 } 681 682 pinfo = malloc(sizeof (KMF_X509EXT_POLICYINFO)); 683 if (pinfo == NULL) { 684 ret = KMF_ERR_MEMORY; 685 goto end; 686 } 687 (void) memset((void *)pinfo, 0, 688 sizeof (KMF_X509EXT_POLICYINFO)); 689 /* 690 * Decode the PolicyInformation SEQUENCE 691 */ 692 if ((tag = kmfber_scanf(asn1, "D", 693 &pinfo->policyIdentifier)) == KMFBER_DEFAULT) { 694 ret = KMF_ERR_BAD_CERT_FORMAT; 695 goto end; 696 } 697 /* 698 * Gather all of the associated PolicyQualifierInfo recs 699 */ 700 pqinfo = get_pqinfo(asn1); 701 if (pqinfo != NULL) { 702 int cnt = 703 pinfo->policyQualifiers.numberOfPolicyQualifiers; 704 cnt++; 705 pinfo->policyQualifiers.policyQualifier = realloc( 706 pinfo->policyQualifiers.policyQualifier, 707 cnt * sizeof (KMF_X509EXT_POLICYQUALIFIERINFO)); 708 if (pinfo->policyQualifiers.policyQualifier == NULL) { 709 ret = KMF_ERR_MEMORY; 710 goto end; 711 } 712 pinfo->policyQualifiers.numberOfPolicyQualifiers = cnt; 713 pinfo->policyQualifiers.policyQualifier[cnt-1] = 714 *pqinfo; 715 716 free(pqinfo); 717 } 718 extptr->numberOfPolicyInfo++; 719 extptr->policyInfo = realloc(extptr->policyInfo, 720 extptr->numberOfPolicyInfo * 721 sizeof (KMF_X509EXT_POLICYINFO)); 722 if (extptr->policyInfo == NULL) { 723 ret = KMF_ERR_MEMORY; 724 goto end; 725 } 726 extptr->policyInfo[extptr->numberOfPolicyInfo-1] = *pinfo; 727 free(pinfo); 728 } 729 730 731 end: 732 kmf_free_extn(&extn); 733 if (asn1 != NULL) 734 kmfber_free(asn1, 1); 735 return (ret); 736 } 737 738 /* 739 * If the given certificate data (X.509 DER encoded data) 740 * contains the Authority Information Access extension, parse that 741 * data and return it in the KMF_X509EXT_AUTHINFOACCESS 742 * record. 743 * 744 * RETURNS: 745 * KMF_OK - success 746 * KMF_ERR_BAD_PARAMETER - input data was bad. 747 * KMF_ERR_EXTENSION_NOT_FOUND - extension not found. 748 */ 749 KMF_RETURN 750 kmf_get_cert_auth_info_access(const KMF_DATA *certdata, 751 KMF_X509EXT_AUTHINFOACCESS *aia) 752 { 753 KMF_RETURN ret = KMF_OK; 754 KMF_X509_EXTENSION extn; 755 BerElement *asn1 = NULL; 756 BerValue exdata; 757 ber_len_t size; 758 char *end = NULL; 759 int tag; 760 KMF_X509EXT_ACCESSDESC *access_info = NULL; 761 762 if (certdata == NULL || aia == NULL) { 763 return (KMF_ERR_BAD_PARAMETER); 764 } 765 766 (void) memset(&extn, 0, sizeof (KMF_X509_EXTENSION)); 767 ret = kmf_get_cert_extn(certdata, 768 (KMF_OID *)&KMFOID_AuthorityInfoAccess, &extn); 769 770 if (ret != KMF_OK) { 771 goto end; 772 } 773 774 /* 775 * Decode the ASN.1 data for the extension. 776 */ 777 exdata.bv_val = (char *)extn.BERvalue.Data; 778 exdata.bv_len = extn.BERvalue.Length; 779 780 (void) memset((void *)aia, 0, sizeof (KMF_X509EXT_AUTHINFOACCESS)); 781 782 if ((asn1 = kmfder_init(&exdata)) == NULL) { 783 ret = KMF_ERR_MEMORY; 784 goto end; 785 } 786 787 /* 788 * AuthorityInfoAccessSyntax ::= 789 * SEQUENCE SIZE (1..MAX) OF AccessDescription 790 */ 791 if ((tag = kmfber_first_element(asn1, &size, &end)) != 792 BER_CONSTRUCTED_SEQUENCE) { 793 ret = KMF_ERR_BAD_CERT_FORMAT; 794 goto end; 795 } 796 797 /* 798 * AccessDescription ::= SEQUENCE { 799 * accessMethod OBJECT IDENTIFIER, 800 * accessLocation GeneralName } 801 */ 802 while ((tag = kmfber_next_element(asn1, &size, end)) == 803 BER_CONSTRUCTED_SEQUENCE) { 804 805 /* Skip over the CONSTRUCTED SET tag */ 806 if (kmfber_scanf(asn1, "T", &tag) == KMFBER_DEFAULT) { 807 ret = KMF_ERR_BAD_CERT_FORMAT; 808 goto end; 809 } 810 811 access_info = malloc(sizeof (KMF_X509EXT_ACCESSDESC)); 812 if (access_info == NULL) { 813 ret = KMF_ERR_MEMORY; 814 goto end; 815 } 816 817 (void) memset((void *)access_info, 0, 818 sizeof (KMF_X509EXT_ACCESSDESC)); 819 820 /* 821 * Read the AccessMethod OID 822 */ 823 if (kmfber_scanf(asn1, "D", 824 &access_info->AccessMethod) == KMFBER_DEFAULT) { 825 ret = KMF_ERR_BAD_CERT_FORMAT; 826 goto end; 827 } 828 829 /* 830 * The OID of the AccessMethod determines what 831 * sort of data comes next. 832 */ 833 if (IsEqualOid(&access_info->AccessMethod, 834 (KMF_OID *)&KMFOID_PkixAdOcsp)) { 835 if (kmfber_scanf(asn1, "tl", &tag, &size) == 836 KMFBER_DEFAULT || size == 0) { 837 ret = KMF_ERR_BAD_CERT_FORMAT; 838 goto end; 839 } 840 841 /* 842 * OCSP uri must be an IA5STRING or a GENNAME_URI 843 * with an implicit tag. 844 */ 845 if (tag != BER_IA5STRING && 846 tag != (0x80 | GENNAME_URI)) { 847 ret = KMF_ERR_BAD_CERT_FORMAT; 848 goto end; 849 } 850 851 if ((access_info->AccessLocation.Data = 852 malloc(size)) == NULL) { 853 ret = KMF_ERR_MEMORY; 854 goto end; 855 } 856 857 if (kmfber_scanf(asn1, "s", 858 access_info->AccessLocation.Data, 859 &access_info->AccessLocation.Length) == 860 KMFBER_DEFAULT) { 861 ret = KMF_ERR_BAD_CERT_FORMAT; 862 goto end; 863 } 864 } else if (IsEqualOid(&access_info->AccessMethod, 865 (KMF_OID *)&KMFOID_PkixAdCaIssuers)) { 866 /* will be supported later with PKIX */ 867 free(access_info); 868 access_info = NULL; 869 continue; 870 } else { 871 ret = KMF_ERR_BAD_CERT_FORMAT; 872 goto end; 873 } 874 875 aia->numberOfAccessDescription++; 876 aia->AccessDesc = realloc(aia->AccessDesc, 877 aia->numberOfAccessDescription * 878 sizeof (KMF_X509EXT_ACCESSDESC)); 879 880 if (aia->AccessDesc == NULL) { 881 ret = KMF_ERR_MEMORY; 882 goto end; 883 } 884 885 aia->AccessDesc[aia->numberOfAccessDescription-1] = 886 *access_info; 887 free(access_info); 888 access_info = NULL; 889 } 890 891 end: 892 kmf_free_extn(&extn); 893 if (access_info != NULL) 894 free(access_info); 895 if (asn1 != NULL) 896 kmfber_free(asn1, 1); 897 return (ret); 898 899 } 900 901 /* 902 * This function parses the name portion of a der-encoded distribution point 903 * returns it in the KMF_CRL_DIST_POINT record. 904 * 905 * The "DistributionPointName" syntax is 906 * 907 * DistributionPointName ::= CHOICE { 908 * fullName [0] GeneralNames, 909 * nameRelativeToCRLIssuer [1] RelativeDistinguishedName } 910 * 911 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GerneralName 912 * 913 * Note: for phase 1, we support fullName only. 914 */ 915 static KMF_RETURN 916 parse_dp_name(char *dp_der_code, int dp_der_size, KMF_CRL_DIST_POINT *dp) 917 { 918 KMF_RETURN ret = KMF_OK; 919 char *url = NULL; 920 BerElement *asn1 = NULL; 921 BerValue ber_data; 922 ber_len_t size; 923 char *end = NULL; 924 int tag; 925 KMF_GENERALNAMES *fullname; 926 927 if (dp_der_code == NULL || dp_der_size == 0 || dp == NULL) 928 return (KMF_ERR_BAD_PARAMETER); 929 930 ber_data.bv_val = dp_der_code; 931 ber_data.bv_len = dp_der_size; 932 if ((asn1 = kmfder_init(&ber_data)) == NULL) 933 return (KMF_ERR_BAD_CERT_FORMAT); 934 935 tag = kmfber_first_element(asn1, &size, &end); 936 if (tag != 0xA0 && tag != 0xA1) { 937 ret = KMF_ERR_BAD_CERT_FORMAT; 938 goto out; 939 } 940 941 if (tag == 0xA0) { /* fullName */ 942 dp->type = DP_GENERAL_NAME; 943 944 fullname = &(dp->name.full_name); 945 fullname->number = 0; 946 947 /* Skip over the explicit tag and size */ 948 (void) kmfber_scanf(asn1, "T", &tag); 949 950 tag = kmfber_next_element(asn1, &size, end); 951 while (tag != KMFBER_DEFAULT && 952 tag != KMFBER_END_OF_SEQORSET) { 953 954 if (kmfber_scanf(asn1, "tl", &tag, &size) == 955 KMFBER_DEFAULT || size == 0) { 956 ret = KMF_ERR_BAD_CERT_FORMAT; 957 goto out; 958 } 959 960 /* For phase 1, we are interested in a URI name only */ 961 if (tag != (0x80 | GENNAME_URI)) { 962 tag = kmfber_next_element(asn1, &size, end); 963 continue; 964 } 965 966 if ((url = malloc(size)) == NULL) { 967 ret = KMF_ERR_MEMORY; 968 goto out; 969 } 970 971 /* Skip type and len, then read url and save it. */ 972 if (kmfber_read(asn1, url, 2) != 2) { 973 ret = KMF_ERR_BAD_CERT_FORMAT; 974 goto out; 975 } 976 977 if (kmfber_read(asn1, url, size) != 978 (ber_slen_t)size) { 979 ret = KMF_ERR_BAD_CERT_FORMAT; 980 goto out; 981 } 982 983 fullname->number++; 984 fullname->namelist = realloc(fullname->namelist, 985 fullname->number * sizeof (KMF_GENERALNAME)); 986 if (fullname->namelist == NULL) { 987 ret = KMF_ERR_MEMORY; 988 goto out; 989 } 990 991 fullname->namelist[fullname->number - 1].choice = 992 GENNAME_URI; 993 fullname->namelist[fullname->number - 1].name.Length = 994 size; 995 fullname->namelist[fullname->number - 1].name.Data = 996 (unsigned char *)url; 997 998 /* next */ 999 tag = kmfber_next_element(asn1, &size, end); 1000 } 1001 1002 } else if (tag == 0xA1) { 1003 /* "nameRelativeToCRLIssuer" is not supported at phase 1. */ 1004 ret = KMF_ERR_BAD_CERT_FORMAT; 1005 goto out; 1006 } 1007 1008 out: 1009 if (asn1 != NULL) 1010 kmfber_free(asn1, 1); 1011 1012 if (ret != KMF_OK) { 1013 free_dp_name(dp); 1014 } 1015 1016 if (ret == KMF_OK && fullname->number == 0) { 1017 ret = KMF_ERR_EXTENSION_NOT_FOUND; 1018 if (url != NULL) 1019 free(url); 1020 } 1021 1022 return (ret); 1023 } 1024 1025 /* 1026 * This function retrieves the CRL Distribution Points extension data from 1027 * a DER encoded certificate if it contains this extension, parses the 1028 * extension data, and returns it in the KMF_X509EXT_CRLDISTPOINTS record. 1029 */ 1030 KMF_RETURN 1031 kmf_get_cert_crl_dist_pts(const KMF_DATA *certdata, 1032 KMF_X509EXT_CRLDISTPOINTS *crl_dps) 1033 { 1034 KMF_RETURN ret = KMF_OK; 1035 KMF_X509_EXTENSION extn; 1036 BerElement *asn1 = NULL; 1037 BerValue exdata; 1038 ber_len_t size; 1039 char *end = NULL; 1040 int tag; 1041 KMF_CRL_DIST_POINT *dp = NULL; 1042 int i; 1043 1044 if (certdata == NULL || crl_dps == NULL) { 1045 return (KMF_ERR_BAD_PARAMETER); 1046 } 1047 1048 /* Get the ASN.1 data for this extension. */ 1049 (void) memset(&extn, 0, sizeof (KMF_X509_EXTENSION)); 1050 ret = kmf_get_cert_extn(certdata, 1051 (KMF_OID *)&KMFOID_CrlDistributionPoints, &extn); 1052 if (ret != KMF_OK) { 1053 return (ret); 1054 } 1055 1056 /* 1057 * Decode the CRLDistributionPoints ASN.1 data. The Syntax for 1058 * CRLDistributionPoints is 1059 * 1060 * CRLDistributionPoints ::= 1061 * SEQUENCE SIZE (1..MAX) OF DistributionPoint 1062 * 1063 * DistributionPoint ::= SEQUENCE { 1064 * distributionPoint [0] DistributionPointName OPTIONAL, 1065 * reasons [1] ReasonFlags OPTIONAL, 1066 * cRLIssuer [2] GeneralNames OPTIONAL } 1067 */ 1068 1069 exdata.bv_val = (char *)extn.BERvalue.Data; 1070 exdata.bv_len = extn.BERvalue.Length; 1071 if ((asn1 = kmfder_init(&exdata)) == NULL) { 1072 ret = KMF_ERR_MEMORY; 1073 goto out; 1074 } 1075 1076 if ((tag = kmfber_first_element(asn1, &size, &end)) != 1077 BER_CONSTRUCTED_SEQUENCE) { 1078 ret = KMF_ERR_BAD_CERT_FORMAT; 1079 goto out; 1080 } 1081 1082 (void) memset((void *)crl_dps, 0, sizeof (KMF_X509EXT_CRLDISTPOINTS)); 1083 1084 while ((tag = kmfber_next_element(asn1, &size, end)) == 1085 BER_CONSTRUCTED_SEQUENCE) { 1086 boolean_t has_name = B_FALSE; 1087 boolean_t has_issuer = B_FALSE; 1088 1089 /* Skip over the CONSTRUCTED SET tag */ 1090 if (kmfber_scanf(asn1, "T", &tag) == KMFBER_DEFAULT) { 1091 ret = KMF_ERR_BAD_CERT_FORMAT; 1092 goto out; 1093 } 1094 1095 tag = kmfber_next_element(asn1, &size, end); 1096 if (tag != 0xA0 && tag != 0xA1 && tag != 0xA2) 1097 goto out; 1098 1099 if ((dp = malloc(sizeof (KMF_CRL_DIST_POINT))) == NULL) { 1100 ret = KMF_ERR_MEMORY; 1101 goto out; 1102 } 1103 (void) memset((void *)dp, 0, sizeof (KMF_CRL_DIST_POINT)); 1104 1105 if (tag == 0xA0) { /* distributionPoint Name */ 1106 char *name_der; 1107 int name_size = size + 2; 1108 1109 if ((name_der = malloc(name_size)) == NULL) { 1110 ret = KMF_ERR_MEMORY; 1111 free(dp); 1112 dp = NULL; 1113 goto out; 1114 } 1115 1116 if (kmfber_read(asn1, name_der, name_size) != 1117 (ber_slen_t)(name_size)) { 1118 ret = KMF_ERR_BAD_CERT_FORMAT; 1119 free(name_der); 1120 free(dp); 1121 dp = NULL; 1122 goto out; 1123 } 1124 has_name = B_TRUE; 1125 1126 ret = parse_dp_name(name_der, name_size, dp); 1127 free(name_der); 1128 if (ret != KMF_OK) { 1129 free(dp); 1130 dp = NULL; 1131 goto out; 1132 } 1133 1134 /* next field */ 1135 tag = kmfber_next_element(asn1, &size, end); 1136 } 1137 1138 if (tag == 0XA1) { /* reasons */ 1139 char *bit_string; 1140 int len; 1141 1142 if (kmfber_scanf(asn1, "B", &bit_string, &len) != 1143 BER_BIT_STRING) { 1144 ret = KMF_ERR_BAD_CERT_FORMAT; 1145 free(dp); 1146 dp = NULL; 1147 goto out; 1148 } 1149 1150 dp->reasons.Length = len / 8; 1151 if ((dp->reasons.Data = malloc(dp->reasons.Length)) == 1152 NULL) { 1153 ret = KMF_ERR_MEMORY; 1154 free(dp); 1155 dp = NULL; 1156 goto out; 1157 } 1158 (void) memcpy(dp->reasons.Data, (uchar_t *)bit_string, 1159 dp->reasons.Length); 1160 1161 /* next field */ 1162 tag = kmfber_next_element(asn1, &size, end); 1163 } 1164 1165 if (tag == 0XA2) { /* cRLIssuer */ 1166 char *issuer_der = NULL; 1167 int issuer_size; 1168 1169 /* For cRLIssuer, read the data only at phase 1 */ 1170 issuer_size = size + 2; 1171 issuer_der = malloc(issuer_size); 1172 if (issuer_der == NULL) { 1173 ret = KMF_ERR_MEMORY; 1174 free(dp); 1175 dp = NULL; 1176 goto out; 1177 } 1178 1179 if (kmfber_read(asn1, issuer_der, issuer_size) != 1180 (ber_slen_t)(issuer_size)) { 1181 free(issuer_der); 1182 ret = KMF_ERR_BAD_CERT_FORMAT; 1183 free(dp); 1184 dp = NULL; 1185 goto out; 1186 } 1187 1188 has_issuer = B_TRUE; 1189 free(issuer_der); 1190 } 1191 1192 /* A distribution point cannot have a "reasons" field only. */ 1193 if (has_name == B_FALSE && has_issuer == B_FALSE) { 1194 ret = KMF_ERR_BAD_CERT_FORMAT; 1195 free_dp(dp); 1196 free(dp); 1197 dp = NULL; 1198 goto out; 1199 } 1200 1201 /* 1202 * Although it is legal that a distributioon point contains 1203 * a cRLIssuer field only, with or without "reasons", we will 1204 * skip it if the name field is not presented for phase 1. 1205 */ 1206 if (has_name == B_FALSE) { 1207 free_dp(dp); 1208 } else { 1209 crl_dps->number++; 1210 crl_dps->dplist = realloc(crl_dps->dplist, 1211 crl_dps->number * sizeof (KMF_CRL_DIST_POINT)); 1212 if (crl_dps->dplist == NULL) { 1213 ret = KMF_ERR_MEMORY; 1214 free_dp(dp); 1215 free(dp); 1216 dp = NULL; 1217 goto out; 1218 } 1219 crl_dps->dplist[crl_dps->number - 1] = *dp; 1220 /* free the dp itself since we just used its contents */ 1221 } 1222 if (dp != NULL) { 1223 free(dp); 1224 dp = NULL; 1225 } 1226 } 1227 1228 out: 1229 kmf_free_extn(&extn); 1230 1231 if (asn1 != NULL) 1232 kmfber_free(asn1, 1); 1233 1234 if (ret != KMF_OK) { 1235 for (i = 0; i < crl_dps->number; i++) 1236 free_dp(&(crl_dps->dplist[i])); 1237 free(crl_dps->dplist); 1238 } 1239 1240 if (ret == KMF_OK && crl_dps->number == 0) { 1241 ret = KMF_ERR_BAD_CERT_FORMAT; 1242 } 1243 1244 return (ret); 1245 } 1246 1247 static KMF_RETURN 1248 KMF_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, 1249 KMF_PRINTABLE_ITEM flag, char *resultStr) 1250 { 1251 KMF_PLUGIN *plugin; 1252 KMF_RETURN (*getPrintableFn)(void *, const KMF_DATA *, 1253 KMF_PRINTABLE_ITEM, char *); 1254 KMF_RETURN ret; 1255 1256 CLEAR_ERROR(handle, ret); 1257 if (ret != KMF_OK) 1258 return (ret); 1259 1260 if (SignedCert == NULL || resultStr == NULL) { 1261 return (KMF_ERR_BAD_PARAMETER); 1262 } 1263 1264 /* 1265 * This framework function is actually implemented in the openssl 1266 * plugin library, so we find the function address and call it. 1267 */ 1268 plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); 1269 if (plugin == NULL || plugin->dldesc == NULL) { 1270 return (KMF_ERR_PLUGIN_NOTFOUND); 1271 } 1272 1273 getPrintableFn = (KMF_RETURN(*)())dlsym(plugin->dldesc, 1274 "OpenSSL_CertGetPrintable"); 1275 if (getPrintableFn == NULL) { 1276 return (KMF_ERR_FUNCTION_NOT_FOUND); 1277 } 1278 1279 return (getPrintableFn(handle, SignedCert, flag, resultStr)); 1280 } 1281 1282 KMF_RETURN 1283 kmf_get_cert_version_str(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, 1284 char **result) 1285 { 1286 KMF_RETURN ret; 1287 char *tmpstr; 1288 1289 CLEAR_ERROR(handle, ret); 1290 if (ret != KMF_OK) 1291 return (ret); 1292 1293 if (SignedCert == NULL || result == NULL) 1294 return (KMF_ERR_BAD_PARAMETER); 1295 tmpstr = malloc(KMF_CERT_PRINTABLE_LEN); 1296 if (tmpstr == NULL) 1297 return (KMF_ERR_MEMORY); 1298 (void) memset(tmpstr, 0, KMF_CERT_PRINTABLE_LEN); 1299 1300 ret = KMF_CertGetPrintable(handle, SignedCert, KMF_CERT_VERSION, 1301 tmpstr); 1302 1303 if (ret == KMF_OK) { 1304 *result = tmpstr; 1305 } else { 1306 free(tmpstr); 1307 *result = NULL; 1308 } 1309 1310 return (ret); 1311 } 1312 1313 1314 KMF_RETURN 1315 kmf_get_cert_subject_str(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, 1316 char **result) 1317 { 1318 KMF_RETURN ret; 1319 char *tmpstr; 1320 1321 CLEAR_ERROR(handle, ret); 1322 if (ret != KMF_OK) 1323 return (ret); 1324 1325 if (SignedCert == NULL || result == NULL) 1326 return (KMF_ERR_BAD_PARAMETER); 1327 tmpstr = malloc(KMF_CERT_PRINTABLE_LEN); 1328 if (tmpstr == NULL) 1329 return (KMF_ERR_MEMORY); 1330 (void) memset(tmpstr, 0, KMF_CERT_PRINTABLE_LEN); 1331 1332 ret = KMF_CertGetPrintable(handle, SignedCert, KMF_CERT_SUBJECT, 1333 tmpstr); 1334 1335 if (ret == KMF_OK) { 1336 *result = tmpstr; 1337 } else { 1338 free(tmpstr); 1339 *result = NULL; 1340 } 1341 1342 return (ret); 1343 1344 } 1345 1346 KMF_RETURN 1347 kmf_get_cert_issuer_str(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, 1348 char **result) 1349 { 1350 KMF_RETURN ret; 1351 char *tmpstr; 1352 1353 CLEAR_ERROR(handle, ret); 1354 if (ret != KMF_OK) 1355 return (ret); 1356 1357 if (SignedCert == NULL || result == NULL) 1358 return (KMF_ERR_BAD_PARAMETER); 1359 1360 tmpstr = malloc(KMF_CERT_PRINTABLE_LEN); 1361 if (tmpstr == NULL) 1362 return (KMF_ERR_MEMORY); 1363 (void) memset(tmpstr, 0, KMF_CERT_PRINTABLE_LEN); 1364 1365 ret = KMF_CertGetPrintable(handle, SignedCert, KMF_CERT_ISSUER, 1366 tmpstr); 1367 1368 if (ret == KMF_OK) { 1369 *result = tmpstr; 1370 } else { 1371 free(tmpstr); 1372 *result = NULL; 1373 } 1374 1375 return (ret); 1376 } 1377 1378 KMF_RETURN 1379 kmf_get_cert_serial_str(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, 1380 char **result) 1381 { 1382 KMF_RETURN ret; 1383 char *tmpstr; 1384 1385 CLEAR_ERROR(handle, ret); 1386 if (ret != KMF_OK) 1387 return (ret); 1388 1389 if (SignedCert == NULL || result == NULL) 1390 return (KMF_ERR_BAD_PARAMETER); 1391 tmpstr = malloc(KMF_CERT_PRINTABLE_LEN); 1392 if (tmpstr == NULL) 1393 return (KMF_ERR_MEMORY); 1394 (void) memset(tmpstr, 0, KMF_CERT_PRINTABLE_LEN); 1395 1396 ret = KMF_CertGetPrintable(handle, SignedCert, KMF_CERT_SERIALNUM, 1397 tmpstr); 1398 1399 if (ret == KMF_OK) { 1400 *result = tmpstr; 1401 } else { 1402 free(tmpstr); 1403 *result = NULL; 1404 } 1405 1406 return (ret); 1407 } 1408 1409 KMF_RETURN 1410 kmf_get_cert_start_date_str(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, 1411 char **result) 1412 { 1413 KMF_RETURN ret; 1414 char *tmpstr; 1415 1416 CLEAR_ERROR(handle, ret); 1417 if (ret != KMF_OK) 1418 return (ret); 1419 1420 if (SignedCert == NULL || result == NULL) 1421 return (KMF_ERR_BAD_PARAMETER); 1422 tmpstr = malloc(KMF_CERT_PRINTABLE_LEN); 1423 if (tmpstr == NULL) 1424 return (KMF_ERR_MEMORY); 1425 (void) memset(tmpstr, 0, KMF_CERT_PRINTABLE_LEN); 1426 1427 ret = KMF_CertGetPrintable(handle, SignedCert, KMF_CERT_NOTBEFORE, 1428 tmpstr); 1429 1430 if (ret == KMF_OK) { 1431 *result = tmpstr; 1432 } else { 1433 free(tmpstr); 1434 *result = NULL; 1435 } 1436 1437 return (ret); 1438 } 1439 1440 KMF_RETURN 1441 kmf_get_cert_end_date_str(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, 1442 char **result) 1443 { 1444 KMF_RETURN ret; 1445 char *tmpstr; 1446 1447 CLEAR_ERROR(handle, ret); 1448 if (ret != KMF_OK) 1449 return (ret); 1450 1451 if (SignedCert == NULL || result == NULL) 1452 return (KMF_ERR_BAD_PARAMETER); 1453 tmpstr = malloc(KMF_CERT_PRINTABLE_LEN); 1454 if (tmpstr == NULL) 1455 return (KMF_ERR_MEMORY); 1456 (void) memset(tmpstr, 0, KMF_CERT_PRINTABLE_LEN); 1457 1458 ret = KMF_CertGetPrintable(handle, SignedCert, KMF_CERT_NOTAFTER, 1459 tmpstr); 1460 1461 if (ret == KMF_OK) { 1462 *result = tmpstr; 1463 } else { 1464 free(tmpstr); 1465 *result = NULL; 1466 } 1467 1468 return (ret); 1469 } 1470 1471 KMF_RETURN 1472 kmf_get_cert_pubkey_alg_str(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, 1473 char **result) 1474 { 1475 KMF_RETURN ret; 1476 char *tmpstr; 1477 1478 CLEAR_ERROR(handle, ret); 1479 if (ret != KMF_OK) 1480 return (ret); 1481 1482 if (SignedCert == NULL || result == NULL) 1483 return (KMF_ERR_BAD_PARAMETER); 1484 tmpstr = malloc(KMF_CERT_PRINTABLE_LEN); 1485 if (tmpstr == NULL) 1486 return (KMF_ERR_MEMORY); 1487 (void) memset(tmpstr, 0, KMF_CERT_PRINTABLE_LEN); 1488 1489 ret = KMF_CertGetPrintable(handle, SignedCert, KMF_CERT_PUBKEY_ALG, 1490 tmpstr); 1491 1492 if (ret == KMF_OK) { 1493 *result = tmpstr; 1494 } else { 1495 free(tmpstr); 1496 *result = NULL; 1497 } 1498 1499 return (ret); 1500 } 1501 1502 KMF_RETURN 1503 kmf_get_cert_sig_alg_str(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, 1504 char **result) 1505 { 1506 KMF_RETURN ret; 1507 char *tmpstr; 1508 1509 CLEAR_ERROR(handle, ret); 1510 if (ret != KMF_OK) 1511 return (ret); 1512 1513 if (SignedCert == NULL || result == NULL) 1514 return (KMF_ERR_BAD_PARAMETER); 1515 tmpstr = malloc(KMF_CERT_PRINTABLE_LEN); 1516 if (tmpstr == NULL) 1517 return (KMF_ERR_MEMORY); 1518 (void) memset(tmpstr, 0, KMF_CERT_PRINTABLE_LEN); 1519 1520 ret = KMF_CertGetPrintable(handle, SignedCert, KMF_CERT_SIGNATURE_ALG, 1521 tmpstr); 1522 1523 if (ret == KMF_OK) { 1524 *result = tmpstr; 1525 } else { 1526 free(tmpstr); 1527 *result = NULL; 1528 } 1529 1530 return (ret); 1531 } 1532 1533 KMF_RETURN 1534 kmf_get_cert_pubkey_str(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, 1535 char **result) 1536 { 1537 KMF_RETURN ret; 1538 char *tmpstr; 1539 1540 CLEAR_ERROR(handle, ret); 1541 if (ret != KMF_OK) 1542 return (ret); 1543 1544 if (SignedCert == NULL || result == NULL) 1545 return (KMF_ERR_BAD_PARAMETER); 1546 tmpstr = malloc(KMF_CERT_PRINTABLE_LEN); 1547 if (tmpstr == NULL) 1548 return (KMF_ERR_MEMORY); 1549 (void) memset(tmpstr, 0, KMF_CERT_PRINTABLE_LEN); 1550 1551 ret = KMF_CertGetPrintable(handle, SignedCert, KMF_CERT_PUBKEY_DATA, 1552 tmpstr); 1553 1554 if (ret == KMF_OK) { 1555 *result = tmpstr; 1556 } else { 1557 free(tmpstr); 1558 *result = NULL; 1559 } 1560 1561 return (ret); 1562 } 1563 1564 KMF_RETURN 1565 kmf_get_cert_email_str(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, 1566 char **result) 1567 { 1568 KMF_RETURN ret; 1569 char *tmpstr; 1570 1571 CLEAR_ERROR(handle, ret); 1572 if (ret != KMF_OK) 1573 return (ret); 1574 1575 if (SignedCert == NULL || result == NULL) 1576 return (KMF_ERR_BAD_PARAMETER); 1577 tmpstr = malloc(KMF_CERT_PRINTABLE_LEN); 1578 if (tmpstr == NULL) 1579 return (KMF_ERR_MEMORY); 1580 (void) memset(tmpstr, 0, KMF_CERT_PRINTABLE_LEN); 1581 1582 ret = KMF_CertGetPrintable(handle, SignedCert, KMF_CERT_EMAIL, tmpstr); 1583 1584 if (ret == KMF_OK) { 1585 *result = tmpstr; 1586 } else { 1587 free(tmpstr); 1588 *result = NULL; 1589 } 1590 1591 return (ret); 1592 } 1593 1594 /* 1595 * Given a certificate (DER Encoded data) and a KMF 1596 * extension identifier constant (e.g. KMF_X509_EXT_*), 1597 * return a human readable interpretation of the 1598 * extension data. 1599 * 1600 * The string will be a maximum of KMF_CERT_PRINTABLE_LEN 1601 * bytes long. The string is allocated locally and 1602 * must be freed by the caller. 1603 */ 1604 KMF_RETURN 1605 kmf_get_cert_extn_str(KMF_HANDLE_T handle, const KMF_DATA *cert, 1606 KMF_PRINTABLE_ITEM extension, char **result) 1607 { 1608 KMF_RETURN ret; 1609 char *tmpstr; 1610 1611 CLEAR_ERROR(handle, ret); 1612 if (ret != KMF_OK) 1613 return (ret); 1614 1615 if (cert == NULL || result == NULL) 1616 return (KMF_ERR_BAD_PARAMETER); 1617 1618 tmpstr = malloc(KMF_CERT_PRINTABLE_LEN); 1619 if (tmpstr == NULL) 1620 return (KMF_ERR_MEMORY); 1621 (void) memset(tmpstr, 0, KMF_CERT_PRINTABLE_LEN); 1622 1623 ret = KMF_CertGetPrintable(handle, cert, extension, tmpstr); 1624 1625 if (ret == KMF_OK) { 1626 *result = tmpstr; 1627 } else { 1628 free(tmpstr); 1629 *result = NULL; 1630 } 1631 1632 return (ret); 1633 } 1634 1635 KMF_RETURN 1636 kmf_get_cert_id_data(const KMF_DATA *SignedCert, KMF_DATA *ID) 1637 { 1638 KMF_RETURN ret; 1639 KMF_X509_CERTIFICATE *cert = NULL; 1640 1641 if (SignedCert == NULL || ID == NULL) 1642 return (KMF_ERR_BAD_PARAMETER); 1643 1644 ret = DerDecodeSignedCertificate(SignedCert, &cert); 1645 if (ret != KMF_OK) 1646 return (ret); 1647 1648 ret = GetIDFromSPKI(&cert->certificate.subjectPublicKeyInfo, ID); 1649 1650 kmf_free_signed_cert(cert); 1651 free(cert); 1652 return (ret); 1653 } 1654 1655 KMF_RETURN 1656 kmf_get_cert_id_str(const KMF_DATA *SignedCert, char **idstr) 1657 { 1658 KMF_RETURN ret; 1659 KMF_DATA ID = { 0, NULL }; 1660 char tmpstr[256]; 1661 int i; 1662 1663 if (SignedCert == NULL || idstr == NULL) 1664 return (KMF_ERR_BAD_PARAMETER); 1665 1666 ret = kmf_get_cert_id_data(SignedCert, &ID); 1667 if (ret != KMF_OK) { 1668 kmf_free_data(&ID); 1669 return (ret); 1670 } 1671 1672 (void) memset(tmpstr, 0, sizeof (tmpstr)); 1673 for (i = 0; i < ID.Length; i++) { 1674 int len = strlen(tmpstr); 1675 (void) snprintf(&tmpstr[len], sizeof (tmpstr) - len, 1676 "%02x", (uchar_t)ID.Data[i]); 1677 if ((i+1) < ID.Length) 1678 (void) strcat(tmpstr, ":"); 1679 } 1680 *idstr = strdup(tmpstr); 1681 if ((*idstr) == NULL) 1682 ret = KMF_ERR_MEMORY; 1683 1684 kmf_free_data(&ID); 1685 1686 return (ret); 1687 } 1688 1689 1690 /* 1691 * This function gets the time_t values of the notbefore and notafter dates 1692 * from a der-encoded certificate. 1693 */ 1694 KMF_RETURN 1695 kmf_get_cert_validity(const KMF_DATA *cert, time_t *not_before, 1696 time_t *not_after) 1697 { 1698 KMF_RETURN rv = KMF_OK; 1699 KMF_X509_CERTIFICATE *certData = NULL; 1700 struct tm tm_tmp; 1701 time_t t_notbefore; 1702 time_t t_notafter; 1703 unsigned char *not_before_str; 1704 unsigned char *not_after_str; 1705 1706 if (cert == NULL || not_before == NULL || not_after == NULL) 1707 return (KMF_ERR_BAD_PARAMETER); 1708 1709 rv = DerDecodeSignedCertificate(cert, &certData); 1710 if (rv != KMF_OK) 1711 return (rv); 1712 1713 /* Get notBefore */ 1714 not_before_str = certData->certificate.validity.notBefore.time.Data; 1715 if (strptime((const char *)not_before_str, "%y %m %d %H %M %S", 1716 &tm_tmp) == NULL) { 1717 rv = KMF_ERR_VALIDITY_PERIOD; 1718 goto out; 1719 } 1720 1721 errno = 0; 1722 if (((t_notbefore = mktime(&tm_tmp)) == (time_t)(-1)) && 1723 errno == EOVERFLOW) { 1724 rv = KMF_ERR_VALIDITY_PERIOD; 1725 goto out; 1726 } 1727 *not_before = t_notbefore; 1728 1729 /* Get notAfter */ 1730 not_after_str = certData->certificate.validity.notAfter.time.Data; 1731 if (strptime((const char *)not_after_str, "%y %m %d %H %M %S", 1732 &tm_tmp) == NULL) { 1733 rv = KMF_ERR_VALIDITY_PERIOD; 1734 goto out; 1735 } 1736 1737 errno = 0; 1738 if (((t_notafter = mktime(&tm_tmp)) == (time_t)(-1)) && 1739 errno == EOVERFLOW) { 1740 rv = KMF_ERR_VALIDITY_PERIOD; 1741 goto out; 1742 } 1743 *not_after = t_notafter; 1744 1745 out: 1746 if (certData != NULL) { 1747 kmf_free_signed_cert(certData); 1748 free(certData); 1749 } 1750 1751 return (rv); 1752 } 1753 1754 KMF_RETURN 1755 kmf_set_cert_pubkey(KMF_HANDLE_T handle, 1756 KMF_KEY_HANDLE *KMFKey, 1757 KMF_X509_CERTIFICATE *Cert) 1758 { 1759 KMF_RETURN ret = KMF_OK; 1760 KMF_X509_SPKI *spki_ptr; 1761 KMF_PLUGIN *plugin; 1762 KMF_DATA KeyData = { 0, NULL }; 1763 1764 CLEAR_ERROR(handle, ret); 1765 if (ret != KMF_OK) 1766 return (ret); 1767 1768 if (KMFKey == NULL || Cert == NULL) { 1769 return (KMF_ERR_BAD_PARAMETER); 1770 } 1771 1772 /* The keystore must extract the pubkey data */ 1773 plugin = FindPlugin(handle, KMFKey->kstype); 1774 if (plugin != NULL && plugin->funclist->EncodePubkeyData != NULL) { 1775 ret = plugin->funclist->EncodePubkeyData(handle, 1776 KMFKey, &KeyData); 1777 } else { 1778 return (KMF_ERR_PLUGIN_NOTFOUND); 1779 } 1780 1781 spki_ptr = &Cert->certificate.subjectPublicKeyInfo; 1782 1783 if (KeyData.Data != NULL) { 1784 ret = DerDecodeSPKI(&KeyData, spki_ptr); 1785 free(KeyData.Data); 1786 } 1787 1788 return (ret); 1789 } 1790 1791 KMF_RETURN 1792 kmf_set_cert_subject(KMF_X509_CERTIFICATE *CertData, 1793 KMF_X509_NAME *subject_name_ptr) 1794 { 1795 1796 KMF_RETURN rv = KMF_OK; 1797 KMF_X509_NAME *temp_name_ptr = NULL; 1798 1799 if (CertData != NULL && subject_name_ptr != NULL) { 1800 rv = CopyRDN(subject_name_ptr, &temp_name_ptr); 1801 if (rv == KMF_OK) { 1802 CertData->certificate.subject = *temp_name_ptr; 1803 } 1804 } else { 1805 return (KMF_ERR_BAD_PARAMETER); 1806 } 1807 return (rv); 1808 } 1809 1810 KMF_RETURN 1811 set_key_usage_extension(KMF_X509_EXTENSIONS *extns, 1812 int critical, uint32_t bits) 1813 { 1814 KMF_RETURN ret = KMF_OK; 1815 KMF_X509_EXTENSION extn; 1816 BerElement *asn1 = NULL; 1817 BerValue *extdata; 1818 int bitlen, i; 1819 uint16_t kubits = (uint16_t)(bits & 0x0000ffff); 1820 1821 if (extns == NULL) 1822 return (KMF_ERR_BAD_PARAMETER); 1823 1824 (void) memset(&extn, 0, sizeof (extn)); 1825 ret = copy_data(&extn.extnId, (KMF_OID *)&KMFOID_KeyUsage); 1826 if (ret != KMF_OK) 1827 return (ret); 1828 extn.critical = critical; 1829 extn.format = KMF_X509_DATAFORMAT_ENCODED; 1830 1831 for (i = 7; i <= 15 && !(kubits & (1 << i)); i++) 1832 /* empty body */ 1833 ; 1834 1835 bitlen = 16 - i; 1836 1837 if ((asn1 = kmfder_alloc()) == NULL) 1838 return (KMF_ERR_MEMORY); 1839 1840 kubits = htons(kubits); 1841 if (kmfber_printf(asn1, "B", (char *)&kubits, bitlen) == -1) { 1842 ret = KMF_ERR_ENCODING; 1843 goto out; 1844 } 1845 if (kmfber_flatten(asn1, &extdata) == -1) { 1846 ret = KMF_ERR_ENCODING; 1847 goto out; 1848 } 1849 1850 extn.BERvalue.Data = (uchar_t *)extdata->bv_val; 1851 extn.BERvalue.Length = extdata->bv_len; 1852 1853 free(extdata); 1854 1855 ret = add_an_extension(extns, &extn); 1856 if (ret != KMF_OK) { 1857 free(extn.BERvalue.Data); 1858 } 1859 out: 1860 if (asn1 != NULL) 1861 kmfber_free(asn1, 1); 1862 1863 return (ret); 1864 } 1865 1866 KMF_RETURN 1867 kmf_set_cert_ku(KMF_X509_CERTIFICATE *CertData, 1868 int critical, uint16_t kubits) 1869 { 1870 KMF_RETURN ret = KMF_OK; 1871 1872 if (CertData == NULL) 1873 return (KMF_ERR_BAD_PARAMETER); 1874 1875 ret = set_key_usage_extension(&CertData->certificate.extensions, 1876 critical, kubits); 1877 1878 return (ret); 1879 } 1880 1881 KMF_RETURN 1882 kmf_set_cert_issuer(KMF_X509_CERTIFICATE *CertData, 1883 KMF_X509_NAME *issuer_name_ptr) 1884 { 1885 1886 KMF_RETURN rv = KMF_OK; 1887 KMF_X509_NAME *temp_name_ptr = NULL; 1888 1889 if (CertData != NULL && issuer_name_ptr != NULL) { 1890 rv = CopyRDN(issuer_name_ptr, &temp_name_ptr); 1891 if (rv == KMF_OK) { 1892 CertData->certificate.issuer = *temp_name_ptr; 1893 } 1894 } else { 1895 return (KMF_ERR_BAD_PARAMETER); 1896 } 1897 1898 return (rv); 1899 } 1900 1901 KMF_RETURN 1902 kmf_set_cert_sig_alg(KMF_X509_CERTIFICATE *CertData, 1903 KMF_ALGORITHM_INDEX sigAlg) 1904 { 1905 KMF_OID *alg; 1906 1907 if (CertData == NULL) 1908 return (KMF_ERR_BAD_PARAMETER); 1909 1910 alg = x509_algid_to_algoid(sigAlg); 1911 1912 if (alg != NULL) { 1913 (void) copy_data((KMF_DATA *) 1914 &CertData->certificate.signature.algorithm, 1915 (KMF_DATA *)alg); 1916 (void) copy_data(&CertData->certificate.signature.parameters, 1917 &CertData->certificate.subjectPublicKeyInfo.algorithm. 1918 parameters); 1919 1920 (void) copy_data( 1921 &CertData->signature.algorithmIdentifier.algorithm, 1922 &CertData->certificate.signature.algorithm); 1923 (void) copy_data( 1924 &CertData->signature.algorithmIdentifier.parameters, 1925 &CertData->certificate.signature.parameters); 1926 } else { 1927 return (KMF_ERR_BAD_PARAMETER); 1928 } 1929 1930 return (KMF_OK); 1931 } 1932 1933 KMF_RETURN 1934 kmf_set_cert_validity(KMF_X509_CERTIFICATE *CertData, 1935 time_t notBefore, uint32_t delta) 1936 { 1937 time_t clock; 1938 struct tm *gmt; 1939 char szNotBefore[256]; 1940 char szNotAfter[256]; 1941 1942 if (CertData == NULL) 1943 return (KMF_ERR_BAD_PARAMETER); 1944 1945 /* Set up validity fields */ 1946 if (notBefore == NULL) 1947 clock = time(NULL); 1948 else 1949 clock = notBefore; 1950 1951 gmt = gmtime(&clock); /* valid starting today */ 1952 1953 /* Build the format in 2 parts so SCCS doesn't get confused */ 1954 (void) strftime(szNotBefore, sizeof (szNotBefore), 1955 "%y%m%d%H" "%M00Z", gmt); 1956 1957 CertData->certificate.validity.notBefore.timeType = BER_UTCTIME; 1958 CertData->certificate.validity.notBefore.time.Length = 1959 strlen((char *)szNotBefore); 1960 CertData->certificate.validity.notBefore.time.Data = 1961 (uchar_t *)strdup(szNotBefore); 1962 1963 clock += delta; 1964 gmt = gmtime(&clock); 1965 1966 /* Build the format in 2 parts so SCCS doesn't get confused */ 1967 (void) strftime(szNotAfter, sizeof (szNotAfter), 1968 "%y%m%d%H" "%M00Z", gmt); 1969 1970 CertData->certificate.validity.notAfter.timeType = BER_UTCTIME; 1971 CertData->certificate.validity.notAfter.time.Length = 1972 strlen((char *)szNotAfter); 1973 CertData->certificate.validity.notAfter.time.Data = 1974 (uchar_t *)strdup(szNotAfter); 1975 1976 return (KMF_OK); 1977 } 1978 1979 /* 1980 * Utility routine to set Integer values in the Certificate template 1981 * for things like serialNumber and Version. The data structure 1982 * expects pointers, not literal values, so we must allocate 1983 * and copy here. Don't use memory from the stack since this data 1984 * is freed later and that would be bad. 1985 */ 1986 KMF_RETURN 1987 set_integer(KMF_DATA *data, void *value, int length) 1988 { 1989 if (data == NULL || value == NULL) 1990 return (KMF_ERR_BAD_PARAMETER); 1991 1992 data->Data = malloc(length); 1993 if (data->Data == NULL) 1994 return (KMF_ERR_MEMORY); 1995 1996 data->Length = length; 1997 (void) memcpy((void *)data->Data, (const void *)value, length); 1998 1999 return (KMF_OK); 2000 } 2001 2002 static KMF_RETURN 2003 set_bigint(KMF_BIGINT *data, KMF_BIGINT *bigint) 2004 { 2005 if (data == NULL || bigint == NULL || bigint->len == NULL) 2006 return (KMF_ERR_BAD_PARAMETER); 2007 2008 data->val = malloc(bigint->len); 2009 if (data->val == NULL) 2010 return (KMF_ERR_MEMORY); 2011 2012 data->len = bigint->len; 2013 2014 (void) memcpy((void *)data->val, bigint->val, bigint->len); 2015 2016 return (KMF_OK); 2017 2018 } 2019 2020 KMF_RETURN 2021 kmf_set_cert_serial(KMF_X509_CERTIFICATE *CertData, 2022 KMF_BIGINT *serno) 2023 { 2024 if (CertData == NULL || serno == NULL || serno->len == 0) 2025 return (KMF_ERR_BAD_PARAMETER); 2026 return (set_bigint(&CertData->certificate.serialNumber, serno)); 2027 } 2028 2029 KMF_RETURN 2030 kmf_set_cert_version(KMF_X509_CERTIFICATE *CertData, 2031 uint32_t version) 2032 { 2033 if (CertData == NULL) 2034 return (KMF_ERR_BAD_PARAMETER); 2035 /* 2036 * From RFC 3280: 2037 * Version ::= INTEGER { v1(0), v2(1), v3(2) } 2038 */ 2039 if (version != 0 && version != 1 && version != 2) 2040 return (KMF_ERR_BAD_PARAMETER); 2041 return (set_integer(&CertData->certificate.version, (void *)&version, 2042 sizeof (uint32_t))); 2043 } 2044 2045 KMF_RETURN 2046 kmf_set_cert_issuer_altname(KMF_X509_CERTIFICATE *CertData, 2047 int critical, 2048 KMF_GENERALNAMECHOICES nametype, 2049 char *namedata) 2050 { 2051 if (CertData == NULL || namedata == NULL) 2052 return (KMF_ERR_BAD_PARAMETER); 2053 2054 return (kmf_set_altname(&CertData->certificate.extensions, 2055 (KMF_OID *)&KMFOID_IssuerAltName, critical, nametype, namedata)); 2056 } 2057 2058 KMF_RETURN 2059 kmf_set_cert_subject_altname(KMF_X509_CERTIFICATE *CertData, 2060 int critical, 2061 KMF_GENERALNAMECHOICES nametype, 2062 char *namedata) 2063 { 2064 if (CertData == NULL || namedata == NULL) 2065 return (KMF_ERR_BAD_PARAMETER); 2066 2067 return (kmf_set_altname(&CertData->certificate.extensions, 2068 (KMF_OID *)&KMFOID_SubjectAltName, critical, nametype, namedata)); 2069 } 2070 2071 KMF_RETURN 2072 kmf_add_cert_eku(KMF_X509_CERTIFICATE *CertData, KMF_OID *ekuOID, 2073 int critical) 2074 { 2075 KMF_RETURN ret = KMF_OK; 2076 KMF_X509_EXTENSION *foundextn; 2077 KMF_X509_EXTENSION newextn; 2078 BerElement *asn1 = NULL; 2079 BerValue *extdata = NULL; 2080 char *olddata = NULL; 2081 size_t oldsize = 0; 2082 KMF_X509EXT_EKU ekudata; 2083 2084 if (CertData == NULL || ekuOID == NULL) 2085 return (KMF_ERR_BAD_PARAMETER); 2086 2087 (void) memset(&ekudata, 0, sizeof (KMF_X509EXT_EKU)); 2088 (void) memset(&newextn, 0, sizeof (newextn)); 2089 2090 foundextn = FindExtn(&CertData->certificate.extensions, 2091 (KMF_OID *)&KMFOID_ExtendedKeyUsage); 2092 if (foundextn != NULL) { 2093 ret = GetSequenceContents((char *)foundextn->BERvalue.Data, 2094 foundextn->BERvalue.Length, &olddata, &oldsize); 2095 if (ret != KMF_OK) 2096 goto out; 2097 2098 /* 2099 * If the EKU is already in the cert, then just return OK. 2100 */ 2101 ret = parse_eku_data(&foundextn->BERvalue, &ekudata); 2102 if (ret == KMF_OK) { 2103 if (is_eku_present(&ekudata, ekuOID)) { 2104 goto out; 2105 } 2106 } 2107 } 2108 if ((asn1 = kmfder_alloc()) == NULL) 2109 return (KMF_ERR_MEMORY); 2110 2111 if (kmfber_printf(asn1, "{") == -1) { 2112 ret = KMF_ERR_ENCODING; 2113 goto out; 2114 } 2115 2116 /* Write the old extension data first */ 2117 if (olddata != NULL && oldsize > 0) { 2118 if (kmfber_write(asn1, olddata, oldsize, 0) == -1) { 2119 ret = KMF_ERR_ENCODING; 2120 goto out; 2121 } 2122 } 2123 2124 /* Append this EKU OID and close the sequence */ 2125 if (kmfber_printf(asn1, "D}", ekuOID) == -1) { 2126 ret = KMF_ERR_ENCODING; 2127 goto out; 2128 } 2129 2130 if (kmfber_flatten(asn1, &extdata) == -1) { 2131 ret = KMF_ERR_ENCODING; 2132 goto out; 2133 } 2134 2135 /* 2136 * If we are just adding to an existing list of EKU OIDs, 2137 * just replace the BER data associated with the found extension. 2138 */ 2139 if (foundextn != NULL) { 2140 free(foundextn->BERvalue.Data); 2141 foundextn->critical = critical; 2142 foundextn->BERvalue.Data = (uchar_t *)extdata->bv_val; 2143 foundextn->BERvalue.Length = extdata->bv_len; 2144 } else { 2145 ret = copy_data(&newextn.extnId, 2146 (KMF_DATA *)&KMFOID_ExtendedKeyUsage); 2147 if (ret != KMF_OK) 2148 goto out; 2149 newextn.critical = critical; 2150 newextn.format = KMF_X509_DATAFORMAT_ENCODED; 2151 newextn.BERvalue.Data = (uchar_t *)extdata->bv_val; 2152 newextn.BERvalue.Length = extdata->bv_len; 2153 ret = kmf_set_cert_extn(CertData, &newextn); 2154 if (ret != KMF_OK) 2155 free(newextn.BERvalue.Data); 2156 } 2157 2158 out: 2159 kmf_free_eku(&ekudata); 2160 if (extdata != NULL) 2161 free(extdata); 2162 2163 if (olddata != NULL) 2164 free(olddata); 2165 2166 if (asn1 != NULL) 2167 kmfber_free(asn1, 1); 2168 2169 if (ret != KMF_OK) 2170 kmf_free_data(&newextn.extnId); 2171 2172 return (ret); 2173 } 2174 2175 KMF_RETURN 2176 kmf_set_cert_extn(KMF_X509_CERTIFICATE *CertData, 2177 KMF_X509_EXTENSION *extn) 2178 { 2179 KMF_RETURN ret = KMF_OK; 2180 KMF_X509_EXTENSIONS *exts; 2181 2182 if (CertData == NULL || extn == NULL) 2183 return (KMF_ERR_BAD_PARAMETER); 2184 2185 exts = &CertData->certificate.extensions; 2186 2187 ret = add_an_extension(exts, extn); 2188 2189 return (ret); 2190 } 2191 2192 KMF_RETURN 2193 kmf_set_cert_basic_constraint(KMF_X509_CERTIFICATE *CertData, 2194 KMF_BOOL critical, KMF_X509EXT_BASICCONSTRAINTS *constraint) 2195 { 2196 KMF_RETURN ret = KMF_OK; 2197 KMF_X509_EXTENSION extn; 2198 BerElement *asn1 = NULL; 2199 BerValue *extdata; 2200 2201 if ((CertData == NULL) || (constraint == NULL)) 2202 return (KMF_ERR_BAD_PARAMETER); 2203 2204 (void) memset(&extn, 0, sizeof (extn)); 2205 ret = copy_data(&extn.extnId, (KMF_OID *)&KMFOID_BasicConstraints); 2206 if (ret != KMF_OK) 2207 return (ret); 2208 extn.critical = critical; 2209 extn.format = KMF_X509_DATAFORMAT_ENCODED; 2210 2211 if ((asn1 = kmfder_alloc()) == NULL) 2212 return (KMF_ERR_MEMORY); 2213 2214 if (kmfber_printf(asn1, "{") == -1) { 2215 ret = KMF_ERR_ENCODING; 2216 goto out; 2217 } 2218 2219 if (kmfber_printf(asn1, "b", constraint->cA) == -1) { 2220 ret = KMF_ERR_ENCODING; 2221 goto out; 2222 } 2223 2224 if (constraint->pathLenConstraintPresent) { 2225 /* Write the pathLenConstraint value */ 2226 if (kmfber_printf(asn1, "i", 2227 constraint->pathLenConstraint) == -1) { 2228 ret = KMF_ERR_ENCODING; 2229 goto out; 2230 } 2231 } 2232 2233 if (kmfber_printf(asn1, "}") == -1) { 2234 ret = KMF_ERR_ENCODING; 2235 goto out; 2236 } 2237 2238 if (kmfber_flatten(asn1, &extdata) == -1) { 2239 ret = KMF_ERR_ENCODING; 2240 goto out; 2241 } 2242 2243 extn.BERvalue.Data = (uchar_t *)extdata->bv_val; 2244 extn.BERvalue.Length = extdata->bv_len; 2245 2246 free(extdata); 2247 ret = kmf_set_cert_extn(CertData, &extn); 2248 if (ret != KMF_OK) { 2249 free(extn.BERvalue.Data); 2250 } 2251 2252 out: 2253 if (asn1 != NULL) 2254 kmfber_free(asn1, 1); 2255 2256 return (ret); 2257 } 2258 2259 2260 /* 2261 * Phase 1 APIs still needed to maintain compat with elfsign. 2262 */ 2263 KMF_RETURN 2264 KMF_GetCertSubjectNameString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, 2265 char **result) 2266 { 2267 return (kmf_get_cert_subject_str(handle, SignedCert, result)); 2268 } 2269 2270 KMF_RETURN 2271 KMF_GetCertIssuerNameString(KMF_HANDLE_T handle, const KMF_DATA *SignedCert, 2272 char **result) 2273 { 2274 return (kmf_get_cert_issuer_str(handle, SignedCert, result)); 2275 } 2276 2277 KMF_RETURN 2278 KMF_GetCertIDString(const KMF_DATA *SignedCert, char **idstr) 2279 { 2280 return (kmf_get_cert_id_str(SignedCert, idstr)); 2281 } 2282