dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / libkmf / ber_der / common / clasn1.c
blob7a0f696d8c3fc862de991de435572bdef83362c1
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 */
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>
16 #include <stdio.h>
18 #define DSA_RAW_SIG_LEN 40
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};
24 static KMF_RETURN
25 encode_algoid(BerElement *asn1, KMF_X509_ALGORITHM_IDENTIFIER *algoid,
26 boolean_t encode_params)
28 KMF_RETURN ret = KMF_OK;
30 if (kmfber_printf(asn1, "{D", &algoid->algorithm) == -1) {
31 ret = KMF_ERR_BAD_CERT_FORMAT;
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 {
42 * The algorithm data can be anything, so we just write it
43 * straight into the buffer. It is already DER encoded.
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;
52 return (ret);
55 static void
56 free_data(KMF_DATA *data)
58 if (data == NULL || data->Data == NULL)
59 return;
61 free(data->Data);
62 data->Data = NULL;
63 data->Length = 0;
66 static void
67 free_algoid(KMF_X509_ALGORITHM_IDENTIFIER *algoid)
69 free_data(&algoid->algorithm);
70 free_data(&algoid->parameters);
73 static void
74 free_decoded_spki(KMF_X509_SPKI *spki)
76 if (spki != NULL) {
77 free_algoid(&spki->algorithm);
78 free_data(&spki->subjectPublicKey);
82 static void
83 free_rdn_data(KMF_X509_NAME *name)
85 KMF_X509_RDN *newrdn = NULL;
86 KMF_X509_TYPE_VALUE_PAIR *av = NULL;
87 int i, j;
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);
97 free(newrdn->AttributeTypeAndValue);
99 free(name->RelativeDistinguishedName);
100 name->numberOfRDNs = 0;
101 name->RelativeDistinguishedName = NULL;
105 static void
106 free_validity(KMF_X509_VALIDITY *validity)
108 free_data(&validity->notBefore.time);
109 free_data(&validity->notAfter.time);
112 static void
113 free_one_extension(KMF_X509_EXTENSION *exptr)
115 free_data(&exptr->extnId);
116 free_data(&exptr->BERvalue);
118 if (exptr->value.tagAndValue) {
119 free_data(&exptr->value.tagAndValue->value);
120 free(exptr->value.tagAndValue);
124 static void
125 free_extensions(KMF_X509_EXTENSIONS *extns)
127 int i;
128 KMF_X509_EXTENSION *exptr;
130 if (extns && extns->numberOfExtensions > 0) {
131 for (i = 0; i < extns->numberOfExtensions; i++) {
132 exptr = &extns->extensions[i];
133 free_one_extension(exptr);
135 free(extns->extensions);
136 extns->numberOfExtensions = 0;
137 extns->extensions = NULL;
141 static void
142 free_tbscsr(KMF_TBS_CSR *tbscsr)
144 if (tbscsr) {
145 free_data(&tbscsr->version);
147 free_rdn_data(&tbscsr->subject);
149 free_decoded_spki(&tbscsr->subjectPublicKeyInfo);
151 free_extensions(&tbscsr->extensions);
156 static void
157 free_bigint(KMF_BIGINT *bn)
159 if (bn != NULL && bn->val != NULL) {
160 free(bn->val);
161 bn->val = NULL;
162 bn->len = 0;
166 static void
167 free_tbscert(KMF_X509_TBS_CERT *tbscert)
169 if (tbscert) {
170 free_data(&tbscert->version);
171 free_bigint(&tbscert->serialNumber);
172 free_algoid(&tbscert->signature);
174 free_rdn_data(&tbscert->issuer);
175 free_rdn_data(&tbscert->subject);
177 free_validity(&tbscert->validity);
179 free_data(&tbscert->issuerUniqueIdentifier);
180 free_data(&tbscert->subjectUniqueIdentifier);
181 free_decoded_spki(&tbscert->subjectPublicKeyInfo);
182 free_extensions(&tbscert->extensions);
184 free_data(&tbscert->issuerUniqueIdentifier);
185 free_data(&tbscert->subjectUniqueIdentifier);
189 static void
190 free_decoded_cert(KMF_X509_CERTIFICATE *certptr)
192 if (!certptr)
193 return;
195 free_tbscert(&certptr->certificate);
197 free_algoid(&certptr->signature.algorithmIdentifier);
198 free_data(&certptr->signature.encrypted);
201 static KMF_RETURN
202 get_sequence_data(BerElement *asn1, BerValue *seqdata)
204 ber_tag_t tag;
205 ber_len_t size;
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);
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);
220 seqdata->bv_len = size;
221 return (KMF_OK);
222 } else if (tag != BER_CONSTRUCTED_SEQUENCE)
223 return (KMF_ERR_BAD_CERT_FORMAT);
225 if ((kmfber_scanf(asn1, "tl", &tag, &size)) == -1) {
226 return (KMF_ERR_BAD_CERT_FORMAT);
229 * We need to read the tag and the length bytes too,
230 * so adjust the size.
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);
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);
242 seqdata->bv_len = size;
243 return (KMF_OK);
246 static KMF_RETURN
247 get_algoid(BerElement *asn1, KMF_X509_ALGORITHM_IDENTIFIER *algoid)
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;
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);
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);
274 if ((tag = kmfber_scanf(oidasn1, "{D", &AlgOID)) == -1) {
275 kmfber_free(oidasn1, 1);
276 return (KMF_ERR_BAD_CERT_FORMAT);
278 algoid->algorithm.Data = (uchar_t *)AlgOID.bv_val;
279 algoid->algorithm.Length = AlgOID.bv_len;
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;
298 * We need to read the tag and the length bytes too,
299 * so adjust the size.
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;
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;
313 algoid->parameters.Length = size;
315 cleanup:
316 if (rv != KMF_OK) {
317 free_algoid(algoid);
319 kmfber_free(oidasn1, 1);
321 return (rv);
324 static KMF_RETURN
325 CopyData(KMF_DATA *src, KMF_DATA *dst)
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);
334 return (KMF_OK);
337 static KMF_RETURN
338 encode_spki(BerElement *asn1, KMF_X509_SPKI *spki)
340 KMF_RETURN ret = KMF_OK;
342 if (kmfber_printf(asn1, "{") == -1)
343 return (KMF_ERR_BAD_CERT_FORMAT);
346 * The SPKI is the only place where algorithm parameters
347 * should be encoded.
349 if ((ret = encode_algoid(asn1, &spki->algorithm, TRUE)) != KMF_OK)
350 return (ret);
352 if (kmfber_printf(asn1, "B}", spki->subjectPublicKey.Data,
353 spki->subjectPublicKey.Length * 8) == -1)
354 return (KMF_ERR_BAD_CERT_FORMAT);
356 return (ret);
359 KMF_RETURN
360 DerEncodeSPKI(KMF_X509_SPKI *spki, KMF_DATA *EncodedSPKI)
362 KMF_RETURN ret = KMF_OK;
363 BerElement *asn1;
364 BerValue *result;
366 if (spki == NULL || EncodedSPKI == NULL)
367 return (KMF_ERR_BAD_PARAMETER);
369 if ((asn1 = kmfder_alloc()) == NULL)
370 return (KMF_ERR_MEMORY);
372 if ((ret = encode_spki(asn1, spki)) != KMF_OK) {
373 return (ret);
376 if (kmfber_flatten(asn1, &result) == -1) {
377 kmfber_free(asn1, 1);
378 return (KMF_ERR_ENCODING);
381 EncodedSPKI->Data = (uchar_t *)result->bv_val;
382 EncodedSPKI->Length = result->bv_len;
384 free(result);
385 kmfber_free(asn1, 1);
386 return (KMF_OK);
389 static KMF_RETURN
390 get_spki(BerElement *asn1, KMF_X509_SPKI *spki)
392 KMF_RETURN ret = KMF_OK;
393 char *bitstr = NULL;
394 ber_len_t size;
396 if (kmfber_scanf(asn1, "{") == -1)
397 return (KMF_ERR_BAD_CERT_FORMAT);
399 if ((ret = get_algoid(asn1, &spki->algorithm)) != KMF_OK)
400 return (ret);
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;
409 cleanup:
410 if (ret != KMF_OK) {
411 free(bitstr);
412 spki->subjectPublicKey.Data = NULL;
413 spki->subjectPublicKey.Length = 0;
415 free_algoid(&spki->algorithm);
417 return (ret);
421 KMF_RETURN
422 DerEncodeDSASignature(KMF_DATA *rawdata, KMF_DATA *signature)
424 BerElement *asn1;
425 BerValue *buf;
426 int n;
428 if (rawdata == NULL || signature == NULL)
429 return (KMF_ERR_BAD_PARAMETER);
431 if (rawdata->Data == NULL || rawdata->Length == 0)
432 return (KMF_ERR_BAD_PARAMETER);
434 asn1 = kmfder_alloc();
435 if (asn1 == NULL)
436 return (KMF_ERR_MEMORY);
439 * The [EC]DSA signature is the concatenation of 2
440 * bignum values.
442 n = rawdata->Length/2;
443 if (kmfber_printf(asn1, "{II}",
444 rawdata->Data, n, &rawdata->Data[n], n) == -1) {
445 kmfber_free(asn1, 1);
446 return (KMF_ERR_MEMORY);
449 if (kmfber_flatten(asn1, &buf) == -1) {
450 kmfber_free(asn1, 1);
451 return (KMF_ERR_ENCODING);
454 signature->Data = (uchar_t *)buf->bv_val;
455 signature->Length = buf->bv_len;
457 kmfber_free(asn1, 1);
458 free(buf);
460 return (KMF_OK);
464 * ECDSA and DSA encode signatures the same way.
466 KMF_RETURN
467 DerEncodeECDSASignature(KMF_DATA *rawdata, KMF_DATA *signature)
469 return (DerEncodeDSASignature(rawdata, signature));
473 * Convert a signed DSA sig to a fixed-length unsigned one.
474 * This is necessary because DER encoding seeks to use the
475 * minimal amount of bytes but we need a full 20 byte DSA
476 * value with leading 0x00 bytes.
478 static KMF_RETURN
479 convert_signed_to_fixed(BerValue *src, BerValue *dst)
481 int cnt;
482 char *p;
483 if (dst->bv_len > src->bv_len) {
484 cnt = dst->bv_len - src->bv_len;
485 /* prepend with leading 0s */
486 (void) memset(dst->bv_val, 0x00, cnt);
487 (void) memcpy(dst->bv_val + cnt, src->bv_val,
488 src->bv_len);
489 return (KMF_OK);
491 if (dst->bv_len == src->bv_len) {
492 (void) memcpy(dst->bv_val, src->bv_val,
493 dst->bv_len);
494 return (KMF_OK);
497 * src is larger than dest, strip leading 0s.
498 * This should not be necessary, but do it just in case.
500 cnt = src->bv_len - dst->bv_len;
501 p = src->bv_val;
502 while (cnt-- > 0) {
503 if (*p++ != 0x00)
504 return (KMF_ERR_ENCODING);
506 (void) memcpy(dst->bv_val, p, dst->bv_len);
507 return (KMF_OK);
510 KMF_RETURN
511 DerDecodeDSASignature(KMF_DATA *encoded, KMF_DATA *signature)
513 KMF_RETURN ret = KMF_OK;
514 BerElement *asn1 = NULL;
515 BerValue buf, *R = NULL, *S = NULL;
516 BerValue fixedR, fixedS;
518 buf.bv_val = (char *)encoded->Data;
519 buf.bv_len = encoded->Length;
521 if (encoded == NULL || encoded->Data == NULL ||
522 signature == NULL)
523 return (KMF_ERR_BAD_PARAMETER);
525 signature->Data = NULL;
526 signature->Length = 0;
528 if ((asn1 = kmfder_init(&buf)) == NULL)
529 return (KMF_ERR_MEMORY);
531 if (kmfber_scanf(asn1, "{II}", &R, &S) == -1) {
532 ret = KMF_ERR_BAD_PARAMETER;
533 goto cleanup;
535 signature->Length = R->bv_len + S->bv_len;
537 * If either of the values had a leading 0 lopped off
538 * they will be 1 byte short and need to be adjusted below.
539 * The stripping is correct as per ASN.1 rules.
541 * We don't know the exact length that the R and S values
542 * must be, it depends on the signature algorithm and,
543 * in the case of EC, the curve used. So instead of
544 * checking for a specific length, we just check to see
545 * if the value came out to be an odd number. If so,
546 * then we know it needs a leading 0x00 byte which
547 * will be added below when we convert it to a fixed
548 * length.
550 if ((R->bv_len % 2) != 0)
551 signature->Length++;
552 if ((S->bv_len % 2) != 0)
553 signature->Length++;
555 signature->Data = malloc(signature->Length);
556 if (signature->Data == NULL) {
557 ret = KMF_ERR_MEMORY;
558 goto cleanup;
560 fixedR.bv_val = (char *)signature->Data;
561 /* adjust length if it needs a leading 0x00 byte */
562 fixedR.bv_len = R->bv_len + (R->bv_len % 2);
564 fixedS.bv_val = (char *)(signature->Data + fixedR.bv_len);
565 /* adjust length if it needs a leading 0x00 byte */
566 fixedS.bv_len = S->bv_len + (S->bv_len % 2);
569 * This will add back any missing leading 0's
570 * that were stripped off earlier when the signature
571 * was parsed. This ensures that the 2 parts of the
572 * signature are the right length and have the proper
573 * leading 0's prepended.
575 ret = convert_signed_to_fixed(R, &fixedR);
576 if (ret)
577 goto cleanup;
579 ret = convert_signed_to_fixed(S, &fixedS);
580 cleanup:
581 if (R)
582 free(R->bv_val);
583 if (S)
584 free(S->bv_val);
586 free(S);
587 free(R);
589 if (asn1) kmfber_free(asn1, 1);
591 return (ret);
594 KMF_RETURN
595 DerDecodeECDSASignature(KMF_DATA *encoded, KMF_DATA *signature)
597 /* ECDSA can be decoded using same code as standard DSA */
598 return (DerDecodeDSASignature(encoded, signature));
601 KMF_RETURN
602 DerDecodeSPKI(KMF_DATA *EncodedSPKI, KMF_X509_SPKI *spki)
604 KMF_RETURN ret = KMF_OK;
605 BerElement *asn1;
606 BerValue bv;
608 if (EncodedSPKI == NULL || EncodedSPKI->Data == NULL ||
609 spki == NULL)
610 return (KMF_ERR_BAD_PARAMETER);
612 (void) memset(spki, 0, sizeof (KMF_X509_SPKI));
614 bv.bv_val = (char *)EncodedSPKI->Data;
615 bv.bv_len = EncodedSPKI->Length;
617 if ((asn1 = kmfder_init(&bv)) == NULL)
618 return (KMF_ERR_MEMORY);
620 ret = get_spki(asn1, spki);
622 cleanup:
623 if (ret != KMF_OK) {
624 free_decoded_spki(spki);
626 kmfber_free(asn1, 1);
628 return (ret);
631 KMF_RETURN
632 CopySPKI(KMF_X509_SPKI *src,
633 KMF_X509_SPKI **dest)
635 KMF_RETURN ret = KMF_OK;
636 KMF_X509_SPKI *newspki;
638 *dest = NULL;
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));
645 ret = CopyData(&src->algorithm.algorithm,
646 &newspki->algorithm.algorithm);
647 if (ret != KMF_OK)
648 goto cleanup;
650 ret = CopyData(&src->algorithm.parameters,
651 &newspki->algorithm.parameters);
652 if (ret != KMF_OK)
653 goto cleanup;
655 ret = CopyData(&src->subjectPublicKey,
656 &newspki->subjectPublicKey);
657 if (ret != KMF_OK)
658 goto cleanup;
660 *dest = newspki;
661 cleanup:
662 if (ret != KMF_OK) {
663 if (newspki)
664 free_decoded_spki(newspki);
666 return (ret);
669 static KMF_RETURN
670 encode_validity(BerElement *asn1, KMF_X509_VALIDITY *validity)
672 int ret;
674 ret = kmfber_printf(asn1, "{tsts}",
675 validity->notBefore.timeType,
676 validity->notBefore.time.Data,
677 validity->notAfter.timeType,
678 validity->notAfter.time.Data);
680 if (ret == -1)
681 return (KMF_ERR_BAD_CERT_FORMAT);
683 return (KMF_OK);
686 static KMF_RETURN
687 get_validity(BerElement *asn1, KMF_X509_VALIDITY *validity)
689 KMF_RETURN ret = KMF_OK;
690 int tag;
691 int t1, t2;
692 ber_len_t size;
693 char *t1str, *t2str;
695 (void) memset(validity, 0, sizeof (KMF_X509_VALIDITY));
697 tag = kmfber_next_element(asn1, &size, NULL);
698 if (tag != BER_CONSTRUCTED_SEQUENCE) {
699 return (KMF_ERR_BAD_CERT_FORMAT);
702 if (kmfber_scanf(asn1, "{tata}", &t1, &t1str, &t2, &t2str) == -1) {
703 return (KMF_ERR_BAD_CERT_FORMAT);
706 validity->notBefore.timeType = t1;
707 validity->notBefore.time.Data = (uchar_t *)t1str;
708 validity->notBefore.time.Length = strlen(t1str);
710 validity->notAfter.timeType = t2;
711 validity->notAfter.time.Data = (uchar_t *)t2str;
712 validity->notAfter.time.Length = strlen(t2str);
714 return (ret);
717 KMF_RETURN
718 AddRDN(KMF_X509_NAME *name, KMF_X509_RDN *newrdn)
720 KMF_RETURN ret = KMF_OK;
721 KMF_X509_RDN *rdnslot = NULL;
723 /* Add new RDN record to existing list */
724 name->numberOfRDNs++;
725 name->RelativeDistinguishedName =
726 reallocarray(name->RelativeDistinguishedName, name->numberOfRDNs,
727 sizeof(KMF_X509_RDN));
729 if (name->RelativeDistinguishedName == NULL) {
730 ret = KMF_ERR_MEMORY;
731 goto cleanup;
733 rdnslot = &name->RelativeDistinguishedName[name->numberOfRDNs-1];
735 if (newrdn) {
736 (void) memcpy(rdnslot, newrdn, sizeof (KMF_X509_RDN));
737 } else {
738 rdnslot->numberOfPairs = 0;
739 rdnslot->AttributeTypeAndValue = NULL;
742 cleanup:
743 /* No cleanup needed here */
744 return (ret);
747 static KMF_RETURN
748 encode_rdn(BerElement *asn1, KMF_X509_NAME *name)
750 KMF_RETURN ret = KMF_OK;
751 KMF_X509_TYPE_VALUE_PAIR *attrtvpair = NULL;
752 int i;
753 KMF_X509_RDN *rdn;
755 if (kmfber_printf(asn1, "{") == -1) {
756 ret = KMF_ERR_MEMORY;
757 goto cleanup;
760 for (i = 0; i < name->numberOfRDNs; i++) {
761 if (kmfber_printf(asn1, "[") == -1) {
762 ret = KMF_ERR_MEMORY;
763 goto cleanup;
765 rdn = &name->RelativeDistinguishedName[i];
766 attrtvpair = rdn->AttributeTypeAndValue;
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;
778 if (kmfber_printf(asn1, "]") == -1) {
779 ret = KMF_ERR_MEMORY;
780 goto cleanup;
784 if (kmfber_printf(asn1, "}") == -1) {
785 ret = KMF_ERR_MEMORY;
786 goto cleanup;
789 cleanup:
790 /* No cleanup needed here */
792 return (ret);
796 KMF_RETURN
797 CopyRDN(KMF_X509_NAME *srcname, KMF_X509_NAME **destname)
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;
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));
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);
819 /* Copy each RDN in the list */
820 for (i = 0; i < newname->numberOfRDNs; i++) {
821 rdn = &srcname->RelativeDistinguishedName[i];
823 dstrdn = &newname->RelativeDistinguishedName[i];
824 (void) memset(dstrdn, 0, sizeof (KMF_X509_RDN));
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;
834 (void) memset(av, 0, dstrdn->numberOfPairs *
835 sizeof (KMF_X509_TYPE_VALUE_PAIR));
837 dstrdn->AttributeTypeAndValue = av;
838 if (av == NULL) {
839 ret = KMF_ERR_MEMORY;
840 goto cleanup;
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;
854 } else {
855 dstrdn->AttributeTypeAndValue = NULL;
858 *destname = newname;
860 cleanup:
861 if (ret != KMF_OK) {
862 if (newname)
863 free_rdn_data(newname);
865 free(newname);
866 *destname = NULL;
868 return (ret);
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))
879 static KMF_RETURN
880 get_rdn(BerElement *asn1, KMF_X509_NAME *name)
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;
892 * AttributeType ::= OBJECT IDENTIFIER
893 * AttributeValue ::= ANY
895 * AttributeTypeAndValue ::= SEQUENCE {
896 * type AttributeType,
897 * value AttributeValue }
899 * Name ::= CHOICE { -- only one possibility for now --
900 * rdnSequence RDNSequence }
902 * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
904 * DistinguishedName ::= RDNSequence
906 * RelativeDistinguishedName ::=
907 * SET SIZE (1 .. MAX) OF AttributeTypeAndValue
911 name->numberOfRDNs = 0;
912 name->RelativeDistinguishedName = NULL;
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;
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;
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;
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;
942 if (!(VALID_DIRECTORYSTRING_TAG(tag))) {
943 ret = KMF_ERR_BAD_CERT_FORMAT;
944 break;
947 if (kmfber_scanf(asn1, "a}]", &AttrValue) == -1) {
948 ret = KMF_ERR_BAD_CERT_FORMAT;
949 break;
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;
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);
965 (void) memset(&newrdn, 0, sizeof (KMF_X509_RDN));
966 newrdn.numberOfPairs = 1;
967 newrdn.AttributeTypeAndValue = newpair;
969 if ((ret = AddRDN(name, &newrdn)) != KMF_OK)
970 break;
973 cleanup:
974 if (ret != KMF_OK) {
975 free_rdn_data(name);
977 return (ret);
980 static KMF_RETURN
981 set_der_integer(KMF_DATA *data, int value)
983 if (data == NULL)
984 return (KMF_ERR_BAD_PARAMETER);
986 data->Data = malloc(sizeof (int));
987 if (data->Data == NULL)
988 return (KMF_ERR_MEMORY);
990 data->Length = sizeof (int);
991 (void) memcpy((void *)data->Data, (const void *)&value, sizeof (int));
993 return (KMF_OK);
996 static KMF_RETURN
997 set_bigint(KMF_BIGINT *data, KMF_BIGINT *bigint)
999 if (data == NULL || bigint == NULL)
1000 return (KMF_ERR_BAD_PARAMETER);
1002 data->val = malloc(bigint->len);
1003 if (data->val == NULL)
1004 return (KMF_ERR_MEMORY);
1006 data->len = bigint->len;
1007 (void) memcpy((void *)data->val, (const void *)bigint->val,
1008 bigint->len);
1010 return (KMF_OK);
1013 static KMF_RETURN
1014 encode_uniqueid(BerElement *asn1, int tag, KMF_DATA *id)
1016 KMF_RETURN ret = KMF_OK;
1017 uint32_t len;
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);
1025 return (ret);
1028 static KMF_RETURN
1029 encode_extension_list(BerElement *asn1, KMF_X509_EXTENSIONS *extns)
1031 KMF_RETURN ret = KMF_OK;
1032 int i;
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;
1039 if (kmfber_printf(asn1, "{D", &v) == -1) {
1040 ret = KMF_ERR_ENCODING;
1041 goto cleanup;
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;
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;
1059 cleanup:
1060 return (ret);
1063 static KMF_RETURN
1064 encode_extensions(BerElement *asn1, KMF_X509_EXTENSIONS *extns)
1066 KMF_RETURN ret = KMF_OK;
1067 BerElement *extn = NULL;
1068 BerValue *extnvalue = NULL;
1070 extn = kmfder_alloc();
1071 if (extn == NULL)
1072 return (KMF_ERR_MEMORY);
1074 if (kmfber_printf(extn, "{") == -1) {
1075 ret = KMF_ERR_ENCODING;
1076 goto cleanup;
1079 ret = encode_extension_list(extn, extns);
1081 if (kmfber_printf(extn, "}") == -1) {
1082 ret = KMF_ERR_ENCODING;
1083 goto cleanup;
1086 if (kmfber_flatten(extn, &extnvalue) == -1) {
1087 ret = KMF_ERR_MEMORY;
1088 goto cleanup;
1091 if (kmfber_printf(asn1, "Tl", 0xA3, extnvalue->bv_len) == -1) {
1092 ret = KMF_ERR_BAD_CERT_FORMAT;
1093 goto cleanup;
1096 if (kmfber_write(asn1, extnvalue->bv_val, extnvalue->bv_len, 0) == -1) {
1097 ret = KMF_ERR_BAD_CERT_FORMAT;
1098 goto cleanup;
1101 cleanup:
1102 kmfber_free(extn, 1);
1103 if (extnvalue != NULL)
1104 kmfber_bvfree(extnvalue);
1106 return (ret);
1109 static KMF_RETURN
1110 get_one_extension(BerElement *asn1, KMF_X509_EXTENSION **retex, char *end)
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;
1120 if (kmfber_scanf(asn1, "T", &tag) == -1) {
1121 ret = KMF_ERR_BAD_CERT_FORMAT;
1122 goto cleanup;
1125 tag = kmfber_next_element(asn1, &size, end);
1126 if (tag != BER_OBJECT_IDENTIFIER) {
1127 ret = KMF_ERR_BAD_CERT_FORMAT;
1128 goto cleanup;
1130 if (kmfber_scanf(asn1, "D", &extOID) == -1) {
1131 ret = KMF_ERR_BAD_CERT_FORMAT;
1132 goto cleanup;
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;
1145 tag = kmfber_next_element(asn1, &size, end);
1146 if (tag != BER_OCTET_STRING) {
1147 ret = KMF_ERR_BAD_CERT_FORMAT;
1148 goto cleanup;
1150 if (kmfber_scanf(asn1, "o", &extValue) == -1) {
1151 ret = KMF_ERR_BAD_CERT_FORMAT;
1152 goto cleanup;
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;
1161 (void) memset(ex, 0, sizeof (ex));
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;
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;
1176 (void) memset(ex->value.tagAndValue, 0,
1177 sizeof (KMF_X509EXT_TAGandVALUE));
1179 /* Parse the Extension value field */
1180 extnber = kmfder_init(&extValue);
1181 if (extnber == NULL) {
1182 ret = KMF_ERR_MEMORY;
1183 goto cleanup;
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;
1192 if (kmfber_scanf(extnber, "T", &tag) == -1) {
1193 ret = KMF_ERR_BAD_CERT_FORMAT;
1194 goto cleanup;
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;
1205 kmfber_free(extnber, 1);
1206 ex->value.tagAndValue->type = tag;
1208 *retex = ex;
1209 cleanup:
1210 if (ret != KMF_OK) {
1211 if (ex != NULL)
1212 free_one_extension(ex);
1215 return (ret);
1218 static KMF_RETURN
1219 get_extensions(BerElement *asn1, KMF_X509_EXTENSIONS *extns)
1221 KMF_RETURN ret = KMF_OK;
1222 ber_len_t size;
1223 char *end = NULL;
1224 KMF_X509_EXTENSION *ex = NULL;
1227 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
1229 * Extension ::= SEQUENCE {
1230 * extnID OBJECT IDENTIFIER,
1231 * critical BOOLEAN DEFAULT FALSE,
1232 * extnValue OCTET STRING }
1234 * { {{D}Bo}, ... }
1236 if (kmfber_first_element(asn1, &size, &end) !=
1237 BER_CONSTRUCTED_SEQUENCE)
1238 return (KMF_ERR_BAD_CERT_FORMAT);
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;
1246 extns->numberOfExtensions++;
1247 extns->extensions = reallocarray(extns->extensions,
1248 extns->numberOfExtensions,
1249 sizeof (KMF_X509_EXTENSION));
1250 if (extns->extensions == NULL) {
1251 ret = KMF_ERR_MEMORY;
1252 break;
1255 extns->extensions[extns->numberOfExtensions-1] = *ex;
1256 free(ex);
1259 cleanup:
1260 if (ret != KMF_OK)
1261 free_extensions(extns);
1263 return (ret);
1266 KMF_RETURN
1267 decode_tbscert_data(BerElement *asn1,
1268 KMF_X509_TBS_CERT **signed_cert_ptr_ptr)
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;
1276 if (kmfber_scanf(asn1, "{t", &tag) == -1) {
1277 ret = KMF_ERR_BAD_CERT_FORMAT;
1278 goto cleanup;
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;
1287 } else {
1288 version = 0; /* DEFAULT v1 (0) */
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;
1300 tbscert = malloc(sizeof (KMF_X509_TBS_CERT));
1301 if (!tbscert) {
1302 ret = KMF_ERR_MEMORY;
1303 goto cleanup;
1306 (void) memset(tbscert, 0, sizeof (KMF_X509_TBS_CERT));
1308 if ((ret = set_der_integer(&tbscert->version, version)) != KMF_OK)
1309 goto cleanup;
1311 if ((ret = set_bigint(&tbscert->serialNumber, &serno)) != KMF_OK)
1312 goto cleanup;
1314 if ((ret = get_algoid(asn1, &tbscert->signature)) != KMF_OK)
1315 goto cleanup;
1317 if ((ret = get_rdn(asn1, &tbscert->issuer)) != KMF_OK)
1318 goto cleanup;
1320 if ((ret = get_validity(asn1, &tbscert->validity)) != KMF_OK)
1321 goto cleanup;
1323 if ((ret = get_rdn(asn1, &tbscert->subject)) != KMF_OK)
1324 goto cleanup;
1326 if ((ret = get_spki(asn1, &tbscert->subjectPublicKeyInfo)) != KMF_OK)
1327 goto cleanup;
1329 /* Check for the optional fields */
1330 tbscert->extensions.numberOfExtensions = 0;
1331 tbscert->extensions.extensions = NULL;
1333 while ((kmfber_scanf(asn1, "t", &tag)) != -1 &&
1334 (tag == 0xA1 || tag == 0xA2 || tag == 0xA3)) {
1335 char *optfield;
1336 ber_len_t len;
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;
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;
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;
1369 *signed_cert_ptr_ptr = tbscert;
1371 cleanup:
1372 if (bvserno != NULL) {
1373 free(bvserno->bv_val);
1374 free(bvserno);
1376 if (ret != KMF_OK) {
1377 if (tbscert) {
1378 free_tbscert(tbscert);
1379 free(tbscert);
1381 *signed_cert_ptr_ptr = NULL;
1383 return (ret);
1386 KMF_RETURN
1387 DerDecodeTbsCertificate(const KMF_DATA *Value,
1388 KMF_X509_TBS_CERT **tbscert)
1390 KMF_RETURN ret = KMF_OK;
1391 BerElement *asn1 = NULL;
1392 BerValue rawcert;
1393 KMF_X509_TBS_CERT *newcert = NULL;
1395 if (!tbscert || !Value || !Value->Data || !Value->Length)
1396 return (KMF_ERR_BAD_PARAMETER);
1398 rawcert.bv_val = (char *)Value->Data;
1399 rawcert.bv_len = Value->Length;
1401 if ((asn1 = kmfder_init(&rawcert)) == NULL)
1402 return (KMF_ERR_MEMORY);
1404 ret = decode_tbscert_data(asn1, &newcert);
1405 if (ret != KMF_OK)
1406 goto cleanup;
1408 *tbscert = newcert;
1410 cleanup:
1411 if (ret != KMF_OK) {
1412 if (newcert)
1413 free_tbscert(newcert);
1414 *tbscert = NULL;
1416 kmfber_free(asn1, 1);
1418 return (ret);
1422 * Name: DerDecodeSignedCertificate
1424 * Description:
1425 * DER decodes the encoded X509 certificate
1427 * Parameters:
1428 * Value (input): DER encoded object that shd be decoded
1430 * signed_cert_ptr_ptr (output) : Decoded KMF_X509_CERTIFICATE object
1432 KMF_RETURN
1433 DerDecodeSignedCertificate(const KMF_DATA *Value,
1434 KMF_X509_CERTIFICATE **signed_cert_ptr_ptr)
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;
1446 if (!signed_cert_ptr_ptr || !Value || !Value->Data || !Value->Length)
1447 return (KMF_ERR_BAD_PARAMETER);
1449 rawcert.bv_val = (char *)Value->Data;
1450 rawcert.bv_len = Value->Length;
1452 if ((asn1 = kmfder_init(&rawcert)) == NULL)
1453 return (KMF_ERR_MEMORY);
1455 if (kmfber_first_element(asn1, &size, &end) !=
1456 BER_CONSTRUCTED_SEQUENCE) {
1457 ret = KMF_ERR_BAD_CERT_FORMAT;
1458 goto cleanup;
1461 certptr = malloc(sizeof (KMF_X509_CERTIFICATE));
1462 if (certptr == NULL) {
1463 ret = KMF_ERR_MEMORY;
1464 goto cleanup;
1466 (void) memset(certptr, 0, sizeof (KMF_X509_CERTIFICATE));
1468 ret = decode_tbscert_data(asn1, &tbscert);
1469 if (ret != KMF_OK)
1470 goto cleanup;
1472 certptr->certificate = *tbscert;
1473 free(tbscert);
1474 tbscert = NULL;
1477 * The signature data my not be present yet.
1479 if ((ret = get_algoid(asn1,
1480 &certptr->signature.algorithmIdentifier)) == KMF_OK) {
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;
1489 if (tag != BER_BIT_STRING) {
1490 ret = KMF_ERR_BAD_CERT_FORMAT;
1491 goto cleanup;
1493 if (kmfber_scanf(asn1, "B}", &signature, &size) == -1) {
1494 ret = KMF_ERR_BAD_CERT_FORMAT;
1495 goto cleanup;
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;
1504 } else {
1505 (void) memset(&certptr->signature, 0,
1506 sizeof (certptr->signature));
1507 ret = KMF_OK;
1510 *signed_cert_ptr_ptr = certptr;
1511 cleanup:
1512 if (ret != KMF_OK) {
1513 if (certptr) {
1514 free_decoded_cert(certptr);
1515 free(certptr);
1518 *signed_cert_ptr_ptr = NULL;
1520 if (asn1)
1521 kmfber_free(asn1, 1);
1523 return (ret);
1527 KMF_RETURN
1528 DerDecodeExtension(KMF_DATA *Data, KMF_X509_EXTENSION **extn)
1530 KMF_RETURN ret = KMF_OK;
1531 BerElement *asn1 = NULL;
1532 BerValue bv;
1534 bv.bv_val = (char *)Data->Data;
1535 bv.bv_len = Data->Length;
1537 asn1 = kmfder_init(&bv);
1538 if (asn1 == NULL)
1539 return (KMF_ERR_MEMORY);
1541 ret = get_one_extension(asn1, extn, NULL);
1543 cleanup:
1544 if (ret != KMF_OK) {
1545 if (*extn != NULL) {
1546 free(*extn);
1548 *extn = NULL;
1551 kmfber_free(asn1, 1);
1552 return (ret);
1555 KMF_RETURN
1556 DerDecodeName(KMF_DATA *encodedname, KMF_X509_NAME *name)
1558 KMF_RETURN ret = KMF_OK;
1559 BerElement *asn1 = NULL;
1560 BerValue bv;
1562 bv.bv_val = (char *)encodedname->Data;
1563 bv.bv_len = encodedname->Length;
1565 asn1 = kmfder_init(&bv);
1566 if (asn1 == NULL)
1567 return (KMF_ERR_MEMORY);
1569 (void) memset(name, 0, sizeof (KMF_X509_NAME));
1571 if ((ret = get_rdn(asn1, name)) != KMF_OK)
1572 goto cleanup;
1574 cleanup:
1575 if (asn1)
1576 kmfber_free(asn1, 1);
1577 return (ret);
1580 KMF_RETURN
1581 DerEncodeName(KMF_X509_NAME *name, KMF_DATA *encodedname)
1583 KMF_RETURN ret = KMF_OK;
1584 BerElement *asn1 = NULL;
1585 BerValue *bv = NULL;
1587 asn1 = kmfder_alloc();
1588 if (asn1 == NULL)
1589 return (KMF_ERR_MEMORY);
1591 if ((ret = encode_rdn(asn1, name)) != KMF_OK)
1592 goto cleanup;
1594 if (kmfber_flatten(asn1, &bv) == -1) {
1595 ret = KMF_ERR_BAD_CERT_FORMAT;
1596 goto cleanup;
1599 encodedname->Data = (uchar_t *)bv->bv_val;
1600 encodedname->Length = bv->bv_len;
1602 cleanup:
1603 free(bv);
1605 if (asn1)
1606 kmfber_free(asn1, 1);
1608 return (ret);
1611 static KMF_RETURN
1612 encode_tbs_cert(BerElement *asn1, KMF_X509_TBS_CERT *tbscert)
1614 KMF_RETURN ret = KMF_OK;
1615 uint32_t version;
1617 /* version should be 4 bytes or less */
1618 if (tbscert->version.Length > sizeof (int))
1619 return (KMF_ERR_BAD_CERT_FORMAT);
1621 (void) memcpy(&version, tbscert->version.Data,
1622 tbscert->version.Length);
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;
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;
1637 /* Don't encode alg parameters in signature algid area */
1638 if ((ret = encode_algoid(asn1, &tbscert->signature, FALSE)) != KMF_OK)
1639 goto cleanup;
1641 /* Encode the Issuer RDN */
1642 if ((ret = encode_rdn(asn1, &tbscert->issuer)) != KMF_OK)
1643 goto cleanup;
1645 /* Encode the Validity fields */
1646 if ((ret = encode_validity(asn1, &tbscert->validity)) != KMF_OK)
1647 goto cleanup;
1649 /* Encode the Subject RDN */
1650 if ((ret = encode_rdn(asn1, &tbscert->subject)) != KMF_OK)
1651 goto cleanup;
1653 /* Encode the Subject Public Key Info */
1654 if ((ret = encode_spki(asn1, &tbscert->subjectPublicKeyInfo)) != KMF_OK)
1655 goto cleanup;
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;
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;
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;
1678 /* Close out the TBSCert sequence */
1679 if (kmfber_printf(asn1, "}") == -1) {
1680 ret = KMF_ERR_BAD_CERT_FORMAT;
1681 goto cleanup;
1684 cleanup:
1686 * Memory cleanup is done in the caller or in the individual
1687 * encoding routines.
1690 return (ret);
1693 KMF_RETURN
1694 DerEncodeTbsCertificate(KMF_X509_TBS_CERT *tbs_cert_ptr,
1695 KMF_DATA *enc_tbs_cert_ptr)
1697 KMF_RETURN ret;
1698 BerElement *asn1 = NULL;
1699 BerValue *tbsdata = NULL;
1701 asn1 = kmfder_alloc();
1702 if (asn1 == NULL)
1703 return (KMF_ERR_MEMORY);
1705 enc_tbs_cert_ptr->Data = NULL;
1706 enc_tbs_cert_ptr->Length = 0;
1708 ret = encode_tbs_cert(asn1, tbs_cert_ptr);
1709 if (ret != KMF_OK)
1710 goto cleanup;
1712 if (kmfber_flatten(asn1, &tbsdata) == -1) {
1713 ret = KMF_ERR_MEMORY;
1714 goto cleanup;
1717 enc_tbs_cert_ptr->Data = (uchar_t *)tbsdata->bv_val;
1718 enc_tbs_cert_ptr->Length = tbsdata->bv_len;
1720 cleanup:
1721 if (ret != KMF_OK)
1722 free_data(enc_tbs_cert_ptr);
1724 if (asn1 != NULL)
1725 kmfber_free(asn1, 1);
1727 free(tbsdata);
1729 return (ret);
1732 KMF_RETURN
1733 DerEncodeSignedCertificate(KMF_X509_CERTIFICATE *signed_cert_ptr,
1734 KMF_DATA *encodedcert)
1736 KMF_RETURN ret = KMF_OK;
1737 KMF_X509_TBS_CERT *tbscert = NULL;
1738 KMF_X509_SIGNATURE *signature = NULL;
1739 BerElement *asn1 = NULL;
1740 BerValue *tbsdata = NULL;
1742 if (signed_cert_ptr == NULL || encodedcert == NULL)
1743 return (KMF_ERR_BAD_PARAMETER);
1745 encodedcert->Data = NULL;
1746 encodedcert->Length = 0;
1748 tbscert = &signed_cert_ptr->certificate;
1749 signature = &signed_cert_ptr->signature;
1751 asn1 = kmfder_alloc();
1752 if (asn1 == NULL)
1753 return (KMF_ERR_MEMORY);
1755 /* Start outer X509 Certificate SEQUENCE */
1756 if (kmfber_printf(asn1, "{") == -1) {
1757 ret = KMF_ERR_BAD_CERT_FORMAT;
1758 goto cleanup;
1761 if ((ret = encode_tbs_cert(asn1, tbscert)) != KMF_OK) {
1762 ret = KMF_ERR_BAD_CERT_FORMAT;
1763 goto cleanup;
1766 /* Add the Algorithm & Signature Sequence (no parameters) */
1767 if ((ret = encode_algoid(asn1,
1768 &signature->algorithmIdentifier, FALSE)) != KMF_OK)
1769 goto cleanup;
1771 if (signature->encrypted.Length > 0) {
1772 if (kmfber_printf(asn1, "B", signature->encrypted.Data,
1773 signature->encrypted.Length * 8) == -1) {
1774 ret = KMF_ERR_BAD_CERT_FORMAT;
1775 goto cleanup;
1779 if (kmfber_printf(asn1, "}") == -1) {
1780 ret = KMF_ERR_BAD_CERT_FORMAT;
1781 goto cleanup;
1784 if (kmfber_flatten(asn1, &tbsdata) == -1) {
1785 ret = KMF_ERR_MEMORY;
1786 goto cleanup;
1789 encodedcert->Data = (uchar_t *)tbsdata->bv_val;
1790 encodedcert->Length = tbsdata->bv_len;
1792 cleanup:
1793 if (ret != KMF_OK)
1794 free_data(encodedcert);
1796 free(tbsdata);
1798 if (asn1)
1799 kmfber_free(asn1, 1);
1801 return (ret);
1804 KMF_RETURN
1805 ExtractX509CertParts(KMF_DATA *x509cert, KMF_DATA *tbscert,
1806 KMF_DATA *signature)
1808 KMF_RETURN ret = KMF_OK;
1809 BerElement *der = NULL;
1810 BerValue x509;
1811 ber_tag_t tag;
1812 ber_len_t size;
1814 if (tbscert == NULL || x509cert == NULL)
1815 return (KMF_ERR_BAD_PARAMETER);
1817 x509.bv_val = (char *)x509cert->Data;
1818 x509.bv_len = x509cert->Length;
1820 der = kmfder_init(&x509);
1821 if (der == NULL)
1822 return (KMF_ERR_MEMORY);
1824 /* Skip over the overall Sequence tag to get at the TBS Cert data */
1825 if (kmfber_scanf(der, "Tl", &tag, &size) == -1) {
1826 ret = KMF_ERR_BAD_CERT_FORMAT;
1827 goto cleanup;
1829 if (tag != BER_CONSTRUCTED_SEQUENCE) {
1830 ret = KMF_ERR_BAD_CERT_FORMAT;
1831 goto cleanup;
1835 * Since we are extracting a copy of the ENCODED bytes, we
1836 * must make sure to also include the bytes for the tag and
1837 * the length fields for the CONSTRUCTED SEQUENCE (TBSCert).
1839 size += kmfber_calc_taglen(tag) + kmfber_calc_lenlen(size);
1841 tbscert->Data = malloc(size);
1842 if (tbscert->Data == NULL) {
1843 ret = KMF_ERR_MEMORY;
1844 goto cleanup;
1846 tbscert->Length = size;
1848 /* The der data ptr is now set to the start of the TBS cert sequence */
1849 size = kmfber_read(der, (char *)tbscert->Data, tbscert->Length);
1850 if (size != tbscert->Length) {
1851 ret = KMF_ERR_BAD_CERT_FORMAT;
1852 goto cleanup;
1855 if (signature != NULL) {
1856 KMF_X509_ALGORITHM_IDENTIFIER algoid;
1857 if ((ret = get_algoid(der, &algoid)) != KMF_OK)
1858 goto cleanup;
1859 free_algoid(&algoid);
1861 if (kmfber_scanf(der, "tl", &tag, &size) != BER_BIT_STRING) {
1862 ret = KMF_ERR_BAD_CERT_FORMAT;
1863 goto cleanup;
1865 /* Now get the signature data */
1866 if (kmfber_scanf(der, "B", (char **)&signature->Data,
1867 (ber_len_t *)&signature->Length) == -1) {
1868 ret = KMF_ERR_BAD_CERT_FORMAT;
1869 goto cleanup;
1871 /* convert bitstring length to bytes */
1872 signature->Length = signature->Length / 8;
1875 cleanup:
1876 if (der)
1877 kmfber_free(der, 1);
1879 if (ret != KMF_OK)
1880 free_data(tbscert);
1882 return (ret);
1885 static KMF_RETURN
1886 decode_csr_extensions(BerElement *asn1, KMF_X509_EXTENSIONS *extns)
1888 KMF_RETURN ret = KMF_OK;
1889 BerValue oid;
1891 if (kmfber_scanf(asn1, "{D", &oid) == -1) {
1892 return (KMF_ERR_UNKNOWN_CSR_ATTRIBUTE);
1895 /* We only understand extension requests in a CSR */
1896 if (memcmp(oid.bv_val, extension_request_oid.Data,
1897 oid.bv_len) != 0) {
1898 return (KMF_ERR_UNKNOWN_CSR_ATTRIBUTE);
1901 if (kmfber_scanf(asn1, "[") == -1) {
1902 return (KMF_ERR_ENCODING);
1904 ret = get_extensions(asn1, extns);
1907 return (ret);
1910 static KMF_RETURN
1911 decode_tbscsr_data(BerElement *asn1,
1912 KMF_TBS_CSR **signed_csr_ptr_ptr)
1914 KMF_RETURN ret = KMF_OK;
1915 KMF_TBS_CSR *tbscsr = NULL;
1916 char *end = NULL;
1917 uint32_t version;
1918 ber_tag_t tag;
1919 ber_len_t size;
1921 /* Now get the version number, it is not optional */
1922 if (kmfber_scanf(asn1, "{i", &version) == -1) {
1923 ret = KMF_ERR_BAD_CERT_FORMAT;
1924 goto cleanup;
1927 tbscsr = malloc(sizeof (KMF_TBS_CSR));
1928 if (!tbscsr) {
1929 ret = KMF_ERR_MEMORY;
1930 goto cleanup;
1933 (void) memset(tbscsr, 0, sizeof (KMF_TBS_CSR));
1935 if ((ret = set_der_integer(&tbscsr->version, version)) != KMF_OK)
1936 goto cleanup;
1938 if ((ret = get_rdn(asn1, &tbscsr->subject)) != KMF_OK)
1939 goto cleanup;
1941 if ((ret = get_spki(asn1, &tbscsr->subjectPublicKeyInfo)) != KMF_OK)
1942 goto cleanup;
1944 /* Check for the optional fields (attributes) */
1945 if (kmfber_next_element(asn1, &size, end) == 0xA0) {
1946 if (kmfber_scanf(asn1, "Tl", &tag, &size) == -1) {
1947 ret = KMF_ERR_ENCODING;
1948 goto cleanup;
1951 ret = decode_csr_extensions(asn1, &tbscsr->extensions);
1953 if (ret == KMF_OK)
1954 *signed_csr_ptr_ptr = tbscsr;
1956 cleanup:
1957 if (ret != KMF_OK) {
1958 if (tbscsr) {
1959 free_tbscsr(tbscsr);
1960 free(tbscsr);
1962 *signed_csr_ptr_ptr = NULL;
1964 return (ret);
1967 KMF_RETURN
1968 DerDecodeTbsCsr(const KMF_DATA *Value,
1969 KMF_TBS_CSR **tbscsr)
1971 KMF_RETURN ret = KMF_OK;
1972 BerElement *asn1 = NULL;
1973 BerValue rawcsr;
1974 KMF_TBS_CSR *newcsr = NULL;
1976 if (!tbscsr || !Value || !Value->Data || !Value->Length)
1977 return (KMF_ERR_BAD_PARAMETER);
1979 rawcsr.bv_val = (char *)Value->Data;
1980 rawcsr.bv_len = Value->Length;
1982 if ((asn1 = kmfder_init(&rawcsr)) == NULL)
1983 return (KMF_ERR_MEMORY);
1985 ret = decode_tbscsr_data(asn1, &newcsr);
1986 if (ret != KMF_OK)
1987 goto cleanup;
1989 *tbscsr = newcsr;
1991 cleanup:
1992 if (ret != KMF_OK) {
1993 if (newcsr)
1994 free_tbscsr(newcsr);
1995 *tbscsr = NULL;
1997 kmfber_free(asn1, 1);
1999 return (ret);
2002 KMF_RETURN
2003 DerDecodeSignedCsr(const KMF_DATA *Value,
2004 KMF_CSR_DATA **signed_csr_ptr_ptr)
2006 KMF_RETURN ret = KMF_OK;
2007 BerElement *asn1 = NULL;
2008 BerValue rawcsr;
2009 int tag;
2010 ber_len_t size;
2011 char *end = NULL;
2012 char *signature;
2013 KMF_TBS_CSR *tbscsr = NULL;
2014 KMF_CSR_DATA *csrptr = NULL;
2016 if (!signed_csr_ptr_ptr || !Value || !Value->Data || !Value->Length)
2017 return (KMF_ERR_BAD_PARAMETER);
2019 rawcsr.bv_val = (char *)Value->Data;
2020 rawcsr.bv_len = Value->Length;
2022 if ((asn1 = kmfder_init(&rawcsr)) == NULL)
2023 return (KMF_ERR_MEMORY);
2025 if (kmfber_first_element(asn1, &size, &end) !=
2026 BER_CONSTRUCTED_SEQUENCE) {
2027 ret = KMF_ERR_BAD_CERT_FORMAT;
2028 goto cleanup;
2031 csrptr = malloc(sizeof (KMF_CSR_DATA));
2032 if (csrptr == NULL) {
2033 ret = KMF_ERR_MEMORY;
2034 goto cleanup;
2036 (void) memset(csrptr, 0, sizeof (KMF_CSR_DATA));
2038 ret = decode_tbscsr_data(asn1, &tbscsr);
2039 if (ret != KMF_OK)
2040 goto cleanup;
2042 csrptr->csr = *tbscsr;
2043 free(tbscsr);
2044 tbscsr = NULL;
2046 if ((ret = get_algoid(asn1,
2047 &csrptr->signature.algorithmIdentifier)) != KMF_OK)
2048 goto cleanup;
2050 /* Check to see if the cert has a signature yet */
2051 if (kmfber_next_element(asn1, &size, end) == BER_BIT_STRING) {
2052 /* Finally, get the encrypted signature BITSTRING */
2053 if (kmfber_scanf(asn1, "tl", &tag, &size) == -1) {
2054 ret = KMF_ERR_BAD_CERT_FORMAT;
2055 goto cleanup;
2057 if (tag != BER_BIT_STRING) {
2058 ret = KMF_ERR_BAD_CERT_FORMAT;
2059 goto cleanup;
2061 if (kmfber_scanf(asn1, "B}", &signature, &size) == -1) {
2062 ret = KMF_ERR_BAD_CERT_FORMAT;
2063 goto cleanup;
2065 csrptr->signature.encrypted.Data = (uchar_t *)signature;
2066 csrptr->signature.encrypted.Length = size / 8;
2067 } else {
2068 csrptr->signature.encrypted.Data = NULL;
2069 csrptr->signature.encrypted.Length = 0;
2072 *signed_csr_ptr_ptr = csrptr;
2073 cleanup:
2074 if (ret != KMF_OK) {
2075 free_tbscsr(&csrptr->csr);
2076 free_algoid(&csrptr->signature.algorithmIdentifier);
2077 free(csrptr->signature.encrypted.Data);
2079 free(csrptr);
2081 *signed_csr_ptr_ptr = NULL;
2083 if (asn1)
2084 kmfber_free(asn1, 1);
2086 return (ret);
2090 static KMF_RETURN
2091 encode_csr_extensions(BerElement *asn1, KMF_TBS_CSR *tbscsr)
2093 KMF_RETURN ret = KMF_OK;
2094 int attlen = 0;
2095 BerElement *extnasn1 = NULL;
2096 BerValue *extnvalue = NULL;
2098 /* Optional field: CSR attributes and extensions */
2099 if (tbscsr->extensions.numberOfExtensions > 0) {
2100 if (kmfber_printf(asn1, "T", 0xA0) == -1) {
2101 ret = KMF_ERR_ENCODING;
2102 goto cleanup;
2104 } else {
2105 /* No extensions or attributes to encode */
2106 return (KMF_OK);
2110 * attributes [0] Attributes
2111 * Attributes := SET OF Attribute
2112 * Attribute := SEQUENCE {
2113 * { ATTRIBUTE ID
2114 * values SET SIZE(1..MAX) of ATTRIBUTE
2117 * Ex: { ExtensionRequest OID [ { {extn1 } , {extn2 } } ] }
2121 * Encode any extensions and add to the attributes section.
2123 if (tbscsr->extensions.numberOfExtensions > 0) {
2124 extnasn1 = kmfder_alloc();
2125 if (extnasn1 == NULL) {
2126 ret = KMF_ERR_MEMORY;
2127 goto cleanup;
2130 if (kmfber_printf(extnasn1, "{D[{",
2131 &extension_request_oid) == -1) {
2132 ret = KMF_ERR_ENCODING;
2133 goto cleanup_1;
2136 if ((ret = encode_extension_list(extnasn1,
2137 &tbscsr->extensions)) != KMF_OK) {
2138 goto cleanup_1;
2141 if (kmfber_printf(extnasn1, "}]}") == -1) {
2142 ret = KMF_ERR_ENCODING;
2143 goto cleanup_1;
2146 if (kmfber_flatten(extnasn1, &extnvalue) == -1) {
2147 ret = KMF_ERR_MEMORY;
2148 goto cleanup_1;
2150 cleanup_1:
2151 kmfber_free(extnasn1, 1);
2153 if (ret == KMF_OK)
2154 /* Add 2 bytes to cover the tag and the length */
2155 attlen = extnvalue->bv_len;
2157 if (ret != KMF_OK)
2158 goto cleanup;
2160 if (kmfber_printf(asn1, "l", attlen) == -1) {
2161 ret = KMF_ERR_ENCODING;
2162 goto cleanup;
2165 /* Write the actual encoded extensions */
2166 if (extnvalue != NULL && extnvalue->bv_val != NULL) {
2167 if (kmfber_write(asn1, extnvalue->bv_val,
2168 extnvalue->bv_len, 0) == -1) {
2169 ret = KMF_ERR_ENCODING;
2170 goto cleanup;
2174 cleanup:
2176 * Memory cleanup is done in the caller or in the individual
2177 * encoding routines.
2179 if (extnvalue) {
2180 free(extnvalue->bv_val);
2181 free(extnvalue);
2184 return (ret);
2187 static KMF_RETURN
2188 encode_tbs_csr(BerElement *asn1, KMF_TBS_CSR *tbscsr)
2190 KMF_RETURN ret = KMF_OK;
2191 uint32_t version;
2193 /* Start the version */
2194 (void) memcpy(&version, tbscsr->version.Data,
2195 tbscsr->version.Length);
2197 if (kmfber_printf(asn1, "{i", version) == -1) {
2198 ret = KMF_ERR_BAD_CERT_FORMAT;
2199 goto cleanup;
2202 /* Encode the Subject RDN */
2203 if ((ret = encode_rdn(asn1, &tbscsr->subject)) != KMF_OK)
2204 goto cleanup;
2206 /* Encode the Subject Public Key Info */
2207 if ((ret = encode_spki(asn1, &tbscsr->subjectPublicKeyInfo)) != KMF_OK)
2208 goto cleanup;
2210 if ((ret = encode_csr_extensions(asn1, tbscsr)) != KMF_OK)
2211 goto cleanup;
2213 /* Close out the TBSCert sequence */
2214 if (kmfber_printf(asn1, "}") == -1) {
2215 ret = KMF_ERR_BAD_CERT_FORMAT;
2216 goto cleanup;
2219 cleanup:
2220 return (ret);
2223 KMF_RETURN
2224 DerEncodeDSAPrivateKey(KMF_DATA *encodedkey, KMF_RAW_DSA_KEY *dsa)
2226 KMF_RETURN rv = KMF_OK;
2227 BerElement *asn1 = NULL;
2228 BerValue *dsadata = NULL;
2230 asn1 = kmfder_alloc();
2231 if (asn1 == NULL)
2232 return (KMF_ERR_MEMORY);
2234 if (kmfber_printf(asn1, "I",
2235 dsa->value.val, dsa->value.len) == -1) {
2236 rv = KMF_ERR_MEMORY;
2237 goto cleanup;
2240 if (kmfber_flatten(asn1, &dsadata) == -1) {
2241 rv = KMF_ERR_MEMORY;
2242 goto cleanup;
2245 encodedkey->Data = (uchar_t *)dsadata->bv_val;
2246 encodedkey->Length = dsadata->bv_len;
2248 free(dsadata);
2249 cleanup:
2250 kmfber_free(asn1, 1);
2251 return (rv);
2254 KMF_RETURN
2255 DerEncodeRSAPrivateKey(KMF_DATA *encodedkey, KMF_RAW_RSA_KEY *rsa)
2257 KMF_RETURN rv = KMF_OK;
2258 BerElement *asn1 = NULL;
2259 uchar_t ver = 0;
2260 BerValue *rsadata = NULL;
2262 asn1 = kmfder_alloc();
2263 if (asn1 == NULL)
2264 return (KMF_ERR_MEMORY);
2266 if (kmfber_printf(asn1, "{IIIIIIIII}",
2267 &ver, 1,
2268 rsa->mod.val, rsa->mod.len,
2269 rsa->pubexp.val, rsa->pubexp.len,
2270 rsa->priexp.val, rsa->priexp.len,
2271 rsa->prime1.val, rsa->prime1.len,
2272 rsa->prime2.val, rsa->prime2.len,
2273 rsa->exp1.val, rsa->exp1.len,
2274 rsa->exp2.val, rsa->exp2.len,
2275 rsa->coef.val, rsa->coef.len) == -1)
2276 goto cleanup;
2278 if (kmfber_flatten(asn1, &rsadata) == -1) {
2279 rv = KMF_ERR_MEMORY;
2280 goto cleanup;
2283 encodedkey->Data = (uchar_t *)rsadata->bv_val;
2284 encodedkey->Length = rsadata->bv_len;
2286 free(rsadata);
2287 cleanup:
2288 kmfber_free(asn1, 1);
2289 return (rv);
2292 KMF_RETURN
2293 DerEncodeECPrivateKey(KMF_DATA *encodedkey, KMF_RAW_EC_KEY *eckey)
2295 KMF_RETURN rv = KMF_OK;
2296 BerElement *asn1 = NULL;
2297 uchar_t ver = 1;
2298 BerValue *data = NULL;
2300 asn1 = kmfder_alloc();
2301 if (asn1 == NULL)
2302 return (KMF_ERR_MEMORY);
2304 if (kmfber_printf(asn1, "{io",
2305 ver, eckey->value.val, eckey->value.len) == -1) {
2306 rv = KMF_ERR_ENCODING;
2307 goto cleanup;
2310 * Indicate that we are using the named curve option
2311 * for the parameters.
2313 if (kmfber_printf(asn1, "T", 0xA0) == -1) {
2314 rv = KMF_ERR_ENCODING;
2315 goto cleanup;
2317 if (kmfber_printf(asn1, "l", eckey->params.Length) == -1) {
2318 rv = KMF_ERR_ENCODING;
2319 goto cleanup;
2321 if (kmfber_write(asn1, (char *)eckey->params.Data,
2322 eckey->params.Length, 0) == -1) {
2323 rv = KMF_ERR_ENCODING;
2324 goto cleanup;
2326 if (kmfber_printf(asn1, "}") == -1) {
2327 rv = KMF_ERR_ENCODING;
2328 goto cleanup;
2330 if (kmfber_flatten(asn1, &data) == -1) {
2331 rv = KMF_ERR_MEMORY;
2332 goto cleanup;
2334 encodedkey->Data = (uchar_t *)data->bv_val;
2335 encodedkey->Length = data->bv_len;
2337 cleanup:
2338 kmfber_free(asn1, 1);
2339 return (rv);
2343 KMF_RETURN
2344 DerEncodeTbsCsr(KMF_TBS_CSR *tbs_csr_ptr,
2345 KMF_DATA *enc_tbs_csr_ptr)
2347 KMF_RETURN ret;
2348 BerValue *tbsdata = NULL;
2349 BerElement *asn1 = NULL;
2351 asn1 = kmfder_alloc();
2353 enc_tbs_csr_ptr->Data = NULL;
2354 enc_tbs_csr_ptr->Length = 0;
2356 if (asn1 == NULL)
2357 return (KMF_ERR_MEMORY);
2359 ret = encode_tbs_csr(asn1, tbs_csr_ptr);
2360 if (ret != KMF_OK)
2361 goto cleanup;
2363 if (kmfber_flatten(asn1, &tbsdata) == -1) {
2364 ret = KMF_ERR_MEMORY;
2365 goto cleanup;
2368 enc_tbs_csr_ptr->Data = (uchar_t *)tbsdata->bv_val;
2369 enc_tbs_csr_ptr->Length = tbsdata->bv_len;
2371 cleanup:
2372 if (ret != KMF_OK)
2373 free_data(enc_tbs_csr_ptr);
2375 if (asn1 != NULL)
2376 kmfber_free(asn1, 1);
2378 free(tbsdata);
2380 return (ret);
2383 KMF_RETURN
2384 DerEncodeSignedCsr(KMF_CSR_DATA *signed_csr_ptr,
2385 KMF_DATA *encodedcsr)
2387 KMF_RETURN ret = KMF_OK;
2388 KMF_TBS_CSR *tbscsr = NULL;
2389 KMF_X509_SIGNATURE *signature = NULL;
2390 BerElement *asn1 = NULL;
2391 BerValue *tbsdata = NULL;
2393 if (signed_csr_ptr == NULL)
2394 return (KMF_ERR_BAD_PARAMETER);
2396 tbscsr = &signed_csr_ptr->csr;
2397 signature = &signed_csr_ptr->signature;
2399 asn1 = kmfder_alloc();
2400 if (asn1 == NULL)
2401 return (KMF_ERR_MEMORY);
2403 /* Start outer CSR SEQUENCE */
2404 if (kmfber_printf(asn1, "{") == -1) {
2405 ret = KMF_ERR_BAD_CERT_FORMAT;
2406 goto cleanup;
2409 ret = encode_tbs_csr(asn1, tbscsr);
2411 /* Add the Algorithm & Signature Sequence */
2412 if ((ret = encode_algoid(asn1,
2413 &signature->algorithmIdentifier, FALSE)) != KMF_OK)
2414 goto cleanup;
2416 if (signature->encrypted.Length > 0) {
2417 if (kmfber_printf(asn1, "B", signature->encrypted.Data,
2418 signature->encrypted.Length * 8) == -1) {
2419 ret = KMF_ERR_BAD_CERT_FORMAT;
2420 goto cleanup;
2424 if (kmfber_printf(asn1, "}") == -1) {
2425 ret = KMF_ERR_BAD_CERT_FORMAT;
2426 goto cleanup;
2429 if (kmfber_flatten(asn1, &tbsdata) == -1) {
2430 ret = KMF_ERR_MEMORY;
2431 goto cleanup;
2434 encodedcsr->Data = (uchar_t *)tbsdata->bv_val;
2435 encodedcsr->Length = tbsdata->bv_len;
2437 cleanup:
2438 if (ret != KMF_OK) {
2439 free_data(encodedcsr);
2442 free(tbsdata);
2444 if (asn1)
2445 kmfber_free(asn1, 1);
2446 return (ret);
2449 static KMF_RETURN
2450 ber_copy_data(KMF_DATA *dst, KMF_DATA *src)
2452 KMF_RETURN ret = KMF_OK;
2454 if (dst == NULL || src == NULL)
2455 return (KMF_ERR_BAD_PARAMETER);
2457 dst->Data = malloc(src->Length);
2458 if (dst->Data == NULL)
2459 return (KMF_ERR_MEMORY);
2461 dst->Length = src->Length;
2462 (void) memcpy(dst->Data, src->Data, src->Length);
2464 return (ret);
2467 KMF_RETURN
2468 ExtractSPKIData(
2469 const KMF_X509_SPKI *pKey,
2470 KMF_ALGORITHM_INDEX AlgorithmId,
2471 KMF_DATA *pKeyParts,
2472 uint32_t *uNumKeyParts)
2474 KMF_RETURN ret = KMF_OK;
2475 BerElement *asn1 = NULL;
2476 BerValue *P, *Q, *G, *Mod, *Exp, *PubKey;
2477 BerValue PubKeyParams, PubKeyData;
2479 if (pKeyParts == NULL || uNumKeyParts == NULL || pKey == NULL)
2480 return (KMF_ERR_BAD_PARAMETER);
2482 switch (AlgorithmId) {
2483 case KMF_ALGID_DSA:
2484 case KMF_ALGID_SHA1WithDSA:
2485 *uNumKeyParts = 0;
2486 /* Get the parameters from the algorithm definition */
2487 PubKeyParams.bv_val =
2488 (char *)pKey->algorithm.parameters.Data;
2489 PubKeyParams.bv_len = pKey->algorithm.parameters.Length;
2490 if ((asn1 = kmfder_init(&PubKeyParams)) == NULL)
2491 return (KMF_ERR_MEMORY);
2493 if (kmfber_scanf(asn1, "{III}", &P, &Q, &G) == -1) {
2494 kmfber_free(asn1, 1);
2495 return (KMF_ERR_BAD_KEY_FORMAT);
2497 pKeyParts[KMF_DSA_PRIME].Data = (uchar_t *)P->bv_val;
2498 pKeyParts[KMF_DSA_PRIME].Length = P->bv_len;
2499 pKeyParts[KMF_DSA_SUB_PRIME].Data =
2500 (uchar_t *)Q->bv_val;
2501 pKeyParts[KMF_DSA_SUB_PRIME].Length = Q->bv_len;
2502 pKeyParts[KMF_DSA_BASE].Data = (uchar_t *)G->bv_val;
2503 pKeyParts[KMF_DSA_BASE].Length = G->bv_len;
2505 free(P);
2506 free(Q);
2507 free(G);
2508 kmfber_free(asn1, 1);
2510 /* Get the PubKey data */
2511 PubKeyData.bv_val = (char *)pKey->subjectPublicKey.Data;
2512 PubKeyData.bv_len = pKey->subjectPublicKey.Length;
2513 if ((asn1 = kmfder_init(&PubKeyData)) == NULL) {
2514 ret = KMF_ERR_MEMORY;
2515 goto cleanup;
2517 PubKey = NULL;
2518 if (kmfber_scanf(asn1, "I", &PubKey) == -1) {
2519 ret = KMF_ERR_BAD_KEY_FORMAT;
2520 goto cleanup;
2522 pKeyParts[KMF_DSA_PUBLIC_VALUE].Data =
2523 (uchar_t *)PubKey->bv_val;
2524 pKeyParts[KMF_DSA_PUBLIC_VALUE].Length = PubKey->bv_len;
2526 free(PubKey);
2528 *uNumKeyParts = KMF_NUMBER_DSA_PUBLIC_KEY_PARTS;
2529 break;
2530 case KMF_ALGID_SHA1WithECDSA:
2531 case KMF_ALGID_ECDSA:
2532 (void) ber_copy_data(&pKeyParts[KMF_ECDSA_PARAMS],
2533 (KMF_DATA *)&pKey->algorithm.parameters);
2535 (void) ber_copy_data(&pKeyParts[KMF_ECDSA_POINT],
2536 (KMF_DATA *)&pKey->subjectPublicKey);
2538 *uNumKeyParts = 2;
2539 break;
2541 case KMF_ALGID_RSA:
2542 case KMF_ALGID_MD2WithRSA:
2543 case KMF_ALGID_MD5WithRSA:
2544 case KMF_ALGID_SHA1WithRSA:
2545 *uNumKeyParts = 0;
2546 PubKeyData.bv_val = (char *)pKey->subjectPublicKey.Data;
2547 PubKeyData.bv_len = pKey->subjectPublicKey.Length;
2548 if ((asn1 = kmfder_init(&PubKeyData)) == NULL) {
2549 ret = KMF_ERR_MEMORY;
2550 goto cleanup;
2552 if (kmfber_scanf(asn1, "{II}", &Mod, &Exp) == -1) {
2553 ret = KMF_ERR_BAD_KEY_FORMAT;
2554 goto cleanup;
2556 pKeyParts[KMF_RSA_MODULUS].Data =
2557 (uchar_t *)Mod->bv_val;
2558 pKeyParts[KMF_RSA_MODULUS].Length = Mod->bv_len;
2559 pKeyParts[KMF_RSA_PUBLIC_EXPONENT].Data =
2560 (uchar_t *)Exp->bv_val;
2561 pKeyParts[KMF_RSA_PUBLIC_EXPONENT].Length = Exp->bv_len;
2562 *uNumKeyParts = KMF_NUMBER_RSA_PUBLIC_KEY_PARTS;
2564 free(Mod);
2565 free(Exp);
2566 break;
2567 default:
2568 return (KMF_ERR_BAD_PARAMETER);
2570 cleanup:
2571 if (ret != KMF_OK) {
2572 int i;
2573 for (i = 0; i < *uNumKeyParts; i++)
2574 free_data(&pKeyParts[i]);
2576 if (asn1 != NULL) {
2577 kmfber_free(asn1, 1);
2580 return (ret);