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 if (CertData != NULL && subject_name_ptr != NULL) 1848 CertData->certificate.subject = *subject_name_ptr; 1849 else 1850 return (KMF_ERR_BAD_PARAMETER); 1851 1852 return (KMF_OK); 1853 } 1854 1855 KMF_RETURN 1856 set_key_usage_extension(KMF_X509_EXTENSIONS *extns, 1857 int critical, uint32_t bits) 1858 { 1859 KMF_RETURN ret = KMF_OK; 1860 KMF_X509_EXTENSION extn; 1861 BerElement *asn1 = NULL; 1862 BerValue *extdata; 1863 int bitlen, i; 1864 uint16_t kubits = (uint16_t)(bits & 0x0000ffff); 1865 1866 if (extns == NULL) 1867 return (KMF_ERR_BAD_PARAMETER); 1868 1869 (void) memset(&extn, 0, sizeof (extn)); 1870 ret = copy_data(&extn.extnId, (KMF_OID *)&KMFOID_KeyUsage); 1871 if (ret != KMF_OK) 1872 return (ret); 1873 extn.critical = critical; 1874 extn.format = KMF_X509_DATAFORMAT_ENCODED; 1875 1876 for (i = 7; i <= 15 && !(kubits & (1 << i)); i++); 1877 1878 bitlen = 16 - i; 1879 1880 if ((asn1 = kmfder_alloc()) == NULL) 1881 return (KMF_ERR_MEMORY); 1882 1883 kubits = htons(kubits); 1884 if (kmfber_printf(asn1, "B", (char *)&kubits, bitlen) == -1) { 1885 ret = KMF_ERR_ENCODING; 1886 goto out; 1887 } 1888 if (kmfber_flatten(asn1, &extdata) == -1) { 1889 ret = KMF_ERR_ENCODING; 1890 goto out; 1891 } 1892 1893 extn.BERvalue.Data = (uchar_t *)extdata->bv_val; 1894 extn.BERvalue.Length = extdata->bv_len; 1895 1896 free(extdata); 1897 1898 ret = add_an_extension(extns, &extn); 1899 if (ret != KMF_OK) { 1900 free(extn.BERvalue.Data); 1901 } 1902 out: 1903 if (asn1 != NULL) 1904 kmfber_free(asn1, 1); 1905 1906 return (ret); 1907 } 1908 1909 KMF_RETURN 1910 KMF_SetCertKeyUsage(KMF_X509_CERTIFICATE *CertData, 1911 int critical, uint16_t kubits) 1912 { 1913 KMF_RETURN ret = KMF_OK; 1914 1915 if (CertData == NULL) 1916 return (KMF_ERR_BAD_PARAMETER); 1917 1918 ret = set_key_usage_extension( 1919 &CertData->certificate.extensions, 1920 critical, kubits); 1921 1922 return (ret); 1923 } 1924 1925 KMF_RETURN 1926 KMF_SetCertIssuerName(KMF_X509_CERTIFICATE *CertData, 1927 KMF_X509_NAME *issuer_name_ptr) 1928 { 1929 if (CertData != NULL && issuer_name_ptr != NULL) 1930 CertData->certificate.issuer = *issuer_name_ptr; 1931 else 1932 return (KMF_ERR_BAD_PARAMETER); 1933 1934 return (KMF_OK); 1935 } 1936 1937 KMF_RETURN 1938 KMF_SetCertSignatureAlgorithm(KMF_X509_CERTIFICATE *CertData, 1939 KMF_ALGORITHM_INDEX sigAlg) 1940 { 1941 KMF_OID *alg; 1942 1943 if (CertData == NULL) 1944 return (KMF_ERR_BAD_PARAMETER); 1945 1946 alg = X509_AlgIdToAlgorithmOid(sigAlg); 1947 1948 if (alg != NULL) { 1949 (void) copy_data((KMF_DATA *) 1950 &CertData->certificate.signature.algorithm, 1951 (KMF_DATA *)alg); 1952 (void) copy_data(&CertData->certificate.signature.parameters, 1953 &CertData->certificate.subjectPublicKeyInfo.algorithm. 1954 parameters); 1955 1956 (void) copy_data( 1957 &CertData->signature.algorithmIdentifier.algorithm, 1958 &CertData->certificate.signature.algorithm); 1959 (void) copy_data( 1960 &CertData->signature.algorithmIdentifier.parameters, 1961 &CertData->certificate.signature.parameters); 1962 } else { 1963 return (KMF_ERR_BAD_PARAMETER); 1964 } 1965 1966 return (KMF_OK); 1967 } 1968 1969 KMF_RETURN 1970 KMF_SetCertValidityTimes(KMF_X509_CERTIFICATE *CertData, 1971 time_t notBefore, uint32_t delta) 1972 { 1973 time_t clock; 1974 struct tm *gmt; 1975 char szNotBefore[256]; 1976 char szNotAfter[256]; 1977 1978 if (CertData == NULL) 1979 return (KMF_ERR_BAD_PARAMETER); 1980 1981 /* Set up validity fields */ 1982 if (notBefore == NULL) 1983 clock = time(NULL); 1984 else 1985 clock = notBefore; 1986 1987 gmt = gmtime(&clock); /* valid starting today */ 1988 1989 /* Build the format in 2 parts so SCCS doesn't get confused */ 1990 (void) strftime(szNotBefore, sizeof (szNotBefore), 1991 "%y%m%d%H" "%M00Z", gmt); 1992 1993 CertData->certificate.validity.notBefore.timeType = BER_UTCTIME; 1994 CertData->certificate.validity.notBefore.time.Length = 1995 strlen((char *)szNotBefore); 1996 CertData->certificate.validity.notBefore.time.Data = 1997 (uchar_t *)strdup(szNotBefore); 1998 1999 clock += delta; 2000 gmt = gmtime(&clock); 2001 2002 /* Build the format in 2 parts so SCCS doesn't get confused */ 2003 (void) strftime(szNotAfter, sizeof (szNotAfter), 2004 "%y%m%d%H" "%M00Z", gmt); 2005 2006 CertData->certificate.validity.notAfter.timeType = BER_UTCTIME; 2007 CertData->certificate.validity.notAfter.time.Length = 2008 strlen((char *)szNotAfter); 2009 CertData->certificate.validity.notAfter.time.Data = 2010 (uchar_t *)strdup(szNotAfter); 2011 2012 return (KMF_OK); 2013 } 2014 2015 /* 2016 * Utility routine to set Integer values in the Certificate template 2017 * for things like serialNumber and Version. The data structure 2018 * expects pointers, not literal values, so we must allocate 2019 * and copy here. Don't use memory from the stack since this data 2020 * is freed later and that would be bad. 2021 */ 2022 KMF_RETURN 2023 set_integer(KMF_DATA *data, void *value, int length) 2024 { 2025 if (data == NULL || value == NULL) 2026 return (KMF_ERR_BAD_PARAMETER); 2027 2028 data->Data = malloc(length); 2029 if (data->Data == NULL) 2030 return (KMF_ERR_MEMORY); 2031 2032 data->Length = length; 2033 (void) memcpy((void *)data->Data, (const void *)value, length); 2034 2035 return (KMF_OK); 2036 } 2037 2038 static KMF_RETURN 2039 set_bigint(KMF_BIGINT *data, KMF_BIGINT *bigint) 2040 { 2041 if (data == NULL || bigint == NULL || bigint->len == NULL) 2042 return (KMF_ERR_BAD_PARAMETER); 2043 2044 data->val = malloc(bigint->len); 2045 if (data->val == NULL) 2046 return (KMF_ERR_MEMORY); 2047 2048 data->len = bigint->len; 2049 2050 (void) memcpy((void *)data->val, bigint->val, bigint->len); 2051 2052 return (KMF_OK); 2053 2054 } 2055 2056 KMF_RETURN 2057 KMF_SetCertSerialNumber(KMF_X509_CERTIFICATE *CertData, 2058 KMF_BIGINT *serno) 2059 { 2060 if (CertData == NULL || serno == NULL || serno->len == 0) 2061 return (KMF_ERR_BAD_PARAMETER); 2062 return (set_bigint(&CertData->certificate.serialNumber, serno)); 2063 } 2064 2065 KMF_RETURN 2066 KMF_SetCertVersion(KMF_X509_CERTIFICATE *CertData, 2067 uint32_t version) 2068 { 2069 if (CertData == NULL) 2070 return (KMF_ERR_BAD_PARAMETER); 2071 /* 2072 * From RFC 3280: 2073 * Version ::= INTEGER { v1(0), v2(1), v3(2) } 2074 */ 2075 if (version != 0 && version != 1 && version != 2) 2076 return (KMF_ERR_BAD_PARAMETER); 2077 return (set_integer(&CertData->certificate.version, (void *)&version, 2078 sizeof (uint32_t))); 2079 } 2080 2081 KMF_RETURN 2082 KMF_SetCertIssuerAltName(KMF_X509_CERTIFICATE *CertData, 2083 int critical, 2084 KMF_GENERALNAMECHOICES nametype, 2085 char *namedata) 2086 { 2087 if (CertData == NULL || namedata == NULL) 2088 return (KMF_ERR_BAD_PARAMETER); 2089 2090 return (KMF_SetAltName( 2091 &CertData->certificate.extensions, 2092 (KMF_OID *)&KMFOID_IssuerAltName, 2093 critical, nametype, namedata)); 2094 } 2095 2096 KMF_RETURN 2097 KMF_SetCertSubjectAltName(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(&CertData->certificate.extensions, 2106 (KMF_OID *)&KMFOID_SubjectAltName, 2107 critical, nametype, namedata)); 2108 } 2109 2110 KMF_RETURN 2111 KMF_AddCertEKU(KMF_X509_CERTIFICATE *CertData, KMF_OID *ekuOID, 2112 int critical) 2113 { 2114 KMF_RETURN ret = KMF_OK; 2115 KMF_X509_EXTENSION *foundextn; 2116 KMF_X509_EXTENSION newextn; 2117 BerElement *asn1 = NULL; 2118 BerValue *extdata = NULL; 2119 char *olddata = NULL; 2120 size_t oldsize = 0; 2121 KMF_X509EXT_EKU ekudata; 2122 2123 if (CertData == NULL || ekuOID == NULL) 2124 return (KMF_ERR_BAD_PARAMETER); 2125 2126 (void) memset(&ekudata, 0, sizeof (KMF_X509EXT_EKU)); 2127 (void) memset(&newextn, 0, sizeof (newextn)); 2128 2129 foundextn = FindExtn(&CertData->certificate.extensions, 2130 (KMF_OID *)&KMFOID_ExtendedKeyUsage); 2131 if (foundextn != NULL) { 2132 ret = GetSequenceContents( 2133 (char *)foundextn->BERvalue.Data, 2134 foundextn->BERvalue.Length, 2135 &olddata, &oldsize); 2136 if (ret != KMF_OK) 2137 goto out; 2138 2139 /* 2140 * If the EKU is already in the cert, then just return OK. 2141 */ 2142 ret = parse_eku_data(&foundextn->BERvalue, &ekudata); 2143 if (ret == KMF_OK) { 2144 if (isEKUPresent(&ekudata, ekuOID)) { 2145 goto out; 2146 } 2147 } 2148 } 2149 if ((asn1 = kmfder_alloc()) == NULL) 2150 return (KMF_ERR_MEMORY); 2151 2152 if (kmfber_printf(asn1, "{") == -1) { 2153 ret = KMF_ERR_ENCODING; 2154 goto out; 2155 } 2156 2157 /* Write the old extension data first */ 2158 if (olddata != NULL && oldsize > 0) { 2159 if (kmfber_write(asn1, olddata, oldsize, 0) == -1) { 2160 ret = KMF_ERR_ENCODING; 2161 goto out; 2162 } 2163 } 2164 2165 /* Append this EKU OID and close the sequence */ 2166 if (kmfber_printf(asn1, "D}", ekuOID) == -1) { 2167 ret = KMF_ERR_ENCODING; 2168 goto out; 2169 } 2170 2171 if (kmfber_flatten(asn1, &extdata) == -1) { 2172 ret = KMF_ERR_ENCODING; 2173 goto out; 2174 } 2175 2176 /* 2177 * If we are just adding to an existing list of EKU OIDs, 2178 * just replace the BER data associated with the found extension. 2179 */ 2180 if (foundextn != NULL) { 2181 free(foundextn->BERvalue.Data); 2182 foundextn->critical = critical; 2183 foundextn->BERvalue.Data = (uchar_t *)extdata->bv_val; 2184 foundextn->BERvalue.Length = extdata->bv_len; 2185 } else { 2186 ret = copy_data(&newextn.extnId, 2187 (KMF_DATA *)&KMFOID_ExtendedKeyUsage); 2188 if (ret != KMF_OK) 2189 goto out; 2190 newextn.critical = critical; 2191 newextn.format = KMF_X509_DATAFORMAT_ENCODED; 2192 newextn.BERvalue.Data = (uchar_t *)extdata->bv_val; 2193 newextn.BERvalue.Length = extdata->bv_len; 2194 ret = KMF_SetCertExtension(CertData, &newextn); 2195 if (ret != KMF_OK) 2196 free(newextn.BERvalue.Data); 2197 } 2198 2199 out: 2200 KMF_FreeEKU(&ekudata); 2201 if (extdata != NULL) 2202 free(extdata); 2203 2204 if (olddata != NULL) 2205 free(olddata); 2206 2207 if (asn1 != NULL) 2208 kmfber_free(asn1, 1); 2209 2210 if (ret != KMF_OK) 2211 KMF_FreeData(&newextn.extnId); 2212 2213 return (ret); 2214 } 2215 2216 KMF_RETURN 2217 KMF_SetCertExtension(KMF_X509_CERTIFICATE *CertData, 2218 KMF_X509_EXTENSION *extn) 2219 { 2220 KMF_RETURN ret = KMF_OK; 2221 KMF_X509_EXTENSIONS *exts; 2222 2223 if (CertData == NULL || extn == NULL) 2224 return (KMF_ERR_BAD_PARAMETER); 2225 2226 exts = &CertData->certificate.extensions; 2227 2228 ret = add_an_extension(exts, extn); 2229 2230 return (ret); 2231 } 2232 2233 KMF_RETURN 2234 KMF_SetCertBasicConstraintExt(KMF_X509_CERTIFICATE *CertData, 2235 KMF_BOOL critical, KMF_X509EXT_BASICCONSTRAINTS *constraint) 2236 { 2237 KMF_RETURN ret = KMF_OK; 2238 KMF_X509_EXTENSION extn; 2239 BerElement *asn1 = NULL; 2240 BerValue *extdata; 2241 2242 if ((CertData == NULL) || (constraint == NULL)) 2243 return (KMF_ERR_BAD_PARAMETER); 2244 2245 (void) memset(&extn, 0, sizeof (extn)); 2246 ret = copy_data(&extn.extnId, (KMF_OID *)&KMFOID_BasicConstraints); 2247 if (ret != KMF_OK) 2248 return (ret); 2249 extn.critical = critical; 2250 extn.format = KMF_X509_DATAFORMAT_ENCODED; 2251 2252 if ((asn1 = kmfder_alloc()) == NULL) 2253 return (KMF_ERR_MEMORY); 2254 2255 if (kmfber_printf(asn1, "{") == -1) { 2256 ret = KMF_ERR_ENCODING; 2257 goto out; 2258 } 2259 2260 if (kmfber_printf(asn1, "b", constraint->cA) == -1) { 2261 ret = KMF_ERR_ENCODING; 2262 goto out; 2263 } 2264 2265 if (constraint->pathLenConstraintPresent) { 2266 /* Write the pathLenConstraint value */ 2267 if (kmfber_printf(asn1, "i", 2268 constraint->pathLenConstraint) == -1) { 2269 ret = KMF_ERR_ENCODING; 2270 goto out; 2271 } 2272 } 2273 2274 if (kmfber_printf(asn1, "}") == -1) { 2275 ret = KMF_ERR_ENCODING; 2276 goto out; 2277 } 2278 2279 if (kmfber_flatten(asn1, &extdata) == -1) { 2280 ret = KMF_ERR_ENCODING; 2281 goto out; 2282 } 2283 2284 extn.BERvalue.Data = (uchar_t *)extdata->bv_val; 2285 extn.BERvalue.Length = extdata->bv_len; 2286 2287 free(extdata); 2288 ret = KMF_SetCertExtension(CertData, &extn); 2289 if (ret != KMF_OK) { 2290 free(extn.BERvalue.Data); 2291 } 2292 2293 out: 2294 if (asn1 != NULL) 2295 kmfber_free(asn1, 1); 2296 2297 return (ret); 2298 } 2299