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