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