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