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