Home | History | Annotate | Download | only in common
      1 /*
      2  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
      3  * Use is subject to license terms.
      4  */
      5 /*
      6  * Copyright (c) 1995-1999 Intel Corporation. All rights reserved.
      7  */
      8 
      9 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     10 
     11 #include <strings.h>
     12 #include <kmftypes.h>
     13 #include <ber_der.h>
     14 #include <kmfapi.h>
     15 #include <kmfapiP.h>
     16 
     17 #include <stdio.h>
     18 
     19 #define	DSA_RAW_SIG_LEN	40
     20 
     21 static uint8_t OID_ExtensionRequest[] = { OID_PKCS_9, 14 };
     22 const KMF_OID extension_request_oid = {OID_PKCS_9_LENGTH + 1,
     23 	OID_ExtensionRequest};
     24 
     25 static KMF_RETURN
     26 encode_algoid(BerElement *asn1, KMF_X509_ALGORITHM_IDENTIFIER *algoid)
     27 {
     28 	KMF_RETURN ret = KMF_OK;
     29 
     30 	if (kmfber_printf(asn1, "{D", &algoid->algorithm) == -1) {
     31 		ret = KMF_ERR_BAD_CERT_FORMAT;
     32 	}
     33 	if (algoid->parameters.Data == NULL ||
     34 	    algoid->parameters.Length == 0) {
     35 		if (kmfber_printf(asn1, "n}") == -1)
     36 			return (KMF_ERR_BAD_CERT_FORMAT);
     37 	} else {
     38 		/*
     39 		 * The algorithm data can be anything, so we just write it
     40 		 * straight into the buffer.  It is already DER encoded.
     41 		 */
     42 		(void) kmfber_write(asn1, (char *)algoid->parameters.Data,
     43 		    algoid->parameters.Length, 0);
     44 		if (kmfber_printf(asn1, "}") == -1) {
     45 			ret = KMF_ERR_BAD_CERT_FORMAT;
     46 		}
     47 	}
     48 
     49 	return (ret);
     50 }
     51 
     52 static void
     53 free_data(KMF_DATA *data)
     54 {
     55 	if (data == NULL || data->Data == NULL)
     56 		return;
     57 
     58 	free(data->Data);
     59 	data->Data = NULL;
     60 	data->Length = 0;
     61 }
     62 
     63 static void
     64 free_algoid(KMF_X509_ALGORITHM_IDENTIFIER *algoid)
     65 {
     66 	free_data(&algoid->algorithm);
     67 	free_data(&algoid->parameters);
     68 }
     69 
     70 static void
     71 free_decoded_spki(KMF_X509_SPKI *spki)
     72 {
     73 	if (spki != NULL) {
     74 		free_algoid(&spki->algorithm);
     75 		free_data(&spki->subjectPublicKey);
     76 	}
     77 }
     78 
     79 static void
     80 free_rdn_data(KMF_X509_NAME *name)
     81 {
     82 	KMF_X509_RDN 		*newrdn = NULL;
     83 	KMF_X509_TYPE_VALUE_PAIR *av = NULL;
     84 	int i, j;
     85 
     86 	if (name && name->numberOfRDNs) {
     87 		for (i = 0; i < name->numberOfRDNs; i++) {
     88 			newrdn = &name->RelativeDistinguishedName[i];
     89 			for (j = 0; j < newrdn->numberOfPairs; j++) {
     90 				av = &newrdn->AttributeTypeAndValue[j];
     91 				free_data(&av->type);
     92 				free_data(&av->value);
     93 			}
     94 			free(newrdn->AttributeTypeAndValue);
     95 		}
     96 		free(name->RelativeDistinguishedName);
     97 		name->numberOfRDNs = 0;
     98 		name->RelativeDistinguishedName = NULL;
     99 	}
    100 }
    101 
    102 static void
    103 free_validity(KMF_X509_VALIDITY *validity)
    104 {
    105 	free_data(&validity->notBefore.time);
    106 	free_data(&validity->notAfter.time);
    107 }
    108 
    109 static void
    110 free_one_extension(KMF_X509_EXTENSION *exptr)
    111 {
    112 	free_data(&exptr->extnId);
    113 	free_data(&exptr->BERvalue);
    114 
    115 	if (exptr->value.tagAndValue) {
    116 		free_data(&exptr->value.tagAndValue->value);
    117 		free(exptr->value.tagAndValue);
    118 	}
    119 }
    120 
    121 static void
    122 free_extensions(KMF_X509_EXTENSIONS *extns)
    123 {
    124 	int i;
    125 	KMF_X509_EXTENSION *exptr;
    126 
    127 	if (extns && extns->numberOfExtensions > 0) {
    128 		for (i = 0; i < extns->numberOfExtensions; i++) {
    129 			exptr = &extns->extensions[i];
    130 			free_one_extension(exptr);
    131 		}
    132 		free(extns->extensions);
    133 		extns->numberOfExtensions = 0;
    134 		extns->extensions = NULL;
    135 	}
    136 }
    137 
    138 static void
    139 free_tbscsr(KMF_TBS_CSR *tbscsr)
    140 {
    141 	if (tbscsr) {
    142 		free_data(&tbscsr->version);
    143 
    144 		free_rdn_data(&tbscsr->subject);
    145 
    146 		free_decoded_spki(&tbscsr->subjectPublicKeyInfo);
    147 
    148 		free_extensions(&tbscsr->extensions);
    149 	}
    150 }
    151 
    152 
    153 static void
    154 free_bigint(KMF_BIGINT *bn)
    155 {
    156 	if (bn != NULL && bn->val != NULL) {
    157 		free(bn->val);
    158 		bn->val = NULL;
    159 		bn->len = 0;
    160 	}
    161 }
    162 
    163 static void
    164 free_tbscert(KMF_X509_TBS_CERT *tbscert)
    165 {
    166 	if (tbscert) {
    167 		free_data(&tbscert->version);
    168 		free_bigint(&tbscert->serialNumber);
    169 		free_algoid(&tbscert->signature);
    170 
    171 		free_rdn_data(&tbscert->issuer);
    172 		free_rdn_data(&tbscert->subject);
    173 
    174 		free_validity(&tbscert->validity);
    175 
    176 		free_data(&tbscert->issuerUniqueIdentifier);
    177 		free_data(&tbscert->subjectUniqueIdentifier);
    178 		free_decoded_spki(&tbscert->subjectPublicKeyInfo);
    179 		free_extensions(&tbscert->extensions);
    180 
    181 		free_data(&tbscert->issuerUniqueIdentifier);
    182 		free_data(&tbscert->subjectUniqueIdentifier);
    183 	}
    184 }
    185 
    186 static void
    187 free_decoded_cert(KMF_X509_CERTIFICATE *certptr)
    188 {
    189 	if (!certptr)
    190 		return;
    191 
    192 	free_tbscert(&certptr->certificate);
    193 
    194 	free_algoid(&certptr->signature.algorithmIdentifier);
    195 	free_data(&certptr->signature.encrypted);
    196 }
    197 
    198 static KMF_RETURN
    199 get_algoid(BerElement *asn1, KMF_X509_ALGORITHM_IDENTIFIER *algoid)
    200 {
    201 	KMF_RETURN ret = KMF_OK;
    202 	ber_tag_t tag, newtag;
    203 	ber_len_t size;
    204 	BerValue AlgOID = {NULL, 0};
    205 
    206 	tag = kmfber_next_element(asn1, &size, NULL);
    207 	if (tag != BER_CONSTRUCTED_SEQUENCE)
    208 		return (KMF_ERR_BAD_CERT_FORMAT);
    209 
    210 	if ((tag = kmfber_scanf(asn1, "{Dt", &AlgOID, &newtag)) == -1) {
    211 		return (KMF_ERR_BAD_CERT_FORMAT);
    212 	}
    213 	algoid->algorithm.Data = (uchar_t *)AlgOID.bv_val;
    214 	algoid->algorithm.Length = AlgOID.bv_len;
    215 
    216 	if (newtag == BER_NULL) {
    217 		(void) kmfber_scanf(asn1, "n}");
    218 		algoid->parameters.Data = NULL;
    219 		algoid->parameters.Length = 0;
    220 	} else {
    221 		/* Peek at the tag and length bytes */
    222 		if ((kmfber_scanf(asn1, "tl", &tag, &size)) == -1) {
    223 			ret = KMF_ERR_BAD_CERT_FORMAT;
    224 			goto cleanup;
    225 		}
    226 
    227 		/*
    228 		 * We need to read the tag and the length bytes too,
    229 		 * so adjust the size.
    230 		 */
    231 		size += kmfber_calc_taglen(tag) + kmfber_calc_lenlen(size);
    232 		algoid->parameters.Data = malloc(size);
    233 		if (algoid->parameters.Data == NULL) {
    234 			ret = KMF_ERR_MEMORY;
    235 			goto cleanup;
    236 		}
    237 		/* read the raw data into the Algoritm params area. */
    238 		if (kmfber_read(asn1, (char *)algoid->parameters.Data,
    239 		    size) == -1) {
    240 			ret = KMF_ERR_BAD_CERT_FORMAT;
    241 			goto cleanup;
    242 		}
    243 		algoid->parameters.Length = size;
    244 		if ((tag = kmfber_scanf(asn1, "}")) == -1) {
    245 			ret = KMF_ERR_BAD_CERT_FORMAT;
    246 		}
    247 	}
    248 cleanup:
    249 	if (ret != KMF_OK) {
    250 		free_algoid(algoid);
    251 	}
    252 
    253 	return (ret);
    254 }
    255 
    256 static KMF_RETURN
    257 CopyData(KMF_DATA *src, KMF_DATA *dst)
    258 {
    259 	if (src && dst && src->Data != NULL && src->Length > 0) {
    260 		dst->Length = src->Length;
    261 		dst->Data = malloc(dst->Length);
    262 		if (dst->Data == NULL)
    263 			return (KMF_ERR_MEMORY);
    264 		(void) memcpy(dst->Data, src->Data, src->Length);
    265 	}
    266 	return (KMF_OK);
    267 }
    268 
    269 static KMF_RETURN
    270 encode_spki(BerElement *asn1, KMF_X509_SPKI *spki)
    271 {
    272 	KMF_RETURN ret = KMF_OK;
    273 
    274 	if (kmfber_printf(asn1, "{") == -1)
    275 		return (KMF_ERR_BAD_CERT_FORMAT);
    276 
    277 	if ((ret = encode_algoid(asn1, &spki->algorithm)) != KMF_OK)
    278 		return (ret);
    279 
    280 	if (kmfber_printf(asn1, "B}", spki->subjectPublicKey.Data,
    281 	    spki->subjectPublicKey.Length * 8) == -1)
    282 		return (KMF_ERR_BAD_CERT_FORMAT);
    283 
    284 	return (ret);
    285 }
    286 
    287 KMF_RETURN
    288 DerEncodeSPKI(KMF_X509_SPKI *spki, KMF_DATA *EncodedSPKI)
    289 {
    290 	KMF_RETURN ret = KMF_OK;
    291 	BerElement *asn1;
    292 	BerValue *result;
    293 
    294 	if (spki == NULL || EncodedSPKI == NULL)
    295 		return (KMF_ERR_BAD_PARAMETER);
    296 
    297 	if ((asn1 = kmfder_alloc()) == NULL)
    298 		return (KMF_ERR_MEMORY);
    299 
    300 	if ((ret = encode_spki(asn1, spki)) != KMF_OK) {
    301 		return (ret);
    302 	}
    303 
    304 	if (kmfber_flatten(asn1, &result) == -1) {
    305 		kmfber_free(asn1, 1);
    306 		return (KMF_ERR_ENCODING);
    307 	}
    308 
    309 	EncodedSPKI->Data = (uchar_t *)result->bv_val;
    310 	EncodedSPKI->Length = result->bv_len;
    311 
    312 	free(result);
    313 	kmfber_free(asn1, 1);
    314 	return (KMF_OK);
    315 }
    316 
    317 static KMF_RETURN
    318 get_spki(BerElement *asn1, KMF_X509_SPKI *spki)
    319 {
    320 	KMF_RETURN ret = KMF_OK;
    321 	char *bitstr = NULL;
    322 	ber_len_t size;
    323 
    324 	if (kmfber_scanf(asn1, "{") == -1)
    325 		return (KMF_ERR_BAD_CERT_FORMAT);
    326 
    327 	if ((ret = get_algoid(asn1, &spki->algorithm)) != KMF_OK)
    328 		return (ret);
    329 
    330 	if (kmfber_scanf(asn1, "B}", &bitstr, &size) == BER_BIT_STRING) {
    331 		spki->subjectPublicKey.Data = (uchar_t *)bitstr;
    332 		spki->subjectPublicKey.Length = size / 8;
    333 	} else {
    334 		ret = KMF_ERR_BAD_CERT_FORMAT;
    335 		goto cleanup;
    336 	}
    337 cleanup:
    338 	if (ret != KMF_OK) {
    339 		if (bitstr != NULL)
    340 			free(bitstr);
    341 		spki->subjectPublicKey.Data = NULL;
    342 		spki->subjectPublicKey.Length = 0;
    343 
    344 		free_algoid(&spki->algorithm);
    345 	}
    346 	return (ret);
    347 }
    348 
    349 KMF_RETURN
    350 DerEncodeDSASignature(KMF_DATA *rawdata, KMF_DATA *signature)
    351 {
    352 	BerElement *asn1;
    353 	BerValue *buf;
    354 	int n;
    355 
    356 	if (rawdata == NULL || signature == NULL)
    357 		return (KMF_ERR_BAD_PARAMETER);
    358 
    359 	if (rawdata->Data == NULL || rawdata->Length != DSA_RAW_SIG_LEN)
    360 		return (KMF_ERR_BAD_PARAMETER);
    361 
    362 	asn1 = kmfder_alloc();
    363 	if (asn1 == NULL)
    364 		return (KMF_ERR_MEMORY);
    365 
    366 	/*
    367 	 * The DSA signature is the concatenation of 2 SHA-1 hashed
    368 	 * bignum values.
    369 	 */
    370 	n = DSA_RAW_SIG_LEN/2;
    371 	if (kmfber_printf(asn1, "{II}",
    372 	    rawdata->Data, n, &rawdata->Data[n], n) == -1) {
    373 		kmfber_free(asn1, 1);
    374 		return (KMF_ERR_MEMORY);
    375 	}
    376 
    377 	if (kmfber_flatten(asn1, &buf) == -1) {
    378 		kmfber_free(asn1, 1);
    379 		return (KMF_ERR_ENCODING);
    380 	}
    381 
    382 	signature->Data = (uchar_t *)buf->bv_val;
    383 	signature->Length = buf->bv_len;
    384 
    385 	kmfber_free(asn1, 1);
    386 	free(buf);
    387 
    388 	return (KMF_OK);
    389 }
    390 
    391 KMF_RETURN
    392 DerDecodeDSASignature(KMF_DATA *encoded, KMF_DATA *signature)
    393 {
    394 	KMF_RETURN ret = KMF_OK;
    395 	BerElement *asn1 = NULL;
    396 	BerValue buf, *R = NULL, *S = NULL;
    397 
    398 	buf.bv_val = (char *)encoded->Data;
    399 	buf.bv_len = encoded->Length;
    400 
    401 	if (encoded == NULL || encoded->Data == NULL ||
    402 	    signature == NULL)
    403 		return (KMF_ERR_BAD_PARAMETER);
    404 
    405 	signature->Data = NULL;
    406 	signature->Length = 0;
    407 
    408 	if ((asn1 = kmfder_init(&buf)) == NULL)
    409 		return (KMF_ERR_MEMORY);
    410 
    411 	if (kmfber_scanf(asn1, "{II}", &R, &S) == -1) {
    412 		ret = KMF_ERR_BAD_PARAMETER;
    413 		goto cleanup;
    414 	}
    415 	signature->Length = R->bv_len + S->bv_len;
    416 	signature->Data = malloc(signature->Length);
    417 	if (signature->Data == NULL)  {
    418 		ret = KMF_ERR_MEMORY;
    419 		goto cleanup;
    420 	}
    421 	(void) memcpy(signature->Data, R->bv_val, R->bv_len);
    422 	(void) memcpy(&signature->Data[R->bv_len], S->bv_val, S->bv_len);
    423 
    424 cleanup:
    425 	if (R && R->bv_val)
    426 		free(R->bv_val);
    427 	if (S && S->bv_val)
    428 		free(S->bv_val);
    429 
    430 	if (S) free(S);
    431 	if (R) free(R);
    432 
    433 	if (asn1) kmfber_free(asn1, 1);
    434 
    435 	return (ret);
    436 }
    437 
    438 KMF_RETURN
    439 DerDecodeSPKI(KMF_DATA *EncodedSPKI, KMF_X509_SPKI *spki)
    440 {
    441 	KMF_RETURN ret = KMF_OK;
    442 	BerElement *asn1;
    443 	BerValue bv;
    444 
    445 	if (EncodedSPKI == NULL || EncodedSPKI->Data == NULL ||
    446 	    spki == NULL)
    447 		return (KMF_ERR_BAD_PARAMETER);
    448 
    449 	(void) memset(spki, 0, sizeof (KMF_X509_SPKI));
    450 
    451 	bv.bv_val = (char *)EncodedSPKI->Data;
    452 	bv.bv_len = EncodedSPKI->Length;
    453 
    454 	if ((asn1 = kmfder_init(&bv)) == NULL)
    455 		return (KMF_ERR_MEMORY);
    456 
    457 	ret = get_spki(asn1, spki);
    458 
    459 cleanup:
    460 	if (ret != KMF_OK) {
    461 		free_decoded_spki(spki);
    462 	}
    463 	kmfber_free(asn1, 1);
    464 
    465 	return (ret);
    466 }
    467 
    468 KMF_RETURN
    469 CopySPKI(KMF_X509_SPKI *src,
    470 		KMF_X509_SPKI **dest)
    471 {
    472 	KMF_RETURN ret = KMF_OK;
    473 	KMF_X509_SPKI *newspki;
    474 
    475 	*dest = NULL;
    476 
    477 	newspki = malloc(sizeof (KMF_X509_SPKI));
    478 	if (newspki == NULL)
    479 		return (KMF_ERR_MEMORY);
    480 	(void) memset(newspki, 0, sizeof (KMF_X509_SPKI));
    481 
    482 	ret = CopyData(&src->algorithm.algorithm,
    483 	    &newspki->algorithm.algorithm);
    484 	if (ret != KMF_OK)
    485 		goto cleanup;
    486 
    487 	ret = CopyData(&src->algorithm.parameters,
    488 	    &newspki->algorithm.parameters);
    489 	if (ret != KMF_OK)
    490 		goto cleanup;
    491 
    492 	ret = CopyData(&src->subjectPublicKey,
    493 	    &newspki->subjectPublicKey);
    494 	if (ret != KMF_OK)
    495 		goto cleanup;
    496 
    497 	*dest = newspki;
    498 cleanup:
    499 	if (ret != KMF_OK) {
    500 		if (newspki)
    501 			free_decoded_spki(newspki);
    502 	}
    503 	return (ret);
    504 }
    505 
    506 static KMF_RETURN
    507 encode_validity(BerElement *asn1, KMF_X509_VALIDITY *validity)
    508 {
    509 	int ret;
    510 
    511 	ret = kmfber_printf(asn1, "{tsts}",
    512 	    validity->notBefore.timeType,
    513 	    validity->notBefore.time.Data,
    514 	    validity->notAfter.timeType,
    515 	    validity->notAfter.time.Data);
    516 
    517 	if (ret == -1)
    518 		return (KMF_ERR_BAD_CERT_FORMAT);
    519 
    520 	return (KMF_OK);
    521 }
    522 
    523 static KMF_RETURN
    524 get_validity(BerElement *asn1, KMF_X509_VALIDITY *validity)
    525 {
    526 	KMF_RETURN ret = KMF_OK;
    527 	int tag;
    528 	int t1, t2;
    529 	ber_len_t size;
    530 	char *t1str, *t2str;
    531 
    532 	(void) memset(validity, 0, sizeof (KMF_X509_VALIDITY));
    533 
    534 	tag = kmfber_next_element(asn1, &size, NULL);
    535 	if (tag != BER_CONSTRUCTED_SEQUENCE) {
    536 		return (KMF_ERR_BAD_CERT_FORMAT);
    537 	}
    538 
    539 	if (kmfber_scanf(asn1, "{tata}", &t1, &t1str, &t2, &t2str) == -1) {
    540 		return (KMF_ERR_BAD_CERT_FORMAT);
    541 	}
    542 
    543 	validity->notBefore.timeType = t1;
    544 	validity->notBefore.time.Data = (uchar_t *)t1str;
    545 	validity->notBefore.time.Length = strlen(t1str);
    546 
    547 	validity->notAfter.timeType = t2;
    548 	validity->notAfter.time.Data = (uchar_t *)t2str;
    549 	validity->notAfter.time.Length = strlen(t2str);
    550 
    551 	return (ret);
    552 }
    553 
    554 KMF_RETURN
    555 AddRDN(KMF_X509_NAME *name, KMF_X509_RDN *newrdn)
    556 {
    557 	KMF_RETURN ret = KMF_OK;
    558 	KMF_X509_RDN *rdnslot = NULL;
    559 
    560 	/* Add new RDN record to existing list */
    561 	name->numberOfRDNs++;
    562 	name->RelativeDistinguishedName =
    563 	    realloc(name->RelativeDistinguishedName,
    564 	    name->numberOfRDNs * sizeof (KMF_X509_RDN));
    565 
    566 	if (name->RelativeDistinguishedName == NULL) {
    567 		ret = KMF_ERR_MEMORY;
    568 		goto cleanup;
    569 	}
    570 	rdnslot = &name->RelativeDistinguishedName[name->numberOfRDNs-1];
    571 
    572 	if (newrdn) {
    573 		(void) memcpy(rdnslot, newrdn, sizeof (KMF_X509_RDN));
    574 	} else {
    575 		rdnslot->numberOfPairs = 0;
    576 		rdnslot->AttributeTypeAndValue = NULL;
    577 	}
    578 
    579 cleanup:
    580 	/* No cleanup needed here */
    581 	return (ret);
    582 }
    583 
    584 static KMF_RETURN
    585 encode_rdn(BerElement *asn1, KMF_X509_NAME *name)
    586 {
    587 	KMF_RETURN ret = KMF_OK;
    588 	KMF_X509_TYPE_VALUE_PAIR *attrtvpair = NULL;
    589 	int i;
    590 	KMF_X509_RDN *rdn;
    591 
    592 	if (kmfber_printf(asn1, "{") == -1) {
    593 		ret = KMF_ERR_MEMORY;
    594 		goto cleanup;
    595 	}
    596 
    597 	for (i = 0; i < name->numberOfRDNs; i++) {
    598 		if (kmfber_printf(asn1, "[") == -1) {
    599 			ret = KMF_ERR_MEMORY;
    600 			goto cleanup;
    601 		}
    602 		rdn = &name->RelativeDistinguishedName[i];
    603 		attrtvpair = rdn->AttributeTypeAndValue;
    604 
    605 		if (rdn->numberOfPairs > 0) {
    606 			if (kmfber_printf(asn1, "{Dto}",
    607 			    &attrtvpair->type,
    608 			    attrtvpair->valueType,
    609 			    attrtvpair->value.Data,
    610 			    attrtvpair->value.Length) == -1) {
    611 				ret = KMF_ERR_MEMORY;
    612 				goto cleanup;
    613 			}
    614 		}
    615 		if (kmfber_printf(asn1, "]") == -1) {
    616 			ret = KMF_ERR_MEMORY;
    617 			goto cleanup;
    618 		}
    619 	}
    620 
    621 	if (kmfber_printf(asn1, "}") == -1) {
    622 		ret = KMF_ERR_MEMORY;
    623 		goto cleanup;
    624 	}
    625 
    626 cleanup:
    627 	/* No cleanup needed here */
    628 
    629 	return (ret);
    630 }
    631 
    632 
    633 KMF_RETURN
    634 CopyRDN(KMF_X509_NAME *srcname, KMF_X509_NAME **destname)
    635 {
    636 	KMF_RETURN ret = KMF_OK;
    637 	KMF_X509_NAME 		*newname = NULL;
    638 	KMF_X509_RDN 		*rdn, *dstrdn;
    639 	KMF_X509_TYPE_VALUE_PAIR *av = NULL;
    640 	KMF_X509_TYPE_VALUE_PAIR *srcav = NULL;
    641 	KMF_X509_TYPE_VALUE_PAIR *dstav = NULL;
    642 	int i, j;
    643 
    644 	newname = malloc(sizeof (KMF_X509_NAME));
    645 	if (newname == NULL)
    646 		return (KMF_ERR_MEMORY);
    647 	(void) memset(newname, 0, sizeof (KMF_X509_NAME));
    648 
    649 	newname->numberOfRDNs = srcname->numberOfRDNs;
    650 	newname->RelativeDistinguishedName = malloc(newname->numberOfRDNs *
    651 	    sizeof (KMF_X509_RDN));
    652 	if (newname->RelativeDistinguishedName == NULL) {
    653 		free(newname);
    654 		return (KMF_ERR_MEMORY);
    655 	}
    656 	/* Copy each RDN in the list */
    657 	for (i = 0; i < newname->numberOfRDNs; i++) {
    658 		rdn = &srcname->RelativeDistinguishedName[i];
    659 
    660 		dstrdn = &newname->RelativeDistinguishedName[i];
    661 		(void) memset(dstrdn, 0, sizeof (KMF_X509_RDN));
    662 
    663 		dstrdn->numberOfPairs = rdn->numberOfPairs;
    664 		if (dstrdn->numberOfPairs > 0) {
    665 			av = malloc(dstrdn->numberOfPairs *
    666 			    sizeof (KMF_X509_TYPE_VALUE_PAIR));
    667 			if (av == NULL) {
    668 				ret = KMF_ERR_MEMORY;
    669 				goto cleanup;
    670 			}
    671 			(void) memset(av, 0, dstrdn->numberOfPairs *
    672 			    sizeof (KMF_X509_TYPE_VALUE_PAIR));
    673 
    674 			dstrdn->AttributeTypeAndValue = av;
    675 			if (av == NULL) {
    676 				ret = KMF_ERR_MEMORY;
    677 				goto cleanup;
    678 			}
    679 			/* Copy each A/V pair in the list */
    680 			for (j = 0; j < dstrdn->numberOfPairs; j++) {
    681 				srcav = &rdn->AttributeTypeAndValue[j];
    682 				dstav = &dstrdn->AttributeTypeAndValue[j];
    683 				if ((ret = CopyData(&srcav->type,
    684 				    &dstav->type)) != KMF_OK)
    685 					goto cleanup;
    686 				dstav->valueType = srcav->valueType;
    687 				if ((ret = CopyData(&srcav->value,
    688 				    &dstav->value)) != KMF_OK)
    689 					goto cleanup;
    690 			}
    691 		} else {
    692 			dstrdn->AttributeTypeAndValue = NULL;
    693 		}
    694 	}
    695 	*destname = newname;
    696 
    697 cleanup:
    698 	if (ret != KMF_OK) {
    699 		if (newname)
    700 			free_rdn_data(newname);
    701 
    702 		free(newname);
    703 		*destname = NULL;
    704 	}
    705 	return (ret);
    706 }
    707 
    708 #define	VALID_DIRECTORYSTRING_TAG(t) ( \
    709 	(t == BER_UTF8_STRING) || \
    710 	(t == BER_PRINTABLE_STRING) || \
    711 	(t == BER_IA5STRING) || \
    712 	(t == BER_T61STRING) || \
    713 	(t == BER_BMP_STRING) || \
    714 	(t == BER_UNIVERSAL_STRING))
    715 
    716 static KMF_RETURN
    717 get_rdn(BerElement *asn1, KMF_X509_NAME *name)
    718 {
    719 	KMF_RETURN ret = KMF_OK;
    720 	ber_len_t size;
    721 	char *end;
    722 	int tag;
    723 	BerValue AttrOID;
    724 	char *AttrValue = NULL;
    725 	KMF_X509_TYPE_VALUE_PAIR *newpair = NULL;
    726 	KMF_X509_RDN 		newrdn;
    727 
    728 	/*
    729 	 * AttributeType	::=  OBJECT IDENTIFIER
    730 	 * AttributeValue	::=  ANY
    731 	 *
    732 	 * AttributeTypeAndValue	::=  SEQUENCE {
    733 	 *	type    AttributeType,
    734 	 *	value   AttributeValue }
    735 	 *
    736 	 * Name ::= CHOICE { -- only one possibility for now --
    737 	 * 		rdnSequence  RDNSequence }
    738 	 *
    739 	 * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
    740 	 *
    741 	 * DistinguishedName ::=   RDNSequence
    742 	 *
    743 	 * RelativeDistinguishedName  ::=
    744 	 *		 SET SIZE (1 .. MAX) OF AttributeTypeAndValue
    745 	 *
    746 	 */
    747 
    748 	name->numberOfRDNs = 0;
    749 	name->RelativeDistinguishedName = NULL;
    750 
    751 	/* Get the beginning of the RDN Set and a ptr to the end */
    752 	tag = kmfber_first_element(asn1, &size, &end);
    753 	if (tag != BER_CONSTRUCTED_SET) {
    754 		goto cleanup;
    755 	}
    756 
    757 	/* Walk through the individual SET items until the "end" is reached */
    758 	while ((tag = kmfber_next_element(asn1, &size, end)) ==
    759 	    BER_CONSTRUCTED_SET) {
    760 		/* Skip over the SET tag */
    761 		if (kmfber_scanf(asn1, "T", &tag) == -1) {
    762 			ret = KMF_ERR_BAD_CERT_FORMAT;
    763 			break;
    764 		}
    765 
    766 		/* An "empty" set member means we tack on an empty node */
    767 		if (size == 0) {
    768 			if ((ret = AddRDN(name, NULL)) != KMF_OK)
    769 				goto cleanup;
    770 			continue;
    771 		}
    772 
    773 		/* Attr OID and peek at the next tag and field length */
    774 		if (kmfber_scanf(asn1, "{Dtl", &AttrOID, &tag, &size) == -1) {
    775 			ret = KMF_ERR_BAD_CERT_FORMAT;
    776 			break;
    777 		}
    778 
    779 		if (!(VALID_DIRECTORYSTRING_TAG(tag))) {
    780 			ret = KMF_ERR_BAD_CERT_FORMAT;
    781 			break;
    782 		}
    783 
    784 		if (kmfber_scanf(asn1, "a}]", &AttrValue) == -1) {
    785 			ret = KMF_ERR_BAD_CERT_FORMAT;
    786 			break;
    787 		}
    788 
    789 		/* Allocate a new name/value pair record */
    790 		newpair = malloc(sizeof (KMF_X509_TYPE_VALUE_PAIR));
    791 		if (newpair == NULL) {
    792 			ret = KMF_ERR_MEMORY;
    793 			break;
    794 		}
    795 		(void) memset(newpair, 0, sizeof (KMF_X509_TYPE_VALUE_PAIR));
    796 		newpair->type.Data = (uchar_t *)AttrOID.bv_val;
    797 		newpair->type.Length = AttrOID.bv_len;
    798 		newpair->valueType = tag; /* what kind of string is it? */
    799 		newpair->value.Data = (uchar_t *)AttrValue;
    800 		newpair->value.Length = strlen(AttrValue);
    801 
    802 		(void) memset(&newrdn, 0, sizeof (KMF_X509_RDN));
    803 		newrdn.numberOfPairs = 1;
    804 		newrdn.AttributeTypeAndValue = newpair;
    805 
    806 		if ((ret = AddRDN(name, &newrdn)) != KMF_OK)
    807 			break;
    808 	}
    809 
    810 cleanup:
    811 	if (ret != KMF_OK) {
    812 		free_rdn_data(name);
    813 	}
    814 	return (ret);
    815 }
    816 
    817 static KMF_RETURN
    818 set_der_integer(KMF_DATA *data, int value)
    819 {
    820 	if (data == NULL)
    821 		return (KMF_ERR_BAD_PARAMETER);
    822 
    823 	data->Data = malloc(sizeof (int));
    824 	if (data->Data == NULL)
    825 		return (KMF_ERR_MEMORY);
    826 
    827 	data->Length = sizeof (int);
    828 	(void) memcpy((void *)data->Data, (const void *)&value, sizeof (int));
    829 
    830 	return (KMF_OK);
    831 }
    832 
    833 static KMF_RETURN
    834 set_bigint(KMF_BIGINT *data, KMF_BIGINT *bigint)
    835 {
    836 	if (data == NULL || bigint == NULL)
    837 		return (KMF_ERR_BAD_PARAMETER);
    838 
    839 	data->val = malloc(bigint->len);
    840 	if (data->val == NULL)
    841 		return (KMF_ERR_MEMORY);
    842 
    843 	data->len = bigint->len;
    844 	(void) memcpy((void *)data->val, (const void *)bigint->val,
    845 	    bigint->len);
    846 
    847 	return (KMF_OK);
    848 }
    849 
    850 static KMF_RETURN
    851 encode_uniqueid(BerElement *asn1, int tag, KMF_DATA *id)
    852 {
    853 	KMF_RETURN ret = KMF_OK;
    854 	uint32_t len;
    855 
    856 	len = kmfber_calc_taglen(BER_BIT_STRING) +
    857 	    kmfber_calc_lenlen(id->Length * 8) + id->Length;
    858 	if (kmfber_printf(asn1, "TlB", tag, len,
    859 	    id->Data, id->Length * 8) == -1)
    860 		return (KMF_ERR_BAD_CERT_FORMAT);
    861 
    862 	return (ret);
    863 }
    864 
    865 static KMF_RETURN
    866 encode_extension_list(BerElement *asn1, KMF_X509_EXTENSIONS *extns)
    867 {
    868 	KMF_RETURN ret = KMF_OK;
    869 	int i;
    870 
    871 	for (i = 0; i < extns->numberOfExtensions; i++) {
    872 		BerValue v;
    873 		v.bv_val = (char *)extns->extensions[i].extnId.Data;
    874 		v.bv_len = extns->extensions[i].extnId.Length;
    875 
    876 		if (kmfber_printf(asn1, "{D", &v) == -1)  {
    877 			ret = KMF_ERR_ENCODING;
    878 			goto cleanup;
    879 		}
    880 
    881 		if (extns->extensions[i].critical) {
    882 			if (kmfber_printf(asn1, "b",
    883 			    extns->extensions[i].critical) == -1) {
    884 				ret = KMF_ERR_ENCODING;
    885 				goto cleanup;
    886 			}
    887 		}
    888 
    889 		if (kmfber_printf(asn1, "o}",
    890 		    extns->extensions[i].BERvalue.Data,
    891 		    extns->extensions[i].BERvalue.Length) == -1) {
    892 			ret = KMF_ERR_ENCODING;
    893 			goto cleanup;
    894 		}
    895 	}
    896 cleanup:
    897 	return (ret);
    898 }
    899 
    900 static KMF_RETURN
    901 encode_extensions(BerElement *asn1, KMF_X509_EXTENSIONS *extns)
    902 {
    903 	KMF_RETURN ret = KMF_OK;
    904 	BerElement *extn = NULL;
    905 	BerValue *extnvalue = NULL;
    906 
    907 	extn = kmfder_alloc();
    908 	if (extn == NULL)
    909 		return (KMF_ERR_MEMORY);
    910 
    911 	if (kmfber_printf(extn, "{") == -1) {
    912 		ret = KMF_ERR_ENCODING;
    913 		goto cleanup;
    914 	}
    915 
    916 	ret = encode_extension_list(extn, extns);
    917 
    918 	if (kmfber_printf(extn, "}") == -1) {
    919 		ret = KMF_ERR_ENCODING;
    920 		goto cleanup;
    921 	}
    922 
    923 	if (kmfber_flatten(extn, &extnvalue) == -1) {
    924 		ret = KMF_ERR_MEMORY;
    925 		goto cleanup;
    926 	}
    927 
    928 	if (kmfber_printf(asn1, "Tl", 0xA3, extnvalue->bv_len) == -1) {
    929 		ret = KMF_ERR_BAD_CERT_FORMAT;
    930 		goto cleanup;
    931 	}
    932 
    933 	if (kmfber_write(asn1, extnvalue->bv_val, extnvalue->bv_len, 0) == -1) {
    934 		ret = KMF_ERR_BAD_CERT_FORMAT;
    935 		goto cleanup;
    936 	}
    937 
    938 cleanup:
    939 	kmfber_free(extn, 1);
    940 	if (extnvalue != NULL)
    941 		kmfber_bvfree(extnvalue);
    942 
    943 	return (ret);
    944 }
    945 
    946 static KMF_RETURN
    947 get_one_extension(BerElement *asn1, KMF_X509_EXTENSION **retex, char *end)
    948 {
    949 	KMF_RETURN ret = KMF_OK;
    950 	ber_len_t size;
    951 	int  critical, tag;
    952 	KMF_X509_EXTENSION *ex = NULL;
    953 	BerValue extOID;
    954 	BerValue extValue;
    955 	BerElement *extnber = NULL;
    956 
    957 	if (kmfber_scanf(asn1, "T", &tag) == -1) {
    958 		ret = KMF_ERR_BAD_CERT_FORMAT;
    959 		goto cleanup;
    960 	}
    961 
    962 	tag = kmfber_next_element(asn1, &size, end);
    963 	if (tag != BER_OBJECT_IDENTIFIER) {
    964 		ret = KMF_ERR_BAD_CERT_FORMAT;
    965 		goto cleanup;
    966 	}
    967 	if (kmfber_scanf(asn1, "D", &extOID) == -1) {
    968 		ret = KMF_ERR_BAD_CERT_FORMAT;
    969 		goto cleanup;
    970 	}
    971 
    972 	tag = kmfber_next_element(asn1, &size, end);
    973 	if (tag != BER_BOOLEAN) {
    974 		critical = 0;
    975 		if (tag != BER_OCTET_STRING)
    976 			goto cleanup;
    977 	} else {
    978 		if (kmfber_scanf(asn1, "b", &critical) == -1)
    979 			goto cleanup;
    980 	}
    981 
    982 	tag = kmfber_next_element(asn1, &size, end);
    983 	if (tag != BER_OCTET_STRING)  {
    984 		ret = KMF_ERR_BAD_CERT_FORMAT;
    985 		goto cleanup;
    986 	}
    987 	if (kmfber_scanf(asn1, "o", &extValue) == -1)  {
    988 		ret = KMF_ERR_BAD_CERT_FORMAT;
    989 		goto cleanup;
    990 	}
    991 
    992 	/* allocate a new Extension record */
    993 	ex = malloc(sizeof (KMF_X509_EXTENSION));
    994 	if (ex == NULL) {
    995 		ret = KMF_ERR_MEMORY;
    996 		goto cleanup;
    997 	}
    998 	(void) memset(ex, 0, sizeof (ex));
    999 
   1000 	ex->extnId.Data = (uchar_t *)extOID.bv_val;
   1001 	ex->extnId.Length = extOID.bv_len;
   1002 	ex->critical = critical;
   1003 	ex->format = KMF_X509_DATAFORMAT_ENCODED;
   1004 	ex->BERvalue.Data = (uchar_t *)extValue.bv_val;
   1005 	ex->BERvalue.Length = extValue.bv_len;
   1006 
   1007 	/* Tag and value is a little tricky */
   1008 	ex->value.tagAndValue = malloc(sizeof (KMF_X509EXT_TAGandVALUE));
   1009 	if (ex->value.tagAndValue == NULL) {
   1010 		ret = KMF_ERR_MEMORY;
   1011 		goto cleanup;
   1012 	}
   1013 	(void) memset(ex->value.tagAndValue, 0,
   1014 	    sizeof (KMF_X509EXT_TAGandVALUE));
   1015 
   1016 	/* Parse the Extension value field */
   1017 	extnber = kmfder_init(&extValue);
   1018 	if (extnber == NULL) {
   1019 		ret = KMF_ERR_MEMORY;
   1020 		goto cleanup;
   1021 	}
   1022 
   1023 	/* Get the tag and length of the extension field */
   1024 	if (kmfber_scanf(extnber, "tl", &tag, &size) == -1) {
   1025 		ret = KMF_ERR_BAD_CERT_FORMAT;
   1026 		goto cleanup;
   1027 	}
   1028 
   1029 	if (kmfber_scanf(extnber, "T", &tag) == -1) {
   1030 		ret = KMF_ERR_BAD_CERT_FORMAT;
   1031 		goto cleanup;
   1032 	}
   1033 
   1034 	ex->value.tagAndValue->value.Data = malloc(size);
   1035 	ex->value.tagAndValue->value.Length = size;
   1036 	size = kmfber_read(extnber,
   1037 	    (char *)ex->value.tagAndValue->value.Data, size);
   1038 	if (size != ex->value.tagAndValue->value.Length) {
   1039 		ret = KMF_ERR_BAD_CERT_FORMAT;
   1040 		goto cleanup;
   1041 	}
   1042 	kmfber_free(extnber, 1);
   1043 	ex->value.tagAndValue->type = tag;
   1044 
   1045 	*retex = ex;
   1046 cleanup:
   1047 	if (ret != KMF_OK) {
   1048 		if (ex != NULL)
   1049 			free_one_extension(ex);
   1050 	}
   1051 
   1052 	return (ret);
   1053 }
   1054 
   1055 static KMF_RETURN
   1056 get_extensions(BerElement *asn1, KMF_X509_EXTENSIONS *extns)
   1057 {
   1058 	KMF_RETURN ret = KMF_OK;
   1059 	ber_len_t size;
   1060 	char *end = NULL;
   1061 	KMF_X509_EXTENSION *ex = NULL;
   1062 
   1063 	/*
   1064 	 * Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
   1065 	 *
   1066 	 * Extension  ::=  SEQUENCE  {
   1067 	 *	extnID		OBJECT IDENTIFIER,
   1068 	 *	critical	BOOLEAN DEFAULT FALSE,
   1069 	 *	extnValue	OCTET STRING  }
   1070 	 *
   1071 	 * { {{D}Bo}, ... }
   1072 	 */
   1073 	if (kmfber_first_element(asn1, &size, &end) !=
   1074 	    BER_CONSTRUCTED_SEQUENCE)
   1075 		return (KMF_ERR_BAD_CERT_FORMAT);
   1076 
   1077 	while (kmfber_next_element(asn1, &size, end) ==
   1078 	    BER_CONSTRUCTED_SEQUENCE) {
   1079 		ret = get_one_extension(asn1, &ex, end);
   1080 		if (ret != KMF_OK)
   1081 			goto cleanup;
   1082 
   1083 		extns->numberOfExtensions++;
   1084 		extns->extensions = realloc(extns->extensions,
   1085 		    extns->numberOfExtensions *
   1086 		    sizeof (KMF_X509_EXTENSION));
   1087 		if (extns->extensions == NULL) {
   1088 			ret = KMF_ERR_MEMORY;
   1089 			break;
   1090 		}
   1091 
   1092 		extns->extensions[extns->numberOfExtensions-1] = *ex;
   1093 		free(ex);
   1094 	}
   1095 
   1096 cleanup:
   1097 	if (ret != KMF_OK)
   1098 		free_extensions(extns);
   1099 
   1100 	return (ret);
   1101 }
   1102 
   1103 KMF_RETURN
   1104 decode_tbscert_data(BerElement *asn1,
   1105 	KMF_X509_TBS_CERT **signed_cert_ptr_ptr)
   1106 {
   1107 	KMF_RETURN ret = KMF_OK;
   1108 	KMF_X509_TBS_CERT	*tbscert = NULL;
   1109 	int tag, version;
   1110 	struct berval *bvserno = NULL;
   1111 	KMF_BIGINT serno;
   1112 
   1113 	if (kmfber_scanf(asn1, "{t", &tag) == -1) {
   1114 		ret = KMF_ERR_BAD_CERT_FORMAT;
   1115 		goto cleanup;
   1116 	}
   1117 
   1118 	/* Version number is optional */
   1119 	if (tag == 0xA0) {
   1120 		if (kmfber_scanf(asn1, "Ti", &tag, &version) == -1) {
   1121 			ret = KMF_ERR_BAD_CERT_FORMAT;
   1122 			goto cleanup;
   1123 		}
   1124 	} else {
   1125 		version = 0; /* DEFAULT v1 (0) */
   1126 	}
   1127 
   1128 	/* Now get the serial number, it is not optional */
   1129 	if (kmfber_scanf(asn1, "I", &bvserno) == -1) {
   1130 		ret = KMF_ERR_BAD_CERT_FORMAT;
   1131 		goto cleanup;
   1132 	} else {
   1133 		serno.val = (uchar_t *)bvserno->bv_val;
   1134 		serno.len = bvserno->bv_len;
   1135 	}
   1136 
   1137 	tbscert = malloc(sizeof (KMF_X509_TBS_CERT));
   1138 	if (!tbscert) {
   1139 		ret = KMF_ERR_MEMORY;
   1140 		goto cleanup;
   1141 	}
   1142 
   1143 	(void) memset(tbscert, 0, sizeof (KMF_X509_TBS_CERT));
   1144 
   1145 	if ((ret = set_der_integer(&tbscert->version, version)) != KMF_OK)
   1146 		goto cleanup;
   1147 
   1148 	if ((ret = set_bigint(&tbscert->serialNumber, &serno)) != KMF_OK)
   1149 		goto cleanup;
   1150 
   1151 	if ((ret = get_algoid(asn1, &tbscert->signature)) != KMF_OK)
   1152 		goto cleanup;
   1153 
   1154 	if ((ret = get_rdn(asn1, &tbscert->issuer)) != KMF_OK)
   1155 		goto cleanup;
   1156 
   1157 	if ((ret = get_validity(asn1, &tbscert->validity)) != KMF_OK)
   1158 		goto cleanup;
   1159 
   1160 	if ((ret = get_rdn(asn1, &tbscert->subject)) != KMF_OK)
   1161 		goto cleanup;
   1162 
   1163 	if ((ret = get_spki(asn1, &tbscert->subjectPublicKeyInfo)) != KMF_OK)
   1164 		goto cleanup;
   1165 
   1166 	/* Check for the optional fields */
   1167 	tbscert->extensions.numberOfExtensions = 0;
   1168 	tbscert->extensions.extensions = NULL;
   1169 
   1170 	while ((kmfber_scanf(asn1, "t", &tag)) != -1 &&
   1171 	    (tag == 0xA1 || tag == 0xA2 || tag == 0xA3)) {
   1172 		char *optfield;
   1173 		ber_len_t len;
   1174 
   1175 		/* consume the tag and length */
   1176 		(void) kmfber_scanf(asn1, "T", &tag);
   1177 		switch (tag) {
   1178 			case 0xA1:
   1179 				if (kmfber_scanf(asn1, "B", &optfield, &len) !=
   1180 				    BER_BIT_STRING) {
   1181 					ret = KMF_ERR_BAD_CERT_FORMAT;
   1182 					goto cleanup;
   1183 				}
   1184 				tbscert->issuerUniqueIdentifier.Data =
   1185 				    (uchar_t *)optfield;
   1186 				tbscert->issuerUniqueIdentifier.Length =
   1187 				    len / 8;
   1188 				break;
   1189 			case 0xA2:
   1190 				if (kmfber_scanf(asn1, "B", &optfield, &len) !=
   1191 				    BER_BIT_STRING) {
   1192 					ret = KMF_ERR_BAD_CERT_FORMAT;
   1193 					goto cleanup;
   1194 				}
   1195 				tbscert->subjectUniqueIdentifier.Data =
   1196 				    (uchar_t *)optfield;
   1197 				tbscert->subjectUniqueIdentifier.Length =
   1198 				    len / 8;
   1199 				break;
   1200 			case 0xA3:
   1201 			ret = get_extensions(asn1, &tbscert->extensions);
   1202 			break;
   1203 		}
   1204 	}
   1205 
   1206 	*signed_cert_ptr_ptr = tbscert;
   1207 
   1208 cleanup:
   1209 	if (bvserno != NULL) {
   1210 		free(bvserno->bv_val);
   1211 		free(bvserno);
   1212 	}
   1213 	if (ret != KMF_OK) {
   1214 		if (tbscert) {
   1215 			free_tbscert(tbscert);
   1216 			free(tbscert);
   1217 		}
   1218 		*signed_cert_ptr_ptr = NULL;
   1219 	}
   1220 	return (ret);
   1221 }
   1222 
   1223 KMF_RETURN
   1224 DerDecodeTbsCertificate(const KMF_DATA *Value,
   1225 	KMF_X509_TBS_CERT **tbscert)
   1226 {
   1227 	KMF_RETURN ret = KMF_OK;
   1228 	BerElement *asn1 = NULL;
   1229 	BerValue 	rawcert;
   1230 	KMF_X509_TBS_CERT *newcert = NULL;
   1231 
   1232 	if (!tbscert || !Value || !Value->Data || !Value->Length)
   1233 		return (KMF_ERR_BAD_PARAMETER);
   1234 
   1235 	rawcert.bv_val = (char *)Value->Data;
   1236 	rawcert.bv_len = Value->Length;
   1237 
   1238 	if ((asn1 = kmfder_init(&rawcert)) == NULL)
   1239 		return (KMF_ERR_MEMORY);
   1240 
   1241 	ret = decode_tbscert_data(asn1, &newcert);
   1242 	if (ret != KMF_OK)
   1243 		goto cleanup;
   1244 
   1245 	*tbscert = newcert;
   1246 
   1247 cleanup:
   1248 	if (ret != KMF_OK) {
   1249 		if (newcert)
   1250 			free_tbscert(newcert);
   1251 		*tbscert = NULL;
   1252 	}
   1253 	kmfber_free(asn1, 1);
   1254 
   1255 	return (ret);
   1256 }
   1257 
   1258 /*
   1259  * Name: DerDecodeSignedCertificate
   1260  *
   1261  * Description:
   1262  * DER decodes the encoded X509 certificate
   1263  *
   1264  * Parameters:
   1265  * Value (input): DER encoded object that shd be decoded
   1266  *
   1267  * signed_cert_ptr_ptr (output) : Decoded KMF_X509_CERTIFICATE object
   1268  */
   1269 KMF_RETURN
   1270 DerDecodeSignedCertificate(const KMF_DATA *Value,
   1271 	KMF_X509_CERTIFICATE **signed_cert_ptr_ptr)
   1272 {
   1273 	KMF_RETURN ret = KMF_OK;
   1274 	BerElement *asn1 = NULL;
   1275 	BerValue 	rawcert;
   1276 	ber_tag_t	tag;
   1277 	ber_len_t	size;
   1278 	char		*end = NULL;
   1279 	char		*signature;
   1280 	KMF_X509_TBS_CERT	*tbscert = NULL;
   1281 	KMF_X509_CERTIFICATE *certptr = NULL;
   1282 
   1283 	if (!signed_cert_ptr_ptr || !Value || !Value->Data || !Value->Length)
   1284 		return (KMF_ERR_BAD_PARAMETER);
   1285 
   1286 	rawcert.bv_val = (char *)Value->Data;
   1287 	rawcert.bv_len = Value->Length;
   1288 
   1289 	if ((asn1 = kmfder_init(&rawcert)) == NULL)
   1290 		return (KMF_ERR_MEMORY);
   1291 
   1292 	if (kmfber_first_element(asn1, &size, &end) !=
   1293 	    BER_CONSTRUCTED_SEQUENCE) {
   1294 		ret = KMF_ERR_BAD_CERT_FORMAT;
   1295 		goto cleanup;
   1296 	}
   1297 
   1298 	certptr = malloc(sizeof (KMF_X509_CERTIFICATE));
   1299 	if (certptr == NULL) {
   1300 		ret = KMF_ERR_MEMORY;
   1301 		goto cleanup;
   1302 	}
   1303 	(void) memset(certptr, 0, sizeof (KMF_X509_CERTIFICATE));
   1304 
   1305 	ret = decode_tbscert_data(asn1, &tbscert);
   1306 	if (ret != KMF_OK)
   1307 		goto cleanup;
   1308 
   1309 	certptr->certificate = *tbscert;
   1310 	free(tbscert);
   1311 	tbscert = NULL;
   1312 
   1313 	/*
   1314 	 * The signature data my not be present yet.
   1315 	 */
   1316 	if ((ret = get_algoid(asn1,
   1317 	    &certptr->signature.algorithmIdentifier)) == KMF_OK) {
   1318 
   1319 		/* Check to see if the cert has a signature yet */
   1320 		if (kmfber_next_element(asn1, &size, end) == BER_BIT_STRING) {
   1321 			/* Finally, get the encrypted signature BITSTRING */
   1322 			if (kmfber_scanf(asn1, "tl", &tag, &size) == -1) {
   1323 				ret = KMF_ERR_BAD_CERT_FORMAT;
   1324 				goto cleanup;
   1325 			}
   1326 			if (tag != BER_BIT_STRING) {
   1327 				ret = KMF_ERR_BAD_CERT_FORMAT;
   1328 				goto cleanup;
   1329 			}
   1330 			if (kmfber_scanf(asn1, "B}", &signature, &size) == -1) {
   1331 				ret = KMF_ERR_BAD_CERT_FORMAT;
   1332 				goto cleanup;
   1333 			}
   1334 			certptr->signature.encrypted.Data =
   1335 			    (uchar_t *)signature;
   1336 			certptr->signature.encrypted.Length = size / 8;
   1337 		} else {
   1338 			certptr->signature.encrypted.Data = NULL;
   1339 			certptr->signature.encrypted.Length = 0;
   1340 		}
   1341 	} else {
   1342 		(void) memset(&certptr->signature, 0,
   1343 		    sizeof (certptr->signature));
   1344 		ret = KMF_OK;
   1345 	}
   1346 
   1347 	*signed_cert_ptr_ptr = certptr;
   1348 cleanup:
   1349 	if (ret != KMF_OK) {
   1350 		if (certptr) {
   1351 			free_decoded_cert(certptr);
   1352 			free(certptr);
   1353 		}
   1354 
   1355 		*signed_cert_ptr_ptr = NULL;
   1356 	}
   1357 	if (asn1)
   1358 		kmfber_free(asn1, 1);
   1359 
   1360 	return (ret);
   1361 
   1362 }
   1363 
   1364 KMF_RETURN
   1365 DerDecodeExtension(KMF_DATA *Data, KMF_X509_EXTENSION **extn)
   1366 {
   1367 	KMF_RETURN ret = KMF_OK;
   1368 	BerElement *asn1 = NULL;
   1369 	BerValue bv;
   1370 
   1371 	bv.bv_val = (char *)Data->Data;
   1372 	bv.bv_len = Data->Length;
   1373 
   1374 	asn1 = kmfder_init(&bv);
   1375 	if (asn1 == NULL)
   1376 		return (KMF_ERR_MEMORY);
   1377 
   1378 	ret = get_one_extension(asn1, extn, NULL);
   1379 
   1380 cleanup:
   1381 	if (ret != KMF_OK) {
   1382 		if (*extn != NULL) {
   1383 			free(*extn);
   1384 		}
   1385 		*extn = NULL;
   1386 	}
   1387 
   1388 	kmfber_free(asn1, 1);
   1389 	return (ret);
   1390 }
   1391 
   1392 KMF_RETURN
   1393 DerDecodeName(KMF_DATA *encodedname, KMF_X509_NAME *name)
   1394 {
   1395 	KMF_RETURN ret = KMF_OK;
   1396 	BerElement *asn1 = NULL;
   1397 	BerValue  bv;
   1398 
   1399 	bv.bv_val = (char *)encodedname->Data;
   1400 	bv.bv_len = encodedname->Length;
   1401 
   1402 	asn1 = kmfder_init(&bv);
   1403 	if (asn1 == NULL)
   1404 		return (KMF_ERR_MEMORY);
   1405 
   1406 	(void) memset((void *)name, 0, sizeof (KMF_X509_NAME));
   1407 
   1408 	if ((ret = get_rdn(asn1, name)) != KMF_OK)
   1409 		goto cleanup;
   1410 
   1411 cleanup:
   1412 	if (asn1)
   1413 		kmfber_free(asn1, 1);
   1414 	return (ret);
   1415 }
   1416 
   1417 KMF_RETURN
   1418 DerEncodeName(KMF_X509_NAME *name, KMF_DATA *encodedname)
   1419 {
   1420 	KMF_RETURN ret = KMF_OK;
   1421 	BerElement *asn1 = NULL;
   1422 	BerValue  *bv = NULL;
   1423 
   1424 	asn1 = kmfder_alloc();
   1425 	if (asn1 == NULL)
   1426 		return (KMF_ERR_MEMORY);
   1427 
   1428 	if ((ret = encode_rdn(asn1, name)) != KMF_OK)
   1429 		goto cleanup;
   1430 
   1431 	if (kmfber_flatten(asn1, &bv) == -1) {
   1432 		ret = KMF_ERR_BAD_CERT_FORMAT;
   1433 		goto cleanup;
   1434 	}
   1435 
   1436 	encodedname->Data = (uchar_t *)bv->bv_val;
   1437 	encodedname->Length = bv->bv_len;
   1438 
   1439 cleanup:
   1440 	if (bv)
   1441 		free(bv);
   1442 
   1443 	if (asn1)
   1444 		kmfber_free(asn1, 1);
   1445 
   1446 	return (ret);
   1447 }
   1448 
   1449 static KMF_RETURN
   1450 encode_tbs_cert(BerElement *asn1, KMF_X509_TBS_CERT *tbscert)
   1451 {
   1452 	KMF_RETURN ret = KMF_OK;
   1453 	uint32_t version;
   1454 
   1455 	/* version should be 4 bytes or less */
   1456 	if (tbscert->version.Length > sizeof (int))
   1457 		return (KMF_ERR_BAD_CERT_FORMAT);
   1458 
   1459 	(void) memcpy(&version, tbscert->version.Data,
   1460 	    tbscert->version.Length);
   1461 
   1462 	/* Start the sequence and add the version */
   1463 	if (kmfber_printf(asn1, "{Tli", 0xA0, 3, version) == -1) {
   1464 		ret = KMF_ERR_BAD_CERT_FORMAT;
   1465 		goto cleanup;
   1466 	}
   1467 	/* Write the serial number */
   1468 	if (kmfber_printf(asn1, "I",
   1469 	    (char *)tbscert->serialNumber.val,
   1470 	    (size_t)tbscert->serialNumber.len) == -1) {
   1471 		ret = KMF_ERR_BAD_CERT_FORMAT;
   1472 		goto cleanup;
   1473 	}
   1474 
   1475 	if ((ret = encode_algoid(asn1, &tbscert->signature)) != KMF_OK)
   1476 		goto cleanup;
   1477 
   1478 	/* Encode the Issuer RDN */
   1479 	if ((ret = encode_rdn(asn1, &tbscert->issuer)) != KMF_OK)
   1480 		goto cleanup;
   1481 
   1482 	/* Encode the Validity fields */
   1483 	if ((ret = encode_validity(asn1, &tbscert->validity)) != KMF_OK)
   1484 		goto cleanup;
   1485 
   1486 	/* Encode the Subject RDN */
   1487 	if ((ret = encode_rdn(asn1, &tbscert->subject)) != KMF_OK)
   1488 		goto cleanup;
   1489 
   1490 	/* Encode the Subject Public Key Info */
   1491 	if ((ret = encode_spki(asn1, &tbscert->subjectPublicKeyInfo)) != KMF_OK)
   1492 		goto cleanup;
   1493 
   1494 	/* Optional field:  issuer Unique ID */
   1495 	if (tbscert->issuerUniqueIdentifier.Length > 0) {
   1496 		if ((ret = encode_uniqueid(asn1, 0xA1,
   1497 		    &tbscert->issuerUniqueIdentifier)) != KMF_OK)
   1498 			goto cleanup;
   1499 	}
   1500 
   1501 	/* Optional field:  Subject Unique ID */
   1502 	if (tbscert->subjectUniqueIdentifier.Length > 0) {
   1503 		if ((ret = encode_uniqueid(asn1, 0xA2,
   1504 		    &tbscert->subjectUniqueIdentifier)) != KMF_OK)
   1505 			goto cleanup;
   1506 	}
   1507 
   1508 	/* Optional field: Certificate Extensions */
   1509 	if (tbscert->extensions.numberOfExtensions > 0) {
   1510 		if ((ret = encode_extensions(asn1,
   1511 		    &tbscert->extensions)) != KMF_OK)
   1512 			goto cleanup;
   1513 	}
   1514 
   1515 	/* Close out the TBSCert sequence */
   1516 	if (kmfber_printf(asn1, "}") == -1) {
   1517 		ret = KMF_ERR_BAD_CERT_FORMAT;
   1518 		goto cleanup;
   1519 	}
   1520 
   1521 cleanup:
   1522 	/*
   1523 	 * Memory cleanup is done in the caller or in the individual
   1524 	 * encoding routines.
   1525 	 */
   1526 
   1527 	return (ret);
   1528 }
   1529 
   1530 KMF_RETURN
   1531 DerEncodeTbsCertificate(KMF_X509_TBS_CERT *tbs_cert_ptr,
   1532 	KMF_DATA *enc_tbs_cert_ptr)
   1533 {
   1534 	KMF_RETURN ret;
   1535 	BerElement *asn1 = NULL;
   1536 	BerValue  *tbsdata = NULL;
   1537 
   1538 	asn1 = kmfder_alloc();
   1539 	if (asn1 == NULL)
   1540 		return (KMF_ERR_MEMORY);
   1541 
   1542 	enc_tbs_cert_ptr->Data = NULL;
   1543 	enc_tbs_cert_ptr->Length = 0;
   1544 
   1545 	ret = encode_tbs_cert(asn1, tbs_cert_ptr);
   1546 	if (ret != KMF_OK)
   1547 		goto cleanup;
   1548 
   1549 	if (kmfber_flatten(asn1, &tbsdata) == -1) {
   1550 		ret = KMF_ERR_MEMORY;
   1551 		goto cleanup;
   1552 	}
   1553 
   1554 	enc_tbs_cert_ptr->Data = (uchar_t *)tbsdata->bv_val;
   1555 	enc_tbs_cert_ptr->Length = tbsdata->bv_len;
   1556 
   1557 cleanup:
   1558 	if (ret != KMF_OK)
   1559 		free_data(enc_tbs_cert_ptr);
   1560 
   1561 	if (asn1 != NULL)
   1562 		kmfber_free(asn1, 1);
   1563 
   1564 	if (tbsdata)
   1565 		free(tbsdata);
   1566 
   1567 	return (ret);
   1568 }
   1569 
   1570 KMF_RETURN
   1571 DerEncodeSignedCertificate(KMF_X509_CERTIFICATE *signed_cert_ptr,
   1572 	KMF_DATA *encodedcert)
   1573 {
   1574 	KMF_RETURN ret = KMF_OK;
   1575 	KMF_X509_TBS_CERT *tbscert = NULL;
   1576 	KMF_X509_SIGNATURE		*signature = NULL;
   1577 	BerElement	*asn1 = NULL;
   1578 	BerValue 	*tbsdata = NULL;
   1579 
   1580 	if (signed_cert_ptr == NULL || encodedcert == NULL)
   1581 		return (KMF_ERR_BAD_PARAMETER);
   1582 
   1583 	encodedcert->Data = NULL;
   1584 	encodedcert->Length = 0;
   1585 
   1586 	tbscert = &signed_cert_ptr->certificate;
   1587 	signature = &signed_cert_ptr->signature;
   1588 
   1589 	asn1 = kmfder_alloc();
   1590 	if (asn1 == NULL)
   1591 		return (KMF_ERR_MEMORY);
   1592 
   1593 	/* Start outer X509 Certificate SEQUENCE */
   1594 	if (kmfber_printf(asn1, "{") == -1) {
   1595 		ret = KMF_ERR_BAD_CERT_FORMAT;
   1596 		goto cleanup;
   1597 	}
   1598 
   1599 	if ((ret = encode_tbs_cert(asn1, tbscert)) != KMF_OK) {
   1600 		ret = KMF_ERR_BAD_CERT_FORMAT;
   1601 		goto cleanup;
   1602 	}
   1603 
   1604 	/* Add the Algorithm & Signature Sequence */
   1605 	if ((ret = encode_algoid(asn1,
   1606 	    &signature->algorithmIdentifier)) != KMF_OK)
   1607 		goto cleanup;
   1608 
   1609 	if (signature->encrypted.Length > 0) {
   1610 		if (kmfber_printf(asn1, "B", signature->encrypted.Data,
   1611 		    signature->encrypted.Length * 8) == -1) {
   1612 			ret = KMF_ERR_BAD_CERT_FORMAT;
   1613 			goto cleanup;
   1614 		}
   1615 	}
   1616 
   1617 	if (kmfber_printf(asn1, "}") == -1) {
   1618 		ret = KMF_ERR_BAD_CERT_FORMAT;
   1619 		goto cleanup;
   1620 	}
   1621 
   1622 	if (kmfber_flatten(asn1, &tbsdata) == -1) {
   1623 		ret = KMF_ERR_MEMORY;
   1624 		goto cleanup;
   1625 	}
   1626 
   1627 	encodedcert->Data = (uchar_t *)tbsdata->bv_val;
   1628 	encodedcert->Length = tbsdata->bv_len;
   1629 
   1630 cleanup:
   1631 	if (ret != KMF_OK)
   1632 		free_data(encodedcert);
   1633 
   1634 	if (tbsdata)
   1635 		free(tbsdata);
   1636 
   1637 	if (asn1)
   1638 		kmfber_free(asn1, 1);
   1639 
   1640 	return (ret);
   1641 }
   1642 
   1643 KMF_RETURN
   1644 ExtractX509CertParts(KMF_DATA *x509cert, KMF_DATA *tbscert,
   1645 		KMF_DATA *signature)
   1646 {
   1647 	KMF_RETURN ret = KMF_OK;
   1648 	BerElement *der = NULL;
   1649 	BerValue x509;
   1650 	ber_tag_t tag;
   1651 	ber_len_t size;
   1652 
   1653 	if (tbscert == NULL || x509cert == NULL)
   1654 		return (KMF_ERR_BAD_PARAMETER);
   1655 
   1656 	x509.bv_val = (char *)x509cert->Data;
   1657 	x509.bv_len = x509cert->Length;
   1658 
   1659 	der = kmfder_init(&x509);
   1660 	if (der == NULL)
   1661 		return (KMF_ERR_MEMORY);
   1662 
   1663 	/* Skip over the overall Sequence tag to get at the TBS Cert data */
   1664 	if (kmfber_scanf(der, "Tl", &tag, &size) == -1) {
   1665 		ret = KMF_ERR_BAD_CERT_FORMAT;
   1666 		goto cleanup;
   1667 	}
   1668 	if (tag != BER_CONSTRUCTED_SEQUENCE) {
   1669 		ret = KMF_ERR_BAD_CERT_FORMAT;
   1670 		goto cleanup;
   1671 	}
   1672 
   1673 	/*
   1674 	 * Since we are extracting a copy of the ENCODED bytes, we
   1675 	 * must make sure to also include the bytes for the tag and
   1676 	 * the length fields for the CONSTRUCTED SEQUENCE (TBSCert).
   1677 	 */
   1678 	size += kmfber_calc_taglen(tag) + kmfber_calc_lenlen(size);
   1679 
   1680 	tbscert->Data = malloc(size);
   1681 	if (tbscert->Data == NULL) {
   1682 		ret = KMF_ERR_MEMORY;
   1683 		goto cleanup;
   1684 	}
   1685 	tbscert->Length = size;
   1686 
   1687 	/* The der data ptr is now set to the start of the TBS cert sequence */
   1688 	size = kmfber_read(der, (char *)tbscert->Data, tbscert->Length);
   1689 	if (size != tbscert->Length) {
   1690 		ret = KMF_ERR_BAD_CERT_FORMAT;
   1691 		goto cleanup;
   1692 	}
   1693 
   1694 	if (signature != NULL) {
   1695 		KMF_X509_ALGORITHM_IDENTIFIER algoid;
   1696 		if ((ret = get_algoid(der, &algoid)) != KMF_OK)
   1697 			goto cleanup;
   1698 		free_algoid(&algoid);
   1699 
   1700 		if (kmfber_scanf(der, "tl", &tag, &size) != BER_BIT_STRING) {
   1701 			ret = KMF_ERR_BAD_CERT_FORMAT;
   1702 			goto cleanup;
   1703 		}
   1704 		/* Now get the signature data */
   1705 		if (kmfber_scanf(der, "B", (char **)&signature->Data,
   1706 		    (ber_len_t *)&signature->Length) == -1) {
   1707 			ret = KMF_ERR_BAD_CERT_FORMAT;
   1708 			goto cleanup;
   1709 		}
   1710 		/* convert bitstring length to bytes */
   1711 		signature->Length = signature->Length / 8;
   1712 	}
   1713 
   1714 cleanup:
   1715 	if (der)
   1716 		kmfber_free(der, 1);
   1717 
   1718 	if (ret != KMF_OK)
   1719 		free_data(tbscert);
   1720 
   1721 	return (ret);
   1722 }
   1723 
   1724 /*
   1725  * Name: GetKeyFromSpki
   1726  *
   1727  * Description:
   1728  * This function parses the KMF_X509_SPKI into its
   1729  * key and parameter components based on the key generation algorithm.
   1730  * NOTE:  Currently, it only checks for the RSA and DSA algorithms.
   1731  *	The RSA algorithm is equivalent to the default behavior.
   1732  *	All other algorithms will default to the parameters = NULL and the
   1733  *	key data equal to whatever is in the CSSM_KEY structure for the key
   1734  *
   1735  * Parameters:
   1736  * AlgId (input) : Algorithm identifier
   1737  * SpkiPtr (input): SPKI structure that contains the key
   1738  * key_ptr(output): The output key
   1739  *
   1740  */
   1741 KMF_RETURN
   1742 GetKeyFromSpki(KMF_ALGORITHM_INDEX AlgId,
   1743 	KMF_X509_SPKI *SpkiPtr,
   1744 	KMF_DATA **key_ptr)
   1745 {
   1746 	KMF_RETURN ret = KMF_OK;
   1747 	BerElement *asn1;
   1748 	BerValue *encodedkey = NULL;
   1749 
   1750 	if (!key_ptr || !SpkiPtr) {
   1751 		return (KMF_ERR_BAD_PARAMETER);
   1752 	}
   1753 	*key_ptr = NULL;
   1754 
   1755 	switch (AlgId) {
   1756 		case KMF_ALGID_DSA:
   1757 			asn1 = kmfder_alloc();
   1758 			if (asn1 == NULL) {
   1759 				return (KMF_ERR_MEMORY);
   1760 			}
   1761 
   1762 			if ((ret = encode_spki(asn1, SpkiPtr)) != KMF_OK) {
   1763 				ret = KMF_ERR_MEMORY;
   1764 				goto cleanup;
   1765 			}
   1766 
   1767 			if (kmfber_flatten(asn1, &encodedkey) == -1) {
   1768 				ret = KMF_ERR_MEMORY;
   1769 				goto cleanup;
   1770 			}
   1771 
   1772 			*key_ptr = malloc(sizeof (KMF_DATA));
   1773 
   1774 			if (!*key_ptr) {
   1775 				ret = KMF_ERR_MEMORY;
   1776 				goto cleanup;
   1777 			}
   1778 
   1779 			(*key_ptr)->Length = encodedkey->bv_len;
   1780 			(*key_ptr)->Data = (uchar_t *)encodedkey->bv_val;
   1781 cleanup:
   1782 			kmfber_free(asn1, 1);
   1783 			if (encodedkey)
   1784 				free(encodedkey);
   1785 		break;
   1786 		default: /* RSA */
   1787 			*key_ptr = malloc(sizeof (KMF_DATA));
   1788 
   1789 			if (!*key_ptr) {
   1790 				return (KMF_ERR_MEMORY);
   1791 			}
   1792 			(*key_ptr)->Length = SpkiPtr->subjectPublicKey.Length;
   1793 			(*key_ptr)->Data = malloc((*key_ptr)->Length);
   1794 
   1795 			if (!(*key_ptr)->Data) {
   1796 				free(*key_ptr);
   1797 				*key_ptr = NULL;
   1798 				return (KMF_ERR_MEMORY);
   1799 			}
   1800 			(void) memcpy((*key_ptr)->Data,
   1801 			    SpkiPtr->subjectPublicKey.Data,
   1802 			    (*key_ptr)->Length);
   1803 			return (ret);
   1804 	}
   1805 	return (ret);
   1806 }
   1807 
   1808 static KMF_RETURN
   1809 decode_csr_extensions(BerElement *asn1, KMF_X509_EXTENSIONS *extns)
   1810 {
   1811 	KMF_RETURN ret = KMF_OK;
   1812 	BerValue oid;
   1813 
   1814 	if (kmfber_scanf(asn1, "{D", &oid) == -1) {
   1815 		return (KMF_ERR_UNKNOWN_CSR_ATTRIBUTE);
   1816 	}
   1817 
   1818 	/* We only understand extension requests in a CSR */
   1819 	if (memcmp(oid.bv_val, extension_request_oid.Data,
   1820 	    oid.bv_len) != 0) {
   1821 		return (KMF_ERR_UNKNOWN_CSR_ATTRIBUTE);
   1822 	}
   1823 
   1824 	if (kmfber_scanf(asn1, "[") == -1) {
   1825 		return (KMF_ERR_ENCODING);
   1826 	}
   1827 	ret = get_extensions(asn1, extns);
   1828 
   1829 
   1830 	return (ret);
   1831 }
   1832 
   1833 static KMF_RETURN
   1834 decode_tbscsr_data(BerElement *asn1,
   1835 	KMF_TBS_CSR **signed_csr_ptr_ptr)
   1836 {
   1837 	KMF_RETURN ret = KMF_OK;
   1838 	KMF_TBS_CSR	*tbscsr = NULL;
   1839 	char *end = NULL;
   1840 	uint32_t version;
   1841 	ber_tag_t tag;
   1842 	ber_len_t size;
   1843 
   1844 	/* Now get the version number, it is not optional */
   1845 	if (kmfber_scanf(asn1, "{i", &version) == -1) {
   1846 		ret = KMF_ERR_BAD_CERT_FORMAT;
   1847 		goto cleanup;
   1848 	}
   1849 
   1850 	tbscsr = malloc(sizeof (KMF_TBS_CSR));
   1851 	if (!tbscsr) {
   1852 		ret = KMF_ERR_MEMORY;
   1853 		goto cleanup;
   1854 	}
   1855 
   1856 	(void) memset(tbscsr, 0, sizeof (KMF_TBS_CSR));
   1857 
   1858 	if ((ret = set_der_integer(&tbscsr->version, version)) != KMF_OK)
   1859 		goto cleanup;
   1860 
   1861 	if ((ret = get_rdn(asn1, &tbscsr->subject)) != KMF_OK)
   1862 		goto cleanup;
   1863 
   1864 	if ((ret = get_spki(asn1, &tbscsr->subjectPublicKeyInfo)) != KMF_OK)
   1865 		goto cleanup;
   1866 
   1867 	/* Check for the optional fields (attributes) */
   1868 	if (kmfber_next_element(asn1, &size, end) == 0xA0) {
   1869 		if (kmfber_scanf(asn1, "Tl", &tag, &size) == -1) {
   1870 			ret = KMF_ERR_ENCODING;
   1871 			goto cleanup;
   1872 		}
   1873 
   1874 		ret = decode_csr_extensions(asn1, &tbscsr->extensions);
   1875 	}
   1876 	if (ret == KMF_OK)
   1877 		*signed_csr_ptr_ptr = tbscsr;
   1878 
   1879 cleanup:
   1880 	if (ret != KMF_OK) {
   1881 		if (tbscsr) {
   1882 			free_tbscsr(tbscsr);
   1883 			free(tbscsr);
   1884 		}
   1885 		*signed_csr_ptr_ptr = NULL;
   1886 	}
   1887 	return (ret);
   1888 }
   1889 
   1890 KMF_RETURN
   1891 DerDecodeTbsCsr(const KMF_DATA *Value,
   1892 	KMF_TBS_CSR **tbscsr)
   1893 {
   1894 	KMF_RETURN ret = KMF_OK;
   1895 	BerElement *asn1 = NULL;
   1896 	BerValue 	rawcsr;
   1897 	KMF_TBS_CSR *newcsr = NULL;
   1898 
   1899 	if (!tbscsr || !Value || !Value->Data || !Value->Length)
   1900 		return (KMF_ERR_BAD_PARAMETER);
   1901 
   1902 	rawcsr.bv_val = (char *)Value->Data;
   1903 	rawcsr.bv_len = Value->Length;
   1904 
   1905 	if ((asn1 = kmfder_init(&rawcsr)) == NULL)
   1906 		return (KMF_ERR_MEMORY);
   1907 
   1908 	ret = decode_tbscsr_data(asn1, &newcsr);
   1909 	if (ret != KMF_OK)
   1910 		goto cleanup;
   1911 
   1912 	*tbscsr = newcsr;
   1913 
   1914 cleanup:
   1915 	if (ret != KMF_OK) {
   1916 		if (newcsr)
   1917 			free_tbscsr(newcsr);
   1918 		*tbscsr = NULL;
   1919 	}
   1920 	kmfber_free(asn1, 1);
   1921 
   1922 	return (ret);
   1923 }
   1924 
   1925 KMF_RETURN
   1926 DerDecodeSignedCsr(const KMF_DATA *Value,
   1927 	KMF_CSR_DATA **signed_csr_ptr_ptr)
   1928 {
   1929 	KMF_RETURN ret = KMF_OK;
   1930 	BerElement *asn1 = NULL;
   1931 	BerValue 	rawcsr;
   1932 	int			tag;
   1933 	ber_len_t	size;
   1934 	char		*end = NULL;
   1935 	char		*signature;
   1936 	KMF_TBS_CSR	*tbscsr = NULL;
   1937 	KMF_CSR_DATA *csrptr = NULL;
   1938 
   1939 	if (!signed_csr_ptr_ptr || !Value || !Value->Data || !Value->Length)
   1940 		return (KMF_ERR_BAD_PARAMETER);
   1941 
   1942 	rawcsr.bv_val = (char *)Value->Data;
   1943 	rawcsr.bv_len = Value->Length;
   1944 
   1945 	if ((asn1 = kmfder_init(&rawcsr)) == NULL)
   1946 		return (KMF_ERR_MEMORY);
   1947 
   1948 	if (kmfber_first_element(asn1, &size, &end) !=
   1949 	    BER_CONSTRUCTED_SEQUENCE) {
   1950 		ret = KMF_ERR_BAD_CERT_FORMAT;
   1951 		goto cleanup;
   1952 	}
   1953 
   1954 	csrptr = malloc(sizeof (KMF_CSR_DATA));
   1955 	if (csrptr == NULL) {
   1956 		ret = KMF_ERR_MEMORY;
   1957 		goto cleanup;
   1958 	}
   1959 	(void) memset(csrptr, 0, sizeof (KMF_CSR_DATA));
   1960 
   1961 	ret = decode_tbscsr_data(asn1, &tbscsr);
   1962 	if (ret != KMF_OK)
   1963 		goto cleanup;
   1964 
   1965 	csrptr->csr = *tbscsr;
   1966 	free(tbscsr);
   1967 	tbscsr = NULL;
   1968 
   1969 	if ((ret = get_algoid(asn1,
   1970 	    &csrptr->signature.algorithmIdentifier)) != KMF_OK)
   1971 		goto cleanup;
   1972 
   1973 	/* Check to see if the cert has a signature yet */
   1974 	if (kmfber_next_element(asn1, &size, end) == BER_BIT_STRING) {
   1975 		/* Finally, get the encrypted signature BITSTRING */
   1976 		if (kmfber_scanf(asn1, "tl", &tag, &size) == -1) {
   1977 			ret = KMF_ERR_BAD_CERT_FORMAT;
   1978 			goto cleanup;
   1979 		}
   1980 		if (tag != BER_BIT_STRING) {
   1981 			ret = KMF_ERR_BAD_CERT_FORMAT;
   1982 			goto cleanup;
   1983 		}
   1984 		if (kmfber_scanf(asn1, "B}", &signature, &size) == -1) {
   1985 			ret = KMF_ERR_BAD_CERT_FORMAT;
   1986 			goto cleanup;
   1987 		}
   1988 		csrptr->signature.encrypted.Data = (uchar_t *)signature;
   1989 		csrptr->signature.encrypted.Length = size / 8;
   1990 	} else {
   1991 		csrptr->signature.encrypted.Data = NULL;
   1992 		csrptr->signature.encrypted.Length = 0;
   1993 	}
   1994 
   1995 	*signed_csr_ptr_ptr = csrptr;
   1996 cleanup:
   1997 	if (ret != KMF_OK) {
   1998 		free_tbscsr(&csrptr->csr);
   1999 		free_algoid(&csrptr->signature.algorithmIdentifier);
   2000 		if (csrptr->signature.encrypted.Data)
   2001 			free(csrptr->signature.encrypted.Data);
   2002 
   2003 		if (csrptr)
   2004 			free(csrptr);
   2005 
   2006 		*signed_csr_ptr_ptr = NULL;
   2007 	}
   2008 	if (asn1)
   2009 		kmfber_free(asn1, 1);
   2010 
   2011 	return (ret);
   2012 
   2013 }
   2014 
   2015 static KMF_RETURN
   2016 encode_csr_extensions(BerElement *asn1, KMF_TBS_CSR *tbscsr)
   2017 {
   2018 	KMF_RETURN ret = KMF_OK;
   2019 	int attlen = 0;
   2020 	BerElement *extnasn1 = NULL;
   2021 	BerValue *extnvalue = NULL;
   2022 
   2023 	/* Optional field: CSR attributes and extensions */
   2024 	if (tbscsr->extensions.numberOfExtensions > 0) {
   2025 		if (kmfber_printf(asn1, "T", 0xA0) == -1) {
   2026 			ret = KMF_ERR_ENCODING;
   2027 			goto cleanup;
   2028 		}
   2029 	} else {
   2030 		/* No extensions or attributes to encode */
   2031 		return (KMF_OK);
   2032 	}
   2033 
   2034 	/*
   2035 	 * attributes [0] Attributes
   2036 	 * Attributes := SET OF Attribute
   2037 	 * Attribute  := SEQUENCE {
   2038 	 *   { ATTRIBUTE ID
   2039 	 *	values SET SIZE(1..MAX) of ATTRIBUTE
   2040 	 *   }
   2041 	 *
   2042 	 * Ex: { ExtensionRequest OID [ { {extn1 } , {extn2 } } ] }
   2043 	 */
   2044 
   2045 	/*
   2046 	 * Encode any extensions and add to the attributes section.
   2047 	 */
   2048 	if (tbscsr->extensions.numberOfExtensions > 0) {
   2049 		extnasn1 = kmfder_alloc();
   2050 		if (extnasn1 == NULL) {
   2051 			ret = KMF_ERR_MEMORY;
   2052 			goto cleanup;
   2053 		}
   2054 
   2055 		if (kmfber_printf(extnasn1, "{D[{",
   2056 		    &extension_request_oid) == -1) {
   2057 			ret = KMF_ERR_ENCODING;
   2058 			goto cleanup_1;
   2059 		}
   2060 
   2061 		if ((ret = encode_extension_list(extnasn1,
   2062 		    &tbscsr->extensions)) != KMF_OK) {
   2063 			goto cleanup_1;
   2064 		}
   2065 
   2066 		if (kmfber_printf(extnasn1, "}]}") == -1) {
   2067 			ret = KMF_ERR_ENCODING;
   2068 			goto cleanup_1;
   2069 		}
   2070 
   2071 		if (kmfber_flatten(extnasn1, &extnvalue) == -1) {
   2072 			ret = KMF_ERR_MEMORY;
   2073 			goto cleanup_1;
   2074 		}
   2075 cleanup_1:
   2076 		kmfber_free(extnasn1, 1);
   2077 
   2078 		if (ret == KMF_OK)
   2079 			/* Add 2 bytes to cover the tag and the length */
   2080 			attlen = extnvalue->bv_len;
   2081 	}
   2082 	if (ret != KMF_OK)
   2083 		goto cleanup;
   2084 
   2085 	if (kmfber_printf(asn1, "l", attlen) == -1) {
   2086 		ret = KMF_ERR_ENCODING;
   2087 		goto cleanup;
   2088 	}
   2089 
   2090 	/* Write the actual encoded extensions */
   2091 	if (extnvalue != NULL && extnvalue->bv_val != NULL) {
   2092 		if (kmfber_write(asn1, extnvalue->bv_val,
   2093 		    extnvalue->bv_len, 0) == -1) {
   2094 			ret = KMF_ERR_ENCODING;
   2095 			goto cleanup;
   2096 		}
   2097 	}
   2098 
   2099 cleanup:
   2100 	/*
   2101 	 * Memory cleanup is done in the caller or in the individual
   2102 	 * encoding routines.
   2103 	 */
   2104 	if (extnvalue) {
   2105 		if (extnvalue->bv_val)
   2106 			free(extnvalue->bv_val);
   2107 		free(extnvalue);
   2108 	}
   2109 
   2110 	return (ret);
   2111 }
   2112 
   2113 static KMF_RETURN
   2114 encode_tbs_csr(BerElement *asn1, KMF_TBS_CSR *tbscsr)
   2115 {
   2116 	KMF_RETURN ret = KMF_OK;
   2117 	uint32_t version;
   2118 
   2119 	/* Start the version */
   2120 	(void) memcpy(&version, tbscsr->version.Data,
   2121 	    tbscsr->version.Length);
   2122 
   2123 	if (kmfber_printf(asn1, "{i", version) == -1) {
   2124 		ret = KMF_ERR_BAD_CERT_FORMAT;
   2125 		goto cleanup;
   2126 	}
   2127 
   2128 	/* Encode the Subject RDN */
   2129 	if ((ret = encode_rdn(asn1, &tbscsr->subject)) != KMF_OK)
   2130 		goto cleanup;
   2131 
   2132 	/* Encode the Subject Public Key Info */
   2133 	if ((ret = encode_spki(asn1, &tbscsr->subjectPublicKeyInfo)) != KMF_OK)
   2134 		goto cleanup;
   2135 
   2136 
   2137 	if ((ret = encode_csr_extensions(asn1, tbscsr)) != KMF_OK)
   2138 		goto cleanup;
   2139 
   2140 	/* Close out the TBSCert sequence */
   2141 	if (kmfber_printf(asn1, "}") == -1) {
   2142 		ret = KMF_ERR_BAD_CERT_FORMAT;
   2143 		goto cleanup;
   2144 	}
   2145 
   2146 cleanup:
   2147 	return (ret);
   2148 }
   2149 
   2150 KMF_RETURN
   2151 DerEncodeDSAPrivateKey(KMF_DATA *encodedkey, KMF_RAW_DSA_KEY *dsa)
   2152 {
   2153 	KMF_RETURN rv = KMF_OK;
   2154 	BerElement *asn1 = NULL;
   2155 	BerValue  *dsadata = NULL;
   2156 
   2157 	asn1 = kmfder_alloc();
   2158 	if (asn1 == NULL)
   2159 		return (KMF_ERR_MEMORY);
   2160 
   2161 	if (kmfber_printf(asn1, "I",
   2162 	    dsa->value.val, dsa->value.len) == -1) {
   2163 		rv = KMF_ERR_MEMORY;
   2164 		goto cleanup;
   2165 	}
   2166 
   2167 	if (kmfber_flatten(asn1, &dsadata) == -1) {
   2168 		rv = KMF_ERR_MEMORY;
   2169 		goto cleanup;
   2170 	}
   2171 
   2172 	encodedkey->Data = (uchar_t *)dsadata->bv_val;
   2173 	encodedkey->Length = dsadata->bv_len;
   2174 
   2175 	free(dsadata);
   2176 cleanup:
   2177 	kmfber_free(asn1, 1);
   2178 	return (rv);
   2179 }
   2180 
   2181 KMF_RETURN
   2182 DerEncodeRSAPrivateKey(KMF_DATA *encodedkey, KMF_RAW_RSA_KEY *rsa)
   2183 {
   2184 	KMF_RETURN rv = KMF_OK;
   2185 	BerElement *asn1 = NULL;
   2186 	uchar_t ver = 0;
   2187 	BerValue  *rsadata = NULL;
   2188 
   2189 	asn1 = kmfder_alloc();
   2190 	if (asn1 == NULL)
   2191 		return (KMF_ERR_MEMORY);
   2192 
   2193 	if (kmfber_printf(asn1, "{IIIIIIIII}",
   2194 	    &ver, 1,
   2195 	    rsa->mod.val, rsa->mod.len,
   2196 	    rsa->pubexp.val, rsa->pubexp.len,
   2197 	    rsa->priexp.val, rsa->priexp.len,
   2198 	    rsa->prime1.val, rsa->prime1.len,
   2199 	    rsa->prime2.val, rsa->prime2.len,
   2200 	    rsa->exp1.val, rsa->exp1.len,
   2201 	    rsa->exp2.val, rsa->exp2.len,
   2202 	    rsa->coef.val, rsa->coef.len) == -1)
   2203 		goto cleanup;
   2204 
   2205 	if (kmfber_flatten(asn1, &rsadata) == -1) {
   2206 		rv = KMF_ERR_MEMORY;
   2207 		goto cleanup;
   2208 	}
   2209 
   2210 	encodedkey->Data = (uchar_t *)rsadata->bv_val;
   2211 	encodedkey->Length = rsadata->bv_len;
   2212 
   2213 	free(rsadata);
   2214 cleanup:
   2215 	kmfber_free(asn1, 1);
   2216 	return (rv);
   2217 }
   2218 
   2219 
   2220 KMF_RETURN
   2221 DerEncodeTbsCsr(KMF_TBS_CSR *tbs_csr_ptr,
   2222 	KMF_DATA *enc_tbs_csr_ptr)
   2223 {
   2224 	KMF_RETURN ret;
   2225 	BerValue  *tbsdata = NULL;
   2226 	BerElement *asn1 = NULL;
   2227 
   2228 	asn1 = kmfder_alloc();
   2229 
   2230 	enc_tbs_csr_ptr->Data = NULL;
   2231 	enc_tbs_csr_ptr->Length = 0;
   2232 
   2233 	if (asn1 == NULL)
   2234 		return (KMF_ERR_MEMORY);
   2235 
   2236 	ret = encode_tbs_csr(asn1, tbs_csr_ptr);
   2237 	if (ret != KMF_OK)
   2238 		goto cleanup;
   2239 
   2240 	if (kmfber_flatten(asn1, &tbsdata) == -1) {
   2241 		ret = KMF_ERR_MEMORY;
   2242 		goto cleanup;
   2243 	}
   2244 
   2245 	enc_tbs_csr_ptr->Data = (uchar_t *)tbsdata->bv_val;
   2246 	enc_tbs_csr_ptr->Length = tbsdata->bv_len;
   2247 
   2248 cleanup:
   2249 	if (ret != KMF_OK)
   2250 		free_data(enc_tbs_csr_ptr);
   2251 
   2252 	if (asn1 != NULL)
   2253 		kmfber_free(asn1, 1);
   2254 
   2255 	if (tbsdata)
   2256 		free(tbsdata);
   2257 
   2258 	return (ret);
   2259 }
   2260 
   2261 KMF_RETURN
   2262 DerEncodeSignedCsr(KMF_CSR_DATA *signed_csr_ptr,
   2263 	KMF_DATA *encodedcsr)
   2264 {
   2265 	KMF_RETURN ret = KMF_OK;
   2266 	KMF_TBS_CSR *tbscsr = NULL;
   2267 	KMF_X509_SIGNATURE		*signature = NULL;
   2268 	BerElement	*asn1 = NULL;
   2269 	BerValue 	*tbsdata = NULL;
   2270 
   2271 	if (signed_csr_ptr == NULL)
   2272 		return (KMF_ERR_BAD_PARAMETER);
   2273 
   2274 	tbscsr = &signed_csr_ptr->csr;
   2275 	signature = &signed_csr_ptr->signature;
   2276 
   2277 	asn1 = kmfder_alloc();
   2278 	if (asn1 == NULL)
   2279 		return (KMF_ERR_MEMORY);
   2280 
   2281 	/* Start outer CSR SEQUENCE */
   2282 	if (kmfber_printf(asn1, "{") == -1) {
   2283 		ret = KMF_ERR_BAD_CERT_FORMAT;
   2284 		goto cleanup;
   2285 	}
   2286 
   2287 	ret = encode_tbs_csr(asn1, tbscsr);
   2288 
   2289 	/* Add the Algorithm & Signature Sequence */
   2290 	if ((ret = encode_algoid(asn1,
   2291 	    &signature->algorithmIdentifier)) != KMF_OK)
   2292 		goto cleanup;
   2293 
   2294 	if (signature->encrypted.Length > 0) {
   2295 		if (kmfber_printf(asn1, "B", signature->encrypted.Data,
   2296 		    signature->encrypted.Length * 8) == -1) {
   2297 			ret = KMF_ERR_BAD_CERT_FORMAT;
   2298 			goto cleanup;
   2299 		}
   2300 	}
   2301 
   2302 	if (kmfber_printf(asn1, "}") == -1) {
   2303 		ret = KMF_ERR_BAD_CERT_FORMAT;
   2304 		goto cleanup;
   2305 	}
   2306 
   2307 	if (kmfber_flatten(asn1, &tbsdata) == -1) {
   2308 		ret = KMF_ERR_MEMORY;
   2309 		goto cleanup;
   2310 	}
   2311 
   2312 	encodedcsr->Data = (uchar_t *)tbsdata->bv_val;
   2313 	encodedcsr->Length = tbsdata->bv_len;
   2314 
   2315 cleanup:
   2316 	if (ret != KMF_OK) {
   2317 		free_data(encodedcsr);
   2318 	}
   2319 
   2320 	if (tbsdata)
   2321 		free(tbsdata);
   2322 
   2323 	if (asn1)
   2324 		kmfber_free(asn1, 1);
   2325 	return (ret);
   2326 }
   2327 
   2328 KMF_RETURN
   2329 ExtractSPKIData(
   2330 	const KMF_X509_SPKI *pKey,
   2331 	KMF_ALGORITHM_INDEX AlgorithmId,
   2332 	KMF_DATA *pKeyParts,
   2333 	uint32_t *uNumKeyParts)
   2334 {
   2335 	KMF_RETURN ret = KMF_OK;
   2336 	BerElement *asn1 = NULL;
   2337 	BerValue 	*P, *Q, *G, *Mod, *Exp, *PubKey;
   2338 	BerValue	PubKeyParams, PubKeyData;
   2339 
   2340 	if (pKeyParts == NULL || uNumKeyParts == NULL || pKey == NULL)
   2341 		return (KMF_ERR_BAD_PARAMETER);
   2342 
   2343 	switch (AlgorithmId) {
   2344 		case KMF_ALGID_DSA:
   2345 		case KMF_ALGID_SHA1WithDSA:
   2346 			*uNumKeyParts = 0;
   2347 			/* Get the parameters from the algorithm definition */
   2348 			PubKeyParams.bv_val =
   2349 			    (char *)pKey->algorithm.parameters.Data;
   2350 			PubKeyParams.bv_len = pKey->algorithm.parameters.Length;
   2351 			if ((asn1 = kmfder_init(&PubKeyParams)) == NULL)
   2352 				return (KMF_ERR_MEMORY);
   2353 
   2354 			if (kmfber_scanf(asn1, "{III}", &P, &Q, &G) == -1) {
   2355 				kmfber_free(asn1, 1);
   2356 				return (KMF_ERR_BAD_KEY_FORMAT);
   2357 			}
   2358 			pKeyParts[KMF_DSA_PRIME].Data = (uchar_t *)P->bv_val;
   2359 			pKeyParts[KMF_DSA_PRIME].Length = P->bv_len;
   2360 			pKeyParts[KMF_DSA_SUB_PRIME].Data =
   2361 			    (uchar_t *)Q->bv_val;
   2362 			pKeyParts[KMF_DSA_SUB_PRIME].Length = Q->bv_len;
   2363 			pKeyParts[KMF_DSA_BASE].Data = (uchar_t *)G->bv_val;
   2364 			pKeyParts[KMF_DSA_BASE].Length = G->bv_len;
   2365 
   2366 			free(P);
   2367 			free(Q);
   2368 			free(G);
   2369 			kmfber_free(asn1, 1);
   2370 
   2371 			/* Get the PubKey data */
   2372 			PubKeyData.bv_val = (char *)pKey->subjectPublicKey.Data;
   2373 			PubKeyData.bv_len = pKey->subjectPublicKey.Length;
   2374 			if ((asn1 = kmfder_init(&PubKeyData)) == NULL) {
   2375 				ret = KMF_ERR_MEMORY;
   2376 				goto cleanup;
   2377 			}
   2378 			PubKey = NULL;
   2379 			if (kmfber_scanf(asn1, "I", &PubKey) == -1) {
   2380 				ret = KMF_ERR_BAD_KEY_FORMAT;
   2381 				goto cleanup;
   2382 			}
   2383 			pKeyParts[KMF_DSA_PUBLIC_VALUE].Data =
   2384 			    (uchar_t *)PubKey->bv_val;
   2385 			pKeyParts[KMF_DSA_PUBLIC_VALUE].Length = PubKey->bv_len;
   2386 
   2387 			free(PubKey);
   2388 
   2389 			*uNumKeyParts = KMF_NUMBER_DSA_PUBLIC_KEY_PARTS;
   2390 			break;
   2391 
   2392 		case KMF_ALGID_RSA:
   2393 		case KMF_ALGID_MD2WithRSA:
   2394 		case KMF_ALGID_MD5WithRSA:
   2395 		case KMF_ALGID_SHA1WithRSA:
   2396 			*uNumKeyParts = 0;
   2397 			PubKeyData.bv_val = (char *)pKey->subjectPublicKey.Data;
   2398 			PubKeyData.bv_len = pKey->subjectPublicKey.Length;
   2399 			if ((asn1 = kmfder_init(&PubKeyData)) == NULL) {
   2400 				ret = KMF_ERR_MEMORY;
   2401 				goto cleanup;
   2402 			}
   2403 			if (kmfber_scanf(asn1, "{II}", &Mod, &Exp) == -1) {
   2404 				ret = KMF_ERR_BAD_KEY_FORMAT;
   2405 				goto cleanup;
   2406 			}
   2407 			pKeyParts[KMF_RSA_MODULUS].Data =
   2408 			    (uchar_t *)Mod->bv_val;
   2409 			pKeyParts[KMF_RSA_MODULUS].Length = Mod->bv_len;
   2410 			pKeyParts[KMF_RSA_PUBLIC_EXPONENT].Data =
   2411 			    (uchar_t *)Exp->bv_val;
   2412 			pKeyParts[KMF_RSA_PUBLIC_EXPONENT].Length = Exp->bv_len;
   2413 			*uNumKeyParts = KMF_NUMBER_RSA_PUBLIC_KEY_PARTS;
   2414 
   2415 			free(Mod);
   2416 			free(Exp);
   2417 			break;
   2418 		default:
   2419 			return (KMF_ERR_BAD_PARAMETER);
   2420 	}
   2421 cleanup:
   2422 	if (ret != KMF_OK) {
   2423 		int i;
   2424 		for (i = 0; i < *uNumKeyParts; i++)
   2425 			free_data(&pKeyParts[i]);
   2426 	}
   2427 	if (asn1 != NULL) {
   2428 		kmfber_free(asn1, 1);
   2429 	}
   2430 
   2431 	return (ret);
   2432 }
   2433