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