2 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
4 * Use is subject to license terms.
7 * Copyright (c) 2012, OmniTI Computer Consulting, Inc. All rights reserved.
10 * Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
14 * ====================================================================
15 * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved.
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
21 * 1. Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
24 * 2. Redistributions in binary form must reproduce the above copyright
25 * notice, this list of conditions and the following disclaimer in
26 * the documentation and/or other materials provided with the
29 * 3. All advertising materials mentioning features or use of this
30 * software must display the following acknowledgment:
31 * "This product includes software developed by the OpenSSL Project
32 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
34 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
35 * endorse or promote products derived from this software without
36 * prior written permission. For written permission, please contact
37 * licensing@OpenSSL.org.
39 * 5. Products derived from this software may not be called "OpenSSL"
40 * nor may "OpenSSL" appear in their names without prior written
41 * permission of the OpenSSL Project.
43 * 6. Redistributions of any form whatsoever must retain the following
45 * "This product includes software developed by the OpenSSL Project
46 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
48 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
49 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
51 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
52 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
53 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
54 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
55 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
57 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
58 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
59 * OF THE POSSIBILITY OF SUCH DAMAGE.
60 * ====================================================================
62 * This product includes cryptographic software written by Eric Young
63 * (eay@cryptsoft.com). This product includes software written by Tim
64 * Hudson (tjh@cryptsoft.com).
74 #include <cryptoutil.h>
78 /* OPENSSL related headers */
79 #include <openssl/bio.h>
80 #include <openssl/bn.h>
81 #include <openssl/asn1.h>
82 #include <openssl/err.h>
83 #include <openssl/bn.h>
84 #include <openssl/x509.h>
85 #include <openssl/rsa.h>
86 #include <openssl/dsa.h>
87 #include <openssl/x509v3.h>
88 #include <openssl/objects.h>
89 #include <openssl/pem.h>
90 #include <openssl/pkcs12.h>
91 #include <openssl/ocsp.h>
92 #include <openssl/des.h>
93 #include <openssl/rand.h>
95 #define PRINT_ANY_EXTENSION (\
96 KMF_X509_EXT_KEY_USAGE |\
97 KMF_X509_EXT_CERT_POLICIES |\
98 KMF_X509_EXT_SUBJALTNAME |\
99 KMF_X509_EXT_BASIC_CONSTRAINTS |\
100 KMF_X509_EXT_NAME_CONSTRAINTS |\
101 KMF_X509_EXT_POLICY_CONSTRAINTS |\
102 KMF_X509_EXT_EXT_KEY_USAGE |\
103 KMF_X509_EXT_INHIBIT_ANY_POLICY |\
104 KMF_X509_EXT_AUTH_KEY_ID |\
105 KMF_X509_EXT_SUBJ_KEY_ID |\
106 KMF_X509_EXT_POLICY_MAPPING)
108 static uchar_t P
[] = { 0x00, 0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76,
109 0xaa, 0x3d, 0x25, 0x75, 0x9b, 0xb0, 0x68, 0x69,
110 0xcb, 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d, 0x0c,
111 0xf7, 0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82,
112 0xe5, 0xd0, 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e,
113 0xaf, 0xc2, 0xe9, 0xad, 0xac, 0x32, 0xab, 0x7a,
114 0xac, 0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24,
115 0xc2, 0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02,
118 static uchar_t Q
[] = { 0x00, 0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8,
119 0xee, 0x99, 0x3b, 0x4f, 0x2d, 0xed, 0x30, 0xf4,
120 0x8e, 0xda, 0xce, 0x91, 0x5f };
122 static uchar_t G
[] = { 0x00, 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a,
123 0x13, 0x41, 0x31, 0x63, 0xa5, 0x5b, 0x4c, 0xb5,
124 0x00, 0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c, 0xef,
125 0xcb, 0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c,
126 0x2e, 0x71, 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba,
127 0xbf, 0x58, 0xe5, 0xb7, 0x95, 0x21, 0x92, 0x5c,
128 0x9c, 0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08,
129 0x8c, 0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88,
132 #define SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_OPENSSL; \
133 h->lasterr.errcode = c;
135 #define SET_SYS_ERROR(h, c) h->lasterr.kstype = -1; h->lasterr.errcode = c;
138 * Declare some new macros for managing stacks of EVP_PKEYS, similar to
141 DECLARE_STACK_OF(EVP_PKEY
)
143 #define sk_EVP_PKEY_new_null() SKM_sk_new_null(EVP_PKEY)
144 #define sk_EVP_PKEY_free(st) SKM_sk_free(EVP_PKEY, (st))
145 #define sk_EVP_PKEY_num(st) SKM_sk_num(EVP_PKEY, (st))
146 #define sk_EVP_PKEY_value(st, i) SKM_sk_value(EVP_PKEY, (st), (i))
147 #define sk_EVP_PKEY_push(st, val) SKM_sk_push(EVP_PKEY, (st), (val))
148 #define sk_EVP_PKEY_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY, (st), \
151 mutex_t init_lock
= DEFAULTMUTEX
;
152 static int ssl_initialized
= 0;
153 static BIO
*bio_err
= NULL
;
156 test_for_file(char *, mode_t
);
158 openssl_parse_bag(PKCS12_SAFEBAG
*, char *, int,
159 STACK_OF(EVP_PKEY
) *, STACK_OF(X509
) *);
162 local_export_pk12(KMF_HANDLE_T
, KMF_CREDENTIAL
*, int, KMF_X509_DER_CERT
*,
163 int, KMF_KEY_HANDLE
*, char *);
165 static KMF_RETURN
set_pkey_attrib(EVP_PKEY
*, ASN1_TYPE
*, int);
168 extract_pem(KMF_HANDLE
*, char *, char *, KMF_BIGINT
*, char *,
169 CK_UTF8CHAR
*, CK_ULONG
, EVP_PKEY
**, KMF_DATA
**, int *);
172 kmf_load_cert(KMF_HANDLE
*, char *, char *, KMF_BIGINT
*, KMF_CERT_VALIDITY
,
176 load_certs(KMF_HANDLE
*, char *, char *, KMF_BIGINT
*, KMF_CERT_VALIDITY
,
177 char *, KMF_DATA
**, uint32_t *);
180 sslBN2KMFBN(BIGNUM
*, KMF_BIGINT
*);
183 ImportRawRSAKey(KMF_RAW_RSA_KEY
*);
186 convertToRawKey(EVP_PKEY
*, KMF_RAW_KEY_DATA
*);
189 OpenSSL_FindCert(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
192 OpenSSL_FreeKMFCert(KMF_HANDLE_T
, KMF_X509_DER_CERT
*);
195 OpenSSL_StoreCert(KMF_HANDLE_T handle
, int, KMF_ATTRIBUTE
*);
198 OpenSSL_DeleteCert(KMF_HANDLE_T handle
, int, KMF_ATTRIBUTE
*);
201 OpenSSL_CreateKeypair(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
204 OpenSSL_StoreKey(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
207 OpenSSL_EncodePubKeyData(KMF_HANDLE_T
, KMF_KEY_HANDLE
*, KMF_DATA
*);
210 OpenSSL_SignData(KMF_HANDLE_T
, KMF_KEY_HANDLE
*, KMF_OID
*,
211 KMF_DATA
*, KMF_DATA
*);
214 OpenSSL_DeleteKey(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
217 OpenSSL_ImportCRL(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
220 OpenSSL_DeleteCRL(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
223 OpenSSL_ListCRL(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
226 OpenSSL_FindCertInCRL(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
229 OpenSSL_CertGetPrintable(KMF_HANDLE_T
, const KMF_DATA
*,
230 KMF_PRINTABLE_ITEM
, char *);
233 OpenSSL_GetErrorString(KMF_HANDLE_T
, char **);
236 OpenSSL_FindPrikeyByCert(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
239 OpenSSL_DecryptData(KMF_HANDLE_T
, KMF_KEY_HANDLE
*, KMF_OID
*,
240 KMF_DATA
*, KMF_DATA
*);
243 OpenSSL_CreateOCSPRequest(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
246 OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
249 OpenSSL_FindKey(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
252 OpenSSL_ExportPK12(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
255 OpenSSL_CreateSymKey(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
258 OpenSSL_GetSymKeyValue(KMF_HANDLE_T
, KMF_KEY_HANDLE
*, KMF_RAW_SYM_KEY
*);
261 OpenSSL_VerifyCRLFile(KMF_HANDLE_T
, char *, KMF_DATA
*);
264 OpenSSL_CheckCRLDate(KMF_HANDLE_T
, char *);
267 KMF_PLUGIN_FUNCLIST openssl_plugin_table
=
270 NULL
, /* ConfigureKeystore */
274 NULL
, /* ImportCert */
278 OpenSSL_CreateKeypair
,
280 OpenSSL_EncodePubKeyData
,
285 OpenSSL_FindCertInCRL
,
286 OpenSSL_GetErrorString
,
287 OpenSSL_FindPrikeyByCert
,
290 OpenSSL_CreateSymKey
,
291 OpenSSL_GetSymKeyValue
,
292 NULL
, /* SetTokenPin */
297 static mutex_t
*lock_cs
;
298 static long *lock_count
;
302 locking_cb(int mode
, int type
, char *file
, int line
)
304 if (mode
& CRYPTO_LOCK
) {
305 (void) mutex_lock(&(lock_cs
[type
]));
308 (void) mutex_unlock(&(lock_cs
[type
]));
315 return ((unsigned long)thr_self());
318 KMF_PLUGIN_FUNCLIST
*
319 KMF_Plugin_Initialize()
323 (void) mutex_lock(&init_lock
);
324 if (!ssl_initialized
) {
326 * Add support for extension OIDs that are not yet in the
327 * openssl default set.
329 (void) OBJ_create("2.5.29.30", "nameConstraints",
330 "X509v3 Name Constraints");
331 (void) OBJ_create("2.5.29.33", "policyMappings",
332 "X509v3 Policy Mappings");
333 (void) OBJ_create("2.5.29.36", "policyConstraints",
334 "X509v3 Policy Constraints");
335 (void) OBJ_create("2.5.29.46", "freshestCRL",
336 "X509v3 Freshest CRL");
337 (void) OBJ_create("2.5.29.54", "inhibitAnyPolicy",
338 "X509v3 Inhibit Any-Policy");
340 * Set up for thread-safe operation.
342 lock_cs
= OPENSSL_malloc(CRYPTO_num_locks() * sizeof (mutex_t
));
343 if (lock_cs
== NULL
) {
344 (void) mutex_unlock(&init_lock
);
348 lock_count
= OPENSSL_malloc(CRYPTO_num_locks() * sizeof (long));
349 if (lock_count
== NULL
) {
350 OPENSSL_free(lock_cs
);
351 (void) mutex_unlock(&init_lock
);
355 for (i
= 0; i
< CRYPTO_num_locks(); i
++) {
357 (void) mutex_init(&lock_cs
[i
], USYNC_THREAD
, NULL
);
360 CRYPTO_set_id_callback((unsigned long (*)())thread_id
);
361 if (CRYPTO_get_locking_callback() == NULL
)
362 CRYPTO_set_locking_callback((void (*)())locking_cb
);
364 OpenSSL_add_all_algorithms();
366 /* Enable error strings for reporting */
367 ERR_load_crypto_strings();
371 (void) mutex_unlock(&init_lock
);
373 return (&openssl_plugin_table
);
376 * Convert an SSL DN to a KMF DN.
379 get_x509_dn(X509_NAME
*sslDN
, KMF_X509_NAME
*kmfDN
)
382 KMF_RETURN rv
= KMF_OK
;
385 /* Convert to raw DER format */
386 derdata
.Length
= i2d_X509_NAME(sslDN
, NULL
);
387 if ((tmp
= derdata
.Data
= (uchar_t
*)OPENSSL_malloc(derdata
.Length
))
389 return (KMF_ERR_MEMORY
);
391 (void) i2d_X509_NAME(sslDN
, &tmp
);
393 /* Decode to KMF format */
394 rv
= DerDecodeName(&derdata
, kmfDN
);
396 rv
= KMF_ERR_BAD_CERT_FORMAT
;
398 OPENSSL_free(derdata
.Data
);
408 if (stat(path
, &s
) == -1)
411 return ((s
.st_mode
& S_IFMT
) == S_IFDIR
);
415 ssl_cert2KMFDATA(KMF_HANDLE
*kmfh
, X509
*x509cert
, KMF_DATA
*cert
)
417 KMF_RETURN rv
= KMF_OK
;
418 unsigned char *buf
= NULL
, *p
;
422 * Convert the X509 internal struct to DER encoded data
424 if ((len
= i2d_X509(x509cert
, NULL
)) < 0) {
425 SET_ERROR(kmfh
, ERR_get_error());
426 rv
= KMF_ERR_BAD_CERT_FORMAT
;
429 if ((buf
= malloc(len
)) == NULL
) {
430 SET_SYS_ERROR(kmfh
, errno
);
436 * i2d_X509 will increment the buf pointer so that we need to
440 if ((len
= i2d_X509(x509cert
, &p
)) < 0) {
441 SET_ERROR(kmfh
, ERR_get_error());
443 rv
= KMF_ERR_BAD_CERT_FORMAT
;
447 /* caller's responsibility to free it */
464 check_cert(X509
*xcert
, char *issuer
, char *subject
, KMF_BIGINT
*serial
,
467 KMF_RETURN rv
= KMF_OK
;
468 boolean_t findIssuer
= FALSE
;
469 boolean_t findSubject
= FALSE
;
470 boolean_t findSerial
= FALSE
;
471 KMF_X509_NAME issuerDN
, subjectDN
;
472 KMF_X509_NAME certIssuerDN
, certSubjectDN
;
476 return (KMF_ERR_BAD_PARAMETER
);
479 (void) memset(&issuerDN
, 0, sizeof (KMF_X509_NAME
));
480 (void) memset(&subjectDN
, 0, sizeof (KMF_X509_NAME
));
481 (void) memset(&certIssuerDN
, 0, sizeof (KMF_X509_NAME
));
482 (void) memset(&certSubjectDN
, 0, sizeof (KMF_X509_NAME
));
484 if (issuer
!= NULL
&& strlen(issuer
)) {
485 rv
= kmf_dn_parser(issuer
, &issuerDN
);
487 return (KMF_ERR_BAD_PARAMETER
);
489 rv
= get_x509_dn(xcert
->cert_info
->issuer
, &certIssuerDN
);
491 kmf_free_dn(&issuerDN
);
492 return (KMF_ERR_BAD_PARAMETER
);
497 if (subject
!= NULL
&& strlen(subject
)) {
498 rv
= kmf_dn_parser(subject
, &subjectDN
);
500 rv
= KMF_ERR_BAD_PARAMETER
;
504 rv
= get_x509_dn(xcert
->cert_info
->subject
, &certSubjectDN
);
506 rv
= KMF_ERR_BAD_PARAMETER
;
511 if (serial
!= NULL
&& serial
->val
!= NULL
)
517 /* Comparing BIGNUMs is a pain! */
518 bn
= ASN1_INTEGER_to_BN(xcert
->cert_info
->serialNumber
, NULL
);
520 int bnlen
= BN_num_bytes(bn
);
522 if (bnlen
== serial
->len
) {
523 uchar_t
*a
= malloc(bnlen
);
529 bnlen
= BN_bn2bin(bn
, a
);
530 *match
= (memcmp(a
, serial
->val
, serial
->len
) ==
544 *match
= (kmf_compare_rdns(&issuerDN
, &certIssuerDN
) == 0);
545 if ((*match
) == B_FALSE
) {
546 /* stop checking and bail */
552 *match
= (kmf_compare_rdns(&subjectDN
, &certSubjectDN
) == 0);
553 if ((*match
) == B_FALSE
) {
554 /* stop checking and bail */
563 kmf_free_dn(&issuerDN
);
564 kmf_free_dn(&certIssuerDN
);
567 kmf_free_dn(&subjectDN
);
568 kmf_free_dn(&certSubjectDN
);
576 * This function loads a certificate file into an X509 data structure, and
577 * checks if its issuer, subject or the serial number matches with those
578 * values. If it matches, then return the X509 data structure.
581 load_X509cert(KMF_HANDLE
*kmfh
,
582 char *issuer
, char *subject
, KMF_BIGINT
*serial
,
583 char *pathname
, X509
**outcert
)
585 KMF_RETURN rv
= KMF_OK
;
588 boolean_t match
= FALSE
;
589 KMF_ENCODE_FORMAT format
;
592 * auto-detect the file format, regardless of what
593 * the 'format' parameters in the params say.
595 rv
= kmf_get_file_format(pathname
, &format
);
597 if (rv
== KMF_ERR_OPEN_FILE
)
598 rv
= KMF_ERR_CERT_NOT_FOUND
;
602 /* Not ASN1(DER) format */
603 if ((bcert
= BIO_new_file(pathname
, "rb")) == NULL
) {
604 SET_ERROR(kmfh
, ERR_get_error());
605 rv
= KMF_ERR_OPEN_FILE
;
609 if (format
== KMF_FORMAT_PEM
)
610 xcert
= PEM_read_bio_X509_AUX(bcert
, NULL
, NULL
, NULL
);
611 else if (format
== KMF_FORMAT_ASN1
)
612 xcert
= d2i_X509_bio(bcert
, NULL
);
613 else if (format
== KMF_FORMAT_PKCS12
) {
614 PKCS12
*p12
= d2i_PKCS12_bio(bcert
, NULL
);
616 (void) PKCS12_parse(p12
, NULL
, NULL
, &xcert
, NULL
);
620 SET_ERROR(kmfh
, ERR_get_error());
621 rv
= KMF_ERR_BAD_CERT_FORMAT
;
624 rv
= KMF_ERR_BAD_PARAMETER
;
629 SET_ERROR(kmfh
, ERR_get_error());
630 rv
= KMF_ERR_BAD_CERT_FORMAT
;
634 if (check_cert(xcert
, issuer
, subject
, serial
, &match
) != KMF_OK
||
636 rv
= KMF_ERR_CERT_NOT_FOUND
;
640 if (outcert
!= NULL
) {
645 if (bcert
!= NULL
) (void) BIO_free(bcert
);
646 if (rv
!= KMF_OK
&& xcert
!= NULL
)
653 datacmp(const void *a
, const void *b
)
655 KMF_DATA
*adata
= (KMF_DATA
*)a
;
656 KMF_DATA
*bdata
= (KMF_DATA
*)b
;
657 if (adata
->Length
> bdata
->Length
)
659 if (adata
->Length
< bdata
->Length
)
665 load_certs(KMF_HANDLE
*kmfh
, char *issuer
, char *subject
, KMF_BIGINT
*serial
,
666 KMF_CERT_VALIDITY validity
, char *pathname
,
667 KMF_DATA
**certlist
, uint32_t *numcerts
)
669 KMF_RETURN rv
= KMF_OK
;
671 KMF_DATA
*certs
= NULL
;
674 KMF_ENCODE_FORMAT format
;
676 rv
= kmf_get_file_format(pathname
, &format
);
678 if (rv
== KMF_ERR_OPEN_FILE
)
679 rv
= KMF_ERR_CERT_NOT_FOUND
;
682 if (format
== KMF_FORMAT_ASN1
) {
683 /* load a single certificate */
684 certs
= (KMF_DATA
*)malloc(sizeof (KMF_DATA
));
686 return (KMF_ERR_MEMORY
);
689 rv
= kmf_load_cert(kmfh
, issuer
, subject
, serial
, validity
,
695 kmf_free_data(certs
);
700 } else if (format
== KMF_FORMAT_PKCS12
) {
701 /* We need a credential to access a PKCS#12 file */
702 rv
= KMF_ERR_BAD_CERT_FORMAT
;
703 } else if (format
== KMF_FORMAT_PEM
||
704 format
!= KMF_FORMAT_PEM_KEYPAIR
) {
706 /* This function only works on PEM files */
707 rv
= extract_pem(kmfh
, issuer
, subject
, serial
, pathname
,
708 (uchar_t
*)NULL
, 0, NULL
, &certs
, &nc
);
710 return (KMF_ERR_ENCODING
);
716 for (i
= 0; i
< nc
; i
++) {
717 if (validity
== KMF_NONEXPIRED_CERTS
) {
718 rv
= kmf_check_cert_date(kmfh
, &certs
[i
]);
719 } else if (validity
== KMF_EXPIRED_CERTS
) {
720 rv
= kmf_check_cert_date(kmfh
, &certs
[i
]);
722 rv
= KMF_ERR_CERT_NOT_FOUND
;
723 if (rv
== KMF_ERR_VALIDITY_PERIOD
)
727 /* Remove this cert from the list by clearing it. */
728 kmf_free_data(&certs
[i
]);
730 hits
++; /* count valid certs found */
734 if (rv
== KMF_OK
&& hits
> 0) {
736 * Sort the list of certs by length to put the cleared ones
737 * at the end so they don't get accessed by the caller.
739 qsort((void *)certs
, nc
, sizeof (KMF_DATA
), datacmp
);
742 /* since we sorted the list, just return the number of hits */
745 if (rv
== KMF_OK
&& hits
== 0)
746 rv
= KMF_ERR_CERT_NOT_FOUND
;
756 kmf_load_cert(KMF_HANDLE
*kmfh
,
757 char *issuer
, char *subject
, KMF_BIGINT
*serial
,
758 KMF_CERT_VALIDITY validity
,
762 KMF_RETURN rv
= KMF_OK
;
763 X509
*x509cert
= NULL
;
765 rv
= load_X509cert(kmfh
, issuer
, subject
, serial
, pathname
, &x509cert
);
766 if (rv
== KMF_OK
&& x509cert
!= NULL
&& cert
!= NULL
) {
767 rv
= ssl_cert2KMFDATA(kmfh
, x509cert
, cert
);
771 if (validity
== KMF_NONEXPIRED_CERTS
) {
772 rv
= kmf_check_cert_date(kmfh
, cert
);
773 } else if (validity
== KMF_EXPIRED_CERTS
) {
774 rv
= kmf_check_cert_date(kmfh
, cert
);
777 * This is a valid cert so skip it.
779 rv
= KMF_ERR_CERT_NOT_FOUND
;
781 if (rv
== KMF_ERR_VALIDITY_PERIOD
) {
783 * We want to return success when we
784 * find an invalid cert.
792 if (x509cert
!= NULL
)
799 readAltFormatPrivateKey(KMF_DATA
*filedata
, EVP_PKEY
**pkey
)
801 KMF_RETURN ret
= KMF_OK
;
803 BerElement
*asn1
= NULL
;
805 BerValue OID
= { NULL
, 0 };
806 BerValue
*Mod
= NULL
, *PubExp
= NULL
;
807 BerValue
*PriExp
= NULL
, *Prime1
= NULL
, *Prime2
= NULL
;
808 BerValue
*Coef
= NULL
;
809 BIGNUM
*D
= NULL
, *P
= NULL
, *Q
= NULL
, *COEF
= NULL
;
810 BIGNUM
*Exp1
= NULL
, *Exp2
= NULL
, *pminus1
= NULL
;
811 BIGNUM
*qminus1
= NULL
;
816 filebuf
.bv_val
= (char *)filedata
->Data
;
817 filebuf
.bv_len
= filedata
->Length
;
819 asn1
= kmfder_init(&filebuf
);
821 ret
= KMF_ERR_MEMORY
;
825 if (kmfber_scanf(asn1
, "{{Dn{IIIIII}}}",
826 &OID
, &Mod
, &PubExp
, &PriExp
, &Prime1
,
827 &Prime2
, &Coef
) == -1) {
828 ret
= KMF_ERR_ENCODING
;
833 * We have to derive the 2 Exponents using Bignumber math.
834 * Exp1 = PriExp mod (Prime1 - 1)
835 * Exp2 = PriExp mod (Prime2 - 1)
838 /* D = PrivateExponent */
839 D
= BN_bin2bn((const uchar_t
*)PriExp
->bv_val
, PriExp
->bv_len
, D
);
841 ret
= KMF_ERR_MEMORY
;
845 /* P = Prime1 (first prime factor of Modulus) */
846 P
= BN_bin2bn((const uchar_t
*)Prime1
->bv_val
, Prime1
->bv_len
, P
);
848 ret
= KMF_ERR_MEMORY
;
852 /* Q = Prime2 (second prime factor of Modulus) */
853 Q
= BN_bin2bn((const uchar_t
*)Prime2
->bv_val
, Prime2
->bv_len
, Q
);
855 if ((ctx
= BN_CTX_new()) == NULL
) {
856 ret
= KMF_ERR_MEMORY
;
860 /* Compute (P - 1) */
862 (void) BN_sub(pminus1
, P
, BN_value_one());
864 /* Exponent1 = D mod (P - 1) */
866 (void) BN_mod(Exp1
, D
, pminus1
, ctx
);
868 /* Compute (Q - 1) */
870 (void) BN_sub(qminus1
, Q
, BN_value_one());
872 /* Exponent2 = D mod (Q - 1) */
874 (void) BN_mod(Exp2
, D
, qminus1
, ctx
);
876 /* Coef = (Inverse Q) mod P */
878 (void) BN_mod_inverse(COEF
, Q
, P
, ctx
);
880 /* Convert back to KMF format */
881 (void) memset(&rsa
, 0, sizeof (rsa
));
883 if ((ret
= sslBN2KMFBN(Exp1
, &rsa
.exp1
)) != KMF_OK
)
885 if ((ret
= sslBN2KMFBN(Exp2
, &rsa
.exp2
)) != KMF_OK
)
887 if ((ret
= sslBN2KMFBN(COEF
, &rsa
.coef
)) != KMF_OK
)
890 rsa
.mod
.val
= (uchar_t
*)Mod
->bv_val
;
891 rsa
.mod
.len
= Mod
->bv_len
;
893 rsa
.pubexp
.val
= (uchar_t
*)PubExp
->bv_val
;
894 rsa
.pubexp
.len
= PubExp
->bv_len
;
896 rsa
.priexp
.val
= (uchar_t
*)PriExp
->bv_val
;
897 rsa
.priexp
.len
= PriExp
->bv_len
;
899 rsa
.prime1
.val
= (uchar_t
*)Prime1
->bv_val
;
900 rsa
.prime1
.len
= Prime1
->bv_len
;
902 rsa
.prime2
.val
= (uchar_t
*)Prime2
->bv_val
;
903 rsa
.prime2
.len
= Prime2
->bv_len
;
905 *pkey
= ImportRawRSAKey(&rsa
);
908 kmfber_free(asn1
, 1);
923 (void) memset(Coef
->bv_val
, 0, Coef
->bv_len
);
942 BN_clear_free(pminus1
);
944 BN_clear_free(qminus1
);
955 openssl_load_key(KMF_HANDLE_T handle
, const char *file
)
958 EVP_PKEY
*pkey
= NULL
;
959 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
960 KMF_ENCODE_FORMAT format
;
968 if (kmf_get_file_format((char *)file
, &format
) != KMF_OK
)
971 keyfile
= BIO_new_file(file
, "rb");
972 if (keyfile
== NULL
) {
976 if (format
== KMF_FORMAT_ASN1
) {
977 pkey
= d2i_PrivateKey_bio(keyfile
, NULL
);
980 (void) BIO_free(keyfile
);
982 /* Try odd ASN.1 variations */
983 rv
= kmf_read_input_file(kmfh
, (char *)file
,
986 (void) readAltFormatPrivateKey(&filedata
,
988 kmf_free_data(&filedata
);
991 } else if (format
== KMF_FORMAT_PEM
||
992 format
== KMF_FORMAT_PEM_KEYPAIR
) {
993 pkey
= PEM_read_bio_PrivateKey(keyfile
, NULL
, NULL
, NULL
);
997 * Check if this is the alt. format
998 * RSA private key file.
1000 rv
= kmf_read_input_file(kmfh
, (char *)file
,
1005 rv
= kmf_pem_to_der(filedata
.Data
,
1006 filedata
.Length
, &d
, &len
);
1007 if (rv
== KMF_OK
&& d
!= NULL
) {
1009 derdata
.Length
= (size_t)len
;
1010 (void) readAltFormatPrivateKey(
1014 kmf_free_data(&filedata
);
1021 SET_ERROR(kmfh
, ERR_get_error());
1023 if (keyfile
!= NULL
)
1024 (void) BIO_free(keyfile
);
1030 OpenSSL_FindCert(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
1032 KMF_RETURN rv
= KMF_OK
;
1033 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1035 uint32_t maxcerts
= 0;
1036 uint32_t *num_certs
;
1037 KMF_X509_DER_CERT
*kmf_cert
= NULL
;
1038 char *dirpath
= NULL
;
1039 char *filename
= NULL
;
1040 char *fullpath
= NULL
;
1041 char *issuer
= NULL
;
1042 char *subject
= NULL
;
1043 KMF_BIGINT
*serial
= NULL
;
1044 KMF_CERT_VALIDITY validity
;
1046 num_certs
= kmf_get_attr_ptr(KMF_COUNT_ATTR
, attrlist
, numattr
);
1047 if (num_certs
== NULL
)
1048 return (KMF_ERR_BAD_PARAMETER
);
1050 /* num_certs should reference the size of kmf_cert */
1051 maxcerts
= *num_certs
;
1053 maxcerts
= 0xFFFFFFFF;
1056 /* Get the optional returned certificate list */
1057 kmf_cert
= kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR
, attrlist
,
1061 * The dirpath attribute and the filename attribute can not be NULL
1064 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
1065 filename
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
,
1068 fullpath
= get_fullpath(dirpath
, filename
);
1069 if (fullpath
== NULL
)
1070 return (KMF_ERR_BAD_PARAMETER
);
1072 /* Get optional search criteria attributes */
1073 issuer
= kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR
, attrlist
, numattr
);
1074 subject
= kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR
, attrlist
, numattr
);
1075 serial
= kmf_get_attr_ptr(KMF_BIGINT_ATTR
, attrlist
, numattr
);
1076 rv
= kmf_get_attr(KMF_CERT_VALIDITY_ATTR
, attrlist
, numattr
,
1079 validity
= KMF_ALL_CERTS
;
1083 if (isdir(fullpath
)) {
1088 /* open all files in the directory and attempt to read them */
1089 if ((dirp
= opendir(fullpath
)) == NULL
) {
1090 return (KMF_ERR_BAD_PARAMETER
);
1092 while ((dp
= readdir(dirp
)) != NULL
) {
1094 KMF_DATA
*certlist
= NULL
;
1095 uint32_t loaded_certs
= 0;
1097 if (strcmp(dp
->d_name
, ".") == 0 ||
1098 strcmp(dp
->d_name
, "..") == 0)
1101 fname
= get_fullpath(fullpath
, (char *)&dp
->d_name
);
1103 rv
= load_certs(kmfh
, issuer
, subject
, serial
,
1104 validity
, fname
, &certlist
, &loaded_certs
);
1108 if (certlist
!= NULL
) {
1109 for (i
= 0; i
< loaded_certs
; i
++)
1110 kmf_free_data(&certlist
[i
]);
1116 /* If load succeeds, add certdata to the list */
1117 if (kmf_cert
!= NULL
) {
1118 for (i
= 0; i
< loaded_certs
&&
1119 n
< maxcerts
; i
++) {
1120 kmf_cert
[n
].certificate
.Data
=
1122 kmf_cert
[n
].certificate
.Length
=
1125 kmf_cert
[n
].kmf_private
.keystore_type
=
1126 KMF_KEYSTORE_OPENSSL
;
1127 kmf_cert
[n
].kmf_private
.flags
=
1128 KMF_FLAG_CERT_VALID
;
1129 kmf_cert
[n
].kmf_private
.label
=
1134 * If maxcerts < loaded_certs, clean up the
1135 * certs that were not used.
1137 for (; i
< loaded_certs
; i
++)
1138 kmf_free_data(&certlist
[i
]);
1140 for (i
= 0; i
< loaded_certs
; i
++)
1141 kmf_free_data(&certlist
[i
]);
1148 if (*num_certs
== 0)
1149 rv
= KMF_ERR_CERT_NOT_FOUND
;
1153 (void) closedir(dirp
);
1155 KMF_DATA
*certlist
= NULL
;
1156 uint32_t loaded_certs
= 0;
1158 rv
= load_certs(kmfh
, issuer
, subject
, serial
, validity
,
1159 fullpath
, &certlist
, &loaded_certs
);
1166 if (kmf_cert
!= NULL
&& certlist
!= NULL
) {
1167 for (i
= 0; i
< loaded_certs
&& i
< maxcerts
; i
++) {
1168 kmf_cert
[n
].certificate
.Data
=
1170 kmf_cert
[n
].certificate
.Length
=
1172 kmf_cert
[n
].kmf_private
.keystore_type
=
1173 KMF_KEYSTORE_OPENSSL
;
1174 kmf_cert
[n
].kmf_private
.flags
=
1175 KMF_FLAG_CERT_VALID
;
1176 kmf_cert
[n
].kmf_private
.label
=
1180 /* If maxcerts < loaded_certs, clean up */
1181 for (; i
< loaded_certs
; i
++)
1182 kmf_free_data(&certlist
[i
]);
1183 } else if (certlist
!= NULL
) {
1184 for (i
= 0; i
< loaded_certs
; i
++)
1185 kmf_free_data(&certlist
[i
]);
1188 if (certlist
!= NULL
)
1200 OpenSSL_FreeKMFCert(KMF_HANDLE_T handle
,
1201 KMF_X509_DER_CERT
*kmf_cert
)
1203 if (kmf_cert
!= NULL
) {
1204 if (kmf_cert
->certificate
.Data
!= NULL
) {
1205 kmf_free_data(&kmf_cert
->certificate
);
1207 if (kmf_cert
->kmf_private
.label
)
1208 free(kmf_cert
->kmf_private
.label
);
1214 OpenSSL_StoreCert(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
1216 KMF_RETURN ret
= KMF_OK
;
1217 KMF_DATA
*cert
= NULL
;
1218 char *outfilename
= NULL
;
1219 char *dirpath
= NULL
;
1220 char *fullpath
= NULL
;
1221 KMF_ENCODE_FORMAT format
;
1223 /* Get the cert data */
1224 cert
= kmf_get_attr_ptr(KMF_CERT_DATA_ATTR
, attrlist
, numattr
);
1225 if (cert
== NULL
|| cert
->Data
== NULL
)
1226 return (KMF_ERR_BAD_PARAMETER
);
1228 /* Check the output filename and directory attributes. */
1229 outfilename
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
,
1231 if (outfilename
== NULL
)
1232 return (KMF_ERR_BAD_PARAMETER
);
1234 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
1235 fullpath
= get_fullpath(dirpath
, outfilename
);
1236 if (fullpath
== NULL
)
1237 return (KMF_ERR_BAD_CERTFILE
);
1239 /* Check the optional format attribute */
1240 ret
= kmf_get_attr(KMF_ENCODE_FORMAT_ATTR
, attrlist
, numattr
,
1242 if (ret
!= KMF_OK
) {
1243 /* If there is no format attribute, then default to PEM */
1244 format
= KMF_FORMAT_PEM
;
1246 } else if (format
!= KMF_FORMAT_ASN1
&& format
!= KMF_FORMAT_PEM
) {
1247 ret
= KMF_ERR_BAD_CERT_FORMAT
;
1251 /* Store the certificate in the file with the specified format */
1252 ret
= kmf_create_cert_file(cert
, format
, fullpath
);
1255 if (fullpath
!= NULL
)
1263 OpenSSL_DeleteCert(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
1266 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1267 KMF_DATA certdata
= { 0, NULL
};
1268 char *dirpath
= NULL
;
1269 char *filename
= NULL
;
1270 char *fullpath
= NULL
;
1271 char *issuer
= NULL
;
1272 char *subject
= NULL
;
1273 KMF_BIGINT
*serial
= NULL
;
1274 KMF_CERT_VALIDITY validity
;
1277 * Get the DIRPATH and CERT_FILENAME attributes. They can not be
1278 * NULL at the same time.
1280 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
1281 filename
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
,
1283 fullpath
= get_fullpath(dirpath
, filename
);
1284 if (fullpath
== NULL
)
1285 return (KMF_ERR_BAD_PARAMETER
);
1287 /* Get optional search criteria attributes */
1288 issuer
= kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR
, attrlist
, numattr
);
1289 subject
= kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR
, attrlist
, numattr
);
1290 serial
= kmf_get_attr_ptr(KMF_BIGINT_ATTR
, attrlist
, numattr
);
1291 rv
= kmf_get_attr(KMF_CERT_VALIDITY_ATTR
, attrlist
, numattr
,
1294 validity
= KMF_ALL_CERTS
;
1298 if (isdir(fullpath
)) {
1302 /* open all files in the directory and attempt to read them */
1303 if ((dirp
= opendir(fullpath
)) == NULL
) {
1304 return (KMF_ERR_BAD_PARAMETER
);
1307 while ((dp
= readdir(dirp
)) != NULL
) {
1308 if (strcmp(dp
->d_name
, ".") != 0 &&
1309 strcmp(dp
->d_name
, "..") != 0) {
1312 fname
= get_fullpath(fullpath
,
1313 (char *)&dp
->d_name
);
1315 if (fname
== NULL
) {
1316 rv
= KMF_ERR_MEMORY
;
1320 rv
= kmf_load_cert(kmfh
, issuer
, subject
,
1321 serial
, validity
, fname
, &certdata
);
1323 if (rv
== KMF_ERR_CERT_NOT_FOUND
) {
1325 kmf_free_data(&certdata
);
1328 } else if (rv
!= KMF_OK
) {
1333 if (unlink(fname
) != 0) {
1334 SET_SYS_ERROR(kmfh
, errno
);
1335 rv
= KMF_ERR_INTERNAL
;
1340 kmf_free_data(&certdata
);
1343 (void) closedir(dirp
);
1345 /* Just try to load a single certificate */
1346 rv
= kmf_load_cert(kmfh
, issuer
, subject
, serial
, validity
,
1347 fullpath
, &certdata
);
1349 if (unlink(fullpath
) != 0) {
1350 SET_SYS_ERROR(kmfh
, errno
);
1351 rv
= KMF_ERR_INTERNAL
;
1357 if (fullpath
!= NULL
)
1360 kmf_free_data(&certdata
);
1366 OpenSSL_EncodePubKeyData(KMF_HANDLE_T handle
, KMF_KEY_HANDLE
*key
,
1369 KMF_RETURN rv
= KMF_OK
;
1370 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1373 if (key
== NULL
|| keydata
== NULL
||
1375 return (KMF_ERR_BAD_PARAMETER
);
1377 if (key
->keyalg
== KMF_RSA
) {
1378 RSA
*pubkey
= EVP_PKEY_get1_RSA(key
->keyp
);
1380 if (!(n
= i2d_RSA_PUBKEY(pubkey
, &keydata
->Data
))) {
1381 SET_ERROR(kmfh
, ERR_get_error());
1382 return (KMF_ERR_ENCODING
);
1385 } else if (key
->keyalg
== KMF_DSA
) {
1386 DSA
*pubkey
= EVP_PKEY_get1_DSA(key
->keyp
);
1388 if (!(n
= i2d_DSA_PUBKEY(pubkey
, &keydata
->Data
))) {
1389 SET_ERROR(kmfh
, ERR_get_error());
1390 return (KMF_ERR_ENCODING
);
1394 return (KMF_ERR_BAD_PARAMETER
);
1396 keydata
->Length
= n
;
1401 free(keydata
->Data
);
1402 keydata
->Data
= NULL
;
1403 keydata
->Length
= 0;
1410 ssl_write_key(KMF_HANDLE
*kmfh
, KMF_ENCODE_FORMAT format
, BIO
*out
,
1411 KMF_CREDENTIAL
*cred
, EVP_PKEY
*pkey
, boolean_t
private)
1417 if (pkey
== NULL
|| out
== NULL
)
1418 return (KMF_ERR_BAD_PARAMETER
);
1421 case KMF_FORMAT_RAWKEY
:
1423 case KMF_FORMAT_ASN1
:
1424 if (pkey
->type
== EVP_PKEY_RSA
) {
1425 rsa
= EVP_PKEY_get1_RSA(pkey
);
1427 rv
= i2d_RSAPrivateKey_bio(out
, rsa
);
1429 rv
= i2d_RSAPublicKey_bio(out
, rsa
);
1431 } else if (pkey
->type
== EVP_PKEY_DSA
) {
1432 dsa
= EVP_PKEY_get1_DSA(pkey
);
1433 rv
= i2d_DSAPrivateKey_bio(out
, dsa
);
1439 SET_ERROR(kmfh
, rv
);
1442 case KMF_FORMAT_PEM
:
1443 if (pkey
->type
== EVP_PKEY_RSA
) {
1444 rsa
= EVP_PKEY_get1_RSA(pkey
);
1446 rv
= PEM_write_bio_RSAPrivateKey(out
,
1447 rsa
, NULL
, NULL
, 0, NULL
,
1448 (cred
!= NULL
? cred
->cred
: NULL
));
1450 rv
= PEM_write_bio_RSAPublicKey(out
,
1453 } else if (pkey
->type
== EVP_PKEY_DSA
) {
1454 dsa
= EVP_PKEY_get1_DSA(pkey
);
1455 rv
= PEM_write_bio_DSAPrivateKey(out
,
1456 dsa
, NULL
, NULL
, 0, NULL
,
1457 (cred
!= NULL
? cred
->cred
: NULL
));
1464 SET_ERROR(kmfh
, rv
);
1469 rv
= KMF_ERR_BAD_PARAMETER
;
1476 OpenSSL_CreateKeypair(KMF_HANDLE_T handle
, int numattr
,
1477 KMF_ATTRIBUTE
*attrlist
)
1479 KMF_RETURN rv
= KMF_OK
;
1480 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1481 uint32_t eValue
= 0x010001;
1482 RSA
*sslPrivKey
= NULL
;
1483 DSA
*sslDSAKey
= NULL
;
1484 EVP_PKEY
*eprikey
= NULL
;
1485 EVP_PKEY
*epubkey
= NULL
;
1487 KMF_KEY_HANDLE
*pubkey
= NULL
, *privkey
= NULL
;
1488 uint32_t keylen
= 1024;
1489 uint32_t keylen_size
= sizeof (uint32_t);
1490 boolean_t storekey
= TRUE
;
1491 KMF_KEY_ALG keytype
= KMF_RSA
;
1493 rv
= kmf_get_attr(KMF_STOREKEY_BOOL_ATTR
, attrlist
, numattr
,
1496 /* "storekey" is optional. Default is TRUE */
1500 rv
= kmf_get_attr(KMF_KEYALG_ATTR
, attrlist
, numattr
,
1501 (void *)&keytype
, NULL
);
1503 /* keytype is optional. KMF_RSA is default */
1506 pubkey
= kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR
, attrlist
, numattr
);
1508 return (KMF_ERR_BAD_PARAMETER
);
1510 privkey
= kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR
, attrlist
, numattr
);
1511 if (privkey
== NULL
)
1512 return (KMF_ERR_BAD_PARAMETER
);
1514 (void) memset(pubkey
, 0, sizeof (KMF_KEY_HANDLE
));
1515 (void) memset(privkey
, 0, sizeof (KMF_KEY_HANDLE
));
1517 eprikey
= EVP_PKEY_new();
1518 if (eprikey
== NULL
) {
1519 SET_ERROR(kmfh
, ERR_get_error());
1520 rv
= KMF_ERR_KEYGEN_FAILED
;
1523 epubkey
= EVP_PKEY_new();
1524 if (epubkey
== NULL
) {
1525 SET_ERROR(kmfh
, ERR_get_error());
1526 rv
= KMF_ERR_KEYGEN_FAILED
;
1529 if (keytype
== KMF_RSA
) {
1530 KMF_BIGINT
*rsaexp
= NULL
;
1532 rsaexp
= kmf_get_attr_ptr(KMF_RSAEXP_ATTR
, attrlist
, numattr
);
1533 if (rsaexp
!= NULL
) {
1534 if (rsaexp
->len
> 0 &&
1535 rsaexp
->len
<= sizeof (eValue
) &&
1536 rsaexp
->val
!= NULL
) {
1537 /* LINTED E_BAD_PTR_CAST_ALIGN */
1538 eValue
= *(uint32_t *)rsaexp
->val
;
1540 rv
= KMF_ERR_BAD_PARAMETER
;
1544 /* RSA Exponent is optional. Default is 0x10001 */
1548 rv
= kmf_get_attr(KMF_KEYLENGTH_ATTR
, attrlist
, numattr
,
1549 &keylen
, &keylen_size
);
1550 if (rv
== KMF_ERR_ATTR_NOT_FOUND
)
1551 /* keylen is optional, default is 1024 */
1554 rv
= KMF_ERR_BAD_PARAMETER
;
1558 sslPrivKey
= RSA_generate_key(keylen
, eValue
, NULL
, NULL
);
1559 if (sslPrivKey
== NULL
) {
1560 SET_ERROR(kmfh
, ERR_get_error());
1561 rv
= KMF_ERR_KEYGEN_FAILED
;
1563 (void) EVP_PKEY_set1_RSA(eprikey
, sslPrivKey
);
1564 privkey
->kstype
= KMF_KEYSTORE_OPENSSL
;
1565 privkey
->keyalg
= KMF_RSA
;
1566 privkey
->keyclass
= KMF_ASYM_PRI
;
1567 privkey
->israw
= FALSE
;
1568 privkey
->keyp
= (void *)eprikey
;
1570 /* OpenSSL derives the public key from the private */
1571 (void) EVP_PKEY_set1_RSA(epubkey
, sslPrivKey
);
1572 pubkey
->kstype
= KMF_KEYSTORE_OPENSSL
;
1573 pubkey
->keyalg
= KMF_RSA
;
1574 pubkey
->israw
= FALSE
;
1575 pubkey
->keyclass
= KMF_ASYM_PUB
;
1576 pubkey
->keyp
= (void *)epubkey
;
1578 } else if (keytype
== KMF_DSA
) {
1580 sslDSAKey
= DSA_new();
1581 if (sslDSAKey
== NULL
) {
1582 SET_ERROR(kmfh
, ERR_get_error());
1583 return (KMF_ERR_MEMORY
);
1586 if ((sslDSAKey
->p
= BN_bin2bn(P
, sizeof (P
), sslDSAKey
->p
)) ==
1588 SET_ERROR(kmfh
, ERR_get_error());
1589 rv
= KMF_ERR_KEYGEN_FAILED
;
1592 if ((sslDSAKey
->q
= BN_bin2bn(Q
, sizeof (Q
), sslDSAKey
->q
)) ==
1594 SET_ERROR(kmfh
, ERR_get_error());
1595 rv
= KMF_ERR_KEYGEN_FAILED
;
1598 if ((sslDSAKey
->g
= BN_bin2bn(G
, sizeof (G
), sslDSAKey
->g
)) ==
1600 SET_ERROR(kmfh
, ERR_get_error());
1601 rv
= KMF_ERR_KEYGEN_FAILED
;
1605 if (!DSA_generate_key(sslDSAKey
)) {
1606 SET_ERROR(kmfh
, ERR_get_error());
1607 rv
= KMF_ERR_KEYGEN_FAILED
;
1611 privkey
->kstype
= KMF_KEYSTORE_OPENSSL
;
1612 privkey
->keyalg
= KMF_DSA
;
1613 privkey
->keyclass
= KMF_ASYM_PRI
;
1614 privkey
->israw
= FALSE
;
1615 if (EVP_PKEY_set1_DSA(eprikey
, sslDSAKey
)) {
1616 privkey
->keyp
= (void *)eprikey
;
1618 SET_ERROR(kmfh
, ERR_get_error());
1619 rv
= KMF_ERR_KEYGEN_FAILED
;
1623 /* Make a copy for the public key */
1625 if ((dp
->p
= BN_new()) == NULL
) {
1626 SET_ERROR(kmfh
, ERR_get_error());
1627 rv
= KMF_ERR_MEMORY
;
1631 if ((dp
->q
= BN_new()) == NULL
) {
1632 SET_ERROR(kmfh
, ERR_get_error());
1633 rv
= KMF_ERR_MEMORY
;
1638 if ((dp
->g
= BN_new()) == NULL
) {
1639 SET_ERROR(kmfh
, ERR_get_error());
1640 rv
= KMF_ERR_MEMORY
;
1646 if ((dp
->pub_key
= BN_new()) == NULL
) {
1647 SET_ERROR(kmfh
, ERR_get_error());
1648 rv
= KMF_ERR_MEMORY
;
1655 (void) BN_copy(dp
->p
, sslDSAKey
->p
);
1656 (void) BN_copy(dp
->q
, sslDSAKey
->q
);
1657 (void) BN_copy(dp
->g
, sslDSAKey
->g
);
1658 (void) BN_copy(dp
->pub_key
, sslDSAKey
->pub_key
);
1660 pubkey
->kstype
= KMF_KEYSTORE_OPENSSL
;
1661 pubkey
->keyalg
= KMF_DSA
;
1662 pubkey
->keyclass
= KMF_ASYM_PUB
;
1663 pubkey
->israw
= FALSE
;
1665 if (EVP_PKEY_set1_DSA(epubkey
, sslDSAKey
)) {
1666 pubkey
->keyp
= (void *)epubkey
;
1668 SET_ERROR(kmfh
, ERR_get_error());
1669 rv
= KMF_ERR_KEYGEN_FAILED
;
1680 KMF_ATTRIBUTE storeattrs
[4]; /* max. 4 attributes needed */
1682 char *keyfile
= NULL
, *dirpath
= NULL
;
1683 KMF_ENCODE_FORMAT format
;
1685 * Construct a new attribute arrray and call openssl_store_key
1687 kmf_set_attr_at_index(storeattrs
, i
, KMF_PRIVKEY_HANDLE_ATTR
,
1688 privkey
, sizeof (privkey
));
1691 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
1692 if (dirpath
!= NULL
) {
1693 storeattrs
[i
].type
= KMF_DIRPATH_ATTR
;
1694 storeattrs
[i
].pValue
= dirpath
;
1695 storeattrs
[i
].valueLen
= strlen(dirpath
);
1698 rv
= KMF_OK
; /* DIRPATH is optional */
1700 keyfile
= kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
,
1702 if (keyfile
!= NULL
) {
1703 storeattrs
[i
].type
= KMF_KEY_FILENAME_ATTR
;
1704 storeattrs
[i
].pValue
= keyfile
;
1705 storeattrs
[i
].valueLen
= strlen(keyfile
);
1708 goto cleanup
; /* KEYFILE is required */
1710 rv
= kmf_get_attr(KMF_ENCODE_FORMAT_ATTR
, attrlist
, numattr
,
1711 (void *)&format
, NULL
);
1713 storeattrs
[i
].type
= KMF_ENCODE_FORMAT_ATTR
;
1714 storeattrs
[i
].pValue
= &format
;
1715 storeattrs
[i
].valueLen
= sizeof (format
);
1719 rv
= OpenSSL_StoreKey(handle
, i
, storeattrs
);
1724 if (eprikey
!= NULL
)
1725 EVP_PKEY_free(eprikey
);
1727 if (epubkey
!= NULL
)
1728 EVP_PKEY_free(epubkey
);
1730 if (pubkey
->keylabel
) {
1731 free(pubkey
->keylabel
);
1732 pubkey
->keylabel
= NULL
;
1735 if (privkey
->keylabel
) {
1736 free(privkey
->keylabel
);
1737 privkey
->keylabel
= NULL
;
1740 pubkey
->keyp
= NULL
;
1741 privkey
->keyp
= NULL
;
1745 RSA_free(sslPrivKey
);
1748 DSA_free(sslDSAKey
);
1751 (void) BIO_free(out
);
1757 * Make sure the BN conversion is properly padded with 0x00
1758 * bytes. If not, signature verification for DSA signatures
1759 * may fail in the case where the bignum value does not use
1763 fixbnlen(BIGNUM
*bn
, unsigned char *buf
, int len
) {
1764 int bytes
= len
- BN_num_bytes(bn
);
1766 /* prepend with leading 0x00 if necessary */
1770 (void) BN_bn2bin(bn
, buf
);
1772 * Return the desired length since we prepended it
1773 * with the necessary 0x00 padding.
1779 OpenSSL_SignData(KMF_HANDLE_T handle
, KMF_KEY_HANDLE
*key
,
1780 KMF_OID
*AlgOID
, KMF_DATA
*tobesigned
, KMF_DATA
*output
)
1782 KMF_RETURN ret
= KMF_OK
;
1783 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1784 KMF_ALGORITHM_INDEX AlgId
;
1788 if (key
== NULL
|| AlgOID
== NULL
||
1789 tobesigned
== NULL
|| output
== NULL
||
1790 tobesigned
->Data
== NULL
||
1791 output
->Data
== NULL
)
1792 return (KMF_ERR_BAD_PARAMETER
);
1794 /* Map the OID to an OpenSSL algorithm */
1795 AlgId
= x509_algoid_to_algid(AlgOID
);
1796 if (AlgId
== KMF_ALGID_NONE
)
1797 return (KMF_ERR_BAD_ALGORITHM
);
1799 if (key
->keyalg
== KMF_RSA
) {
1800 EVP_PKEY
*pkey
= (EVP_PKEY
*)key
->keyp
;
1803 if (AlgId
== KMF_ALGID_MD5WithRSA
)
1805 else if (AlgId
== KMF_ALGID_SHA1WithRSA
)
1807 else if (AlgId
== KMF_ALGID_SHA256WithRSA
)
1809 else if (AlgId
== KMF_ALGID_SHA384WithRSA
)
1811 else if (AlgId
== KMF_ALGID_SHA512WithRSA
)
1813 else if (AlgId
== KMF_ALGID_RSA
)
1816 return (KMF_ERR_BAD_ALGORITHM
);
1818 if ((md
== NULL
) && (AlgId
== KMF_ALGID_RSA
)) {
1819 RSA
*rsa
= EVP_PKEY_get1_RSA((EVP_PKEY
*)pkey
);
1822 if ((len
= RSA_private_encrypt(tobesigned
->Length
,
1823 tobesigned
->Data
, p
, rsa
,
1824 RSA_PKCS1_PADDING
)) <= 0) {
1825 SET_ERROR(kmfh
, ERR_get_error());
1826 ret
= KMF_ERR_INTERNAL
;
1828 output
->Length
= len
;
1830 (void) EVP_MD_CTX_init(&ctx
);
1831 (void) EVP_SignInit_ex(&ctx
, md
, NULL
);
1832 (void) EVP_SignUpdate(&ctx
, tobesigned
->Data
,
1833 (uint32_t)tobesigned
->Length
);
1834 len
= (uint32_t)output
->Length
;
1836 if (!EVP_SignFinal(&ctx
, p
, (uint32_t *)&len
, pkey
)) {
1837 SET_ERROR(kmfh
, ERR_get_error());
1839 ret
= KMF_ERR_INTERNAL
;
1841 output
->Length
= len
;
1842 (void) EVP_MD_CTX_cleanup(&ctx
);
1844 } else if (key
->keyalg
== KMF_DSA
) {
1845 DSA
*dsa
= EVP_PKEY_get1_DSA(key
->keyp
);
1847 uchar_t hash
[EVP_MAX_MD_SIZE
];
1851 if (AlgId
== KMF_ALGID_DSA
||
1852 AlgId
== KMF_ALGID_SHA1WithDSA
)
1854 else if (AlgId
== KMF_ALGID_SHA256WithDSA
)
1856 else /* Bad algorithm */
1857 return (KMF_ERR_BAD_ALGORITHM
);
1860 * OpenSSL EVP_Sign operation automatically converts to
1861 * ASN.1 output so we do the operations separately so we
1862 * are assured of NOT getting ASN.1 output returned.
1863 * KMF does not want ASN.1 encoded results because
1864 * not all mechanisms return ASN.1 encodings (PKCS#11
1865 * and NSS return raw signature data).
1867 EVP_MD_CTX_init(&ctx
);
1868 (void) EVP_DigestInit_ex(&ctx
, md
, NULL
);
1869 (void) EVP_DigestUpdate(&ctx
, tobesigned
->Data
,
1870 tobesigned
->Length
);
1871 (void) EVP_DigestFinal_ex(&ctx
, hash
, &hashlen
);
1873 /* Only sign first 20 bytes for SHA2 */
1874 if (AlgId
== KMF_ALGID_SHA256WithDSA
)
1876 dsasig
= DSA_do_sign(hash
, hashlen
, dsa
);
1877 if (dsasig
!= NULL
) {
1879 output
->Length
= i
= fixbnlen(dsasig
->r
, output
->Data
,
1882 output
->Length
+= fixbnlen(dsasig
->s
, &output
->Data
[i
],
1885 DSA_SIG_free(dsasig
);
1887 SET_ERROR(kmfh
, ERR_get_error());
1889 (void) EVP_MD_CTX_cleanup(&ctx
);
1891 return (KMF_ERR_BAD_PARAMETER
);
1899 OpenSSL_DeleteKey(KMF_HANDLE_T handle
,
1900 int numattr
, KMF_ATTRIBUTE
*attrlist
)
1902 KMF_RETURN rv
= KMF_OK
;
1903 KMF_KEY_HANDLE
*key
;
1904 boolean_t destroy
= B_TRUE
;
1906 key
= kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR
, attrlist
, numattr
);
1907 if (key
== NULL
|| key
->keyp
== NULL
)
1908 return (KMF_ERR_BAD_PARAMETER
);
1910 rv
= kmf_get_attr(KMF_DESTROY_BOOL_ATTR
, attrlist
, numattr
,
1911 (void *)&destroy
, NULL
);
1913 /* "destroy" is optional. Default is TRUE */
1917 if (key
->keyclass
!= KMF_ASYM_PUB
&&
1918 key
->keyclass
!= KMF_ASYM_PRI
&&
1919 key
->keyclass
!= KMF_SYMMETRIC
)
1920 return (KMF_ERR_BAD_KEY_CLASS
);
1922 if (key
->keyclass
== KMF_SYMMETRIC
) {
1923 kmf_free_raw_sym_key((KMF_RAW_SYM_KEY
*)key
->keyp
);
1926 if (key
->keyp
!= NULL
) {
1927 EVP_PKEY_free(key
->keyp
);
1932 if (key
->keylabel
!= NULL
) {
1933 EVP_PKEY
*pkey
= NULL
;
1934 /* If the file exists, make sure it is a proper key. */
1935 pkey
= openssl_load_key(handle
, key
->keylabel
);
1937 if (key
->keylabel
!= NULL
) {
1938 free(key
->keylabel
);
1939 key
->keylabel
= NULL
;
1941 return (KMF_ERR_KEY_NOT_FOUND
);
1943 EVP_PKEY_free(pkey
);
1946 if (unlink(key
->keylabel
) != 0) {
1947 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1948 SET_SYS_ERROR(kmfh
, errno
);
1949 rv
= KMF_ERR_INTERNAL
;
1952 if (key
->keylabel
!= NULL
) {
1953 free(key
->keylabel
);
1954 key
->keylabel
= NULL
;
1961 OpenSSL_GetErrorString(KMF_HANDLE_T handle
, char **msgstr
)
1963 KMF_RETURN ret
= KMF_OK
;
1964 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1965 char str
[256]; /* OpenSSL needs at least 120 byte buffer */
1967 ERR_error_string_n(kmfh
->lasterr
.errcode
, str
, sizeof (str
));
1969 *msgstr
= (char *)strdup(str
);
1970 if ((*msgstr
) == NULL
)
1971 ret
= KMF_ERR_MEMORY
;
1983 case KMF_X509_EXT_KEY_USAGE
:
1984 return (NID_key_usage
);
1985 case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD
:
1986 return (NID_private_key_usage_period
);
1987 case KMF_X509_EXT_CERT_POLICIES
:
1988 return (NID_certificate_policies
);
1989 case KMF_X509_EXT_SUBJ_ALTNAME
:
1990 return (NID_subject_alt_name
);
1991 case KMF_X509_EXT_ISSUER_ALTNAME
:
1992 return (NID_issuer_alt_name
);
1993 case KMF_X509_EXT_BASIC_CONSTRAINTS
:
1994 return (NID_basic_constraints
);
1995 case KMF_X509_EXT_EXT_KEY_USAGE
:
1996 return (NID_ext_key_usage
);
1997 case KMF_X509_EXT_AUTH_KEY_ID
:
1998 return (NID_authority_key_identifier
);
1999 case KMF_X509_EXT_CRL_DIST_POINTS
:
2000 return (NID_crl_distribution_points
);
2001 case KMF_X509_EXT_SUBJ_KEY_ID
:
2002 return (NID_subject_key_identifier
);
2003 case KMF_X509_EXT_POLICY_MAPPINGS
:
2004 return (OBJ_sn2nid("policyMappings"));
2005 case KMF_X509_EXT_NAME_CONSTRAINTS
:
2006 return (OBJ_sn2nid("nameConstraints"));
2007 case KMF_X509_EXT_POLICY_CONSTRAINTS
:
2008 return (OBJ_sn2nid("policyConstraints"));
2009 case KMF_X509_EXT_INHIBIT_ANY_POLICY
:
2010 return (OBJ_sn2nid("inhibitAnyPolicy"));
2011 case KMF_X509_EXT_FRESHEST_CRL
:
2012 return (OBJ_sn2nid("freshestCRL"));
2019 OpenSSL_CertGetPrintable(KMF_HANDLE_T handle
, const KMF_DATA
*pcert
,
2020 KMF_PRINTABLE_ITEM flag
, char *resultStr
)
2022 KMF_RETURN ret
= KMF_OK
;
2023 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2025 unsigned char *outbuf
= NULL
;
2026 unsigned char *outbuf_p
;
2027 char *tmpstr
= NULL
;
2029 int ext_index
, nid
, len
;
2031 #if OPENSSL_VERSION_NUMBER < 0x10000000L
2032 STACK
*emlst
= NULL
;
2034 STACK_OF(OPENSSL_STRING
) *emlst
= NULL
;
2039 if (pcert
== NULL
|| pcert
->Data
== NULL
|| pcert
->Length
== 0) {
2040 return (KMF_ERR_BAD_PARAMETER
);
2043 /* copy cert data to outbuf */
2044 outbuf
= malloc(pcert
->Length
);
2045 if (outbuf
== NULL
) {
2046 return (KMF_ERR_MEMORY
);
2048 (void) memcpy(outbuf
, pcert
->Data
, pcert
->Length
);
2050 outbuf_p
= outbuf
; /* use a temp pointer; required by openssl */
2051 xcert
= d2i_X509(NULL
, (const uchar_t
**)&outbuf_p
, pcert
->Length
);
2052 if (xcert
== NULL
) {
2053 SET_ERROR(kmfh
, ERR_get_error());
2054 ret
= KMF_ERR_ENCODING
;
2058 mem
= BIO_new(BIO_s_mem());
2060 SET_ERROR(kmfh
, ERR_get_error());
2061 ret
= KMF_ERR_MEMORY
;
2066 case KMF_CERT_ISSUER
:
2067 (void) X509_NAME_print_ex(mem
, X509_get_issuer_name(xcert
), 0,
2068 XN_FLAG_SEP_CPLUS_SPC
);
2069 len
= BIO_gets(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2072 case KMF_CERT_SUBJECT
:
2073 (void) X509_NAME_print_ex(mem
, X509_get_subject_name(xcert
), 0,
2074 XN_FLAG_SEP_CPLUS_SPC
);
2075 len
= BIO_gets(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2078 case KMF_CERT_VERSION
:
2079 tmpstr
= i2s_ASN1_INTEGER(NULL
, xcert
->cert_info
->version
);
2080 (void) strncpy(resultStr
, tmpstr
, KMF_CERT_PRINTABLE_LEN
);
2081 OPENSSL_free(tmpstr
);
2082 len
= strlen(resultStr
);
2085 case KMF_CERT_SERIALNUM
:
2086 if (i2a_ASN1_INTEGER(mem
, X509_get_serialNumber(xcert
)) > 0) {
2087 (void) strcpy(resultStr
, "0x");
2088 len
= BIO_gets(mem
, &resultStr
[2],
2089 KMF_CERT_PRINTABLE_LEN
- 2);
2093 case KMF_CERT_NOTBEFORE
:
2094 (void) ASN1_TIME_print(mem
, X509_get_notBefore(xcert
));
2095 len
= BIO_gets(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2098 case KMF_CERT_NOTAFTER
:
2099 (void) ASN1_TIME_print(mem
, X509_get_notAfter(xcert
));
2100 len
= BIO_gets(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2103 case KMF_CERT_PUBKEY_DATA
:
2105 EVP_PKEY
*pkey
= X509_get_pubkey(xcert
);
2107 SET_ERROR(kmfh
, ERR_get_error());
2108 ret
= KMF_ERR_ENCODING
;
2112 if (pkey
->type
== EVP_PKEY_RSA
) {
2113 (void) BIO_printf(mem
,
2114 "RSA Public Key: (%d bit)\n",
2115 BN_num_bits(pkey
->pkey
.rsa
->n
));
2116 (void) RSA_print(mem
, pkey
->pkey
.rsa
, 0);
2117 } else if (pkey
->type
== EVP_PKEY_DSA
) {
2118 (void) BIO_printf(mem
,
2119 "%12sDSA Public Key:\n", "");
2120 (void) DSA_print(mem
, pkey
->pkey
.dsa
, 0);
2122 (void) BIO_printf(mem
,
2123 "%12sUnknown Public Key:\n", "");
2125 (void) BIO_printf(mem
, "\n");
2126 EVP_PKEY_free(pkey
);
2128 len
= BIO_read(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2130 case KMF_CERT_SIGNATURE_ALG
:
2131 case KMF_CERT_PUBKEY_ALG
:
2132 if (flag
== KMF_CERT_SIGNATURE_ALG
) {
2133 len
= i2a_ASN1_OBJECT(mem
,
2134 xcert
->sig_alg
->algorithm
);
2136 len
= i2a_ASN1_OBJECT(mem
,
2137 xcert
->cert_info
->key
->algor
->algorithm
);
2141 len
= BIO_read(mem
, resultStr
,
2142 KMF_CERT_PRINTABLE_LEN
);
2146 case KMF_CERT_EMAIL
:
2147 emlst
= X509_get1_email(xcert
);
2148 #if OPENSSL_VERSION_NUMBER < 0x10000000L
2149 for (j
= 0; j
< sk_num(emlst
); j
++)
2150 (void) BIO_printf(mem
, "%s\n", sk_value(emlst
, j
));
2152 for (j
= 0; j
< sk_OPENSSL_STRING_num(emlst
); j
++)
2153 (void) BIO_printf(mem
, "%s\n",
2154 sk_OPENSSL_STRING_value(emlst
, j
));
2157 len
= BIO_gets(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2158 X509_email_free(emlst
);
2160 case KMF_X509_EXT_ISSUER_ALTNAME
:
2161 case KMF_X509_EXT_SUBJ_ALTNAME
:
2162 case KMF_X509_EXT_KEY_USAGE
:
2163 case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD
:
2164 case KMF_X509_EXT_CERT_POLICIES
:
2165 case KMF_X509_EXT_BASIC_CONSTRAINTS
:
2166 case KMF_X509_EXT_NAME_CONSTRAINTS
:
2167 case KMF_X509_EXT_POLICY_CONSTRAINTS
:
2168 case KMF_X509_EXT_EXT_KEY_USAGE
:
2169 case KMF_X509_EXT_INHIBIT_ANY_POLICY
:
2170 case KMF_X509_EXT_AUTH_KEY_ID
:
2171 case KMF_X509_EXT_SUBJ_KEY_ID
:
2172 case KMF_X509_EXT_POLICY_MAPPINGS
:
2173 case KMF_X509_EXT_CRL_DIST_POINTS
:
2174 case KMF_X509_EXT_FRESHEST_CRL
:
2175 nid
= ext2NID(flag
);
2176 if (nid
== NID_undef
) {
2177 ret
= KMF_ERR_EXTENSION_NOT_FOUND
;
2180 ci
= xcert
->cert_info
;
2182 ext_index
= X509v3_get_ext_by_NID(ci
->extensions
, nid
, -1);
2183 if (ext_index
== -1) {
2184 SET_ERROR(kmfh
, ERR_get_error());
2186 ret
= KMF_ERR_EXTENSION_NOT_FOUND
;
2189 ex
= X509v3_get_ext(ci
->extensions
, ext_index
);
2191 (void) i2a_ASN1_OBJECT(mem
, X509_EXTENSION_get_object(ex
));
2193 if (BIO_printf(mem
, ": %s\n",
2194 X509_EXTENSION_get_critical(ex
) ? "critical" : "") <= 0) {
2195 SET_ERROR(kmfh
, ERR_get_error());
2196 ret
= KMF_ERR_ENCODING
;
2199 if (!X509V3_EXT_print(mem
, ex
, X509V3_EXT_DUMP_UNKNOWN
, 4)) {
2200 (void) BIO_printf(mem
, "%*s", 4, "");
2201 (void) M_ASN1_OCTET_STRING_print(mem
, ex
->value
);
2203 if (BIO_write(mem
, "\n", 1) <= 0) {
2204 SET_ERROR(kmfh
, ERR_get_error());
2205 ret
= KMF_ERR_ENCODING
;
2208 len
= BIO_read(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2211 SET_ERROR(kmfh
, ERR_get_error());
2212 ret
= KMF_ERR_ENCODING
;
2216 if (outbuf
!= NULL
) {
2220 if (xcert
!= NULL
) {
2225 (void) BIO_free(mem
);
2233 OpenSSL_FindPrikeyByCert(KMF_HANDLE_T handle
, int numattr
,
2234 KMF_ATTRIBUTE
*attrlist
)
2236 KMF_RETURN rv
= KMF_OK
;
2237 KMF_KEYSTORE_TYPE kstype
= KMF_KEYSTORE_OPENSSL
;
2238 KMF_KEY_CLASS keyclass
= KMF_ASYM_PRI
;
2239 KMF_KEY_HANDLE
*key
= NULL
;
2240 uint32_t numkeys
= 1; /* 1 key only */
2241 char *dirpath
= NULL
;
2242 char *keyfile
= NULL
;
2243 KMF_ATTRIBUTE new_attrlist
[16];
2247 * This is really just a FindKey operation, reuse the
2250 kmf_set_attr_at_index(new_attrlist
, i
,
2251 KMF_KEYSTORE_TYPE_ATTR
, &kstype
, sizeof (kstype
));
2254 kmf_set_attr_at_index(new_attrlist
, i
,
2255 KMF_COUNT_ATTR
, &numkeys
, sizeof (uint32_t));
2258 kmf_set_attr_at_index(new_attrlist
, i
,
2259 KMF_KEYCLASS_ATTR
, &keyclass
, sizeof (keyclass
));
2262 key
= kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR
, attrlist
, numattr
);
2264 return (KMF_ERR_BAD_PARAMETER
);
2266 kmf_set_attr_at_index(new_attrlist
, i
,
2267 KMF_KEY_HANDLE_ATTR
, key
, sizeof (KMF_KEY_HANDLE
));
2271 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
2272 if (dirpath
!= NULL
) {
2273 kmf_set_attr_at_index(new_attrlist
, i
,
2274 KMF_DIRPATH_ATTR
, dirpath
, strlen(dirpath
));
2278 keyfile
= kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
, attrlist
, numattr
);
2279 if (keyfile
== NULL
)
2280 return (KMF_ERR_BAD_PARAMETER
);
2282 kmf_set_attr_at_index(new_attrlist
, i
,
2283 KMF_KEY_FILENAME_ATTR
, keyfile
, strlen(keyfile
));
2287 rv
= OpenSSL_FindKey(handle
, i
, new_attrlist
);
2293 OpenSSL_DecryptData(KMF_HANDLE_T handle
, KMF_KEY_HANDLE
*key
,
2294 KMF_OID
*AlgOID
, KMF_DATA
*ciphertext
,
2297 KMF_RETURN ret
= KMF_OK
;
2299 unsigned int in_len
= 0, out_len
= 0;
2300 unsigned int total_decrypted
= 0, modulus_len
= 0;
2301 uint8_t *in_data
, *out_data
;
2304 if (key
== NULL
|| AlgOID
== NULL
||
2305 ciphertext
== NULL
|| output
== NULL
||
2306 ciphertext
->Data
== NULL
||
2307 output
->Data
== NULL
)
2308 return (KMF_ERR_BAD_PARAMETER
);
2310 if (key
->keyalg
== KMF_RSA
) {
2311 rsa
= EVP_PKEY_get1_RSA((EVP_PKEY
*)key
->keyp
);
2312 modulus_len
= RSA_size(rsa
);
2314 return (KMF_ERR_BAD_PARAMETER
);
2317 blocks
= ciphertext
->Length
/modulus_len
;
2318 out_data
= output
->Data
;
2319 in_data
= ciphertext
->Data
;
2320 out_len
= modulus_len
- 11;
2321 in_len
= modulus_len
;
2323 for (i
= 0; i
< blocks
; i
++) {
2324 out_len
= RSA_private_decrypt(in_len
,
2325 in_data
, out_data
, rsa
, RSA_PKCS1_PADDING
);
2328 ret
= KMF_ERR_INTERNAL
;
2332 out_data
+= out_len
;
2333 total_decrypted
+= out_len
;
2337 output
->Length
= total_decrypted
;
2349 * This function will create a certid from issuer_cert and user_cert.
2350 * The caller should use OCSP_CERTID_free(OCSP_CERTID *) to deallocate
2351 * certid memory after use.
2354 create_certid(KMF_HANDLE_T handle
, const KMF_DATA
*issuer_cert
,
2355 const KMF_DATA
*user_cert
, OCSP_CERTID
**certid
)
2357 KMF_RETURN ret
= KMF_OK
;
2358 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2359 X509
*issuer
= NULL
;
2361 unsigned char *ptmp
;
2363 if (issuer_cert
== NULL
|| user_cert
== NULL
) {
2364 return (KMF_ERR_BAD_PARAMETER
);
2367 /* convert the DER-encoded issuer cert to an internal X509 */
2368 ptmp
= issuer_cert
->Data
;
2369 issuer
= d2i_X509(NULL
, (const uchar_t
**)&ptmp
,
2370 issuer_cert
->Length
);
2371 if (issuer
== NULL
) {
2372 SET_ERROR(kmfh
, ERR_get_error());
2373 ret
= KMF_ERR_OCSP_BAD_ISSUER
;
2377 /* convert the DER-encoded user cert to an internal X509 */
2378 ptmp
= user_cert
->Data
;
2379 cert
= d2i_X509(NULL
, (const uchar_t
**)&ptmp
,
2382 SET_ERROR(kmfh
, ERR_get_error());
2384 ret
= KMF_ERR_OCSP_BAD_CERT
;
2388 /* create a CERTID */
2389 *certid
= OCSP_cert_to_id(NULL
, cert
, issuer
);
2390 if (*certid
== NULL
) {
2391 SET_ERROR(kmfh
, ERR_get_error());
2392 ret
= KMF_ERR_OCSP_CERTID
;
2397 if (issuer
!= NULL
) {
2409 OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle
,
2410 int numattr
, KMF_ATTRIBUTE
*attrlist
)
2412 KMF_RETURN ret
= KMF_OK
;
2413 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2414 OCSP_CERTID
*id
= NULL
;
2415 OCSP_REQUEST
*req
= NULL
;
2418 KMF_DATA
*issuer_cert
;
2419 KMF_DATA
*user_cert
;
2421 user_cert
= kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR
,
2423 if (user_cert
== NULL
)
2424 return (KMF_ERR_BAD_PARAMETER
);
2426 issuer_cert
= kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR
,
2428 if (issuer_cert
== NULL
)
2429 return (KMF_ERR_BAD_PARAMETER
);
2431 reqfile
= kmf_get_attr_ptr(KMF_OCSP_REQUEST_FILENAME_ATTR
,
2433 if (reqfile
== NULL
)
2434 return (KMF_ERR_BAD_PARAMETER
);
2436 ret
= create_certid(handle
, issuer_cert
, user_cert
, &id
);
2437 if (ret
!= KMF_OK
) {
2441 /* Create an OCSP request */
2442 req
= OCSP_REQUEST_new();
2444 SET_ERROR(kmfh
, ERR_get_error());
2445 ret
= KMF_ERR_OCSP_CREATE_REQUEST
;
2449 if (!OCSP_request_add0_id(req
, id
)) {
2450 ret
= KMF_ERR_OCSP_CREATE_REQUEST
;
2454 /* Write the request to the output file with DER encoding */
2455 derbio
= BIO_new_file(reqfile
, "wb");
2457 SET_ERROR(kmfh
, ERR_get_error());
2458 ret
= KMF_ERR_OPEN_FILE
;
2461 if (i2d_OCSP_REQUEST_bio(derbio
, req
) <= 0) {
2462 ret
= KMF_ERR_ENCODING
;
2467 * We don't need to free "id" explicitely, because OCSP_REQUEST_free()
2468 * will also deallocate certid's space.
2471 OCSP_REQUEST_free(req
);
2474 if (derbio
!= NULL
) {
2475 (void) BIO_free(derbio
);
2481 /* ocsp_find_signer_sk() is copied from openssl source */
2482 static X509
*ocsp_find_signer_sk(STACK_OF(X509
) *certs
, OCSP_RESPID
*id
)
2485 unsigned char tmphash
[SHA_DIGEST_LENGTH
], *keyhash
;
2487 /* Easy if lookup by name */
2488 if (id
->type
== V_OCSP_RESPID_NAME
)
2489 return (X509_find_by_subject(certs
, id
->value
.byName
));
2491 /* Lookup by key hash */
2493 /* If key hash isn't SHA1 length then forget it */
2494 if (id
->value
.byKey
->length
!= SHA_DIGEST_LENGTH
)
2497 keyhash
= id
->value
.byKey
->data
;
2498 /* Calculate hash of each key and compare */
2499 for (i
= 0; i
< sk_X509_num(certs
); i
++) {
2500 /* LINTED E_BAD_PTR_CAST_ALIGN */
2501 X509
*x
= sk_X509_value(certs
, i
);
2502 /* Use pubkey_digest to get the key ID value */
2503 (void) X509_pubkey_digest(x
, EVP_sha1(), tmphash
, NULL
);
2504 if (!memcmp(keyhash
, tmphash
, SHA_DIGEST_LENGTH
))
2510 /* ocsp_find_signer() is copied from openssl source */
2513 ocsp_find_signer(X509
**psigner
, OCSP_BASICRESP
*bs
, STACK_OF(X509
) *certs
,
2514 X509_STORE
*st
, unsigned long flags
)
2517 OCSP_RESPID
*rid
= bs
->tbsResponseData
->responderId
;
2518 if ((signer
= ocsp_find_signer_sk(certs
, rid
))) {
2522 if (!(flags
& OCSP_NOINTERN
) &&
2523 (signer
= ocsp_find_signer_sk(bs
->certs
, rid
))) {
2527 /* Maybe lookup from store if by subject name */
2534 * This function will verify the signature of a basic response, using
2535 * the public key from the OCSP responder certificate.
2538 check_response_signature(KMF_HANDLE_T handle
, OCSP_BASICRESP
*bs
,
2539 KMF_DATA
*signer_cert
, KMF_DATA
*issuer_cert
)
2541 KMF_RETURN ret
= KMF_OK
;
2542 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2543 STACK_OF(X509
) *cert_stack
= NULL
;
2544 X509
*signer
= NULL
;
2545 X509
*issuer
= NULL
;
2546 EVP_PKEY
*skey
= NULL
;
2547 unsigned char *ptmp
;
2550 if (bs
== NULL
|| issuer_cert
== NULL
)
2551 return (KMF_ERR_BAD_PARAMETER
);
2554 * Find the certificate that signed the basic response.
2556 * If signer_cert is not NULL, we will use that as the signer cert.
2557 * Otherwise, we will check if the issuer cert is actually the signer.
2558 * If we still do not find a signer, we will look for it from the
2559 * certificate list came with the response file.
2561 if (signer_cert
!= NULL
) {
2562 ptmp
= signer_cert
->Data
;
2563 signer
= d2i_X509(NULL
, (const uchar_t
**)&ptmp
,
2564 signer_cert
->Length
);
2565 if (signer
== NULL
) {
2566 SET_ERROR(kmfh
, ERR_get_error());
2567 ret
= KMF_ERR_OCSP_BAD_SIGNER
;
2572 * Convert the issuer cert into X509 and push it into a
2573 * stack to be used by ocsp_find_signer().
2575 ptmp
= issuer_cert
->Data
;
2576 issuer
= d2i_X509(NULL
, (const uchar_t
**)&ptmp
,
2577 issuer_cert
->Length
);
2578 if (issuer
== NULL
) {
2579 SET_ERROR(kmfh
, ERR_get_error());
2580 ret
= KMF_ERR_OCSP_BAD_ISSUER
;
2584 if ((cert_stack
= sk_X509_new_null()) == NULL
) {
2585 ret
= KMF_ERR_INTERNAL
;
2589 if (sk_X509_push(cert_stack
, issuer
) == NULL
) {
2590 ret
= KMF_ERR_INTERNAL
;
2594 ret
= ocsp_find_signer(&signer
, bs
, cert_stack
, NULL
, 0);
2596 /* can not find the signer */
2597 ret
= KMF_ERR_OCSP_BAD_SIGNER
;
2602 /* Verify the signature of the response */
2603 skey
= X509_get_pubkey(signer
);
2605 ret
= KMF_ERR_OCSP_BAD_SIGNER
;
2609 ret
= OCSP_BASICRESP_verify(bs
, skey
, 0);
2611 ret
= KMF_ERR_OCSP_RESPONSE_SIGNATURE
;
2616 if (issuer
!= NULL
) {
2620 if (signer
!= NULL
) {
2625 EVP_PKEY_free(skey
);
2628 if (cert_stack
!= NULL
) {
2629 sk_X509_free(cert_stack
);
2638 OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle
,
2639 int numattr
, KMF_ATTRIBUTE
*attrlist
)
2641 KMF_RETURN ret
= KMF_OK
;
2643 OCSP_RESPONSE
*resp
= NULL
;
2644 OCSP_BASICRESP
*bs
= NULL
;
2645 OCSP_CERTID
*id
= NULL
;
2646 OCSP_SINGLERESP
*single
= NULL
;
2647 ASN1_GENERALIZEDTIME
*rev
, *thisupd
, *nextupd
;
2648 int index
, status
, reason
;
2649 KMF_DATA
*issuer_cert
;
2650 KMF_DATA
*user_cert
;
2651 KMF_DATA
*signer_cert
;
2653 int *response_reason
, *response_status
, *cert_status
;
2654 boolean_t ignore_response_sign
= B_FALSE
; /* default is FALSE */
2655 uint32_t response_lifetime
;
2657 issuer_cert
= kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR
,
2659 if (issuer_cert
== NULL
)
2660 return (KMF_ERR_BAD_PARAMETER
);
2662 user_cert
= kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR
,
2664 if (user_cert
== NULL
)
2665 return (KMF_ERR_BAD_PARAMETER
);
2667 response
= kmf_get_attr_ptr(KMF_OCSP_RESPONSE_DATA_ATTR
,
2669 if (response
== NULL
)
2670 return (KMF_ERR_BAD_PARAMETER
);
2672 response_status
= kmf_get_attr_ptr(KMF_OCSP_RESPONSE_STATUS_ATTR
,
2674 if (response_status
== NULL
)
2675 return (KMF_ERR_BAD_PARAMETER
);
2677 response_reason
= kmf_get_attr_ptr(KMF_OCSP_RESPONSE_REASON_ATTR
,
2679 if (response_reason
== NULL
)
2680 return (KMF_ERR_BAD_PARAMETER
);
2682 cert_status
= kmf_get_attr_ptr(KMF_OCSP_RESPONSE_CERT_STATUS_ATTR
,
2684 if (cert_status
== NULL
)
2685 return (KMF_ERR_BAD_PARAMETER
);
2687 /* Read in the response */
2688 derbio
= BIO_new_mem_buf(response
->Data
, response
->Length
);
2690 ret
= KMF_ERR_MEMORY
;
2694 resp
= d2i_OCSP_RESPONSE_bio(derbio
, NULL
);
2696 ret
= KMF_ERR_OCSP_MALFORMED_RESPONSE
;
2700 /* Check the response status */
2701 status
= OCSP_response_status(resp
);
2702 *response_status
= status
;
2703 if (status
!= OCSP_RESPONSE_STATUS_SUCCESSFUL
) {
2704 ret
= KMF_ERR_OCSP_RESPONSE_STATUS
;
2709 printf("Successfully checked the response file status.\n");
2712 /* Extract basic response */
2713 bs
= OCSP_response_get1_basic(resp
);
2715 ret
= KMF_ERR_OCSP_NO_BASIC_RESPONSE
;
2720 printf("Successfully retrieved the basic response.\n");
2723 /* Check the basic response signature if required */
2724 ret
= kmf_get_attr(KMF_IGNORE_RESPONSE_SIGN_ATTR
, attrlist
, numattr
,
2725 (void *)&ignore_response_sign
, NULL
);
2729 signer_cert
= kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR
,
2732 if (ignore_response_sign
== B_FALSE
) {
2733 ret
= check_response_signature(handle
, bs
,
2734 signer_cert
, issuer_cert
);
2740 printf("Successfully verified the response signature.\n");
2743 /* Create a certid for the certificate in question */
2744 ret
= create_certid(handle
, issuer_cert
, user_cert
, &id
);
2745 if (ret
!= KMF_OK
) {
2746 ret
= KMF_ERR_OCSP_CERTID
;
2751 printf("successfully created a certid for the cert.\n");
2754 /* Find the index of the single response for the certid */
2755 index
= OCSP_resp_find(bs
, id
, -1);
2757 /* cound not find this certificate in the response */
2758 ret
= KMF_ERR_OCSP_UNKNOWN_CERT
;
2763 printf("Successfully found the single response index for the cert.\n");
2766 /* Retrieve the single response and get the cert status */
2767 single
= OCSP_resp_get0(bs
, index
);
2768 status
= OCSP_single_get0_status(single
, &reason
, &rev
, &thisupd
,
2770 if (status
== V_OCSP_CERTSTATUS_GOOD
) {
2771 *cert_status
= OCSP_GOOD
;
2772 } else if (status
== V_OCSP_CERTSTATUS_UNKNOWN
) {
2773 *cert_status
= OCSP_UNKNOWN
;
2774 } else { /* revoked */
2775 *cert_status
= OCSP_REVOKED
;
2776 *response_reason
= reason
;
2780 /* resp. time is optional, so we don't care about the return code. */
2781 (void) kmf_get_attr(KMF_RESPONSE_LIFETIME_ATTR
, attrlist
, numattr
,
2782 (void *)&response_lifetime
, NULL
);
2784 if (!OCSP_check_validity(thisupd
, nextupd
, 300,
2785 response_lifetime
)) {
2786 ret
= KMF_ERR_OCSP_STATUS_TIME_INVALID
;
2791 printf("Successfully verify the time.\n");
2796 (void) BIO_free(derbio
);
2799 OCSP_RESPONSE_free(resp
);
2802 OCSP_BASICRESP_free(bs
);
2805 OCSP_CERTID_free(id
);
2811 fetch_key(KMF_HANDLE_T handle
, char *path
,
2812 KMF_KEY_CLASS keyclass
, KMF_KEY_HANDLE
*key
)
2814 KMF_RETURN rv
= KMF_OK
;
2815 EVP_PKEY
*pkey
= NULL
;
2816 KMF_RAW_SYM_KEY
*rkey
= NULL
;
2818 if (keyclass
== KMF_ASYM_PRI
||
2819 keyclass
== KMF_ASYM_PUB
) {
2820 pkey
= openssl_load_key(handle
, path
);
2822 return (KMF_ERR_KEY_NOT_FOUND
);
2825 if (pkey
->type
== EVP_PKEY_RSA
)
2826 key
->keyalg
= KMF_RSA
;
2827 else if (pkey
->type
== EVP_PKEY_DSA
)
2828 key
->keyalg
= KMF_DSA
;
2830 key
->kstype
= KMF_KEYSTORE_OPENSSL
;
2831 key
->keyclass
= keyclass
;
2832 key
->keyp
= (void *)pkey
;
2835 ((key
->keylabel
= strdup(path
)) == NULL
)) {
2836 EVP_PKEY_free(pkey
);
2837 return (KMF_ERR_MEMORY
);
2840 EVP_PKEY_free(pkey
);
2843 } else if (keyclass
== KMF_SYMMETRIC
) {
2844 KMF_ENCODE_FORMAT fmt
;
2846 * If the file is a recognized format,
2847 * then it is NOT a symmetric key.
2849 rv
= kmf_get_file_format(path
, &fmt
);
2850 if (rv
== KMF_OK
|| fmt
!= 0) {
2851 return (KMF_ERR_KEY_NOT_FOUND
);
2852 } else if (rv
== KMF_ERR_ENCODING
) {
2854 * If we don't know the encoding,
2855 * it is probably a symmetric key.
2858 } else if (rv
== KMF_ERR_OPEN_FILE
) {
2859 return (KMF_ERR_KEY_NOT_FOUND
);
2864 rkey
= malloc(sizeof (KMF_RAW_SYM_KEY
));
2866 rv
= KMF_ERR_MEMORY
;
2870 (void) memset(rkey
, 0, sizeof (KMF_RAW_SYM_KEY
));
2871 rv
= kmf_read_input_file(handle
, path
, &keyvalue
);
2875 rkey
->keydata
.len
= keyvalue
.Length
;
2876 rkey
->keydata
.val
= keyvalue
.Data
;
2878 key
->kstype
= KMF_KEYSTORE_OPENSSL
;
2879 key
->keyclass
= keyclass
;
2881 key
->keyp
= (void *)rkey
;
2883 ((key
->keylabel
= strdup(path
)) == NULL
)) {
2884 rv
= KMF_ERR_MEMORY
;
2891 kmf_free_raw_sym_key(rkey
);
2894 EVP_PKEY_free(pkey
);
2897 key
->keyalg
= KMF_KEYALG_NONE
;
2898 key
->keyclass
= KMF_KEYCLASS_NONE
;
2907 OpenSSL_FindKey(KMF_HANDLE_T handle
,
2908 int numattr
, KMF_ATTRIBUTE
*attrlist
)
2910 KMF_RETURN rv
= KMF_OK
;
2911 char *fullpath
= NULL
;
2913 KMF_KEY_HANDLE
*key
;
2915 KMF_KEY_CLASS keyclass
;
2916 KMF_RAW_KEY_DATA
*rawkey
;
2921 return (KMF_ERR_BAD_PARAMETER
);
2923 numkeys
= kmf_get_attr_ptr(KMF_COUNT_ATTR
, attrlist
, numattr
);
2924 if (numkeys
== NULL
)
2925 return (KMF_ERR_BAD_PARAMETER
);
2927 rv
= kmf_get_attr(KMF_KEYCLASS_ATTR
, attrlist
, numattr
,
2928 (void *)&keyclass
, NULL
);
2930 return (KMF_ERR_BAD_PARAMETER
);
2932 if (keyclass
!= KMF_ASYM_PUB
&&
2933 keyclass
!= KMF_ASYM_PRI
&&
2934 keyclass
!= KMF_SYMMETRIC
)
2935 return (KMF_ERR_BAD_KEY_CLASS
);
2937 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
2938 keyfile
= kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
, attrlist
, numattr
);
2940 fullpath
= get_fullpath(dirpath
, keyfile
);
2942 if (fullpath
== NULL
)
2943 return (KMF_ERR_BAD_PARAMETER
);
2947 maxkeys
= 0xFFFFFFFF;
2950 key
= kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR
, attrlist
, numattr
);
2951 /* it is okay to have "keys" contains NULL */
2954 * The caller may want a list of the raw key data as well.
2955 * Useful for importing keys from a file into other keystores.
2957 rawkey
= kmf_get_attr_ptr(KMF_RAW_KEY_ATTR
, attrlist
, numattr
);
2959 if (isdir(fullpath
)) {
2964 /* open all files in the directory and attempt to read them */
2965 if ((dirp
= opendir(fullpath
)) == NULL
) {
2966 return (KMF_ERR_BAD_PARAMETER
);
2969 while ((dp
= readdir(dirp
)) != NULL
&& n
< maxkeys
) {
2970 if (strcmp(dp
->d_name
, ".") &&
2971 strcmp(dp
->d_name
, "..")) {
2974 fname
= get_fullpath(fullpath
,
2975 (char *)&dp
->d_name
);
2977 rv
= fetch_key(handle
, fname
,
2978 keyclass
, key
? &key
[n
] : NULL
);
2981 if (key
!= NULL
&& rawkey
!= NULL
)
2982 rv
= convertToRawKey(
2983 key
[n
].keyp
, &rawkey
[n
]);
2987 if (rv
!= KMF_OK
|| key
== NULL
)
2991 (void) closedir(dirp
);
2995 rv
= fetch_key(handle
, fullpath
, keyclass
, key
);
2999 if (rv
!= KMF_OK
|| key
== NULL
)
3002 if (rv
== KMF_OK
&& key
!= NULL
&& rawkey
!= NULL
) {
3003 rv
= convertToRawKey(key
->keyp
, rawkey
);
3007 if (rv
== KMF_OK
&& (*numkeys
) == 0)
3008 rv
= KMF_ERR_KEY_NOT_FOUND
;
3009 else if (rv
== KMF_ERR_KEY_NOT_FOUND
&& (*numkeys
) > 0)
3015 #define HANDLE_PK12_ERROR { \
3016 SET_ERROR(kmfh, ERR_get_error()); \
3017 rv = KMF_ERR_ENCODING; \
3022 add_alias_to_bag(PKCS12_SAFEBAG
*bag
, X509
*xcert
)
3024 if (xcert
!= NULL
&& xcert
->aux
!= NULL
&&
3025 xcert
->aux
->alias
!= NULL
) {
3026 if (PKCS12_add_friendlyname_asc(bag
,
3027 (const char *)xcert
->aux
->alias
->data
,
3028 xcert
->aux
->alias
->length
) == 0)
3035 add_cert_to_safe(X509
*sslcert
, KMF_CREDENTIAL
*cred
,
3036 uchar_t
*keyid
, unsigned int keyidlen
)
3038 PKCS12_SAFEBAG
*bag
= NULL
;
3039 PKCS7
*cert_authsafe
= NULL
;
3040 STACK_OF(PKCS12_SAFEBAG
) *bag_stack
;
3042 bag_stack
= sk_PKCS12_SAFEBAG_new_null();
3043 if (bag_stack
== NULL
)
3046 /* Convert cert from X509 struct to PKCS#12 bag */
3047 bag
= PKCS12_x5092certbag(sslcert
);
3052 /* Add the key id to the certificate bag. */
3053 if (keyidlen
> 0 && !PKCS12_add_localkeyid(bag
, keyid
, keyidlen
)) {
3057 if (!add_alias_to_bag(bag
, sslcert
))
3060 /* Pile it on the bag_stack. */
3061 if (!sk_PKCS12_SAFEBAG_push(bag_stack
, bag
)) {
3064 /* Turn bag_stack of certs into encrypted authsafe. */
3065 cert_authsafe
= PKCS12_pack_p7encdata(
3066 NID_pbe_WithSHA1And40BitRC2_CBC
,
3067 cred
->cred
, cred
->credlen
, NULL
, 0,
3068 PKCS12_DEFAULT_ITER
, bag_stack
);
3071 if (bag_stack
!= NULL
)
3072 sk_PKCS12_SAFEBAG_pop_free(bag_stack
, PKCS12_SAFEBAG_free
);
3074 return (cert_authsafe
);
3078 add_key_to_safe(EVP_PKEY
*pkey
, KMF_CREDENTIAL
*cred
,
3079 uchar_t
*keyid
, unsigned int keyidlen
,
3080 char *label
, int label_len
)
3082 PKCS8_PRIV_KEY_INFO
*p8
= NULL
;
3083 STACK_OF(PKCS12_SAFEBAG
) *bag_stack
= NULL
;
3084 PKCS12_SAFEBAG
*bag
= NULL
;
3085 PKCS7
*key_authsafe
= NULL
;
3087 p8
= EVP_PKEY2PKCS8(pkey
);
3091 /* Put the shrouded key into a PKCS#12 bag. */
3092 bag
= PKCS12_MAKE_SHKEYBAG(
3093 NID_pbe_WithSHA1And3_Key_TripleDES_CBC
,
3094 cred
->cred
, cred
->credlen
,
3095 NULL
, 0, PKCS12_DEFAULT_ITER
, p8
);
3097 /* Clean up the PKCS#8 shrouded key, don't need it now. */
3098 PKCS8_PRIV_KEY_INFO_free(p8
);
3104 if (keyidlen
&& !PKCS12_add_localkeyid(bag
, keyid
, keyidlen
))
3106 if (label
!= NULL
&& !PKCS12_add_friendlyname(bag
, label
, label_len
))
3109 /* Start a PKCS#12 safebag container for the private key. */
3110 bag_stack
= sk_PKCS12_SAFEBAG_new_null();
3111 if (bag_stack
== NULL
)
3114 /* Pile on the private key on the bag_stack. */
3115 if (!sk_PKCS12_SAFEBAG_push(bag_stack
, bag
))
3118 key_authsafe
= PKCS12_pack_p7data(bag_stack
);
3121 if (bag_stack
!= NULL
)
3122 sk_PKCS12_SAFEBAG_pop_free(bag_stack
, PKCS12_SAFEBAG_free
);
3124 return (key_authsafe
);
3128 ImportRawRSAKey(KMF_RAW_RSA_KEY
*key
)
3131 EVP_PKEY
*newkey
= NULL
;
3133 if ((rsa
= RSA_new()) == NULL
)
3136 if ((rsa
->n
= BN_bin2bn(key
->mod
.val
, key
->mod
.len
, rsa
->n
)) == NULL
)
3139 if ((rsa
->e
= BN_bin2bn(key
->pubexp
.val
, key
->pubexp
.len
, rsa
->e
)) ==
3143 if (key
->priexp
.val
!= NULL
)
3144 if ((rsa
->d
= BN_bin2bn(key
->priexp
.val
, key
->priexp
.len
,
3148 if (key
->prime1
.val
!= NULL
)
3149 if ((rsa
->p
= BN_bin2bn(key
->prime1
.val
, key
->prime1
.len
,
3153 if (key
->prime2
.val
!= NULL
)
3154 if ((rsa
->q
= BN_bin2bn(key
->prime2
.val
, key
->prime2
.len
,
3158 if (key
->exp1
.val
!= NULL
)
3159 if ((rsa
->dmp1
= BN_bin2bn(key
->exp1
.val
, key
->exp1
.len
,
3160 rsa
->dmp1
)) == NULL
)
3163 if (key
->exp2
.val
!= NULL
)
3164 if ((rsa
->dmq1
= BN_bin2bn(key
->exp2
.val
, key
->exp2
.len
,
3165 rsa
->dmq1
)) == NULL
)
3168 if (key
->coef
.val
!= NULL
)
3169 if ((rsa
->iqmp
= BN_bin2bn(key
->coef
.val
, key
->coef
.len
,
3170 rsa
->iqmp
)) == NULL
)
3173 if ((newkey
= EVP_PKEY_new()) == NULL
)
3176 (void) EVP_PKEY_set1_RSA(newkey
, rsa
);
3178 /* The original key must be freed once here or it leaks memory */
3185 ImportRawDSAKey(KMF_RAW_DSA_KEY
*key
)
3188 EVP_PKEY
*newkey
= NULL
;
3190 if ((dsa
= DSA_new()) == NULL
)
3193 if ((dsa
->p
= BN_bin2bn(key
->prime
.val
, key
->prime
.len
,
3197 if ((dsa
->q
= BN_bin2bn(key
->subprime
.val
, key
->subprime
.len
,
3201 if ((dsa
->g
= BN_bin2bn(key
->base
.val
, key
->base
.len
,
3205 if ((dsa
->priv_key
= BN_bin2bn(key
->value
.val
, key
->value
.len
,
3206 dsa
->priv_key
)) == NULL
)
3209 if (key
->pubvalue
.val
!= NULL
) {
3210 if ((dsa
->pub_key
= BN_bin2bn(key
->pubvalue
.val
,
3211 key
->pubvalue
.len
, dsa
->pub_key
)) == NULL
)
3215 if ((newkey
= EVP_PKEY_new()) == NULL
)
3218 (void) EVP_PKEY_set1_DSA(newkey
, dsa
);
3220 /* The original key must be freed once here or it leaks memory */
3226 raw_key_to_pkey(KMF_KEY_HANDLE
*key
)
3228 EVP_PKEY
*pkey
= NULL
;
3229 KMF_RAW_KEY_DATA
*rawkey
;
3230 ASN1_TYPE
*attr
= NULL
;
3233 if (key
== NULL
|| !key
->israw
)
3236 rawkey
= (KMF_RAW_KEY_DATA
*)key
->keyp
;
3237 if (rawkey
->keytype
== KMF_RSA
) {
3238 pkey
= ImportRawRSAKey(&rawkey
->rawdata
.rsa
);
3239 } else if (rawkey
->keytype
== KMF_DSA
) {
3240 pkey
= ImportRawDSAKey(&rawkey
->rawdata
.dsa
);
3241 } else if (rawkey
->keytype
== KMF_ECDSA
) {
3243 * OpenSSL in Solaris does not support EC for
3248 /* wrong kind of key */
3252 if (rawkey
->label
!= NULL
) {
3253 if ((attr
= ASN1_TYPE_new()) == NULL
) {
3254 EVP_PKEY_free(pkey
);
3257 attr
->value
.bmpstring
= ASN1_STRING_type_new(V_ASN1_BMPSTRING
);
3258 (void) ASN1_STRING_set(attr
->value
.bmpstring
, rawkey
->label
,
3259 strlen(rawkey
->label
));
3260 attr
->type
= V_ASN1_BMPSTRING
;
3261 attr
->value
.ptr
= (char *)attr
->value
.bmpstring
;
3262 ret
= set_pkey_attrib(pkey
, attr
, NID_friendlyName
);
3263 if (ret
!= KMF_OK
) {
3264 EVP_PKEY_free(pkey
);
3265 ASN1_TYPE_free(attr
);
3269 if (rawkey
->id
.Data
!= NULL
) {
3270 if ((attr
= ASN1_TYPE_new()) == NULL
) {
3271 EVP_PKEY_free(pkey
);
3274 attr
->value
.octet_string
=
3275 ASN1_STRING_type_new(V_ASN1_OCTET_STRING
);
3276 attr
->type
= V_ASN1_OCTET_STRING
;
3277 (void) ASN1_STRING_set(attr
->value
.octet_string
,
3278 rawkey
->id
.Data
, rawkey
->id
.Length
);
3279 attr
->value
.ptr
= (char *)attr
->value
.octet_string
;
3280 ret
= set_pkey_attrib(pkey
, attr
, NID_localKeyID
);
3281 if (ret
!= KMF_OK
) {
3282 EVP_PKEY_free(pkey
);
3283 ASN1_TYPE_free(attr
);
3291 * Search a list of private keys to find one that goes with the certificate.
3294 find_matching_key(X509
*xcert
, int numkeys
, KMF_KEY_HANDLE
*keylist
)
3297 EVP_PKEY
*pkey
= NULL
;
3299 if (numkeys
== 0 || keylist
== NULL
|| xcert
== NULL
)
3301 for (i
= 0; i
< numkeys
; i
++) {
3302 if (keylist
[i
].israw
)
3303 pkey
= raw_key_to_pkey(&keylist
[i
]);
3305 pkey
= (EVP_PKEY
*)keylist
[i
].keyp
;
3307 if (X509_check_private_key(xcert
, pkey
)) {
3310 EVP_PKEY_free(pkey
);
3319 local_export_pk12(KMF_HANDLE_T handle
,
3320 KMF_CREDENTIAL
*cred
,
3321 int numcerts
, KMF_X509_DER_CERT
*certlist
,
3322 int numkeys
, KMF_KEY_HANDLE
*keylist
,
3325 KMF_RETURN rv
= KMF_OK
;
3326 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
3328 PKCS7
*cert_authsafe
= NULL
;
3329 PKCS7
*key_authsafe
= NULL
;
3330 STACK_OF(PKCS7
) *authsafe_stack
= NULL
;
3331 PKCS12
*p12_elem
= NULL
;
3334 if (numcerts
== 0 && numkeys
== 0)
3335 return (KMF_ERR_BAD_PARAMETER
);
3338 * Open the output file.
3340 if ((bio
= BIO_new_file(filename
, "wb")) == NULL
) {
3341 SET_ERROR(kmfh
, ERR_get_error());
3342 rv
= KMF_ERR_OPEN_FILE
;
3346 /* Start a PKCS#7 stack. */
3347 authsafe_stack
= sk_PKCS7_new_null();
3348 if (authsafe_stack
== NULL
) {
3349 rv
= KMF_ERR_MEMORY
;
3353 for (i
= 0; rv
== KMF_OK
&& i
< numcerts
; i
++) {
3354 const uchar_t
*p
= certlist
[i
].certificate
.Data
;
3355 long len
= certlist
[i
].certificate
.Length
;
3357 EVP_PKEY
*pkey
= NULL
;
3358 unsigned char keyid
[EVP_MAX_MD_SIZE
];
3359 unsigned int keyidlen
= 0;
3361 xcert
= d2i_X509(NULL
, &p
, len
);
3362 if (xcert
== NULL
) {
3363 SET_ERROR(kmfh
, ERR_get_error());
3364 rv
= KMF_ERR_ENCODING
;
3366 if (certlist
[i
].kmf_private
.label
!= NULL
) {
3367 /* Set alias attribute */
3368 (void) X509_alias_set1(xcert
,
3369 (uchar_t
*)certlist
[i
].kmf_private
.label
,
3370 strlen(certlist
[i
].kmf_private
.label
));
3372 /* Check if there is a key corresponding to this cert */
3373 pkey
= find_matching_key(xcert
, numkeys
, keylist
);
3376 * If key is found, get fingerprint and create a
3380 (void) X509_digest(xcert
, EVP_sha1(),
3382 key_authsafe
= add_key_to_safe(pkey
, cred
,
3384 certlist
[i
].kmf_private
.label
,
3385 (certlist
[i
].kmf_private
.label
?
3386 strlen(certlist
[i
].kmf_private
.label
) : 0));
3388 if (key_authsafe
== NULL
) {
3390 EVP_PKEY_free(pkey
);
3393 /* Put the key safe into the Auth Safe */
3394 if (!sk_PKCS7_push(authsafe_stack
,
3397 EVP_PKEY_free(pkey
);
3402 /* create a certificate safebag */
3403 cert_authsafe
= add_cert_to_safe(xcert
, cred
, keyid
,
3405 if (cert_authsafe
== NULL
) {
3407 EVP_PKEY_free(pkey
);
3410 if (!sk_PKCS7_push(authsafe_stack
, cert_authsafe
)) {
3412 EVP_PKEY_free(pkey
);
3418 EVP_PKEY_free(pkey
);
3420 } else if (numcerts
== 0 && numkeys
> 0) {
3422 * If only adding keys to the file.
3424 for (i
= 0; i
< numkeys
; i
++) {
3425 EVP_PKEY
*pkey
= NULL
;
3427 if (keylist
[i
].israw
)
3428 pkey
= raw_key_to_pkey(&keylist
[i
]);
3430 pkey
= (EVP_PKEY
*)keylist
[i
].keyp
;
3435 key_authsafe
= add_key_to_safe(pkey
, cred
,
3438 if (key_authsafe
== NULL
) {
3439 EVP_PKEY_free(pkey
);
3442 if (!sk_PKCS7_push(authsafe_stack
, key_authsafe
)) {
3443 EVP_PKEY_free(pkey
);
3448 p12_elem
= PKCS12_init(NID_pkcs7_data
);
3449 if (p12_elem
== NULL
) {
3453 /* Put the PKCS#7 stack into the PKCS#12 element. */
3454 if (!PKCS12_pack_authsafes(p12_elem
, authsafe_stack
)) {
3458 /* Set the integrity MAC on the PKCS#12 element. */
3459 if (!PKCS12_set_mac(p12_elem
, cred
->cred
, cred
->credlen
,
3460 NULL
, 0, PKCS12_DEFAULT_ITER
, NULL
)) {
3464 /* Write the PKCS#12 element to the export file. */
3465 if (!i2d_PKCS12_bio(bio
, p12_elem
)) {
3468 PKCS12_free(p12_elem
);
3471 /* Clear away the PKCS#7 stack, we're done with it. */
3473 sk_PKCS7_pop_free(authsafe_stack
, PKCS7_free
);
3476 (void) BIO_free_all(bio
);
3482 openssl_build_pk12(KMF_HANDLE_T handle
, int numcerts
,
3483 KMF_X509_DER_CERT
*certlist
, int numkeys
, KMF_KEY_HANDLE
*keylist
,
3484 KMF_CREDENTIAL
*p12cred
, char *filename
)
3488 if (certlist
== NULL
&& keylist
== NULL
)
3489 return (KMF_ERR_BAD_PARAMETER
);
3491 rv
= local_export_pk12(handle
, p12cred
, numcerts
, certlist
,
3492 numkeys
, keylist
, filename
);
3498 OpenSSL_ExportPK12(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
3501 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
3502 char *fullpath
= NULL
;
3503 char *dirpath
= NULL
;
3504 char *certfile
= NULL
;
3505 char *keyfile
= NULL
;
3506 char *filename
= NULL
;
3507 KMF_CREDENTIAL
*p12cred
= NULL
;
3508 KMF_X509_DER_CERT certdata
;
3514 return (KMF_ERR_BAD_PARAMETER
);
3517 * First, find the certificate.
3519 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
3520 certfile
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
, numattr
);
3521 if (certfile
!= NULL
) {
3522 fullpath
= get_fullpath(dirpath
, certfile
);
3523 if (fullpath
== NULL
)
3524 return (KMF_ERR_BAD_PARAMETER
);
3526 if (isdir(fullpath
)) {
3528 return (KMF_ERR_AMBIGUOUS_PATHNAME
);
3531 (void) memset(&certdata
, 0, sizeof (certdata
));
3532 rv
= kmf_load_cert(kmfh
, NULL
, NULL
, NULL
, NULL
,
3533 fullpath
, &certdata
.certificate
);
3538 certdata
.kmf_private
.keystore_type
= KMF_KEYSTORE_OPENSSL
;
3543 * Now find the private key.
3545 keyfile
= kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
, attrlist
, numattr
);
3546 if (keyfile
!= NULL
) {
3547 fullpath
= get_fullpath(dirpath
, keyfile
);
3548 if (fullpath
== NULL
)
3549 return (KMF_ERR_BAD_PARAMETER
);
3551 if (isdir(fullpath
)) {
3553 return (KMF_ERR_AMBIGUOUS_PATHNAME
);
3556 (void) memset(&key
, 0, sizeof (KMF_KEY_HANDLE
));
3557 rv
= fetch_key(handle
, fullpath
, KMF_ASYM_PRI
, &key
);
3564 * Open the output file.
3566 filename
= kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR
, attrlist
,
3568 if (filename
== NULL
) {
3569 rv
= KMF_ERR_BAD_PARAMETER
;
3573 /* Stick the key and the cert into a PKCS#12 file */
3574 p12cred
= kmf_get_attr_ptr(KMF_PK12CRED_ATTR
, attrlist
, numattr
);
3575 if (p12cred
== NULL
) {
3576 rv
= KMF_ERR_BAD_PARAMETER
;
3580 rv
= local_export_pk12(handle
, p12cred
, 1, &certdata
,
3588 kmf_free_kmf_cert(handle
, &certdata
);
3590 kmf_free_kmf_key(handle
, &key
);
3595 * Helper function to extract keys and certificates from
3596 * a single PEM file. Typically the file should contain a
3597 * private key and an associated public key wrapped in an x509 cert.
3598 * However, the file may be just a list of X509 certs with no keys.
3601 extract_pem(KMF_HANDLE
*kmfh
,
3602 char *issuer
, char *subject
, KMF_BIGINT
*serial
,
3603 char *filename
, CK_UTF8CHAR
*pin
,
3604 CK_ULONG pinlen
, EVP_PKEY
**priv_key
, KMF_DATA
**certs
,
3608 KMF_RETURN rv
= KMF_OK
;
3610 STACK_OF(X509_INFO
) *x509_info_stack
= NULL
;
3611 int i
, ncerts
= 0, matchcerts
= 0;
3612 EVP_PKEY
*pkey
= NULL
;
3615 X509_INFO
**cert_infos
= NULL
;
3616 KMF_DATA
*certlist
= NULL
;
3622 fp
= fopen(filename
, "r");
3624 return (KMF_ERR_OPEN_FILE
);
3626 x509_info_stack
= PEM_X509_INFO_read(fp
, NULL
, NULL
, pin
);
3627 if (x509_info_stack
== NULL
) {
3629 return (KMF_ERR_ENCODING
);
3631 cert_infos
= (X509_INFO
**)malloc(sk_X509_INFO_num(x509_info_stack
) *
3632 sizeof (X509_INFO
*));
3633 if (cert_infos
== NULL
) {
3635 rv
= KMF_ERR_MEMORY
;
3639 for (i
= 0; i
< sk_X509_INFO_num(x509_info_stack
); i
++) {
3640 /* LINTED E_BAD_PTR_CAST_ALIGN */
3641 cert_infos
[ncerts
] = sk_X509_INFO_value(x509_info_stack
, i
);
3647 rv
= KMF_ERR_CERT_NOT_FOUND
;
3651 if (priv_key
!= NULL
) {
3653 pkey
= PEM_read_PrivateKey(fp
, NULL
, NULL
, pin
);
3657 x
= cert_infos
[ncerts
- 1]->x509
;
3659 * Make sure the private key matchs the last cert in the file.
3661 if (pkey
!= NULL
&& !X509_check_private_key(x
, pkey
)) {
3662 EVP_PKEY_free(pkey
);
3663 rv
= KMF_ERR_KEY_MISMATCH
;
3667 certlist
= (KMF_DATA
*)calloc(ncerts
, sizeof (KMF_DATA
));
3668 if (certlist
== NULL
) {
3670 EVP_PKEY_free(pkey
);
3671 rv
= KMF_ERR_MEMORY
;
3676 * Convert all of the certs to DER format.
3679 for (i
= 0; rv
== KMF_OK
&& certs
!= NULL
&& i
< ncerts
; i
++) {
3680 boolean_t match
= FALSE
;
3681 info
= cert_infos
[ncerts
- 1 - i
];
3683 rv
= check_cert(info
->x509
, issuer
, subject
, serial
, &match
);
3684 if (rv
!= KMF_OK
|| match
!= TRUE
) {
3689 rv
= ssl_cert2KMFDATA(kmfh
, info
->x509
,
3690 &certlist
[matchcerts
++]);
3694 for (j
= 0; j
< matchcerts
; j
++)
3695 kmf_free_data(&certlist
[j
]);
3698 ncerts
= matchcerts
= 0;
3702 if (numcerts
!= NULL
)
3703 *numcerts
= matchcerts
;
3707 else if (certlist
!= NULL
) {
3708 for (i
= 0; i
< ncerts
; i
++)
3709 kmf_free_data(&certlist
[i
]);
3714 if (priv_key
== NULL
&& pkey
!= NULL
)
3715 EVP_PKEY_free(pkey
);
3716 else if (priv_key
!= NULL
&& pkey
!= NULL
)
3720 /* Cleanup the stack of X509 info records */
3721 for (i
= 0; i
< sk_X509_INFO_num(x509_info_stack
); i
++) {
3722 /* LINTED E_BAD_PTR_CAST_ALIGN */
3723 info
= (X509_INFO
*)sk_X509_INFO_value(x509_info_stack
, i
);
3724 X509_INFO_free(info
);
3726 if (x509_info_stack
)
3727 sk_X509_INFO_free(x509_info_stack
);
3729 if (cert_infos
!= NULL
)
3736 openssl_parse_bags(STACK_OF(PKCS12_SAFEBAG
) *bags
, char *pin
,
3737 STACK_OF(EVP_PKEY
) *keys
, STACK_OF(X509
) *certs
)
3742 for (i
= 0; i
< sk_PKCS12_SAFEBAG_num(bags
); i
++) {
3743 /* LINTED E_BAD_PTR_CAST_ALIGN */
3744 PKCS12_SAFEBAG
*bag
= sk_PKCS12_SAFEBAG_value(bags
, i
);
3745 ret
= openssl_parse_bag(bag
, pin
, (pin
? strlen(pin
) : 0),
3756 set_pkey_attrib(EVP_PKEY
*pkey
, ASN1_TYPE
*attrib
, int nid
)
3758 X509_ATTRIBUTE
*attr
= NULL
;
3760 if (pkey
== NULL
|| attrib
== NULL
)
3761 return (KMF_ERR_BAD_PARAMETER
);
3763 if (pkey
->attributes
== NULL
) {
3764 pkey
->attributes
= sk_X509_ATTRIBUTE_new_null();
3765 if (pkey
->attributes
== NULL
)
3766 return (KMF_ERR_MEMORY
);
3768 attr
= X509_ATTRIBUTE_create(nid
, attrib
->type
, attrib
->value
.ptr
);
3773 i
< sk_X509_ATTRIBUTE_num(pkey
->attributes
); i
++) {
3774 /* LINTED E_BAD_PTR_CASE_ALIGN */
3775 a
= sk_X509_ATTRIBUTE_value(pkey
->attributes
, i
);
3776 if (OBJ_obj2nid(a
->object
) == nid
) {
3777 X509_ATTRIBUTE_free(a
);
3778 /* LINTED E_BAD_PTR_CAST_ALIGN */
3779 (void) sk_X509_ATTRIBUTE_set(pkey
->attributes
,
3784 if (sk_X509_ATTRIBUTE_push(pkey
->attributes
, attr
) == NULL
) {
3785 X509_ATTRIBUTE_free(attr
);
3786 return (KMF_ERR_MEMORY
);
3789 return (KMF_ERR_MEMORY
);
3796 openssl_parse_bag(PKCS12_SAFEBAG
*bag
, char *pass
, int passlen
,
3797 STACK_OF(EVP_PKEY
) *keylist
, STACK_OF(X509
) *certlist
)
3799 KMF_RETURN ret
= KMF_OK
;
3800 PKCS8_PRIV_KEY_INFO
*p8
= NULL
;
3801 EVP_PKEY
*pkey
= NULL
;
3803 ASN1_TYPE
*keyid
= NULL
;
3804 ASN1_TYPE
*fname
= NULL
;
3805 uchar_t
*data
= NULL
;
3807 keyid
= PKCS12_get_attr(bag
, NID_localKeyID
);
3808 fname
= PKCS12_get_attr(bag
, NID_friendlyName
);
3810 switch (M_PKCS12_bag_type(bag
)) {
3812 if (keylist
== NULL
)
3814 pkey
= EVP_PKCS82PKEY(bag
->value
.keybag
);
3816 ret
= KMF_ERR_PKCS12_FORMAT
;
3819 case NID_pkcs8ShroudedKeyBag
:
3820 if (keylist
== NULL
)
3822 p8
= M_PKCS12_decrypt_skey(bag
, pass
, passlen
);
3824 return (KMF_ERR_AUTH_FAILED
);
3825 pkey
= EVP_PKCS82PKEY(p8
);
3826 PKCS8_PRIV_KEY_INFO_free(p8
);
3828 ret
= KMF_ERR_PKCS12_FORMAT
;
3831 if (certlist
== NULL
)
3833 if (M_PKCS12_cert_bag_type(bag
) != NID_x509Certificate
)
3834 return (KMF_ERR_PKCS12_FORMAT
);
3835 xcert
= M_PKCS12_certbag2x509(bag
);
3836 if (xcert
== NULL
) {
3837 ret
= KMF_ERR_PKCS12_FORMAT
;
3840 if (keyid
!= NULL
) {
3841 if (X509_keyid_set1(xcert
,
3842 keyid
->value
.octet_string
->data
,
3843 keyid
->value
.octet_string
->length
) == 0) {
3844 ret
= KMF_ERR_PKCS12_FORMAT
;
3848 if (fname
!= NULL
) {
3850 len
= ASN1_STRING_to_UTF8(&data
,
3851 fname
->value
.asn1_string
);
3852 if (len
> 0 && data
!= NULL
) {
3853 r
= X509_alias_set1(xcert
, data
, len
);
3855 ret
= KMF_ERR_PKCS12_FORMAT
;
3859 ret
= KMF_ERR_PKCS12_FORMAT
;
3863 if (sk_X509_push(certlist
, xcert
) == 0)
3864 ret
= KMF_ERR_MEMORY
;
3868 case NID_safeContentsBag
:
3869 return (openssl_parse_bags(bag
->value
.safes
, pass
,
3870 keylist
, certlist
));
3872 ret
= KMF_ERR_PKCS12_FORMAT
;
3877 * Set the ID and/or FriendlyName attributes on the key.
3878 * If converting to PKCS11 objects, these can translate to CKA_ID
3879 * and CKA_LABEL values.
3881 if (pkey
!= NULL
&& ret
== KMF_OK
) {
3882 ASN1_TYPE
*attr
= NULL
;
3883 if (keyid
!= NULL
&& keyid
->type
== V_ASN1_OCTET_STRING
) {
3884 if ((attr
= ASN1_TYPE_new()) == NULL
)
3885 return (KMF_ERR_MEMORY
);
3886 attr
->value
.octet_string
=
3887 ASN1_STRING_dup(keyid
->value
.octet_string
);
3888 attr
->type
= V_ASN1_OCTET_STRING
;
3889 attr
->value
.ptr
= (char *)attr
->value
.octet_string
;
3890 ret
= set_pkey_attrib(pkey
, attr
, NID_localKeyID
);
3894 if (ret
== KMF_OK
&& fname
!= NULL
&&
3895 fname
->type
== V_ASN1_BMPSTRING
) {
3896 if ((attr
= ASN1_TYPE_new()) == NULL
)
3897 return (KMF_ERR_MEMORY
);
3898 attr
->value
.bmpstring
=
3899 ASN1_STRING_dup(fname
->value
.bmpstring
);
3900 attr
->type
= V_ASN1_BMPSTRING
;
3901 attr
->value
.ptr
= (char *)attr
->value
.bmpstring
;
3902 ret
= set_pkey_attrib(pkey
, attr
, NID_friendlyName
);
3906 if (ret
== KMF_OK
&& keylist
!= NULL
&&
3907 sk_EVP_PKEY_push(keylist
, pkey
) == 0)
3908 ret
= KMF_ERR_MEMORY
;
3910 if (ret
== KMF_OK
&& keylist
!= NULL
)
3914 EVP_PKEY_free(pkey
);
3924 openssl_pkcs12_parse(PKCS12
*p12
, char *pin
,
3925 STACK_OF(EVP_PKEY
) *keys
,
3926 STACK_OF(X509
) *certs
,
3930 KMF_RETURN ret
= KMF_OK
;
3931 STACK_OF(PKCS7
) *asafes
= NULL
;
3932 STACK_OF(PKCS12_SAFEBAG
) *bags
= NULL
;
3936 if (p12
== NULL
|| (keys
== NULL
&& certs
== NULL
))
3937 return (KMF_ERR_BAD_PARAMETER
);
3939 if (pin
== NULL
|| *pin
== NULL
) {
3940 if (PKCS12_verify_mac(p12
, NULL
, 0)) {
3942 } else if (PKCS12_verify_mac(p12
, "", 0)) {
3945 return (KMF_ERR_AUTH_FAILED
);
3947 } else if (!PKCS12_verify_mac(p12
, pin
, -1)) {
3948 return (KMF_ERR_AUTH_FAILED
);
3951 if ((asafes
= PKCS12_unpack_authsafes(p12
)) == NULL
)
3952 return (KMF_ERR_PKCS12_FORMAT
);
3954 for (i
= 0; ret
== KMF_OK
&& i
< sk_PKCS7_num(asafes
); i
++) {
3956 /* LINTED E_BAD_PTR_CAST_ALIGN */
3957 p7
= sk_PKCS7_value(asafes
, i
);
3958 bagnid
= OBJ_obj2nid(p7
->type
);
3960 if (bagnid
== NID_pkcs7_data
) {
3961 bags
= PKCS12_unpack_p7data(p7
);
3962 } else if (bagnid
== NID_pkcs7_encrypted
) {
3963 bags
= PKCS12_unpack_p7encdata(p7
, pin
,
3964 (pin
? strlen(pin
) : 0));
3969 ret
= KMF_ERR_PKCS12_FORMAT
;
3973 if (openssl_parse_bags(bags
, pin
, keys
, certs
) != KMF_OK
)
3974 ret
= KMF_ERR_PKCS12_FORMAT
;
3976 sk_PKCS12_SAFEBAG_pop_free(bags
, PKCS12_SAFEBAG_free
);
3980 sk_PKCS7_pop_free(asafes
, PKCS7_free
);
3986 * Helper function to decrypt and parse PKCS#12 import file.
3989 extract_pkcs12(BIO
*fbio
, CK_UTF8CHAR
*pin
, CK_ULONG pinlen
,
3990 STACK_OF(EVP_PKEY
) **priv_key
, STACK_OF(X509
) **certs
,
3991 STACK_OF(X509
) **ca
)
3994 PKCS12
*pk12
, *pk12_tmp
;
3995 STACK_OF(EVP_PKEY
) *pkeylist
= NULL
;
3996 STACK_OF(X509
) *xcertlist
= NULL
;
3997 STACK_OF(X509
) *cacertlist
= NULL
;
3999 if ((pk12
= PKCS12_new()) == NULL
) {
4000 return (KMF_ERR_MEMORY
);
4003 if ((pk12_tmp
= d2i_PKCS12_bio(fbio
, &pk12
)) == NULL
) {
4004 /* This is ok; it seems to mean there is no more to read. */
4005 if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_ASN1
&&
4006 ERR_GET_REASON(ERR_peek_error()) == ASN1_R_HEADER_TOO_LONG
)
4007 goto end_extract_pkcs12
;
4010 return (KMF_ERR_PKCS12_FORMAT
);
4014 xcertlist
= sk_X509_new_null();
4015 if (xcertlist
== NULL
) {
4017 return (KMF_ERR_MEMORY
);
4019 pkeylist
= sk_EVP_PKEY_new_null();
4020 if (pkeylist
== NULL
) {
4021 sk_X509_pop_free(xcertlist
, X509_free
);
4023 return (KMF_ERR_MEMORY
);
4026 if (openssl_pkcs12_parse(pk12
, (char *)pin
, pkeylist
, xcertlist
,
4027 cacertlist
) != KMF_OK
) {
4028 sk_X509_pop_free(xcertlist
, X509_free
);
4029 sk_EVP_PKEY_pop_free(pkeylist
, EVP_PKEY_free
);
4031 return (KMF_ERR_PKCS12_FORMAT
);
4034 if (priv_key
&& pkeylist
)
4035 *priv_key
= pkeylist
;
4037 sk_EVP_PKEY_pop_free(pkeylist
, EVP_PKEY_free
);
4038 if (certs
&& xcertlist
)
4041 sk_X509_pop_free(xcertlist
, X509_free
);
4042 if (ca
&& cacertlist
)
4044 else if (cacertlist
)
4045 sk_X509_pop_free(cacertlist
, X509_free
);
4054 sslBN2KMFBN(BIGNUM
*from
, KMF_BIGINT
*to
)
4056 KMF_RETURN rv
= KMF_OK
;
4059 sz
= BN_num_bytes(from
);
4060 to
->val
= (uchar_t
*)malloc(sz
);
4061 if (to
->val
== NULL
)
4062 return (KMF_ERR_MEMORY
);
4064 if ((to
->len
= BN_bn2bin(from
, to
->val
)) != sz
) {
4068 rv
= KMF_ERR_MEMORY
;
4075 exportRawRSAKey(RSA
*rsa
, KMF_RAW_KEY_DATA
*key
)
4078 KMF_RAW_RSA_KEY
*kmfkey
= &key
->rawdata
.rsa
;
4080 (void) memset(kmfkey
, 0, sizeof (KMF_RAW_RSA_KEY
));
4081 if ((rv
= sslBN2KMFBN(rsa
->n
, &kmfkey
->mod
)) != KMF_OK
)
4084 if ((rv
= sslBN2KMFBN(rsa
->e
, &kmfkey
->pubexp
)) != KMF_OK
)
4088 if ((rv
= sslBN2KMFBN(rsa
->d
, &kmfkey
->priexp
)) != KMF_OK
)
4092 if ((rv
= sslBN2KMFBN(rsa
->p
, &kmfkey
->prime1
)) != KMF_OK
)
4096 if ((rv
= sslBN2KMFBN(rsa
->q
, &kmfkey
->prime2
)) != KMF_OK
)
4099 if (rsa
->dmp1
!= NULL
)
4100 if ((rv
= sslBN2KMFBN(rsa
->dmp1
, &kmfkey
->exp1
)) != KMF_OK
)
4103 if (rsa
->dmq1
!= NULL
)
4104 if ((rv
= sslBN2KMFBN(rsa
->dmq1
, &kmfkey
->exp2
)) != KMF_OK
)
4107 if (rsa
->iqmp
!= NULL
)
4108 if ((rv
= sslBN2KMFBN(rsa
->iqmp
, &kmfkey
->coef
)) != KMF_OK
)
4112 kmf_free_raw_key(key
);
4114 key
->keytype
= KMF_RSA
;
4117 * Free the reference to this key, SSL will not actually free
4118 * the memory until the refcount == 0, so this is safe.
4126 exportRawDSAKey(DSA
*dsa
, KMF_RAW_KEY_DATA
*key
)
4129 KMF_RAW_DSA_KEY
*kmfkey
= &key
->rawdata
.dsa
;
4131 (void) memset(kmfkey
, 0, sizeof (KMF_RAW_DSA_KEY
));
4132 if ((rv
= sslBN2KMFBN(dsa
->p
, &kmfkey
->prime
)) != KMF_OK
)
4135 if ((rv
= sslBN2KMFBN(dsa
->q
, &kmfkey
->subprime
)) != KMF_OK
)
4138 if ((rv
= sslBN2KMFBN(dsa
->g
, &kmfkey
->base
)) != KMF_OK
)
4141 if ((rv
= sslBN2KMFBN(dsa
->priv_key
, &kmfkey
->value
)) != KMF_OK
)
4146 kmf_free_raw_key(key
);
4148 key
->keytype
= KMF_DSA
;
4151 * Free the reference to this key, SSL will not actually free
4152 * the memory until the refcount == 0, so this is safe.
4160 add_cert_to_list(KMF_HANDLE
*kmfh
, X509
*sslcert
,
4161 KMF_X509_DER_CERT
**certlist
, int *ncerts
)
4163 KMF_RETURN rv
= KMF_OK
;
4164 KMF_X509_DER_CERT
*list
= (*certlist
);
4165 KMF_X509_DER_CERT cert
;
4169 list
= (KMF_X509_DER_CERT
*)malloc(sizeof (KMF_X509_DER_CERT
));
4171 list
= (KMF_X509_DER_CERT
*)realloc(list
,
4172 sizeof (KMF_X509_DER_CERT
) * (n
+ 1));
4176 return (KMF_ERR_MEMORY
);
4178 (void) memset(&cert
, 0, sizeof (cert
));
4179 rv
= ssl_cert2KMFDATA(kmfh
, sslcert
, &cert
.certificate
);
4182 /* Get the alias name for the cert if there is one */
4183 char *a
= (char *)X509_alias_get0(sslcert
, &len
);
4185 cert
.kmf_private
.label
= strdup(a
);
4186 cert
.kmf_private
.keystore_type
= KMF_KEYSTORE_OPENSSL
;
4200 add_key_to_list(KMF_RAW_KEY_DATA
**keylist
,
4201 KMF_RAW_KEY_DATA
*newkey
, int *nkeys
)
4203 KMF_RAW_KEY_DATA
*list
= (*keylist
);
4207 list
= (KMF_RAW_KEY_DATA
*)malloc(sizeof (KMF_RAW_KEY_DATA
));
4209 list
= (KMF_RAW_KEY_DATA
*)realloc(list
,
4210 sizeof (KMF_RAW_KEY_DATA
) * (n
+ 1));
4214 return (KMF_ERR_MEMORY
);
4224 static X509_ATTRIBUTE
*
4225 find_attr(STACK_OF(X509_ATTRIBUTE
) *attrs
, int nid
)
4233 for (i
= 0; i
< sk_X509_ATTRIBUTE_num(attrs
); i
++) {
4234 /* LINTED E_BAD_PTR_CAST_ALIGN */
4235 a
= sk_X509_ATTRIBUTE_value(attrs
, i
);
4236 if (OBJ_obj2nid(a
->object
) == nid
)
4243 convertToRawKey(EVP_PKEY
*pkey
, KMF_RAW_KEY_DATA
*key
)
4245 KMF_RETURN rv
= KMF_OK
;
4246 X509_ATTRIBUTE
*attr
;
4248 if (pkey
== NULL
|| key
== NULL
)
4249 return (KMF_ERR_BAD_PARAMETER
);
4250 /* Convert SSL key to raw key */
4251 switch (pkey
->type
) {
4253 rv
= exportRawRSAKey(EVP_PKEY_get1_RSA(pkey
),
4259 rv
= exportRawDSAKey(EVP_PKEY_get1_DSA(pkey
),
4265 return (KMF_ERR_BAD_PARAMETER
);
4268 * If friendlyName, add it to record.
4270 attr
= find_attr(pkey
->attributes
, NID_friendlyName
);
4272 ASN1_TYPE
*ty
= NULL
;
4273 int numattr
= sk_ASN1_TYPE_num(attr
->value
.set
);
4274 if (attr
->single
== 0 && numattr
> 0) {
4275 /* LINTED E_BAD_PTR_CAST_ALIGN */
4276 ty
= sk_ASN1_TYPE_value(attr
->value
.set
, 0);
4279 #if OPENSSL_VERSION_NUMBER < 0x10000000L
4280 key
->label
= uni2asc(ty
->value
.bmpstring
->data
,
4281 ty
->value
.bmpstring
->length
);
4283 key
->label
= OPENSSL_uni2asc(ty
->value
.bmpstring
->data
,
4284 ty
->value
.bmpstring
->length
);
4292 * If KeyID, add it to record as a KMF_DATA object.
4294 attr
= find_attr(pkey
->attributes
, NID_localKeyID
);
4296 ASN1_TYPE
*ty
= NULL
;
4297 int numattr
= sk_ASN1_TYPE_num(attr
->value
.set
);
4298 if (attr
->single
== 0 && numattr
> 0) {
4299 /* LINTED E_BAD_PTR_CAST_ALIGN */
4300 ty
= sk_ASN1_TYPE_value(attr
->value
.set
, 0);
4302 key
->id
.Data
= (uchar_t
*)malloc(
4303 ty
->value
.octet_string
->length
);
4304 if (key
->id
.Data
== NULL
)
4305 return (KMF_ERR_MEMORY
);
4306 (void) memcpy(key
->id
.Data
, ty
->value
.octet_string
->data
,
4307 ty
->value
.octet_string
->length
);
4308 key
->id
.Length
= ty
->value
.octet_string
->length
;
4310 (void) memset(&key
->id
, 0, sizeof (KMF_DATA
));
4319 STACK_OF(EVP_PKEY
) *sslkeys
,
4320 STACK_OF(X509
) *sslcert
,
4321 STACK_OF(X509
) *sslcacerts
,
4322 KMF_RAW_KEY_DATA
**keylist
, int *nkeys
,
4323 KMF_X509_DER_CERT
**certlist
, int *ncerts
)
4325 KMF_RETURN rv
= KMF_OK
;
4326 KMF_RAW_KEY_DATA key
;
4329 for (i
= 0; sslkeys
!= NULL
&& i
< sk_EVP_PKEY_num(sslkeys
); i
++) {
4330 /* LINTED E_BAD_PTR_CAST_ALIGN */
4331 EVP_PKEY
*pkey
= sk_EVP_PKEY_value(sslkeys
, i
);
4332 rv
= convertToRawKey(pkey
, &key
);
4334 rv
= add_key_to_list(keylist
, &key
, nkeys
);
4340 /* Now add the certificate to the certlist */
4341 for (i
= 0; sslcert
!= NULL
&& i
< sk_X509_num(sslcert
); i
++) {
4342 /* LINTED E_BAD_PTR_CAST_ALIGN */
4343 X509
*cert
= sk_X509_value(sslcert
, i
);
4344 rv
= add_cert_to_list(kmfh
, cert
, certlist
, ncerts
);
4349 /* Also add any included CA certs to the list */
4350 for (i
= 0; sslcacerts
!= NULL
&& i
< sk_X509_num(sslcacerts
); i
++) {
4353 * sk_X509_value() is macro that embeds a cast to (X509 *).
4354 * Here it translates into ((X509 *)sk_value((ca), (i))).
4355 * Lint is complaining about the embedded casting, and
4356 * to fix it, you need to fix openssl header files.
4358 /* LINTED E_BAD_PTR_CAST_ALIGN */
4359 c
= sk_X509_value(sslcacerts
, i
);
4361 /* Now add the ca cert to the certlist */
4362 rv
= add_cert_to_list(kmfh
, c
, certlist
, ncerts
);
4370 openssl_import_objects(KMF_HANDLE
*kmfh
,
4371 char *filename
, KMF_CREDENTIAL
*cred
,
4372 KMF_X509_DER_CERT
**certlist
, int *ncerts
,
4373 KMF_RAW_KEY_DATA
**keylist
, int *nkeys
)
4375 KMF_RETURN rv
= KMF_OK
;
4376 KMF_ENCODE_FORMAT format
;
4378 STACK_OF(EVP_PKEY
) *privkeys
= NULL
;
4379 STACK_OF(X509
) *certs
= NULL
;
4380 STACK_OF(X509
) *cacerts
= NULL
;
4383 * auto-detect the file format, regardless of what
4384 * the 'format' parameters in the params say.
4386 rv
= kmf_get_file_format(filename
, &format
);
4391 /* This function only works for PEM or PKCS#12 files */
4392 if (format
!= KMF_FORMAT_PEM
&&
4393 format
!= KMF_FORMAT_PEM_KEYPAIR
&&
4394 format
!= KMF_FORMAT_PKCS12
)
4395 return (KMF_ERR_ENCODING
);
4402 if (format
== KMF_FORMAT_PKCS12
) {
4403 bio
= BIO_new_file(filename
, "rb");
4405 SET_ERROR(kmfh
, ERR_get_error());
4406 rv
= KMF_ERR_OPEN_FILE
;
4410 rv
= extract_pkcs12(bio
, (uchar_t
*)cred
->cred
,
4411 (uint32_t)cred
->credlen
, &privkeys
, &certs
, &cacerts
);
4414 /* Convert keys and certs to exportable format */
4415 rv
= convertPK12Objects(kmfh
, privkeys
, certs
, cacerts
,
4416 keylist
, nkeys
, certlist
, ncerts
);
4419 KMF_DATA
*certdata
= NULL
;
4420 KMF_X509_DER_CERT
*kmfcerts
= NULL
;
4422 rv
= extract_pem(kmfh
, NULL
, NULL
, NULL
, filename
,
4423 (uchar_t
*)cred
->cred
, (uint32_t)cred
->credlen
,
4424 &pkey
, &certdata
, ncerts
);
4426 /* Reached end of import file? */
4427 if (rv
== KMF_OK
&& pkey
!= NULL
) {
4428 privkeys
= sk_EVP_PKEY_new_null();
4429 if (privkeys
== NULL
) {
4430 rv
= KMF_ERR_MEMORY
;
4433 (void) sk_EVP_PKEY_push(privkeys
, pkey
);
4434 /* convert the certificate list here */
4435 if (*ncerts
> 0 && certlist
!= NULL
) {
4436 kmfcerts
= (KMF_X509_DER_CERT
*)calloc(*ncerts
,
4437 sizeof (KMF_X509_DER_CERT
));
4438 if (kmfcerts
== NULL
) {
4439 rv
= KMF_ERR_MEMORY
;
4442 for (i
= 0; i
< *ncerts
; i
++) {
4443 kmfcerts
[i
].certificate
= certdata
[i
];
4444 kmfcerts
[i
].kmf_private
.keystore_type
=
4445 KMF_KEYSTORE_OPENSSL
;
4447 *certlist
= kmfcerts
;
4450 * Convert keys to exportable format, the certs
4453 rv
= convertPK12Objects(kmfh
, privkeys
, NULL
, NULL
,
4454 keylist
, nkeys
, NULL
, NULL
);
4459 (void) BIO_free(bio
);
4462 sk_EVP_PKEY_pop_free(privkeys
, EVP_PKEY_free
);
4464 sk_X509_pop_free(certs
, X509_free
);
4466 sk_X509_pop_free(cacerts
, X509_free
);
4472 create_deskey(DES_cblock
**deskey
)
4476 key
= (DES_cblock
*) malloc(sizeof (DES_cblock
));
4478 return (KMF_ERR_MEMORY
);
4481 if (DES_random_key(key
) == 0) {
4483 return (KMF_ERR_KEYGEN_FAILED
);
4490 #define KEYGEN_RETRY 3
4491 #define DES3_KEY_SIZE 24
4494 create_des3key(unsigned char **des3key
)
4496 KMF_RETURN ret
= KMF_OK
;
4497 DES_cblock
*deskey1
= NULL
;
4498 DES_cblock
*deskey2
= NULL
;
4499 DES_cblock
*deskey3
= NULL
;
4500 unsigned char *newkey
= NULL
;
4503 if ((newkey
= malloc(DES3_KEY_SIZE
)) == NULL
) {
4504 return (KMF_ERR_MEMORY
);
4507 /* create the 1st DES key */
4508 if ((ret
= create_deskey(&deskey1
)) != KMF_OK
) {
4513 * Create the 2nd DES key and make sure its value is different
4514 * from the 1st DES key.
4518 if (deskey2
!= NULL
) {
4523 if ((ret
= create_deskey(&deskey2
)) != KMF_OK
) {
4527 if (memcmp((const void *) deskey1
, (const void *) deskey2
, 8)
4529 ret
= KMF_ERR_KEYGEN_FAILED
;
4532 } while (ret
== KMF_ERR_KEYGEN_FAILED
&& retry
< KEYGEN_RETRY
);
4534 if (ret
!= KMF_OK
) {
4539 * Create the 3rd DES key and make sure its value is different
4540 * from the 2nd DES key.
4544 if (deskey3
!= NULL
) {
4549 if ((ret
= create_deskey(&deskey3
)) != KMF_OK
) {
4553 if (memcmp((const void *)deskey2
, (const void *)deskey3
, 8)
4555 ret
= KMF_ERR_KEYGEN_FAILED
;
4558 } while (ret
== KMF_ERR_KEYGEN_FAILED
&& retry
< KEYGEN_RETRY
);
4560 if (ret
!= KMF_OK
) {
4564 /* Concatenate 3 DES keys into a DES3 key */
4565 (void) memcpy((void *)newkey
, (const void *)deskey1
, 8);
4566 (void) memcpy((void *)(newkey
+ 8), (const void *)deskey2
, 8);
4567 (void) memcpy((void *)(newkey
+ 16), (const void *)deskey3
, 8);
4571 if (deskey1
!= NULL
)
4574 if (deskey2
!= NULL
)
4577 if (deskey3
!= NULL
)
4580 if (ret
!= KMF_OK
&& newkey
!= NULL
)
4587 OpenSSL_CreateSymKey(KMF_HANDLE_T handle
,
4588 int numattr
, KMF_ATTRIBUTE
*attrlist
)
4590 KMF_RETURN ret
= KMF_OK
;
4591 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
4592 char *fullpath
= NULL
;
4593 KMF_RAW_SYM_KEY
*rkey
= NULL
;
4594 DES_cblock
*deskey
= NULL
;
4595 unsigned char *des3key
= NULL
;
4596 unsigned char *random
= NULL
;
4598 KMF_KEY_HANDLE
*symkey
;
4599 KMF_KEY_ALG keytype
;
4601 uint32_t keylen_size
= sizeof (keylen
);
4606 return (KMF_ERR_UNINITIALIZED
);
4608 symkey
= kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR
, attrlist
, numattr
);
4610 return (KMF_ERR_BAD_PARAMETER
);
4612 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
4614 keyfile
= kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
, attrlist
, numattr
);
4615 if (keyfile
== NULL
)
4616 return (KMF_ERR_BAD_PARAMETER
);
4618 ret
= kmf_get_attr(KMF_KEYALG_ATTR
, attrlist
, numattr
,
4619 (void *)&keytype
, NULL
);
4621 return (KMF_ERR_BAD_PARAMETER
);
4623 ret
= kmf_get_attr(KMF_KEYLENGTH_ATTR
, attrlist
, numattr
,
4624 &keylen
, &keylen_size
);
4625 if (ret
== KMF_ERR_ATTR_NOT_FOUND
&&
4626 (keytype
== KMF_DES
|| keytype
== KMF_DES3
))
4627 /* keylength is not required for DES and 3DES */
4630 return (KMF_ERR_BAD_PARAMETER
);
4632 fullpath
= get_fullpath(dirpath
, keyfile
);
4633 if (fullpath
== NULL
)
4634 return (KMF_ERR_BAD_PARAMETER
);
4636 /* If the requested file exists, return an error */
4637 if (test_for_file(fullpath
, 0400) == 1) {
4639 return (KMF_ERR_DUPLICATE_KEYFILE
);
4642 fd
= open(fullpath
, O_CREAT
|O_TRUNC
|O_RDWR
, 0400);
4644 ret
= KMF_ERR_OPEN_FILE
;
4648 rkey
= malloc(sizeof (KMF_RAW_SYM_KEY
));
4650 ret
= KMF_ERR_MEMORY
;
4653 (void) memset(rkey
, 0, sizeof (KMF_RAW_SYM_KEY
));
4655 if (keytype
== KMF_DES
) {
4656 if ((ret
= create_deskey(&deskey
)) != KMF_OK
) {
4659 rkey
->keydata
.val
= (uchar_t
*)deskey
;
4660 rkey
->keydata
.len
= 8;
4662 symkey
->keyalg
= KMF_DES
;
4664 } else if (keytype
== KMF_DES3
) {
4665 if ((ret
= create_des3key(&des3key
)) != KMF_OK
) {
4668 rkey
->keydata
.val
= (uchar_t
*)des3key
;
4669 rkey
->keydata
.len
= DES3_KEY_SIZE
;
4670 symkey
->keyalg
= KMF_DES3
;
4672 } else if (keytype
== KMF_AES
|| keytype
== KMF_RC4
||
4673 keytype
== KMF_GENERIC_SECRET
) {
4676 if (keylen
% 8 != 0) {
4677 ret
= KMF_ERR_BAD_KEY_SIZE
;
4681 if (keytype
== KMF_AES
) {
4682 if (keylen
!= 128 &&
4685 ret
= KMF_ERR_BAD_KEY_SIZE
;
4691 random
= malloc(bytes
);
4692 if (random
== NULL
) {
4693 ret
= KMF_ERR_MEMORY
;
4696 if (RAND_bytes(random
, bytes
) != 1) {
4697 ret
= KMF_ERR_KEYGEN_FAILED
;
4701 rkey
->keydata
.val
= (uchar_t
*)random
;
4702 rkey
->keydata
.len
= bytes
;
4703 symkey
->keyalg
= keytype
;
4706 ret
= KMF_ERR_BAD_KEY_TYPE
;
4710 (void) write(fd
, (const void *) rkey
->keydata
.val
, rkey
->keydata
.len
);
4712 symkey
->kstype
= KMF_KEYSTORE_OPENSSL
;
4713 symkey
->keyclass
= KMF_SYMMETRIC
;
4714 symkey
->keylabel
= (char *)fullpath
;
4715 symkey
->israw
= TRUE
;
4716 symkey
->keyp
= rkey
;
4722 if (ret
!= KMF_OK
&& fullpath
!= NULL
) {
4725 if (ret
!= KMF_OK
) {
4726 kmf_free_raw_sym_key(rkey
);
4727 symkey
->keyp
= NULL
;
4728 symkey
->keyalg
= KMF_KEYALG_NONE
;
4735 * Check a file to see if it is a CRL file with PEM or DER format.
4736 * If success, return its format in the "pformat" argument.
4739 OpenSSL_IsCRLFile(KMF_HANDLE_T handle
, char *filename
, int *pformat
)
4741 KMF_RETURN ret
= KMF_OK
;
4742 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
4744 X509_CRL
*xcrl
= NULL
;
4746 if (filename
== NULL
) {
4747 return (KMF_ERR_BAD_PARAMETER
);
4750 bio
= BIO_new_file(filename
, "rb");
4752 SET_ERROR(kmfh
, ERR_get_error());
4753 ret
= KMF_ERR_OPEN_FILE
;
4757 if ((xcrl
= PEM_read_bio_X509_CRL(bio
, NULL
, NULL
, NULL
)) != NULL
) {
4758 *pformat
= KMF_FORMAT_PEM
;
4761 (void) BIO_free(bio
);
4764 * Now try to read it as raw DER data.
4766 bio
= BIO_new_file(filename
, "rb");
4768 SET_ERROR(kmfh
, ERR_get_error());
4769 ret
= KMF_ERR_OPEN_FILE
;
4773 if ((xcrl
= d2i_X509_CRL_bio(bio
, NULL
)) != NULL
) {
4774 *pformat
= KMF_FORMAT_ASN1
;
4776 ret
= KMF_ERR_BAD_CRLFILE
;
4781 (void) BIO_free(bio
);
4784 X509_CRL_free(xcrl
);
4790 OpenSSL_GetSymKeyValue(KMF_HANDLE_T handle
, KMF_KEY_HANDLE
*symkey
,
4791 KMF_RAW_SYM_KEY
*rkey
)
4793 KMF_RETURN rv
= KMF_OK
;
4794 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
4798 return (KMF_ERR_UNINITIALIZED
);
4800 if (symkey
== NULL
|| rkey
== NULL
)
4801 return (KMF_ERR_BAD_PARAMETER
);
4802 else if (symkey
->keyclass
!= KMF_SYMMETRIC
)
4803 return (KMF_ERR_BAD_KEY_CLASS
);
4805 if (symkey
->israw
) {
4806 KMF_RAW_SYM_KEY
*rawkey
= (KMF_RAW_SYM_KEY
*)symkey
->keyp
;
4808 if (rawkey
== NULL
||
4809 rawkey
->keydata
.val
== NULL
||
4810 rawkey
->keydata
.len
== 0)
4811 return (KMF_ERR_BAD_KEYHANDLE
);
4813 rkey
->keydata
.len
= rawkey
->keydata
.len
;
4814 if ((rkey
->keydata
.val
= malloc(rkey
->keydata
.len
)) == NULL
)
4815 return (KMF_ERR_MEMORY
);
4816 (void) memcpy(rkey
->keydata
.val
, rawkey
->keydata
.val
,
4819 rv
= kmf_read_input_file(handle
, symkey
->keylabel
, &keyvalue
);
4822 rkey
->keydata
.len
= keyvalue
.Length
;
4823 rkey
->keydata
.val
= keyvalue
.Data
;
4830 * substitute for the unsafe access(2) function.
4831 * If the file in question already exists, return 1.
4832 * else 0. If an error occurs during testing (other
4833 * than EEXIST), return -1.
4836 test_for_file(char *filename
, mode_t mode
)
4841 * Try to create the file with the EXCL flag.
4842 * The call should fail if the file exists.
4844 fd
= open(filename
, O_WRONLY
|O_CREAT
|O_EXCL
, mode
);
4845 if (fd
== -1 && errno
== EEXIST
)
4847 else if (fd
== -1) /* some other error */
4850 /* The file did NOT exist. Delete the testcase. */
4852 (void) unlink(filename
);
4857 OpenSSL_StoreKey(KMF_HANDLE_T handle
, int numattr
,
4858 KMF_ATTRIBUTE
*attrlist
)
4860 KMF_RETURN rv
= KMF_OK
;
4861 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
4862 KMF_KEY_HANDLE
*pubkey
= NULL
, *prikey
= NULL
;
4863 KMF_RAW_KEY_DATA
*rawkey
;
4864 EVP_PKEY
*pkey
= NULL
;
4865 KMF_ENCODE_FORMAT format
= KMF_FORMAT_PEM
;
4866 KMF_CREDENTIAL cred
= { NULL
, 0 };
4869 char *fullpath
= NULL
;
4870 char *keyfile
= NULL
;
4871 char *dirpath
= NULL
;
4873 pubkey
= kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR
, attrlist
, numattr
);
4877 prikey
= kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR
, attrlist
, numattr
);
4881 rawkey
= kmf_get_attr_ptr(KMF_RAW_KEY_ATTR
, attrlist
, numattr
);
4886 * Exactly 1 type of key must be passed to this function.
4889 return (KMF_ERR_BAD_PARAMETER
);
4891 keyfile
= (char *)kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
, attrlist
,
4893 if (keyfile
== NULL
)
4894 return (KMF_ERR_BAD_PARAMETER
);
4896 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
4898 fullpath
= get_fullpath(dirpath
, keyfile
);
4900 /* Once we have the full path, we don't need the pieces */
4901 if (fullpath
== NULL
)
4902 return (KMF_ERR_BAD_PARAMETER
);
4904 /* If the requested file exists, return an error */
4905 if (test_for_file(fullpath
, 0400) == 1) {
4907 return (KMF_ERR_DUPLICATE_KEYFILE
);
4910 rv
= kmf_get_attr(KMF_ENCODE_FORMAT_ATTR
, attrlist
, numattr
,
4913 /* format is optional. */
4916 /* CRED is not required for OpenSSL files */
4917 (void) kmf_get_attr(KMF_CREDENTIAL_ATTR
, attrlist
, numattr
,
4920 /* Store the private key to the keyfile */
4921 out
= BIO_new_file(fullpath
, "wb");
4923 SET_ERROR(kmfh
, ERR_get_error());
4924 rv
= KMF_ERR_OPEN_FILE
;
4928 if (prikey
!= NULL
&& prikey
->keyp
!= NULL
) {
4929 if (prikey
->keyalg
== KMF_RSA
||
4930 prikey
->keyalg
== KMF_DSA
) {
4931 pkey
= (EVP_PKEY
*)prikey
->keyp
;
4933 rv
= ssl_write_key(kmfh
, format
,
4934 out
, &cred
, pkey
, TRUE
);
4936 if (rv
== KMF_OK
&& prikey
->keylabel
== NULL
) {
4937 prikey
->keylabel
= strdup(fullpath
);
4938 if (prikey
->keylabel
== NULL
)
4939 rv
= KMF_ERR_MEMORY
;
4942 } else if (pubkey
!= NULL
&& pubkey
->keyp
!= NULL
) {
4943 if (pubkey
->keyalg
== KMF_RSA
||
4944 pubkey
->keyalg
== KMF_DSA
) {
4945 pkey
= (EVP_PKEY
*)pubkey
->keyp
;
4947 rv
= ssl_write_key(kmfh
, format
,
4948 out
, &cred
, pkey
, FALSE
);
4950 if (rv
== KMF_OK
&& pubkey
->keylabel
== NULL
) {
4951 pubkey
->keylabel
= strdup(fullpath
);
4952 if (pubkey
->keylabel
== NULL
)
4953 rv
= KMF_ERR_MEMORY
;
4956 } else if (rawkey
!= NULL
) {
4957 if (rawkey
->keytype
== KMF_RSA
) {
4958 pkey
= ImportRawRSAKey(&rawkey
->rawdata
.rsa
);
4959 } else if (rawkey
->keytype
== KMF_DSA
) {
4960 pkey
= ImportRawDSAKey(&rawkey
->rawdata
.dsa
);
4962 rv
= KMF_ERR_BAD_PARAMETER
;
4965 KMF_KEY_CLASS kclass
= KMF_ASYM_PRI
;
4967 rv
= kmf_get_attr(KMF_KEYCLASS_ATTR
, attrlist
, numattr
,
4968 (void *)&kclass
, NULL
);
4971 rv
= ssl_write_key(kmfh
, format
, out
,
4972 &cred
, pkey
, (kclass
== KMF_ASYM_PRI
));
4973 EVP_PKEY_free(pkey
);
4980 (void) BIO_free(out
);
4984 (void) chmod(fullpath
, 0400);
4991 OpenSSL_ImportCRL(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
4993 KMF_RETURN ret
= KMF_OK
;
4994 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
4995 X509_CRL
*xcrl
= NULL
;
4998 KMF_ENCODE_FORMAT format
;
4999 BIO
*in
= NULL
, *out
= NULL
;
5000 int openssl_ret
= 0;
5001 KMF_ENCODE_FORMAT outformat
;
5002 boolean_t crlcheck
= FALSE
;
5003 char *certfile
, *dirpath
, *crlfile
, *incrl
, *outcrl
, *outcrlfile
;
5005 if (numattr
== 0 || attrlist
== NULL
) {
5006 return (KMF_ERR_BAD_PARAMETER
);
5009 /* CRL check is optional */
5010 (void) kmf_get_attr(KMF_CRL_CHECK_ATTR
, attrlist
, numattr
,
5013 certfile
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
, numattr
);
5014 if (crlcheck
== B_TRUE
&& certfile
== NULL
) {
5015 return (KMF_ERR_BAD_CERTFILE
);
5018 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
5019 incrl
= kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR
, attrlist
, numattr
);
5020 outcrl
= kmf_get_attr_ptr(KMF_CRL_OUTFILE_ATTR
, attrlist
, numattr
);
5022 crlfile
= get_fullpath(dirpath
, incrl
);
5024 if (crlfile
== NULL
)
5025 return (KMF_ERR_BAD_CRLFILE
);
5027 outcrlfile
= get_fullpath(dirpath
, outcrl
);
5028 if (outcrlfile
== NULL
)
5029 return (KMF_ERR_BAD_CRLFILE
);
5031 if (isdir(outcrlfile
)) {
5033 return (KMF_ERR_BAD_CRLFILE
);
5036 ret
= kmf_is_crl_file(handle
, crlfile
, &format
);
5037 if (ret
!= KMF_OK
) {
5042 in
= BIO_new_file(crlfile
, "rb");
5044 SET_ERROR(kmfh
, ERR_get_error());
5045 ret
= KMF_ERR_OPEN_FILE
;
5049 if (format
== KMF_FORMAT_ASN1
) {
5050 xcrl
= d2i_X509_CRL_bio(in
, NULL
);
5051 } else if (format
== KMF_FORMAT_PEM
) {
5052 xcrl
= PEM_read_bio_X509_CRL(in
, NULL
, NULL
, NULL
);
5056 SET_ERROR(kmfh
, ERR_get_error());
5057 ret
= KMF_ERR_BAD_CRLFILE
;
5061 /* If bypasscheck is specified, no need to verify. */
5062 if (crlcheck
== B_FALSE
)
5065 ret
= kmf_is_cert_file(handle
, certfile
, &format
);
5069 /* Read in the CA cert file and convert to X509 */
5070 if (BIO_read_filename(in
, certfile
) <= 0) {
5071 SET_ERROR(kmfh
, ERR_get_error());
5072 ret
= KMF_ERR_OPEN_FILE
;
5076 if (format
== KMF_FORMAT_ASN1
) {
5077 xcert
= d2i_X509_bio(in
, NULL
);
5078 } else if (format
== KMF_FORMAT_PEM
) {
5079 xcert
= PEM_read_bio_X509(in
, NULL
, NULL
, NULL
);
5081 ret
= KMF_ERR_BAD_CERT_FORMAT
;
5085 if (xcert
== NULL
) {
5086 SET_ERROR(kmfh
, ERR_get_error());
5087 ret
= KMF_ERR_BAD_CERT_FORMAT
;
5090 /* Now get the public key from the CA cert */
5091 pkey
= X509_get_pubkey(xcert
);
5093 SET_ERROR(kmfh
, ERR_get_error());
5094 ret
= KMF_ERR_BAD_CERTFILE
;
5098 /* Verify the CRL with the CA's public key */
5099 openssl_ret
= X509_CRL_verify(xcrl
, pkey
);
5100 EVP_PKEY_free(pkey
);
5101 if (openssl_ret
> 0) {
5102 ret
= KMF_OK
; /* verify succeed */
5104 SET_ERROR(kmfh
, openssl_ret
);
5105 ret
= KMF_ERR_BAD_CRLFILE
;
5109 ret
= kmf_get_attr(KMF_ENCODE_FORMAT_ATTR
, attrlist
, numattr
,
5111 if (ret
!= KMF_OK
) {
5113 outformat
= KMF_FORMAT_PEM
;
5116 out
= BIO_new_file(outcrlfile
, "wb");
5118 SET_ERROR(kmfh
, ERR_get_error());
5119 ret
= KMF_ERR_OPEN_FILE
;
5123 if (outformat
== KMF_FORMAT_ASN1
) {
5124 openssl_ret
= (int)i2d_X509_CRL_bio(out
, xcrl
);
5125 } else if (outformat
== KMF_FORMAT_PEM
) {
5126 openssl_ret
= PEM_write_bio_X509_CRL(out
, xcrl
);
5128 ret
= KMF_ERR_BAD_PARAMETER
;
5132 if (openssl_ret
<= 0) {
5133 SET_ERROR(kmfh
, ERR_get_error());
5134 ret
= KMF_ERR_WRITE_FILE
;
5141 X509_CRL_free(xcrl
);
5147 (void) BIO_free(in
);
5150 (void) BIO_free(out
);
5152 if (outcrlfile
!= NULL
)
5159 OpenSSL_ListCRL(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
5161 KMF_RETURN ret
= KMF_OK
;
5162 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
5164 KMF_ENCODE_FORMAT format
;
5165 char *crlfile
= NULL
;
5172 char *crlfilename
, *dirpath
;
5174 if (numattr
== 0 || attrlist
== NULL
) {
5175 return (KMF_ERR_BAD_PARAMETER
);
5177 crlfilename
= kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR
,
5179 if (crlfilename
== NULL
)
5180 return (KMF_ERR_BAD_CRLFILE
);
5182 crldata
= (char **)kmf_get_attr_ptr(KMF_CRL_DATA_ATTR
,
5185 if (crldata
== NULL
)
5186 return (KMF_ERR_BAD_PARAMETER
);
5188 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
5190 crlfile
= get_fullpath(dirpath
, crlfilename
);
5192 if (crlfile
== NULL
)
5193 return (KMF_ERR_BAD_CRLFILE
);
5195 if (isdir(crlfile
)) {
5197 return (KMF_ERR_BAD_CRLFILE
);
5200 ret
= kmf_is_crl_file(handle
, crlfile
, &format
);
5201 if (ret
!= KMF_OK
) {
5206 if (bio_err
== NULL
)
5207 bio_err
= BIO_new_fp(stderr
, BIO_NOCLOSE
);
5209 in
= BIO_new_file(crlfile
, "rb");
5211 SET_ERROR(kmfh
, ERR_get_error());
5212 ret
= KMF_ERR_OPEN_FILE
;
5216 if (format
== KMF_FORMAT_ASN1
) {
5217 x
= d2i_X509_CRL_bio(in
, NULL
);
5218 } else if (format
== KMF_FORMAT_PEM
) {
5219 x
= PEM_read_bio_X509_CRL(in
, NULL
, NULL
, NULL
);
5222 if (x
== NULL
) { /* should not happen */
5223 SET_ERROR(kmfh
, ERR_get_error());
5224 ret
= KMF_ERR_OPEN_FILE
;
5228 mem
= BIO_new(BIO_s_mem());
5230 SET_ERROR(kmfh
, ERR_get_error());
5231 ret
= KMF_ERR_MEMORY
;
5235 (void) X509_CRL_print(mem
, x
);
5236 len
= BIO_get_mem_data(mem
, &memptr
);
5238 SET_ERROR(kmfh
, ERR_get_error());
5239 ret
= KMF_ERR_MEMORY
;
5243 data
= malloc(len
+ 1);
5245 ret
= KMF_ERR_MEMORY
;
5249 (void) memcpy(data
, memptr
, len
);
5257 if (crlfile
!= NULL
)
5261 (void) BIO_free(in
);
5264 (void) BIO_free(mem
);
5270 OpenSSL_DeleteCRL(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
5272 KMF_RETURN ret
= KMF_OK
;
5273 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
5274 KMF_ENCODE_FORMAT format
;
5275 char *crlfile
= NULL
;
5277 char *crlfilename
, *dirpath
;
5279 if (numattr
== 0 || attrlist
== NULL
) {
5280 return (KMF_ERR_BAD_PARAMETER
);
5283 crlfilename
= kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR
,
5286 if (crlfilename
== NULL
)
5287 return (KMF_ERR_BAD_CRLFILE
);
5289 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
5291 crlfile
= get_fullpath(dirpath
, crlfilename
);
5293 if (crlfile
== NULL
)
5294 return (KMF_ERR_BAD_CRLFILE
);
5296 if (isdir(crlfile
)) {
5297 ret
= KMF_ERR_BAD_CRLFILE
;
5301 ret
= kmf_is_crl_file(handle
, crlfile
, &format
);
5305 if (unlink(crlfile
) != 0) {
5306 SET_SYS_ERROR(kmfh
, errno
);
5307 ret
= KMF_ERR_INTERNAL
;
5313 (void) BIO_free(in
);
5314 if (crlfile
!= NULL
)
5321 OpenSSL_FindCertInCRL(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
5323 KMF_RETURN ret
= KMF_OK
;
5324 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
5325 KMF_ENCODE_FORMAT format
;
5328 X509_CRL
*xcrl
= NULL
;
5329 STACK_OF(X509_REVOKED
) *revoke_stack
= NULL
;
5330 X509_REVOKED
*revoke
;
5332 char *crlfilename
, *crlfile
, *dirpath
, *certfile
;
5334 if (numattr
== 0 || attrlist
== NULL
) {
5335 return (KMF_ERR_BAD_PARAMETER
);
5338 crlfilename
= kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR
,
5341 if (crlfilename
== NULL
)
5342 return (KMF_ERR_BAD_CRLFILE
);
5344 certfile
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
, numattr
);
5345 if (certfile
== NULL
)
5346 return (KMF_ERR_BAD_CRLFILE
);
5348 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
5350 crlfile
= get_fullpath(dirpath
, crlfilename
);
5352 if (crlfile
== NULL
)
5353 return (KMF_ERR_BAD_CRLFILE
);
5355 if (isdir(crlfile
)) {
5356 ret
= KMF_ERR_BAD_CRLFILE
;
5360 ret
= kmf_is_crl_file(handle
, crlfile
, &format
);
5364 /* Read the CRL file and load it into a X509_CRL structure */
5365 in
= BIO_new_file(crlfilename
, "rb");
5367 SET_ERROR(kmfh
, ERR_get_error());
5368 ret
= KMF_ERR_OPEN_FILE
;
5372 if (format
== KMF_FORMAT_ASN1
) {
5373 xcrl
= d2i_X509_CRL_bio(in
, NULL
);
5374 } else if (format
== KMF_FORMAT_PEM
) {
5375 xcrl
= PEM_read_bio_X509_CRL(in
, NULL
, NULL
, NULL
);
5379 SET_ERROR(kmfh
, ERR_get_error());
5380 ret
= KMF_ERR_BAD_CRLFILE
;
5383 (void) BIO_free(in
);
5385 /* Read the Certificate file and load it into a X509 structure */
5386 ret
= kmf_is_cert_file(handle
, certfile
, &format
);
5390 in
= BIO_new_file(certfile
, "rb");
5392 SET_ERROR(kmfh
, ERR_get_error());
5393 ret
= KMF_ERR_OPEN_FILE
;
5397 if (format
== KMF_FORMAT_ASN1
) {
5398 xcert
= d2i_X509_bio(in
, NULL
);
5399 } else if (format
== KMF_FORMAT_PEM
) {
5400 xcert
= PEM_read_bio_X509(in
, NULL
, NULL
, NULL
);
5403 if (xcert
== NULL
) {
5404 SET_ERROR(kmfh
, ERR_get_error());
5405 ret
= KMF_ERR_BAD_CERTFILE
;
5409 /* Check if the certificate and the CRL have same issuer */
5410 if (X509_NAME_cmp(xcert
->cert_info
->issuer
, xcrl
->crl
->issuer
) != 0) {
5411 ret
= KMF_ERR_ISSUER
;
5415 /* Check to see if the certificate serial number is revoked */
5416 revoke_stack
= X509_CRL_get_REVOKED(xcrl
);
5417 if (sk_X509_REVOKED_num(revoke_stack
) <= 0) {
5418 /* No revoked certificates in the CRL file */
5419 SET_ERROR(kmfh
, ERR_get_error());
5420 ret
= KMF_ERR_EMPTY_CRL
;
5424 for (i
= 0; i
< sk_X509_REVOKED_num(revoke_stack
); i
++) {
5425 /* LINTED E_BAD_PTR_CAST_ALIGN */
5426 revoke
= sk_X509_REVOKED_value(revoke_stack
, i
);
5427 if (ASN1_INTEGER_cmp(xcert
->cert_info
->serialNumber
,
5428 revoke
->serialNumber
) == 0) {
5433 if (i
< sk_X509_REVOKED_num(revoke_stack
)) {
5436 ret
= KMF_ERR_NOT_REVOKED
;
5441 (void) BIO_free(in
);
5443 X509_CRL_free(xcrl
);
5451 OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle
, char *crlname
, KMF_DATA
*tacert
)
5453 KMF_RETURN ret
= KMF_OK
;
5454 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
5456 X509_CRL
*xcrl
= NULL
;
5460 KMF_ENCODE_FORMAT crl_format
;
5464 if (handle
== NULL
|| crlname
== NULL
|| tacert
== NULL
) {
5465 return (KMF_ERR_BAD_PARAMETER
);
5468 ret
= kmf_get_file_format(crlname
, &crl_format
);
5472 bcrl
= BIO_new_file(crlname
, "rb");
5474 SET_ERROR(kmfh
, ERR_get_error());
5475 ret
= KMF_ERR_OPEN_FILE
;
5479 if (crl_format
== KMF_FORMAT_ASN1
) {
5480 xcrl
= d2i_X509_CRL_bio(bcrl
, NULL
);
5481 } else if (crl_format
== KMF_FORMAT_PEM
) {
5482 xcrl
= PEM_read_bio_X509_CRL(bcrl
, NULL
, NULL
, NULL
);
5484 ret
= KMF_ERR_BAD_PARAMETER
;
5489 SET_ERROR(kmfh
, ERR_get_error());
5490 ret
= KMF_ERR_BAD_CRLFILE
;
5495 len
= tacert
->Length
;
5496 xcert
= d2i_X509(NULL
, (const uchar_t
**)&p
, len
);
5498 if (xcert
== NULL
) {
5499 SET_ERROR(kmfh
, ERR_get_error());
5500 ret
= KMF_ERR_BAD_CERTFILE
;
5504 /* Get issuer certificate public key */
5505 pkey
= X509_get_pubkey(xcert
);
5507 SET_ERROR(kmfh
, ERR_get_error());
5508 ret
= KMF_ERR_BAD_CERT_FORMAT
;
5512 /* Verify CRL signature */
5513 sslret
= X509_CRL_verify(xcrl
, pkey
);
5514 EVP_PKEY_free(pkey
);
5518 SET_ERROR(kmfh
, sslret
);
5519 ret
= KMF_ERR_BAD_CRLFILE
;
5524 (void) BIO_free(bcrl
);
5527 X509_CRL_free(xcrl
);
5537 OpenSSL_CheckCRLDate(KMF_HANDLE_T handle
, char *crlname
)
5539 KMF_RETURN ret
= KMF_OK
;
5540 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
5541 KMF_ENCODE_FORMAT crl_format
;
5543 X509_CRL
*xcrl
= NULL
;
5546 if (handle
== NULL
|| crlname
== NULL
) {
5547 return (KMF_ERR_BAD_PARAMETER
);
5550 ret
= kmf_is_crl_file(handle
, crlname
, &crl_format
);
5554 bcrl
= BIO_new_file(crlname
, "rb");
5556 SET_ERROR(kmfh
, ERR_get_error());
5557 ret
= KMF_ERR_OPEN_FILE
;
5561 if (crl_format
== KMF_FORMAT_ASN1
)
5562 xcrl
= d2i_X509_CRL_bio(bcrl
, NULL
);
5563 else if (crl_format
== KMF_FORMAT_PEM
)
5564 xcrl
= PEM_read_bio_X509_CRL(bcrl
, NULL
, NULL
, NULL
);
5567 SET_ERROR(kmfh
, ERR_get_error());
5568 ret
= KMF_ERR_BAD_CRLFILE
;
5571 i
= X509_cmp_time(X509_CRL_get_lastUpdate(xcrl
), NULL
);
5573 ret
= KMF_ERR_VALIDITY_PERIOD
;
5576 if (X509_CRL_get_nextUpdate(xcrl
)) {
5577 i
= X509_cmp_time(X509_CRL_get_nextUpdate(xcrl
), NULL
);
5580 ret
= KMF_ERR_VALIDITY_PERIOD
;
5589 (void) BIO_free(bcrl
);
5592 X509_CRL_free(xcrl
);