2 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
6 * Copyright (c) 1995-1999 Intel Corporation. All rights reserved.
12 #include <kmfber_int.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
};
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
;
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
);
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
;
56 free_data(KMF_DATA
*data
)
58 if (data
== NULL
|| data
->Data
== NULL
)
67 free_algoid(KMF_X509_ALGORITHM_IDENTIFIER
*algoid
)
69 free_data(&algoid
->algorithm
);
70 free_data(&algoid
->parameters
);
74 free_decoded_spki(KMF_X509_SPKI
*spki
)
77 free_algoid(&spki
->algorithm
);
78 free_data(&spki
->subjectPublicKey
);
83 free_rdn_data(KMF_X509_NAME
*name
)
85 KMF_X509_RDN
*newrdn
= NULL
;
86 KMF_X509_TYPE_VALUE_PAIR
*av
= NULL
;
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
];
95 free_data(&av
->value
);
97 free(newrdn
->AttributeTypeAndValue
);
99 free(name
->RelativeDistinguishedName
);
100 name
->numberOfRDNs
= 0;
101 name
->RelativeDistinguishedName
= NULL
;
106 free_validity(KMF_X509_VALIDITY
*validity
)
108 free_data(&validity
->notBefore
.time
);
109 free_data(&validity
->notAfter
.time
);
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
);
125 free_extensions(KMF_X509_EXTENSIONS
*extns
)
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
;
142 free_tbscsr(KMF_TBS_CSR
*tbscsr
)
145 free_data(&tbscsr
->version
);
147 free_rdn_data(&tbscsr
->subject
);
149 free_decoded_spki(&tbscsr
->subjectPublicKeyInfo
);
151 free_extensions(&tbscsr
->extensions
);
157 free_bigint(KMF_BIGINT
*bn
)
159 if (bn
!= NULL
&& bn
->val
!= NULL
) {
167 free_tbscert(KMF_X509_TBS_CERT
*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
);
190 free_decoded_cert(KMF_X509_CERTIFICATE
*certptr
)
195 free_tbscert(&certptr
->certificate
);
197 free_algoid(&certptr
->signature
.algorithmIdentifier
);
198 free_data(&certptr
->signature
.encrypted
);
202 get_sequence_data(BerElement
*asn1
, BerValue
*seqdata
)
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
) ==
218 return (KMF_ERR_BAD_CERT_FORMAT
);
220 seqdata
->bv_len
= size
;
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
) ==
240 return (KMF_ERR_BAD_CERT_FORMAT
);
242 seqdata
->bv_len
= size
;
247 get_algoid(BerElement
*asn1
, KMF_X509_ALGORITHM_IDENTIFIER
*algoid
)
249 KMF_RETURN rv
= KMF_OK
;
252 BerValue algoid_data
;
254 BerElement
*oidasn1
= NULL
;
256 /* Read the entire OID seq into it's own data block */
257 rv
= get_sequence_data(asn1
, &algoid_data
);
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);
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;
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
;
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
) {
307 /* read the raw data into the Algoritm params area. */
308 if (kmfber_read(oidasn1
, (char *)algoid
->parameters
.Data
,
310 rv
= KMF_ERR_BAD_CERT_FORMAT
;
313 algoid
->parameters
.Length
= size
;
319 kmfber_free(oidasn1
, 1);
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
);
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
349 if ((ret
= encode_algoid(asn1
, &spki
->algorithm
, TRUE
)) != KMF_OK
)
352 if (kmfber_printf(asn1
, "B}", spki
->subjectPublicKey
.Data
,
353 spki
->subjectPublicKey
.Length
* 8) == -1)
354 return (KMF_ERR_BAD_CERT_FORMAT
);
360 DerEncodeSPKI(KMF_X509_SPKI
*spki
, KMF_DATA
*EncodedSPKI
)
362 KMF_RETURN ret
= KMF_OK
;
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
) {
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
;
385 kmfber_free(asn1
, 1);
390 get_spki(BerElement
*asn1
, KMF_X509_SPKI
*spki
)
392 KMF_RETURN ret
= KMF_OK
;
396 if (kmfber_scanf(asn1
, "{") == -1)
397 return (KMF_ERR_BAD_CERT_FORMAT
);
399 if ((ret
= get_algoid(asn1
, &spki
->algorithm
)) != KMF_OK
)
402 if (kmfber_scanf(asn1
, "B}", &bitstr
, &size
) == BER_BIT_STRING
) {
403 spki
->subjectPublicKey
.Data
= (uchar_t
*)bitstr
;
404 spki
->subjectPublicKey
.Length
= size
/ 8;
406 ret
= KMF_ERR_BAD_CERT_FORMAT
;
412 spki
->subjectPublicKey
.Data
= NULL
;
413 spki
->subjectPublicKey
.Length
= 0;
415 free_algoid(&spki
->algorithm
);
422 DerEncodeDSASignature(KMF_DATA
*rawdata
, KMF_DATA
*signature
)
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();
436 return (KMF_ERR_MEMORY
);
439 * The [EC]DSA signature is the concatenation of 2
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);
464 * ECDSA and DSA encode signatures the same way.
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.
479 convert_signed_to_fixed(BerValue
*src
, BerValue
*dst
)
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
,
491 if (dst
->bv_len
== src
->bv_len
) {
492 (void) memcpy(dst
->bv_val
, src
->bv_val
,
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
;
504 return (KMF_ERR_ENCODING
);
506 (void) memcpy(dst
->bv_val
, p
, dst
->bv_len
);
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
||
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
;
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
550 if ((R
->bv_len
% 2) != 0)
552 if ((S
->bv_len
% 2) != 0)
555 signature
->Data
= malloc(signature
->Length
);
556 if (signature
->Data
== NULL
) {
557 ret
= KMF_ERR_MEMORY
;
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
);
579 ret
= convert_signed_to_fixed(S
, &fixedS
);
589 if (asn1
) kmfber_free(asn1
, 1);
595 DerDecodeECDSASignature(KMF_DATA
*encoded
, KMF_DATA
*signature
)
597 /* ECDSA can be decoded using same code as standard DSA */
598 return (DerDecodeDSASignature(encoded
, signature
));
602 DerDecodeSPKI(KMF_DATA
*EncodedSPKI
, KMF_X509_SPKI
*spki
)
604 KMF_RETURN ret
= KMF_OK
;
608 if (EncodedSPKI
== NULL
|| EncodedSPKI
->Data
== 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
);
624 free_decoded_spki(spki
);
626 kmfber_free(asn1
, 1);
632 CopySPKI(KMF_X509_SPKI
*src
,
633 KMF_X509_SPKI
**dest
)
635 KMF_RETURN ret
= KMF_OK
;
636 KMF_X509_SPKI
*newspki
;
640 newspki
= malloc(sizeof (KMF_X509_SPKI
));
642 return (KMF_ERR_MEMORY
);
643 (void) memset(newspki
, 0, sizeof (KMF_X509_SPKI
));
645 ret
= CopyData(&src
->algorithm
.algorithm
,
646 &newspki
->algorithm
.algorithm
);
650 ret
= CopyData(&src
->algorithm
.parameters
,
651 &newspki
->algorithm
.parameters
);
655 ret
= CopyData(&src
->subjectPublicKey
,
656 &newspki
->subjectPublicKey
);
664 free_decoded_spki(newspki
);
670 encode_validity(BerElement
*asn1
, KMF_X509_VALIDITY
*validity
)
674 ret
= kmfber_printf(asn1
, "{tsts}",
675 validity
->notBefore
.timeType
,
676 validity
->notBefore
.time
.Data
,
677 validity
->notAfter
.timeType
,
678 validity
->notAfter
.time
.Data
);
681 return (KMF_ERR_BAD_CERT_FORMAT
);
687 get_validity(BerElement
*asn1
, KMF_X509_VALIDITY
*validity
)
689 KMF_RETURN ret
= KMF_OK
;
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
);
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
;
733 rdnslot
= &name
->RelativeDistinguishedName
[name
->numberOfRDNs
-1];
736 (void) memcpy(rdnslot
, newrdn
, sizeof (KMF_X509_RDN
));
738 rdnslot
->numberOfPairs
= 0;
739 rdnslot
->AttributeTypeAndValue
= NULL
;
743 /* No cleanup needed here */
748 encode_rdn(BerElement
*asn1
, KMF_X509_NAME
*name
)
750 KMF_RETURN ret
= KMF_OK
;
751 KMF_X509_TYPE_VALUE_PAIR
*attrtvpair
= NULL
;
755 if (kmfber_printf(asn1
, "{") == -1) {
756 ret
= KMF_ERR_MEMORY
;
760 for (i
= 0; i
< name
->numberOfRDNs
; i
++) {
761 if (kmfber_printf(asn1
, "[") == -1) {
762 ret
= KMF_ERR_MEMORY
;
765 rdn
= &name
->RelativeDistinguishedName
[i
];
766 attrtvpair
= rdn
->AttributeTypeAndValue
;
768 if (rdn
->numberOfPairs
> 0) {
769 if (kmfber_printf(asn1
, "{Dto}",
771 attrtvpair
->valueType
,
772 attrtvpair
->value
.Data
,
773 attrtvpair
->value
.Length
) == -1) {
774 ret
= KMF_ERR_MEMORY
;
778 if (kmfber_printf(asn1
, "]") == -1) {
779 ret
= KMF_ERR_MEMORY
;
784 if (kmfber_printf(asn1
, "}") == -1) {
785 ret
= KMF_ERR_MEMORY
;
790 /* No cleanup needed here */
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
;
807 newname
= malloc(sizeof (KMF_X509_NAME
));
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
) {
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
));
831 ret
= KMF_ERR_MEMORY
;
834 (void) memset(av
, 0, dstrdn
->numberOfPairs
*
835 sizeof (KMF_X509_TYPE_VALUE_PAIR
));
837 dstrdn
->AttributeTypeAndValue
= av
;
839 ret
= KMF_ERR_MEMORY
;
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
)
849 dstav
->valueType
= srcav
->valueType
;
850 if ((ret
= CopyData(&srcav
->value
,
851 &dstav
->value
)) != KMF_OK
)
855 dstrdn
->AttributeTypeAndValue
= NULL
;
863 free_rdn_data(newname
);
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))
880 get_rdn(BerElement
*asn1
, KMF_X509_NAME
*name
)
882 KMF_RETURN ret
= KMF_OK
;
887 char *AttrValue
= NULL
;
888 KMF_X509_TYPE_VALUE_PAIR
*newpair
= NULL
;
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
) {
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
;
929 /* An "empty" set member means we tack on an empty node */
931 if ((ret
= AddRDN(name
, NULL
)) != KMF_OK
)
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
;
942 if (!(VALID_DIRECTORYSTRING_TAG(tag
))) {
943 ret
= KMF_ERR_BAD_CERT_FORMAT
;
947 if (kmfber_scanf(asn1
, "a}]", &AttrValue
) == -1) {
948 ret
= KMF_ERR_BAD_CERT_FORMAT
;
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
;
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
)
981 set_der_integer(KMF_DATA
*data
, int value
)
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));
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
,
1014 encode_uniqueid(BerElement
*asn1
, int tag
, KMF_DATA
*id
)
1016 KMF_RETURN ret
= KMF_OK
;
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
);
1029 encode_extension_list(BerElement
*asn1
, KMF_X509_EXTENSIONS
*extns
)
1031 KMF_RETURN ret
= KMF_OK
;
1034 for (i
= 0; i
< extns
->numberOfExtensions
; i
++) {
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
;
1044 if (extns
->extensions
[i
].critical
) {
1045 if (kmfber_printf(asn1
, "b",
1046 extns
->extensions
[i
].critical
) == -1) {
1047 ret
= KMF_ERR_ENCODING
;
1052 if (kmfber_printf(asn1
, "o}",
1053 extns
->extensions
[i
].BERvalue
.Data
,
1054 extns
->extensions
[i
].BERvalue
.Length
) == -1) {
1055 ret
= KMF_ERR_ENCODING
;
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();
1072 return (KMF_ERR_MEMORY
);
1074 if (kmfber_printf(extn
, "{") == -1) {
1075 ret
= KMF_ERR_ENCODING
;
1079 ret
= encode_extension_list(extn
, extns
);
1081 if (kmfber_printf(extn
, "}") == -1) {
1082 ret
= KMF_ERR_ENCODING
;
1086 if (kmfber_flatten(extn
, &extnvalue
) == -1) {
1087 ret
= KMF_ERR_MEMORY
;
1091 if (kmfber_printf(asn1
, "Tl", 0xA3, extnvalue
->bv_len
) == -1) {
1092 ret
= KMF_ERR_BAD_CERT_FORMAT
;
1096 if (kmfber_write(asn1
, extnvalue
->bv_val
, extnvalue
->bv_len
, 0) == -1) {
1097 ret
= KMF_ERR_BAD_CERT_FORMAT
;
1102 kmfber_free(extn
, 1);
1103 if (extnvalue
!= NULL
)
1104 kmfber_bvfree(extnvalue
);
1110 get_one_extension(BerElement
*asn1
, KMF_X509_EXTENSION
**retex
, char *end
)
1112 KMF_RETURN ret
= KMF_OK
;
1115 KMF_X509_EXTENSION
*ex
= NULL
;
1118 BerElement
*extnber
= NULL
;
1120 if (kmfber_scanf(asn1
, "T", &tag
) == -1) {
1121 ret
= KMF_ERR_BAD_CERT_FORMAT
;
1125 tag
= kmfber_next_element(asn1
, &size
, end
);
1126 if (tag
!= BER_OBJECT_IDENTIFIER
) {
1127 ret
= KMF_ERR_BAD_CERT_FORMAT
;
1130 if (kmfber_scanf(asn1
, "D", &extOID
) == -1) {
1131 ret
= KMF_ERR_BAD_CERT_FORMAT
;
1135 tag
= kmfber_next_element(asn1
, &size
, end
);
1136 if (tag
!= BER_BOOLEAN
) {
1138 if (tag
!= BER_OCTET_STRING
)
1141 if (kmfber_scanf(asn1
, "b", &critical
) == -1)
1145 tag
= kmfber_next_element(asn1
, &size
, end
);
1146 if (tag
!= BER_OCTET_STRING
) {
1147 ret
= KMF_ERR_BAD_CERT_FORMAT
;
1150 if (kmfber_scanf(asn1
, "o", &extValue
) == -1) {
1151 ret
= KMF_ERR_BAD_CERT_FORMAT
;
1155 /* allocate a new Extension record */
1156 ex
= malloc(sizeof (KMF_X509_EXTENSION
));
1158 ret
= KMF_ERR_MEMORY
;
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
;
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
;
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
;
1192 if (kmfber_scanf(extnber
, "T", &tag
) == -1) {
1193 ret
= KMF_ERR_BAD_CERT_FORMAT
;
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
;
1205 kmfber_free(extnber
, 1);
1206 ex
->value
.tagAndValue
->type
= tag
;
1210 if (ret
!= KMF_OK
) {
1212 free_one_extension(ex
);
1219 get_extensions(BerElement
*asn1
, KMF_X509_EXTENSIONS
*extns
)
1221 KMF_RETURN ret
= KMF_OK
;
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 }
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
);
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
;
1255 extns
->extensions
[extns
->numberOfExtensions
-1] = *ex
;
1261 free_extensions(extns
);
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
;
1273 struct berval
*bvserno
= NULL
;
1276 if (kmfber_scanf(asn1
, "{t", &tag
) == -1) {
1277 ret
= KMF_ERR_BAD_CERT_FORMAT
;
1281 /* Version number is optional */
1283 if (kmfber_scanf(asn1
, "Ti", &tag
, &version
) == -1) {
1284 ret
= KMF_ERR_BAD_CERT_FORMAT
;
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
;
1296 serno
.val
= (uchar_t
*)bvserno
->bv_val
;
1297 serno
.len
= bvserno
->bv_len
;
1300 tbscert
= malloc(sizeof (KMF_X509_TBS_CERT
));
1302 ret
= KMF_ERR_MEMORY
;
1306 (void) memset(tbscert
, 0, sizeof (KMF_X509_TBS_CERT
));
1308 if ((ret
= set_der_integer(&tbscert
->version
, version
)) != KMF_OK
)
1311 if ((ret
= set_bigint(&tbscert
->serialNumber
, &serno
)) != KMF_OK
)
1314 if ((ret
= get_algoid(asn1
, &tbscert
->signature
)) != KMF_OK
)
1317 if ((ret
= get_rdn(asn1
, &tbscert
->issuer
)) != KMF_OK
)
1320 if ((ret
= get_validity(asn1
, &tbscert
->validity
)) != KMF_OK
)
1323 if ((ret
= get_rdn(asn1
, &tbscert
->subject
)) != KMF_OK
)
1326 if ((ret
= get_spki(asn1
, &tbscert
->subjectPublicKeyInfo
)) != KMF_OK
)
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)) {
1338 /* consume the tag and length */
1339 (void) kmfber_scanf(asn1
, "T", &tag
);
1342 if (kmfber_scanf(asn1
, "B", &optfield
, &len
) !=
1344 ret
= KMF_ERR_BAD_CERT_FORMAT
;
1347 tbscert
->issuerUniqueIdentifier
.Data
=
1348 (uchar_t
*)optfield
;
1349 tbscert
->issuerUniqueIdentifier
.Length
=
1353 if (kmfber_scanf(asn1
, "B", &optfield
, &len
) !=
1355 ret
= KMF_ERR_BAD_CERT_FORMAT
;
1358 tbscert
->subjectUniqueIdentifier
.Data
=
1359 (uchar_t
*)optfield
;
1360 tbscert
->subjectUniqueIdentifier
.Length
=
1364 ret
= get_extensions(asn1
, &tbscert
->extensions
);
1369 *signed_cert_ptr_ptr
= tbscert
;
1372 if (bvserno
!= NULL
) {
1373 free(bvserno
->bv_val
);
1376 if (ret
!= KMF_OK
) {
1378 free_tbscert(tbscert
);
1381 *signed_cert_ptr_ptr
= NULL
;
1387 DerDecodeTbsCertificate(const KMF_DATA
*Value
,
1388 KMF_X509_TBS_CERT
**tbscert
)
1390 KMF_RETURN ret
= KMF_OK
;
1391 BerElement
*asn1
= NULL
;
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
);
1411 if (ret
!= KMF_OK
) {
1413 free_tbscert(newcert
);
1416 kmfber_free(asn1
, 1);
1422 * Name: DerDecodeSignedCertificate
1425 * DER decodes the encoded X509 certificate
1428 * Value (input): DER encoded object that shd be decoded
1430 * signed_cert_ptr_ptr (output) : Decoded KMF_X509_CERTIFICATE object
1433 DerDecodeSignedCertificate(const KMF_DATA
*Value
,
1434 KMF_X509_CERTIFICATE
**signed_cert_ptr_ptr
)
1436 KMF_RETURN ret
= KMF_OK
;
1437 BerElement
*asn1
= NULL
;
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
;
1461 certptr
= malloc(sizeof (KMF_X509_CERTIFICATE
));
1462 if (certptr
== NULL
) {
1463 ret
= KMF_ERR_MEMORY
;
1466 (void) memset(certptr
, 0, sizeof (KMF_X509_CERTIFICATE
));
1468 ret
= decode_tbscert_data(asn1
, &tbscert
);
1472 certptr
->certificate
= *tbscert
;
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
;
1489 if (tag
!= BER_BIT_STRING
) {
1490 ret
= KMF_ERR_BAD_CERT_FORMAT
;
1493 if (kmfber_scanf(asn1
, "B}", &signature
, &size
) == -1) {
1494 ret
= KMF_ERR_BAD_CERT_FORMAT
;
1497 certptr
->signature
.encrypted
.Data
=
1498 (uchar_t
*)signature
;
1499 certptr
->signature
.encrypted
.Length
= size
/ 8;
1501 certptr
->signature
.encrypted
.Data
= NULL
;
1502 certptr
->signature
.encrypted
.Length
= 0;
1505 (void) memset(&certptr
->signature
, 0,
1506 sizeof (certptr
->signature
));
1510 *signed_cert_ptr_ptr
= certptr
;
1512 if (ret
!= KMF_OK
) {
1514 free_decoded_cert(certptr
);
1518 *signed_cert_ptr_ptr
= NULL
;
1521 kmfber_free(asn1
, 1);
1528 DerDecodeExtension(KMF_DATA
*Data
, KMF_X509_EXTENSION
**extn
)
1530 KMF_RETURN ret
= KMF_OK
;
1531 BerElement
*asn1
= NULL
;
1534 bv
.bv_val
= (char *)Data
->Data
;
1535 bv
.bv_len
= Data
->Length
;
1537 asn1
= kmfder_init(&bv
);
1539 return (KMF_ERR_MEMORY
);
1541 ret
= get_one_extension(asn1
, extn
, NULL
);
1544 if (ret
!= KMF_OK
) {
1545 if (*extn
!= NULL
) {
1551 kmfber_free(asn1
, 1);
1556 DerDecodeName(KMF_DATA
*encodedname
, KMF_X509_NAME
*name
)
1558 KMF_RETURN ret
= KMF_OK
;
1559 BerElement
*asn1
= NULL
;
1562 bv
.bv_val
= (char *)encodedname
->Data
;
1563 bv
.bv_len
= encodedname
->Length
;
1565 asn1
= kmfder_init(&bv
);
1567 return (KMF_ERR_MEMORY
);
1569 (void) memset(name
, 0, sizeof (KMF_X509_NAME
));
1571 if ((ret
= get_rdn(asn1
, name
)) != KMF_OK
)
1576 kmfber_free(asn1
, 1);
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();
1589 return (KMF_ERR_MEMORY
);
1591 if ((ret
= encode_rdn(asn1
, name
)) != KMF_OK
)
1594 if (kmfber_flatten(asn1
, &bv
) == -1) {
1595 ret
= KMF_ERR_BAD_CERT_FORMAT
;
1599 encodedname
->Data
= (uchar_t
*)bv
->bv_val
;
1600 encodedname
->Length
= bv
->bv_len
;
1606 kmfber_free(asn1
, 1);
1612 encode_tbs_cert(BerElement
*asn1
, KMF_X509_TBS_CERT
*tbscert
)
1614 KMF_RETURN ret
= KMF_OK
;
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
;
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
;
1637 /* Don't encode alg parameters in signature algid area */
1638 if ((ret
= encode_algoid(asn1
, &tbscert
->signature
, FALSE
)) != KMF_OK
)
1641 /* Encode the Issuer RDN */
1642 if ((ret
= encode_rdn(asn1
, &tbscert
->issuer
)) != KMF_OK
)
1645 /* Encode the Validity fields */
1646 if ((ret
= encode_validity(asn1
, &tbscert
->validity
)) != KMF_OK
)
1649 /* Encode the Subject RDN */
1650 if ((ret
= encode_rdn(asn1
, &tbscert
->subject
)) != KMF_OK
)
1653 /* Encode the Subject Public Key Info */
1654 if ((ret
= encode_spki(asn1
, &tbscert
->subjectPublicKeyInfo
)) != KMF_OK
)
1657 /* Optional field: issuer Unique ID */
1658 if (tbscert
->issuerUniqueIdentifier
.Length
> 0) {
1659 if ((ret
= encode_uniqueid(asn1
, 0xA1,
1660 &tbscert
->issuerUniqueIdentifier
)) != KMF_OK
)
1664 /* Optional field: Subject Unique ID */
1665 if (tbscert
->subjectUniqueIdentifier
.Length
> 0) {
1666 if ((ret
= encode_uniqueid(asn1
, 0xA2,
1667 &tbscert
->subjectUniqueIdentifier
)) != KMF_OK
)
1671 /* Optional field: Certificate Extensions */
1672 if (tbscert
->extensions
.numberOfExtensions
> 0) {
1673 if ((ret
= encode_extensions(asn1
,
1674 &tbscert
->extensions
)) != KMF_OK
)
1678 /* Close out the TBSCert sequence */
1679 if (kmfber_printf(asn1
, "}") == -1) {
1680 ret
= KMF_ERR_BAD_CERT_FORMAT
;
1686 * Memory cleanup is done in the caller or in the individual
1687 * encoding routines.
1694 DerEncodeTbsCertificate(KMF_X509_TBS_CERT
*tbs_cert_ptr
,
1695 KMF_DATA
*enc_tbs_cert_ptr
)
1698 BerElement
*asn1
= NULL
;
1699 BerValue
*tbsdata
= NULL
;
1701 asn1
= kmfder_alloc();
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
);
1712 if (kmfber_flatten(asn1
, &tbsdata
) == -1) {
1713 ret
= KMF_ERR_MEMORY
;
1717 enc_tbs_cert_ptr
->Data
= (uchar_t
*)tbsdata
->bv_val
;
1718 enc_tbs_cert_ptr
->Length
= tbsdata
->bv_len
;
1722 free_data(enc_tbs_cert_ptr
);
1725 kmfber_free(asn1
, 1);
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();
1753 return (KMF_ERR_MEMORY
);
1755 /* Start outer X509 Certificate SEQUENCE */
1756 if (kmfber_printf(asn1
, "{") == -1) {
1757 ret
= KMF_ERR_BAD_CERT_FORMAT
;
1761 if ((ret
= encode_tbs_cert(asn1
, tbscert
)) != KMF_OK
) {
1762 ret
= KMF_ERR_BAD_CERT_FORMAT
;
1766 /* Add the Algorithm & Signature Sequence (no parameters) */
1767 if ((ret
= encode_algoid(asn1
,
1768 &signature
->algorithmIdentifier
, FALSE
)) != KMF_OK
)
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
;
1779 if (kmfber_printf(asn1
, "}") == -1) {
1780 ret
= KMF_ERR_BAD_CERT_FORMAT
;
1784 if (kmfber_flatten(asn1
, &tbsdata
) == -1) {
1785 ret
= KMF_ERR_MEMORY
;
1789 encodedcert
->Data
= (uchar_t
*)tbsdata
->bv_val
;
1790 encodedcert
->Length
= tbsdata
->bv_len
;
1794 free_data(encodedcert
);
1799 kmfber_free(asn1
, 1);
1805 ExtractX509CertParts(KMF_DATA
*x509cert
, KMF_DATA
*tbscert
,
1806 KMF_DATA
*signature
)
1808 KMF_RETURN ret
= KMF_OK
;
1809 BerElement
*der
= NULL
;
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
);
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
;
1829 if (tag
!= BER_CONSTRUCTED_SEQUENCE
) {
1830 ret
= KMF_ERR_BAD_CERT_FORMAT
;
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
;
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
;
1855 if (signature
!= NULL
) {
1856 KMF_X509_ALGORITHM_IDENTIFIER algoid
;
1857 if ((ret
= get_algoid(der
, &algoid
)) != KMF_OK
)
1859 free_algoid(&algoid
);
1861 if (kmfber_scanf(der
, "tl", &tag
, &size
) != BER_BIT_STRING
) {
1862 ret
= KMF_ERR_BAD_CERT_FORMAT
;
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
;
1871 /* convert bitstring length to bytes */
1872 signature
->Length
= signature
->Length
/ 8;
1877 kmfber_free(der
, 1);
1886 decode_csr_extensions(BerElement
*asn1
, KMF_X509_EXTENSIONS
*extns
)
1888 KMF_RETURN ret
= KMF_OK
;
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
,
1898 return (KMF_ERR_UNKNOWN_CSR_ATTRIBUTE
);
1901 if (kmfber_scanf(asn1
, "[") == -1) {
1902 return (KMF_ERR_ENCODING
);
1904 ret
= get_extensions(asn1
, extns
);
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
;
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
;
1927 tbscsr
= malloc(sizeof (KMF_TBS_CSR
));
1929 ret
= KMF_ERR_MEMORY
;
1933 (void) memset(tbscsr
, 0, sizeof (KMF_TBS_CSR
));
1935 if ((ret
= set_der_integer(&tbscsr
->version
, version
)) != KMF_OK
)
1938 if ((ret
= get_rdn(asn1
, &tbscsr
->subject
)) != KMF_OK
)
1941 if ((ret
= get_spki(asn1
, &tbscsr
->subjectPublicKeyInfo
)) != KMF_OK
)
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
;
1951 ret
= decode_csr_extensions(asn1
, &tbscsr
->extensions
);
1954 *signed_csr_ptr_ptr
= tbscsr
;
1957 if (ret
!= KMF_OK
) {
1959 free_tbscsr(tbscsr
);
1962 *signed_csr_ptr_ptr
= NULL
;
1968 DerDecodeTbsCsr(const KMF_DATA
*Value
,
1969 KMF_TBS_CSR
**tbscsr
)
1971 KMF_RETURN ret
= KMF_OK
;
1972 BerElement
*asn1
= NULL
;
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
);
1992 if (ret
!= KMF_OK
) {
1994 free_tbscsr(newcsr
);
1997 kmfber_free(asn1
, 1);
2003 DerDecodeSignedCsr(const KMF_DATA
*Value
,
2004 KMF_CSR_DATA
**signed_csr_ptr_ptr
)
2006 KMF_RETURN ret
= KMF_OK
;
2007 BerElement
*asn1
= NULL
;
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
;
2031 csrptr
= malloc(sizeof (KMF_CSR_DATA
));
2032 if (csrptr
== NULL
) {
2033 ret
= KMF_ERR_MEMORY
;
2036 (void) memset(csrptr
, 0, sizeof (KMF_CSR_DATA
));
2038 ret
= decode_tbscsr_data(asn1
, &tbscsr
);
2042 csrptr
->csr
= *tbscsr
;
2046 if ((ret
= get_algoid(asn1
,
2047 &csrptr
->signature
.algorithmIdentifier
)) != KMF_OK
)
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
;
2057 if (tag
!= BER_BIT_STRING
) {
2058 ret
= KMF_ERR_BAD_CERT_FORMAT
;
2061 if (kmfber_scanf(asn1
, "B}", &signature
, &size
) == -1) {
2062 ret
= KMF_ERR_BAD_CERT_FORMAT
;
2065 csrptr
->signature
.encrypted
.Data
= (uchar_t
*)signature
;
2066 csrptr
->signature
.encrypted
.Length
= size
/ 8;
2068 csrptr
->signature
.encrypted
.Data
= NULL
;
2069 csrptr
->signature
.encrypted
.Length
= 0;
2072 *signed_csr_ptr_ptr
= csrptr
;
2074 if (ret
!= KMF_OK
) {
2075 free_tbscsr(&csrptr
->csr
);
2076 free_algoid(&csrptr
->signature
.algorithmIdentifier
);
2077 free(csrptr
->signature
.encrypted
.Data
);
2081 *signed_csr_ptr_ptr
= NULL
;
2084 kmfber_free(asn1
, 1);
2091 encode_csr_extensions(BerElement
*asn1
, KMF_TBS_CSR
*tbscsr
)
2093 KMF_RETURN ret
= KMF_OK
;
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
;
2105 /* No extensions or attributes to encode */
2110 * attributes [0] Attributes
2111 * Attributes := SET OF Attribute
2112 * Attribute := SEQUENCE {
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
;
2130 if (kmfber_printf(extnasn1
, "{D[{",
2131 &extension_request_oid
) == -1) {
2132 ret
= KMF_ERR_ENCODING
;
2136 if ((ret
= encode_extension_list(extnasn1
,
2137 &tbscsr
->extensions
)) != KMF_OK
) {
2141 if (kmfber_printf(extnasn1
, "}]}") == -1) {
2142 ret
= KMF_ERR_ENCODING
;
2146 if (kmfber_flatten(extnasn1
, &extnvalue
) == -1) {
2147 ret
= KMF_ERR_MEMORY
;
2151 kmfber_free(extnasn1
, 1);
2154 /* Add 2 bytes to cover the tag and the length */
2155 attlen
= extnvalue
->bv_len
;
2160 if (kmfber_printf(asn1
, "l", attlen
) == -1) {
2161 ret
= KMF_ERR_ENCODING
;
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
;
2176 * Memory cleanup is done in the caller or in the individual
2177 * encoding routines.
2180 free(extnvalue
->bv_val
);
2188 encode_tbs_csr(BerElement
*asn1
, KMF_TBS_CSR
*tbscsr
)
2190 KMF_RETURN ret
= KMF_OK
;
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
;
2202 /* Encode the Subject RDN */
2203 if ((ret
= encode_rdn(asn1
, &tbscsr
->subject
)) != KMF_OK
)
2206 /* Encode the Subject Public Key Info */
2207 if ((ret
= encode_spki(asn1
, &tbscsr
->subjectPublicKeyInfo
)) != KMF_OK
)
2210 if ((ret
= encode_csr_extensions(asn1
, tbscsr
)) != KMF_OK
)
2213 /* Close out the TBSCert sequence */
2214 if (kmfber_printf(asn1
, "}") == -1) {
2215 ret
= KMF_ERR_BAD_CERT_FORMAT
;
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();
2232 return (KMF_ERR_MEMORY
);
2234 if (kmfber_printf(asn1
, "I",
2235 dsa
->value
.val
, dsa
->value
.len
) == -1) {
2236 rv
= KMF_ERR_MEMORY
;
2240 if (kmfber_flatten(asn1
, &dsadata
) == -1) {
2241 rv
= KMF_ERR_MEMORY
;
2245 encodedkey
->Data
= (uchar_t
*)dsadata
->bv_val
;
2246 encodedkey
->Length
= dsadata
->bv_len
;
2250 kmfber_free(asn1
, 1);
2255 DerEncodeRSAPrivateKey(KMF_DATA
*encodedkey
, KMF_RAW_RSA_KEY
*rsa
)
2257 KMF_RETURN rv
= KMF_OK
;
2258 BerElement
*asn1
= NULL
;
2260 BerValue
*rsadata
= NULL
;
2262 asn1
= kmfder_alloc();
2264 return (KMF_ERR_MEMORY
);
2266 if (kmfber_printf(asn1
, "{IIIIIIIII}",
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)
2278 if (kmfber_flatten(asn1
, &rsadata
) == -1) {
2279 rv
= KMF_ERR_MEMORY
;
2283 encodedkey
->Data
= (uchar_t
*)rsadata
->bv_val
;
2284 encodedkey
->Length
= rsadata
->bv_len
;
2288 kmfber_free(asn1
, 1);
2293 DerEncodeECPrivateKey(KMF_DATA
*encodedkey
, KMF_RAW_EC_KEY
*eckey
)
2295 KMF_RETURN rv
= KMF_OK
;
2296 BerElement
*asn1
= NULL
;
2298 BerValue
*data
= NULL
;
2300 asn1
= kmfder_alloc();
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
;
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
;
2317 if (kmfber_printf(asn1
, "l", eckey
->params
.Length
) == -1) {
2318 rv
= KMF_ERR_ENCODING
;
2321 if (kmfber_write(asn1
, (char *)eckey
->params
.Data
,
2322 eckey
->params
.Length
, 0) == -1) {
2323 rv
= KMF_ERR_ENCODING
;
2326 if (kmfber_printf(asn1
, "}") == -1) {
2327 rv
= KMF_ERR_ENCODING
;
2330 if (kmfber_flatten(asn1
, &data
) == -1) {
2331 rv
= KMF_ERR_MEMORY
;
2334 encodedkey
->Data
= (uchar_t
*)data
->bv_val
;
2335 encodedkey
->Length
= data
->bv_len
;
2338 kmfber_free(asn1
, 1);
2344 DerEncodeTbsCsr(KMF_TBS_CSR
*tbs_csr_ptr
,
2345 KMF_DATA
*enc_tbs_csr_ptr
)
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;
2357 return (KMF_ERR_MEMORY
);
2359 ret
= encode_tbs_csr(asn1
, tbs_csr_ptr
);
2363 if (kmfber_flatten(asn1
, &tbsdata
) == -1) {
2364 ret
= KMF_ERR_MEMORY
;
2368 enc_tbs_csr_ptr
->Data
= (uchar_t
*)tbsdata
->bv_val
;
2369 enc_tbs_csr_ptr
->Length
= tbsdata
->bv_len
;
2373 free_data(enc_tbs_csr_ptr
);
2376 kmfber_free(asn1
, 1);
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();
2401 return (KMF_ERR_MEMORY
);
2403 /* Start outer CSR SEQUENCE */
2404 if (kmfber_printf(asn1
, "{") == -1) {
2405 ret
= KMF_ERR_BAD_CERT_FORMAT
;
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
)
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
;
2424 if (kmfber_printf(asn1
, "}") == -1) {
2425 ret
= KMF_ERR_BAD_CERT_FORMAT
;
2429 if (kmfber_flatten(asn1
, &tbsdata
) == -1) {
2430 ret
= KMF_ERR_MEMORY
;
2434 encodedcsr
->Data
= (uchar_t
*)tbsdata
->bv_val
;
2435 encodedcsr
->Length
= tbsdata
->bv_len
;
2438 if (ret
!= KMF_OK
) {
2439 free_data(encodedcsr
);
2445 kmfber_free(asn1
, 1);
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
);
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
) {
2484 case KMF_ALGID_SHA1WithDSA
:
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
;
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
;
2518 if (kmfber_scanf(asn1
, "I", &PubKey
) == -1) {
2519 ret
= KMF_ERR_BAD_KEY_FORMAT
;
2522 pKeyParts
[KMF_DSA_PUBLIC_VALUE
].Data
=
2523 (uchar_t
*)PubKey
->bv_val
;
2524 pKeyParts
[KMF_DSA_PUBLIC_VALUE
].Length
= PubKey
->bv_len
;
2528 *uNumKeyParts
= KMF_NUMBER_DSA_PUBLIC_KEY_PARTS
;
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
);
2542 case KMF_ALGID_MD2WithRSA
:
2543 case KMF_ALGID_MD5WithRSA
:
2544 case KMF_ALGID_SHA1WithRSA
:
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
;
2552 if (kmfber_scanf(asn1
, "{II}", &Mod
, &Exp
) == -1) {
2553 ret
= KMF_ERR_BAD_KEY_FORMAT
;
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
;
2568 return (KMF_ERR_BAD_PARAMETER
);
2571 if (ret
!= KMF_OK
) {
2573 for (i
= 0; i
< *uNumKeyParts
; i
++)
2574 free_data(&pKeyParts
[i
]);
2577 kmfber_free(asn1
, 1);