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.
8 * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
9 * Copyright 2018 RackTop Systems.
12 * Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
16 * ====================================================================
17 * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved.
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions
23 * 1. Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
26 * 2. Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in
28 * the documentation and/or other materials provided with the
31 * 3. All advertising materials mentioning features or use of this
32 * software must display the following acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
36 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
37 * endorse or promote products derived from this software without
38 * prior written permission. For written permission, please contact
39 * licensing@OpenSSL.org.
41 * 5. Products derived from this software may not be called "OpenSSL"
42 * nor may "OpenSSL" appear in their names without prior written
43 * permission of the OpenSSL Project.
45 * 6. Redistributions of any form whatsoever must retain the following
47 * "This product includes software developed by the OpenSSL Project
48 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
50 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
51 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
53 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
54 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
56 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
57 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
59 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
60 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
61 * OF THE POSSIBILITY OF SUCH DAMAGE.
62 * ====================================================================
64 * This product includes cryptographic software written by Eric Young
65 * (eay@cryptsoft.com). This product includes software written by Tim
66 * Hudson (tjh@cryptsoft.com).
76 #include <cryptoutil.h>
80 /* OPENSSL related headers */
81 #include <openssl/bio.h>
82 #include <openssl/bn.h>
83 #include <openssl/asn1.h>
84 #include <openssl/err.h>
85 #include <openssl/x509.h>
86 #include <openssl/rsa.h>
87 #include <openssl/dsa.h>
88 #include <openssl/x509v3.h>
89 #include <openssl/objects.h>
90 #include <openssl/pem.h>
91 #include <openssl/pkcs12.h>
92 #include <openssl/ocsp.h>
93 #include <openssl/des.h>
94 #include <openssl/rand.h>
97 #define PRINT_ANY_EXTENSION (\
98 KMF_X509_EXT_KEY_USAGE |\
99 KMF_X509_EXT_CERT_POLICIES |\
100 KMF_X509_EXT_SUBJALTNAME |\
101 KMF_X509_EXT_BASIC_CONSTRAINTS |\
102 KMF_X509_EXT_NAME_CONSTRAINTS |\
103 KMF_X509_EXT_POLICY_CONSTRAINTS |\
104 KMF_X509_EXT_EXT_KEY_USAGE |\
105 KMF_X509_EXT_INHIBIT_ANY_POLICY |\
106 KMF_X509_EXT_AUTH_KEY_ID |\
107 KMF_X509_EXT_SUBJ_KEY_ID |\
108 KMF_X509_EXT_POLICY_MAPPING)
110 static uchar_t P
[] = { 0x00, 0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76,
111 0xaa, 0x3d, 0x25, 0x75, 0x9b, 0xb0, 0x68, 0x69,
112 0xcb, 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d, 0x0c,
113 0xf7, 0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82,
114 0xe5, 0xd0, 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e,
115 0xaf, 0xc2, 0xe9, 0xad, 0xac, 0x32, 0xab, 0x7a,
116 0xac, 0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24,
117 0xc2, 0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02,
120 static uchar_t Q
[] = { 0x00, 0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8,
121 0xee, 0x99, 0x3b, 0x4f, 0x2d, 0xed, 0x30, 0xf4,
122 0x8e, 0xda, 0xce, 0x91, 0x5f };
124 static uchar_t G
[] = { 0x00, 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a,
125 0x13, 0x41, 0x31, 0x63, 0xa5, 0x5b, 0x4c, 0xb5,
126 0x00, 0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c, 0xef,
127 0xcb, 0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c,
128 0x2e, 0x71, 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba,
129 0xbf, 0x58, 0xe5, 0xb7, 0x95, 0x21, 0x92, 0x5c,
130 0x9c, 0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08,
131 0x8c, 0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88,
134 #define SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_OPENSSL; \
135 h->lasterr.errcode = c;
137 #define SET_SYS_ERROR(h, c) h->lasterr.kstype = -1; h->lasterr.errcode = c;
140 * Declare some new macros for managing stacks of EVP_PKEYS.
142 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
143 DECLARE_STACK_OF(EVP_PKEY
)
145 #define sk_EVP_PKEY_new_null() SKM_sk_new_null(EVP_PKEY)
146 #define sk_EVP_PKEY_free(st) SKM_sk_free(EVP_PKEY, (st))
147 #define sk_EVP_PKEY_num(st) SKM_sk_num(EVP_PKEY, (st))
148 #define sk_EVP_PKEY_value(st, i) SKM_sk_value(EVP_PKEY, (st), (i))
149 #define sk_EVP_PKEY_push(st, val) SKM_sk_push(EVP_PKEY, (st), (val))
150 #define sk_EVP_PKEY_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY, (st), \
154 /* LINTED E_STATIC_UNUSED */
155 DEFINE_STACK_OF(EVP_PKEY
)
158 mutex_t init_lock
= DEFAULTMUTEX
;
159 static int ssl_initialized
= 0;
160 static BIO
*bio_err
= NULL
;
163 test_for_file(char *, mode_t
);
165 openssl_parse_bag(PKCS12_SAFEBAG
*, char *, int,
166 STACK_OF(EVP_PKEY
) *, STACK_OF(X509
) *);
169 local_export_pk12(KMF_HANDLE_T
, KMF_CREDENTIAL
*, int, KMF_X509_DER_CERT
*,
170 int, KMF_KEY_HANDLE
*, char *);
172 static KMF_RETURN
set_pkey_attrib(EVP_PKEY
*, ASN1_TYPE
*, int);
175 extract_pem(KMF_HANDLE
*, char *, char *, KMF_BIGINT
*, char *,
176 CK_UTF8CHAR
*, CK_ULONG
, EVP_PKEY
**, KMF_DATA
**, int *);
179 kmf_load_cert(KMF_HANDLE
*, char *, char *, KMF_BIGINT
*, KMF_CERT_VALIDITY
,
183 load_certs(KMF_HANDLE
*, char *, char *, KMF_BIGINT
*, KMF_CERT_VALIDITY
,
184 char *, KMF_DATA
**, uint32_t *);
187 sslBN2KMFBN(BIGNUM
*, KMF_BIGINT
*);
190 ImportRawRSAKey(KMF_RAW_RSA_KEY
*);
193 convertToRawKey(EVP_PKEY
*, KMF_RAW_KEY_DATA
*);
196 OpenSSL_FindCert(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
199 OpenSSL_FreeKMFCert(KMF_HANDLE_T
, KMF_X509_DER_CERT
*);
202 OpenSSL_StoreCert(KMF_HANDLE_T handle
, int, KMF_ATTRIBUTE
*);
205 OpenSSL_DeleteCert(KMF_HANDLE_T handle
, int, KMF_ATTRIBUTE
*);
208 OpenSSL_CreateKeypair(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
211 OpenSSL_StoreKey(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
214 OpenSSL_EncodePubKeyData(KMF_HANDLE_T
, KMF_KEY_HANDLE
*, KMF_DATA
*);
217 OpenSSL_SignData(KMF_HANDLE_T
, KMF_KEY_HANDLE
*, KMF_OID
*,
218 KMF_DATA
*, KMF_DATA
*);
221 OpenSSL_DeleteKey(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
224 OpenSSL_ImportCRL(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
227 OpenSSL_DeleteCRL(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
230 OpenSSL_ListCRL(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
233 OpenSSL_FindCertInCRL(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
236 OpenSSL_CertGetPrintable(KMF_HANDLE_T
, const KMF_DATA
*,
237 KMF_PRINTABLE_ITEM
, char *);
240 OpenSSL_GetErrorString(KMF_HANDLE_T
, char **);
243 OpenSSL_FindPrikeyByCert(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
246 OpenSSL_DecryptData(KMF_HANDLE_T
, KMF_KEY_HANDLE
*, KMF_OID
*,
247 KMF_DATA
*, KMF_DATA
*);
250 OpenSSL_CreateOCSPRequest(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
253 OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
256 OpenSSL_FindKey(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
259 OpenSSL_ExportPK12(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
262 OpenSSL_CreateSymKey(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
265 OpenSSL_GetSymKeyValue(KMF_HANDLE_T
, KMF_KEY_HANDLE
*, KMF_RAW_SYM_KEY
*);
268 OpenSSL_VerifyCRLFile(KMF_HANDLE_T
, char *, KMF_DATA
*);
271 OpenSSL_CheckCRLDate(KMF_HANDLE_T
, char *);
274 KMF_PLUGIN_FUNCLIST openssl_plugin_table
=
277 NULL
, /* ConfigureKeystore */
281 NULL
, /* ImportCert */
285 OpenSSL_CreateKeypair
,
287 OpenSSL_EncodePubKeyData
,
292 OpenSSL_FindCertInCRL
,
293 OpenSSL_GetErrorString
,
294 OpenSSL_FindPrikeyByCert
,
297 OpenSSL_CreateSymKey
,
298 OpenSSL_GetSymKeyValue
,
299 NULL
, /* SetTokenPin */
304 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
305 static mutex_t
*lock_cs
;
306 static long *lock_count
;
310 locking_cb(int mode
, int type
, char *file
, int line
)
312 if (mode
& CRYPTO_LOCK
) {
313 (void) mutex_lock(&(lock_cs
[type
]));
316 (void) mutex_unlock(&(lock_cs
[type
]));
323 return ((unsigned long)thr_self());
325 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L || LIBRESSL_VERSION_NUMBER */
327 KMF_PLUGIN_FUNCLIST
*
328 KMF_Plugin_Initialize()
330 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
334 (void) mutex_lock(&init_lock
);
335 if (!ssl_initialized
) {
337 * Add support for extension OIDs that are not yet in the
338 * openssl default set.
340 (void) OBJ_create("2.5.29.30", "nameConstraints",
341 "X509v3 Name Constraints");
342 (void) OBJ_create("2.5.29.33", "policyMappings",
343 "X509v3 Policy Mappings");
344 (void) OBJ_create("2.5.29.36", "policyConstraints",
345 "X509v3 Policy Constraints");
346 (void) OBJ_create("2.5.29.46", "freshestCRL",
347 "X509v3 Freshest CRL");
348 (void) OBJ_create("2.5.29.54", "inhibitAnyPolicy",
349 "X509v3 Inhibit Any-Policy");
351 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
353 * Set up for thread-safe operation.
354 * This is not required for OpenSSL 1.1
356 lock_cs
= OPENSSL_malloc(CRYPTO_num_locks() * sizeof (mutex_t
));
357 if (lock_cs
== NULL
) {
358 (void) mutex_unlock(&init_lock
);
362 lock_count
= OPENSSL_malloc(CRYPTO_num_locks() * sizeof (long));
363 if (lock_count
== NULL
) {
364 OPENSSL_free(lock_cs
);
365 (void) mutex_unlock(&init_lock
);
369 for (i
= 0; i
< CRYPTO_num_locks(); i
++) {
371 (void) mutex_init(&lock_cs
[i
], USYNC_THREAD
, NULL
);
374 CRYPTO_set_id_callback((unsigned long (*)())thread_id
);
375 if (CRYPTO_get_locking_callback() == NULL
)
376 CRYPTO_set_locking_callback((void (*)())locking_cb
);
378 (void) OpenSSL_add_all_algorithms();
380 /* Enable error strings for reporting */
381 (void) ERR_load_crypto_strings();
386 (void) mutex_unlock(&init_lock
);
388 return (&openssl_plugin_table
);
392 * Convert an SSL DN to a KMF DN.
395 get_x509_dn(X509_NAME
*sslDN
, KMF_X509_NAME
*kmfDN
)
398 KMF_RETURN rv
= KMF_OK
;
401 /* Convert to raw DER format */
402 derdata
.Length
= i2d_X509_NAME(sslDN
, NULL
);
403 if ((tmp
= derdata
.Data
= (uchar_t
*)OPENSSL_malloc(derdata
.Length
))
405 return (KMF_ERR_MEMORY
);
407 (void) i2d_X509_NAME(sslDN
, &tmp
);
409 /* Decode to KMF format */
410 rv
= DerDecodeName(&derdata
, kmfDN
);
412 rv
= KMF_ERR_BAD_CERT_FORMAT
;
414 OPENSSL_free(derdata
.Data
);
424 if (stat(path
, &s
) == -1)
427 return ((s
.st_mode
& S_IFMT
) == S_IFDIR
);
431 ssl_cert2KMFDATA(KMF_HANDLE
*kmfh
, X509
*x509cert
, KMF_DATA
*cert
)
433 KMF_RETURN rv
= KMF_OK
;
434 unsigned char *buf
= NULL
, *p
;
438 * Convert the X509 internal struct to DER encoded data
440 if ((len
= i2d_X509(x509cert
, NULL
)) < 0) {
441 SET_ERROR(kmfh
, ERR_get_error());
442 rv
= KMF_ERR_BAD_CERT_FORMAT
;
445 if ((buf
= malloc(len
)) == NULL
) {
446 SET_SYS_ERROR(kmfh
, errno
);
452 * i2d_X509 will increment the buf pointer so that we need to
456 if ((len
= i2d_X509(x509cert
, &p
)) < 0) {
457 SET_ERROR(kmfh
, ERR_get_error());
459 rv
= KMF_ERR_BAD_CERT_FORMAT
;
463 /* caller's responsibility to free it */
480 check_cert(X509
*xcert
, char *issuer
, char *subject
, KMF_BIGINT
*serial
,
483 KMF_RETURN rv
= KMF_OK
;
484 boolean_t findIssuer
= FALSE
;
485 boolean_t findSubject
= FALSE
;
486 boolean_t findSerial
= FALSE
;
487 KMF_X509_NAME issuerDN
, subjectDN
;
488 KMF_X509_NAME certIssuerDN
, certSubjectDN
;
492 return (KMF_ERR_BAD_PARAMETER
);
495 (void) memset(&issuerDN
, 0, sizeof (KMF_X509_NAME
));
496 (void) memset(&subjectDN
, 0, sizeof (KMF_X509_NAME
));
497 (void) memset(&certIssuerDN
, 0, sizeof (KMF_X509_NAME
));
498 (void) memset(&certSubjectDN
, 0, sizeof (KMF_X509_NAME
));
500 if (issuer
!= NULL
&& strlen(issuer
)) {
501 rv
= kmf_dn_parser(issuer
, &issuerDN
);
503 return (KMF_ERR_BAD_PARAMETER
);
505 rv
= get_x509_dn(X509_get_issuer_name(xcert
), &certIssuerDN
);
507 kmf_free_dn(&issuerDN
);
508 return (KMF_ERR_BAD_PARAMETER
);
513 if (subject
!= NULL
&& strlen(subject
)) {
514 rv
= kmf_dn_parser(subject
, &subjectDN
);
516 rv
= KMF_ERR_BAD_PARAMETER
;
520 rv
= get_x509_dn(X509_get_subject_name(xcert
), &certSubjectDN
);
522 rv
= KMF_ERR_BAD_PARAMETER
;
527 if (serial
!= NULL
&& serial
->val
!= NULL
)
533 /* Comparing BIGNUMs is a pain! */
534 bn
= ASN1_INTEGER_to_BN(X509_get_serialNumber(xcert
), NULL
);
536 int bnlen
= BN_num_bytes(bn
);
538 if (bnlen
== serial
->len
) {
539 uchar_t
*a
= malloc(bnlen
);
545 bnlen
= BN_bn2bin(bn
, a
);
546 *match
= (memcmp(a
, serial
->val
, serial
->len
) ==
560 *match
= (kmf_compare_rdns(&issuerDN
, &certIssuerDN
) == 0);
561 if ((*match
) == B_FALSE
) {
562 /* stop checking and bail */
568 *match
= (kmf_compare_rdns(&subjectDN
, &certSubjectDN
) == 0);
569 if ((*match
) == B_FALSE
) {
570 /* stop checking and bail */
579 kmf_free_dn(&issuerDN
);
580 kmf_free_dn(&certIssuerDN
);
583 kmf_free_dn(&subjectDN
);
584 kmf_free_dn(&certSubjectDN
);
592 * This function loads a certificate file into an X509 data structure, and
593 * checks if its issuer, subject or the serial number matches with those
594 * values. If it matches, then return the X509 data structure.
597 load_X509cert(KMF_HANDLE
*kmfh
,
598 char *issuer
, char *subject
, KMF_BIGINT
*serial
,
599 char *pathname
, X509
**outcert
)
601 KMF_RETURN rv
= KMF_OK
;
604 boolean_t match
= FALSE
;
605 KMF_ENCODE_FORMAT format
;
608 * auto-detect the file format, regardless of what
609 * the 'format' parameters in the params say.
611 rv
= kmf_get_file_format(pathname
, &format
);
613 if (rv
== KMF_ERR_OPEN_FILE
)
614 rv
= KMF_ERR_CERT_NOT_FOUND
;
618 /* Not ASN1(DER) format */
619 if ((bcert
= BIO_new_file(pathname
, "rb")) == NULL
) {
620 SET_ERROR(kmfh
, ERR_get_error());
621 rv
= KMF_ERR_OPEN_FILE
;
625 if (format
== KMF_FORMAT_PEM
)
626 xcert
= PEM_read_bio_X509_AUX(bcert
, NULL
, NULL
, NULL
);
627 else if (format
== KMF_FORMAT_ASN1
)
628 xcert
= d2i_X509_bio(bcert
, NULL
);
629 else if (format
== KMF_FORMAT_PKCS12
) {
630 PKCS12
*p12
= d2i_PKCS12_bio(bcert
, NULL
);
632 (void) PKCS12_parse(p12
, NULL
, NULL
, &xcert
, NULL
);
636 SET_ERROR(kmfh
, ERR_get_error());
637 rv
= KMF_ERR_BAD_CERT_FORMAT
;
640 rv
= KMF_ERR_BAD_PARAMETER
;
645 SET_ERROR(kmfh
, ERR_get_error());
646 rv
= KMF_ERR_BAD_CERT_FORMAT
;
650 if (check_cert(xcert
, issuer
, subject
, serial
, &match
) != KMF_OK
||
652 rv
= KMF_ERR_CERT_NOT_FOUND
;
656 if (outcert
!= NULL
) {
661 if (bcert
!= NULL
) (void) BIO_free(bcert
);
662 if (rv
!= KMF_OK
&& xcert
!= NULL
)
669 datacmp(const void *a
, const void *b
)
671 KMF_DATA
*adata
= (KMF_DATA
*)a
;
672 KMF_DATA
*bdata
= (KMF_DATA
*)b
;
673 if (adata
->Length
> bdata
->Length
)
675 if (adata
->Length
< bdata
->Length
)
681 load_certs(KMF_HANDLE
*kmfh
, char *issuer
, char *subject
, KMF_BIGINT
*serial
,
682 KMF_CERT_VALIDITY validity
, char *pathname
,
683 KMF_DATA
**certlist
, uint32_t *numcerts
)
685 KMF_RETURN rv
= KMF_OK
;
687 KMF_DATA
*certs
= NULL
;
690 KMF_ENCODE_FORMAT format
;
692 rv
= kmf_get_file_format(pathname
, &format
);
694 if (rv
== KMF_ERR_OPEN_FILE
)
695 rv
= KMF_ERR_CERT_NOT_FOUND
;
698 if (format
== KMF_FORMAT_ASN1
) {
699 /* load a single certificate */
700 certs
= (KMF_DATA
*)malloc(sizeof (KMF_DATA
));
702 return (KMF_ERR_MEMORY
);
705 rv
= kmf_load_cert(kmfh
, issuer
, subject
, serial
, validity
,
711 kmf_free_data(certs
);
716 } else if (format
== KMF_FORMAT_PKCS12
) {
717 /* We need a credential to access a PKCS#12 file */
718 rv
= KMF_ERR_BAD_CERT_FORMAT
;
719 } else if (format
== KMF_FORMAT_PEM
||
720 format
!= KMF_FORMAT_PEM_KEYPAIR
) {
722 /* This function only works on PEM files */
723 rv
= extract_pem(kmfh
, issuer
, subject
, serial
, pathname
,
724 (uchar_t
*)NULL
, 0, NULL
, &certs
, &nc
);
726 return (KMF_ERR_ENCODING
);
732 for (i
= 0; i
< nc
; i
++) {
733 if (validity
== KMF_NONEXPIRED_CERTS
) {
734 rv
= kmf_check_cert_date(kmfh
, &certs
[i
]);
735 } else if (validity
== KMF_EXPIRED_CERTS
) {
736 rv
= kmf_check_cert_date(kmfh
, &certs
[i
]);
738 rv
= KMF_ERR_CERT_NOT_FOUND
;
739 if (rv
== KMF_ERR_VALIDITY_PERIOD
)
743 /* Remove this cert from the list by clearing it. */
744 kmf_free_data(&certs
[i
]);
746 hits
++; /* count valid certs found */
750 if (rv
== KMF_OK
&& hits
> 0) {
752 * Sort the list of certs by length to put the cleared ones
753 * at the end so they don't get accessed by the caller.
755 qsort((void *)certs
, nc
, sizeof (KMF_DATA
), datacmp
);
758 /* since we sorted the list, just return the number of hits */
761 if (rv
== KMF_OK
&& hits
== 0)
762 rv
= KMF_ERR_CERT_NOT_FOUND
;
772 kmf_load_cert(KMF_HANDLE
*kmfh
,
773 char *issuer
, char *subject
, KMF_BIGINT
*serial
,
774 KMF_CERT_VALIDITY validity
,
778 KMF_RETURN rv
= KMF_OK
;
779 X509
*x509cert
= NULL
;
781 rv
= load_X509cert(kmfh
, issuer
, subject
, serial
, pathname
, &x509cert
);
782 if (rv
== KMF_OK
&& x509cert
!= NULL
&& cert
!= NULL
) {
783 rv
= ssl_cert2KMFDATA(kmfh
, x509cert
, cert
);
787 if (validity
== KMF_NONEXPIRED_CERTS
) {
788 rv
= kmf_check_cert_date(kmfh
, cert
);
789 } else if (validity
== KMF_EXPIRED_CERTS
) {
790 rv
= kmf_check_cert_date(kmfh
, cert
);
793 * This is a valid cert so skip it.
795 rv
= KMF_ERR_CERT_NOT_FOUND
;
797 if (rv
== KMF_ERR_VALIDITY_PERIOD
) {
799 * We want to return success when we
800 * find an invalid cert.
808 if (x509cert
!= NULL
)
815 readAltFormatPrivateKey(KMF_DATA
*filedata
, EVP_PKEY
**pkey
)
817 KMF_RETURN ret
= KMF_OK
;
819 BerElement
*asn1
= NULL
;
821 BerValue OID
= { NULL
, 0 };
822 BerValue
*Mod
= NULL
, *PubExp
= NULL
;
823 BerValue
*PriExp
= NULL
, *Prime1
= NULL
, *Prime2
= NULL
;
824 BerValue
*Coef
= NULL
;
825 BIGNUM
*D
= NULL
, *P
= NULL
, *Q
= NULL
, *COEF
= NULL
;
826 BIGNUM
*Exp1
= NULL
, *Exp2
= NULL
, *pminus1
= NULL
;
827 BIGNUM
*qminus1
= NULL
;
832 filebuf
.bv_val
= (char *)filedata
->Data
;
833 filebuf
.bv_len
= filedata
->Length
;
835 asn1
= kmfder_init(&filebuf
);
837 ret
= KMF_ERR_MEMORY
;
841 if (kmfber_scanf(asn1
, "{{Dn{IIIIII}}}",
842 &OID
, &Mod
, &PubExp
, &PriExp
, &Prime1
,
843 &Prime2
, &Coef
) == -1) {
844 ret
= KMF_ERR_ENCODING
;
849 * We have to derive the 2 Exponents using Bignumber math.
850 * Exp1 = PriExp mod (Prime1 - 1)
851 * Exp2 = PriExp mod (Prime2 - 1)
854 /* D = PrivateExponent */
855 D
= BN_bin2bn((const uchar_t
*)PriExp
->bv_val
, PriExp
->bv_len
, D
);
857 ret
= KMF_ERR_MEMORY
;
861 /* P = Prime1 (first prime factor of Modulus) */
862 P
= BN_bin2bn((const uchar_t
*)Prime1
->bv_val
, Prime1
->bv_len
, P
);
864 ret
= KMF_ERR_MEMORY
;
868 /* Q = Prime2 (second prime factor of Modulus) */
869 Q
= BN_bin2bn((const uchar_t
*)Prime2
->bv_val
, Prime2
->bv_len
, Q
);
871 if ((ctx
= BN_CTX_new()) == NULL
) {
872 ret
= KMF_ERR_MEMORY
;
876 /* Compute (P - 1) */
878 (void) BN_sub(pminus1
, P
, BN_value_one());
880 /* Exponent1 = D mod (P - 1) */
882 (void) BN_mod(Exp1
, D
, pminus1
, ctx
);
884 /* Compute (Q - 1) */
886 (void) BN_sub(qminus1
, Q
, BN_value_one());
888 /* Exponent2 = D mod (Q - 1) */
890 (void) BN_mod(Exp2
, D
, qminus1
, ctx
);
892 /* Coef = (Inverse Q) mod P */
894 (void) BN_mod_inverse(COEF
, Q
, P
, ctx
);
896 /* Convert back to KMF format */
897 (void) memset(&rsa
, 0, sizeof (rsa
));
899 if ((ret
= sslBN2KMFBN(Exp1
, &rsa
.exp1
)) != KMF_OK
)
901 if ((ret
= sslBN2KMFBN(Exp2
, &rsa
.exp2
)) != KMF_OK
)
903 if ((ret
= sslBN2KMFBN(COEF
, &rsa
.coef
)) != KMF_OK
)
906 rsa
.mod
.val
= (uchar_t
*)Mod
->bv_val
;
907 rsa
.mod
.len
= Mod
->bv_len
;
909 rsa
.pubexp
.val
= (uchar_t
*)PubExp
->bv_val
;
910 rsa
.pubexp
.len
= PubExp
->bv_len
;
912 rsa
.priexp
.val
= (uchar_t
*)PriExp
->bv_val
;
913 rsa
.priexp
.len
= PriExp
->bv_len
;
915 rsa
.prime1
.val
= (uchar_t
*)Prime1
->bv_val
;
916 rsa
.prime1
.len
= Prime1
->bv_len
;
918 rsa
.prime2
.val
= (uchar_t
*)Prime2
->bv_val
;
919 rsa
.prime2
.len
= Prime2
->bv_len
;
921 *pkey
= ImportRawRSAKey(&rsa
);
924 kmfber_free(asn1
, 1);
939 (void) memset(Coef
->bv_val
, 0, Coef
->bv_len
);
958 BN_clear_free(pminus1
);
960 BN_clear_free(qminus1
);
971 openssl_load_key(KMF_HANDLE_T handle
, const char *file
)
974 EVP_PKEY
*pkey
= NULL
;
975 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
976 KMF_ENCODE_FORMAT format
;
984 if (kmf_get_file_format((char *)file
, &format
) != KMF_OK
)
987 keyfile
= BIO_new_file(file
, "rb");
988 if (keyfile
== NULL
) {
992 if (format
== KMF_FORMAT_ASN1
) {
993 pkey
= d2i_PrivateKey_bio(keyfile
, NULL
);
996 (void) BIO_free(keyfile
);
998 /* Try odd ASN.1 variations */
999 rv
= kmf_read_input_file(kmfh
, (char *)file
,
1002 (void) readAltFormatPrivateKey(&filedata
,
1004 kmf_free_data(&filedata
);
1007 } else if (format
== KMF_FORMAT_PEM
||
1008 format
== KMF_FORMAT_PEM_KEYPAIR
) {
1009 pkey
= PEM_read_bio_PrivateKey(keyfile
, NULL
, NULL
, NULL
);
1013 * Check if this is the alt. format
1014 * RSA private key file.
1016 rv
= kmf_read_input_file(kmfh
, (char *)file
,
1021 rv
= kmf_pem_to_der(filedata
.Data
,
1022 filedata
.Length
, &d
, &len
);
1023 if (rv
== KMF_OK
&& d
!= NULL
) {
1025 derdata
.Length
= (size_t)len
;
1026 (void) readAltFormatPrivateKey(
1030 kmf_free_data(&filedata
);
1037 SET_ERROR(kmfh
, ERR_get_error());
1039 if (keyfile
!= NULL
)
1040 (void) BIO_free(keyfile
);
1046 OpenSSL_FindCert(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
1048 KMF_RETURN rv
= KMF_OK
;
1049 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1051 uint32_t maxcerts
= 0;
1052 uint32_t *num_certs
;
1053 KMF_X509_DER_CERT
*kmf_cert
= NULL
;
1054 char *dirpath
= NULL
;
1055 char *filename
= NULL
;
1056 char *fullpath
= NULL
;
1057 char *issuer
= NULL
;
1058 char *subject
= NULL
;
1059 KMF_BIGINT
*serial
= NULL
;
1060 KMF_CERT_VALIDITY validity
;
1062 num_certs
= kmf_get_attr_ptr(KMF_COUNT_ATTR
, attrlist
, numattr
);
1063 if (num_certs
== NULL
)
1064 return (KMF_ERR_BAD_PARAMETER
);
1066 /* num_certs should reference the size of kmf_cert */
1067 maxcerts
= *num_certs
;
1069 maxcerts
= 0xFFFFFFFF;
1072 /* Get the optional returned certificate list */
1073 kmf_cert
= kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR
, attrlist
,
1077 * The dirpath attribute and the filename attribute can not be NULL
1080 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
1081 filename
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
,
1084 fullpath
= get_fullpath(dirpath
, filename
);
1085 if (fullpath
== NULL
)
1086 return (KMF_ERR_BAD_PARAMETER
);
1088 /* Get optional search criteria attributes */
1089 issuer
= kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR
, attrlist
, numattr
);
1090 subject
= kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR
, attrlist
, numattr
);
1091 serial
= kmf_get_attr_ptr(KMF_BIGINT_ATTR
, attrlist
, numattr
);
1092 rv
= kmf_get_attr(KMF_CERT_VALIDITY_ATTR
, attrlist
, numattr
,
1095 validity
= KMF_ALL_CERTS
;
1099 if (isdir(fullpath
)) {
1104 /* open all files in the directory and attempt to read them */
1105 if ((dirp
= opendir(fullpath
)) == NULL
) {
1106 return (KMF_ERR_BAD_PARAMETER
);
1108 while ((dp
= readdir(dirp
)) != NULL
) {
1110 KMF_DATA
*certlist
= NULL
;
1111 uint32_t loaded_certs
= 0;
1113 if (strcmp(dp
->d_name
, ".") == 0 ||
1114 strcmp(dp
->d_name
, "..") == 0)
1117 fname
= get_fullpath(fullpath
, (char *)&dp
->d_name
);
1119 rv
= load_certs(kmfh
, issuer
, subject
, serial
,
1120 validity
, fname
, &certlist
, &loaded_certs
);
1124 if (certlist
!= NULL
) {
1125 for (i
= 0; i
< loaded_certs
; i
++)
1126 kmf_free_data(&certlist
[i
]);
1132 /* If load succeeds, add certdata to the list */
1133 if (kmf_cert
!= NULL
) {
1134 for (i
= 0; i
< loaded_certs
&&
1135 n
< maxcerts
; i
++) {
1136 kmf_cert
[n
].certificate
.Data
=
1138 kmf_cert
[n
].certificate
.Length
=
1141 kmf_cert
[n
].kmf_private
.keystore_type
=
1142 KMF_KEYSTORE_OPENSSL
;
1143 kmf_cert
[n
].kmf_private
.flags
=
1144 KMF_FLAG_CERT_VALID
;
1145 kmf_cert
[n
].kmf_private
.label
=
1150 * If maxcerts < loaded_certs, clean up the
1151 * certs that were not used.
1153 for (; i
< loaded_certs
; i
++)
1154 kmf_free_data(&certlist
[i
]);
1156 for (i
= 0; i
< loaded_certs
; i
++)
1157 kmf_free_data(&certlist
[i
]);
1164 if (*num_certs
== 0)
1165 rv
= KMF_ERR_CERT_NOT_FOUND
;
1169 (void) closedir(dirp
);
1171 KMF_DATA
*certlist
= NULL
;
1172 uint32_t loaded_certs
= 0;
1174 rv
= load_certs(kmfh
, issuer
, subject
, serial
, validity
,
1175 fullpath
, &certlist
, &loaded_certs
);
1182 if (kmf_cert
!= NULL
&& certlist
!= NULL
) {
1183 for (i
= 0; i
< loaded_certs
&& i
< maxcerts
; i
++) {
1184 kmf_cert
[n
].certificate
.Data
=
1186 kmf_cert
[n
].certificate
.Length
=
1188 kmf_cert
[n
].kmf_private
.keystore_type
=
1189 KMF_KEYSTORE_OPENSSL
;
1190 kmf_cert
[n
].kmf_private
.flags
=
1191 KMF_FLAG_CERT_VALID
;
1192 kmf_cert
[n
].kmf_private
.label
=
1196 /* If maxcerts < loaded_certs, clean up */
1197 for (; i
< loaded_certs
; i
++)
1198 kmf_free_data(&certlist
[i
]);
1199 } else if (certlist
!= NULL
) {
1200 for (i
= 0; i
< loaded_certs
; i
++)
1201 kmf_free_data(&certlist
[i
]);
1204 if (certlist
!= NULL
)
1216 OpenSSL_FreeKMFCert(KMF_HANDLE_T handle
,
1217 KMF_X509_DER_CERT
*kmf_cert
)
1219 if (kmf_cert
!= NULL
) {
1220 if (kmf_cert
->certificate
.Data
!= NULL
) {
1221 kmf_free_data(&kmf_cert
->certificate
);
1223 if (kmf_cert
->kmf_private
.label
)
1224 free(kmf_cert
->kmf_private
.label
);
1230 OpenSSL_StoreCert(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
1232 KMF_RETURN ret
= KMF_OK
;
1233 KMF_DATA
*cert
= NULL
;
1234 char *outfilename
= NULL
;
1235 char *dirpath
= NULL
;
1236 char *fullpath
= NULL
;
1237 KMF_ENCODE_FORMAT format
;
1239 /* Get the cert data */
1240 cert
= kmf_get_attr_ptr(KMF_CERT_DATA_ATTR
, attrlist
, numattr
);
1241 if (cert
== NULL
|| cert
->Data
== NULL
)
1242 return (KMF_ERR_BAD_PARAMETER
);
1244 /* Check the output filename and directory attributes. */
1245 outfilename
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
,
1247 if (outfilename
== NULL
)
1248 return (KMF_ERR_BAD_PARAMETER
);
1250 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
1251 fullpath
= get_fullpath(dirpath
, outfilename
);
1252 if (fullpath
== NULL
)
1253 return (KMF_ERR_BAD_CERTFILE
);
1255 /* Check the optional format attribute */
1256 ret
= kmf_get_attr(KMF_ENCODE_FORMAT_ATTR
, attrlist
, numattr
,
1258 if (ret
!= KMF_OK
) {
1259 /* If there is no format attribute, then default to PEM */
1260 format
= KMF_FORMAT_PEM
;
1262 } else if (format
!= KMF_FORMAT_ASN1
&& format
!= KMF_FORMAT_PEM
) {
1263 ret
= KMF_ERR_BAD_CERT_FORMAT
;
1267 /* Store the certificate in the file with the specified format */
1268 ret
= kmf_create_cert_file(cert
, format
, fullpath
);
1271 if (fullpath
!= NULL
)
1279 OpenSSL_DeleteCert(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
1282 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1283 KMF_DATA certdata
= { 0, NULL
};
1284 char *dirpath
= NULL
;
1285 char *filename
= NULL
;
1286 char *fullpath
= NULL
;
1287 char *issuer
= NULL
;
1288 char *subject
= NULL
;
1289 KMF_BIGINT
*serial
= NULL
;
1290 KMF_CERT_VALIDITY validity
;
1293 * Get the DIRPATH and CERT_FILENAME attributes. They can not be
1294 * NULL at the same time.
1296 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
1297 filename
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
,
1299 fullpath
= get_fullpath(dirpath
, filename
);
1300 if (fullpath
== NULL
)
1301 return (KMF_ERR_BAD_PARAMETER
);
1303 /* Get optional search criteria attributes */
1304 issuer
= kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR
, attrlist
, numattr
);
1305 subject
= kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR
, attrlist
, numattr
);
1306 serial
= kmf_get_attr_ptr(KMF_BIGINT_ATTR
, attrlist
, numattr
);
1307 rv
= kmf_get_attr(KMF_CERT_VALIDITY_ATTR
, attrlist
, numattr
,
1310 validity
= KMF_ALL_CERTS
;
1314 if (isdir(fullpath
)) {
1318 /* open all files in the directory and attempt to read them */
1319 if ((dirp
= opendir(fullpath
)) == NULL
) {
1320 return (KMF_ERR_BAD_PARAMETER
);
1323 while ((dp
= readdir(dirp
)) != NULL
) {
1324 if (strcmp(dp
->d_name
, ".") != 0 &&
1325 strcmp(dp
->d_name
, "..") != 0) {
1328 fname
= get_fullpath(fullpath
,
1329 (char *)&dp
->d_name
);
1331 if (fname
== NULL
) {
1332 rv
= KMF_ERR_MEMORY
;
1336 rv
= kmf_load_cert(kmfh
, issuer
, subject
,
1337 serial
, validity
, fname
, &certdata
);
1339 if (rv
== KMF_ERR_CERT_NOT_FOUND
) {
1341 kmf_free_data(&certdata
);
1344 } else if (rv
!= KMF_OK
) {
1349 if (unlink(fname
) != 0) {
1350 SET_SYS_ERROR(kmfh
, errno
);
1351 rv
= KMF_ERR_INTERNAL
;
1356 kmf_free_data(&certdata
);
1359 (void) closedir(dirp
);
1361 /* Just try to load a single certificate */
1362 rv
= kmf_load_cert(kmfh
, issuer
, subject
, serial
, validity
,
1363 fullpath
, &certdata
);
1365 if (unlink(fullpath
) != 0) {
1366 SET_SYS_ERROR(kmfh
, errno
);
1367 rv
= KMF_ERR_INTERNAL
;
1373 if (fullpath
!= NULL
)
1376 kmf_free_data(&certdata
);
1382 OpenSSL_EncodePubKeyData(KMF_HANDLE_T handle
, KMF_KEY_HANDLE
*key
,
1385 KMF_RETURN rv
= KMF_OK
;
1386 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1389 if (key
== NULL
|| keydata
== NULL
||
1391 return (KMF_ERR_BAD_PARAMETER
);
1393 if (key
->keyalg
== KMF_RSA
) {
1394 RSA
*pubkey
= EVP_PKEY_get1_RSA(key
->keyp
);
1396 if (!(n
= i2d_RSA_PUBKEY(pubkey
, &keydata
->Data
))) {
1397 SET_ERROR(kmfh
, ERR_get_error());
1398 return (KMF_ERR_ENCODING
);
1401 } else if (key
->keyalg
== KMF_DSA
) {
1402 DSA
*pubkey
= EVP_PKEY_get1_DSA(key
->keyp
);
1404 if (!(n
= i2d_DSA_PUBKEY(pubkey
, &keydata
->Data
))) {
1405 SET_ERROR(kmfh
, ERR_get_error());
1406 return (KMF_ERR_ENCODING
);
1410 return (KMF_ERR_BAD_PARAMETER
);
1412 keydata
->Length
= n
;
1417 free(keydata
->Data
);
1418 keydata
->Data
= NULL
;
1419 keydata
->Length
= 0;
1426 ssl_write_key(KMF_HANDLE
*kmfh
, KMF_ENCODE_FORMAT format
, BIO
*out
,
1427 KMF_CREDENTIAL
*cred
, EVP_PKEY
*pkey
, boolean_t
private)
1433 if (pkey
== NULL
|| out
== NULL
)
1434 return (KMF_ERR_BAD_PARAMETER
);
1437 case KMF_FORMAT_RAWKEY
:
1439 case KMF_FORMAT_ASN1
:
1440 if ((rsa
= EVP_PKEY_get0_RSA(pkey
)) != NULL
) {
1442 rv
= i2d_RSAPrivateKey_bio(out
, rsa
);
1444 rv
= i2d_RSAPublicKey_bio(out
, rsa
);
1445 } else if ((dsa
= EVP_PKEY_get0_DSA(pkey
)) != NULL
) {
1446 rv
= i2d_DSAPrivateKey_bio(out
, dsa
);
1451 SET_ERROR(kmfh
, rv
);
1454 case KMF_FORMAT_PEM
:
1455 if ((rsa
= EVP_PKEY_get0_RSA(pkey
)) != NULL
) {
1457 rv
= PEM_write_bio_RSAPrivateKey(out
,
1458 rsa
, NULL
, NULL
, 0, NULL
,
1459 (cred
!= NULL
? cred
->cred
: NULL
));
1461 rv
= PEM_write_bio_RSAPublicKey(out
,
1463 } else if ((dsa
= EVP_PKEY_get0_DSA(pkey
)) != NULL
) {
1464 rv
= PEM_write_bio_DSAPrivateKey(out
,
1465 dsa
, NULL
, NULL
, 0, NULL
,
1466 (cred
!= NULL
? cred
->cred
: NULL
));
1472 SET_ERROR(kmfh
, rv
);
1477 rv
= KMF_ERR_BAD_PARAMETER
;
1484 OpenSSL_CreateKeypair(KMF_HANDLE_T handle
, int numattr
,
1485 KMF_ATTRIBUTE
*attrlist
)
1487 KMF_RETURN rv
= KMF_OK
;
1488 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1489 uint32_t eValue
= RSA_F4
;
1490 BIGNUM
*eValue_bn
= NULL
;
1491 RSA
*sslPrivKey
= NULL
;
1492 DSA
*sslDSAKey
= NULL
;
1493 EVP_PKEY
*eprikey
= NULL
;
1494 EVP_PKEY
*epubkey
= NULL
;
1496 KMF_KEY_HANDLE
*pubkey
= NULL
, *privkey
= NULL
;
1497 uint32_t keylen
= 1024;
1498 uint32_t keylen_size
= sizeof (uint32_t);
1499 boolean_t storekey
= TRUE
;
1500 KMF_KEY_ALG keytype
= KMF_RSA
;
1502 eValue_bn
= BN_new();
1503 if (eValue_bn
== NULL
)
1504 return (KMF_ERR_MEMORY
);
1505 if (BN_set_word(eValue_bn
, eValue
) == 0) {
1506 rv
= KMF_ERR_KEYGEN_FAILED
;
1510 rv
= kmf_get_attr(KMF_STOREKEY_BOOL_ATTR
, attrlist
, numattr
,
1513 /* "storekey" is optional. Default is TRUE */
1517 rv
= kmf_get_attr(KMF_KEYALG_ATTR
, attrlist
, numattr
,
1518 (void *)&keytype
, NULL
);
1520 /* keytype is optional. KMF_RSA is default */
1523 pubkey
= kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR
, attrlist
, numattr
);
1524 if (pubkey
== NULL
) {
1525 rv
= KMF_ERR_BAD_PARAMETER
;
1529 privkey
= kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR
, attrlist
, numattr
);
1530 if (privkey
== NULL
) {
1531 rv
= KMF_ERR_BAD_PARAMETER
;
1535 (void) memset(pubkey
, 0, sizeof (KMF_KEY_HANDLE
));
1536 (void) memset(privkey
, 0, sizeof (KMF_KEY_HANDLE
));
1538 eprikey
= EVP_PKEY_new();
1539 if (eprikey
== NULL
) {
1540 SET_ERROR(kmfh
, ERR_get_error());
1541 rv
= KMF_ERR_KEYGEN_FAILED
;
1544 epubkey
= EVP_PKEY_new();
1545 if (epubkey
== NULL
) {
1546 SET_ERROR(kmfh
, ERR_get_error());
1547 rv
= KMF_ERR_KEYGEN_FAILED
;
1550 if (keytype
== KMF_RSA
) {
1551 KMF_BIGINT
*rsaexp
= NULL
;
1553 rsaexp
= kmf_get_attr_ptr(KMF_RSAEXP_ATTR
, attrlist
, numattr
);
1554 if (rsaexp
!= NULL
) {
1555 if (rsaexp
->len
> 0 &&
1556 rsaexp
->len
<= sizeof (eValue
) &&
1557 rsaexp
->val
!= NULL
) {
1558 /* LINTED E_BAD_PTR_CAST_ALIGN */
1559 eValue
= *(uint32_t *)rsaexp
->val
;
1560 if (BN_set_word(eValue_bn
, eValue
) == 0) {
1561 rv
= KMF_ERR_BAD_PARAMETER
;
1565 rv
= KMF_ERR_BAD_PARAMETER
;
1569 /* RSA Exponent is optional. Default is 0x10001 */
1573 rv
= kmf_get_attr(KMF_KEYLENGTH_ATTR
, attrlist
, numattr
,
1574 &keylen
, &keylen_size
);
1575 if (rv
== KMF_ERR_ATTR_NOT_FOUND
)
1576 /* keylen is optional, default is 1024 */
1579 rv
= KMF_ERR_BAD_PARAMETER
;
1583 sslPrivKey
= RSA_new();
1584 if (sslPrivKey
== NULL
||
1585 RSA_generate_key_ex(sslPrivKey
, keylen
, eValue_bn
, NULL
)
1587 SET_ERROR(kmfh
, ERR_get_error());
1588 rv
= KMF_ERR_KEYGEN_FAILED
;
1590 (void) EVP_PKEY_set1_RSA(eprikey
, sslPrivKey
);
1591 privkey
->kstype
= KMF_KEYSTORE_OPENSSL
;
1592 privkey
->keyalg
= KMF_RSA
;
1593 privkey
->keyclass
= KMF_ASYM_PRI
;
1594 privkey
->israw
= FALSE
;
1595 privkey
->keyp
= (void *)eprikey
;
1597 /* OpenSSL derives the public key from the private */
1598 (void) EVP_PKEY_set1_RSA(epubkey
, sslPrivKey
);
1599 pubkey
->kstype
= KMF_KEYSTORE_OPENSSL
;
1600 pubkey
->keyalg
= KMF_RSA
;
1601 pubkey
->israw
= FALSE
;
1602 pubkey
->keyclass
= KMF_ASYM_PUB
;
1603 pubkey
->keyp
= (void *)epubkey
;
1605 } else if (keytype
== KMF_DSA
) {
1608 sslDSAKey
= DSA_new();
1609 if (sslDSAKey
== NULL
) {
1610 SET_ERROR(kmfh
, ERR_get_error());
1611 return (KMF_ERR_MEMORY
);
1614 p
= BN_bin2bn(P
, sizeof (P
), NULL
);
1615 q
= BN_bin2bn(Q
, sizeof (Q
), NULL
);
1616 g
= BN_bin2bn(G
, sizeof (G
), NULL
);
1617 if (p
== NULL
|| q
== NULL
|| g
== NULL
) {
1621 SET_ERROR(kmfh
, ERR_get_error());
1622 rv
= KMF_ERR_KEYGEN_FAILED
;
1626 if (DSA_set0_pqg(sslDSAKey
, p
, q
, g
) == 0) {
1627 SET_ERROR(kmfh
, ERR_get_error());
1628 rv
= KMF_ERR_KEYGEN_FAILED
;
1632 if (!DSA_generate_key(sslDSAKey
)) {
1633 SET_ERROR(kmfh
, ERR_get_error());
1634 rv
= KMF_ERR_KEYGEN_FAILED
;
1638 privkey
->kstype
= KMF_KEYSTORE_OPENSSL
;
1639 privkey
->keyalg
= KMF_DSA
;
1640 privkey
->keyclass
= KMF_ASYM_PRI
;
1641 privkey
->israw
= FALSE
;
1642 if (EVP_PKEY_set1_DSA(eprikey
, sslDSAKey
)) {
1643 privkey
->keyp
= (void *)eprikey
;
1645 SET_ERROR(kmfh
, ERR_get_error());
1646 rv
= KMF_ERR_KEYGEN_FAILED
;
1650 pubkey
->kstype
= KMF_KEYSTORE_OPENSSL
;
1651 pubkey
->keyalg
= KMF_DSA
;
1652 pubkey
->keyclass
= KMF_ASYM_PUB
;
1653 pubkey
->israw
= FALSE
;
1655 if (EVP_PKEY_set1_DSA(epubkey
, sslDSAKey
)) {
1656 pubkey
->keyp
= (void *)epubkey
;
1658 SET_ERROR(kmfh
, ERR_get_error());
1659 rv
= KMF_ERR_KEYGEN_FAILED
;
1669 KMF_ATTRIBUTE storeattrs
[4]; /* max. 4 attributes needed */
1671 char *keyfile
= NULL
, *dirpath
= NULL
;
1672 KMF_ENCODE_FORMAT format
;
1674 * Construct a new attribute arrray and call openssl_store_key
1676 kmf_set_attr_at_index(storeattrs
, i
, KMF_PRIVKEY_HANDLE_ATTR
,
1677 privkey
, sizeof (privkey
));
1680 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
1681 if (dirpath
!= NULL
) {
1682 storeattrs
[i
].type
= KMF_DIRPATH_ATTR
;
1683 storeattrs
[i
].pValue
= dirpath
;
1684 storeattrs
[i
].valueLen
= strlen(dirpath
);
1687 rv
= KMF_OK
; /* DIRPATH is optional */
1689 keyfile
= kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
,
1691 if (keyfile
!= NULL
) {
1692 storeattrs
[i
].type
= KMF_KEY_FILENAME_ATTR
;
1693 storeattrs
[i
].pValue
= keyfile
;
1694 storeattrs
[i
].valueLen
= strlen(keyfile
);
1697 goto cleanup
; /* KEYFILE is required */
1699 rv
= kmf_get_attr(KMF_ENCODE_FORMAT_ATTR
, attrlist
, numattr
,
1700 (void *)&format
, NULL
);
1702 storeattrs
[i
].type
= KMF_ENCODE_FORMAT_ATTR
;
1703 storeattrs
[i
].pValue
= &format
;
1704 storeattrs
[i
].valueLen
= sizeof (format
);
1708 rv
= OpenSSL_StoreKey(handle
, i
, storeattrs
);
1712 if (eValue_bn
!= NULL
)
1716 if (eprikey
!= NULL
)
1717 EVP_PKEY_free(eprikey
);
1719 if (epubkey
!= NULL
)
1720 EVP_PKEY_free(epubkey
);
1722 if (pubkey
->keylabel
) {
1723 free(pubkey
->keylabel
);
1724 pubkey
->keylabel
= NULL
;
1727 if (privkey
->keylabel
) {
1728 free(privkey
->keylabel
);
1729 privkey
->keylabel
= NULL
;
1732 pubkey
->keyp
= NULL
;
1733 privkey
->keyp
= NULL
;
1737 RSA_free(sslPrivKey
);
1740 DSA_free(sslDSAKey
);
1743 (void) BIO_free(out
);
1749 * Make sure the BN conversion is properly padded with 0x00
1750 * bytes. If not, signature verification for DSA signatures
1751 * may fail in the case where the bignum value does not use
1755 fixbnlen(const BIGNUM
*bn
, unsigned char *buf
, int len
) {
1756 int bytes
= len
- BN_num_bytes(bn
);
1758 /* prepend with leading 0x00 if necessary */
1762 (void) BN_bn2bin(bn
, buf
);
1764 * Return the desired length since we prepended it
1765 * with the necessary 0x00 padding.
1771 OpenSSL_SignData(KMF_HANDLE_T handle
, KMF_KEY_HANDLE
*key
,
1772 KMF_OID
*AlgOID
, KMF_DATA
*tobesigned
, KMF_DATA
*output
)
1774 KMF_RETURN ret
= KMF_OK
;
1775 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1776 KMF_ALGORITHM_INDEX AlgId
;
1780 if (key
== NULL
|| AlgOID
== NULL
||
1781 tobesigned
== NULL
|| output
== NULL
||
1782 tobesigned
->Data
== NULL
||
1783 output
->Data
== NULL
)
1784 return (KMF_ERR_BAD_PARAMETER
);
1786 /* Map the OID to an OpenSSL algorithm */
1787 AlgId
= x509_algoid_to_algid(AlgOID
);
1788 if (AlgId
== KMF_ALGID_NONE
)
1789 return (KMF_ERR_BAD_ALGORITHM
);
1791 if (key
->keyalg
== KMF_RSA
) {
1792 EVP_PKEY
*pkey
= (EVP_PKEY
*)key
->keyp
;
1796 #ifndef OPENSSL_NO_MD5
1797 case KMF_ALGID_MD5WithRSA
:
1801 #ifndef OPENSSL_NO_SHA
1802 case KMF_ALGID_SHA1WithRSA
:
1806 #ifndef OPENSSL_NO_SHA256
1807 case KMF_ALGID_SHA256WithRSA
:
1811 #ifndef OPENSSL_NO_SHA512
1812 case KMF_ALGID_SHA384WithRSA
:
1815 case KMF_ALGID_SHA512WithRSA
:
1823 return (KMF_ERR_BAD_ALGORITHM
);
1826 if ((md
== NULL
) && (AlgId
== KMF_ALGID_RSA
)) {
1827 RSA
*rsa
= EVP_PKEY_get1_RSA((EVP_PKEY
*)pkey
);
1830 if ((len
= RSA_private_encrypt(tobesigned
->Length
,
1831 tobesigned
->Data
, p
, rsa
,
1832 RSA_PKCS1_PADDING
)) <= 0) {
1833 SET_ERROR(kmfh
, ERR_get_error());
1834 ret
= KMF_ERR_INTERNAL
;
1836 output
->Length
= len
;
1838 if ((ctx
= EVP_MD_CTX_new()) == NULL
)
1839 return (KMF_ERR_MEMORY
);
1840 (void) EVP_SignInit_ex(ctx
, md
, NULL
);
1841 (void) EVP_SignUpdate(ctx
, tobesigned
->Data
,
1842 (uint32_t)tobesigned
->Length
);
1843 len
= (uint32_t)output
->Length
;
1845 if (!EVP_SignFinal(ctx
, p
, (uint32_t *)&len
, pkey
)) {
1846 SET_ERROR(kmfh
, ERR_get_error());
1848 ret
= KMF_ERR_INTERNAL
;
1850 output
->Length
= len
;
1851 EVP_MD_CTX_free(ctx
);
1853 } else if (key
->keyalg
== KMF_DSA
) {
1854 DSA
*dsa
= EVP_PKEY_get1_DSA(key
->keyp
);
1856 uchar_t hash
[EVP_MAX_MD_SIZE
];
1860 if (AlgId
== KMF_ALGID_DSA
||
1861 AlgId
== KMF_ALGID_SHA1WithDSA
)
1863 else if (AlgId
== KMF_ALGID_SHA256WithDSA
)
1865 else /* Bad algorithm */
1866 return (KMF_ERR_BAD_ALGORITHM
);
1869 * OpenSSL EVP_Sign operation automatically converts to
1870 * ASN.1 output so we do the operations separately so we
1871 * are assured of NOT getting ASN.1 output returned.
1872 * KMF does not want ASN.1 encoded results because
1873 * not all mechanisms return ASN.1 encodings (PKCS#11
1874 * and NSS return raw signature data).
1876 if ((ctx
= EVP_MD_CTX_new()) == NULL
)
1877 return (KMF_ERR_MEMORY
);
1878 (void) EVP_DigestInit_ex(ctx
, md
, NULL
);
1879 (void) EVP_DigestUpdate(ctx
, tobesigned
->Data
,
1880 tobesigned
->Length
);
1881 (void) EVP_DigestFinal_ex(ctx
, hash
, &hashlen
);
1883 /* Only sign first 20 bytes for SHA2 */
1884 if (AlgId
== KMF_ALGID_SHA256WithDSA
)
1886 dsasig
= DSA_do_sign(hash
, hashlen
, dsa
);
1887 if (dsasig
!= NULL
) {
1889 const BIGNUM
*r
, *s
;
1891 DSA_SIG_get0(dsasig
, &r
, &s
);
1892 output
->Length
= i
= fixbnlen(r
, output
->Data
,
1895 output
->Length
+= fixbnlen(s
, &output
->Data
[i
],
1898 DSA_SIG_free(dsasig
);
1900 SET_ERROR(kmfh
, ERR_get_error());
1902 EVP_MD_CTX_free(ctx
);
1904 return (KMF_ERR_BAD_PARAMETER
);
1912 OpenSSL_DeleteKey(KMF_HANDLE_T handle
,
1913 int numattr
, KMF_ATTRIBUTE
*attrlist
)
1915 KMF_RETURN rv
= KMF_OK
;
1916 KMF_KEY_HANDLE
*key
;
1917 boolean_t destroy
= B_TRUE
;
1919 key
= kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR
, attrlist
, numattr
);
1920 if (key
== NULL
|| key
->keyp
== NULL
)
1921 return (KMF_ERR_BAD_PARAMETER
);
1923 rv
= kmf_get_attr(KMF_DESTROY_BOOL_ATTR
, attrlist
, numattr
,
1924 (void *)&destroy
, NULL
);
1926 /* "destroy" is optional. Default is TRUE */
1930 if (key
->keyclass
!= KMF_ASYM_PUB
&&
1931 key
->keyclass
!= KMF_ASYM_PRI
&&
1932 key
->keyclass
!= KMF_SYMMETRIC
)
1933 return (KMF_ERR_BAD_KEY_CLASS
);
1935 if (key
->keyclass
== KMF_SYMMETRIC
) {
1936 kmf_free_raw_sym_key((KMF_RAW_SYM_KEY
*)key
->keyp
);
1939 if (key
->keyp
!= NULL
) {
1940 EVP_PKEY_free(key
->keyp
);
1945 if (key
->keylabel
!= NULL
) {
1946 EVP_PKEY
*pkey
= NULL
;
1947 /* If the file exists, make sure it is a proper key. */
1948 pkey
= openssl_load_key(handle
, key
->keylabel
);
1950 if (key
->keylabel
!= NULL
) {
1951 free(key
->keylabel
);
1952 key
->keylabel
= NULL
;
1954 return (KMF_ERR_KEY_NOT_FOUND
);
1956 EVP_PKEY_free(pkey
);
1959 if (unlink(key
->keylabel
) != 0) {
1960 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1961 SET_SYS_ERROR(kmfh
, errno
);
1962 rv
= KMF_ERR_INTERNAL
;
1965 if (key
->keylabel
!= NULL
) {
1966 free(key
->keylabel
);
1967 key
->keylabel
= NULL
;
1974 OpenSSL_GetErrorString(KMF_HANDLE_T handle
, char **msgstr
)
1976 KMF_RETURN ret
= KMF_OK
;
1977 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1978 char str
[256]; /* OpenSSL needs at least 120 byte buffer */
1980 ERR_error_string_n(kmfh
->lasterr
.errcode
, str
, sizeof (str
));
1982 *msgstr
= (char *)strdup(str
);
1983 if ((*msgstr
) == NULL
)
1984 ret
= KMF_ERR_MEMORY
;
1996 case KMF_X509_EXT_KEY_USAGE
:
1997 return (NID_key_usage
);
1998 case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD
:
1999 return (NID_private_key_usage_period
);
2000 case KMF_X509_EXT_CERT_POLICIES
:
2001 return (NID_certificate_policies
);
2002 case KMF_X509_EXT_SUBJ_ALTNAME
:
2003 return (NID_subject_alt_name
);
2004 case KMF_X509_EXT_ISSUER_ALTNAME
:
2005 return (NID_issuer_alt_name
);
2006 case KMF_X509_EXT_BASIC_CONSTRAINTS
:
2007 return (NID_basic_constraints
);
2008 case KMF_X509_EXT_EXT_KEY_USAGE
:
2009 return (NID_ext_key_usage
);
2010 case KMF_X509_EXT_AUTH_KEY_ID
:
2011 return (NID_authority_key_identifier
);
2012 case KMF_X509_EXT_CRL_DIST_POINTS
:
2013 return (NID_crl_distribution_points
);
2014 case KMF_X509_EXT_SUBJ_KEY_ID
:
2015 return (NID_subject_key_identifier
);
2016 case KMF_X509_EXT_POLICY_MAPPINGS
:
2017 return (OBJ_sn2nid("policyMappings"));
2018 case KMF_X509_EXT_NAME_CONSTRAINTS
:
2019 return (OBJ_sn2nid("nameConstraints"));
2020 case KMF_X509_EXT_POLICY_CONSTRAINTS
:
2021 return (OBJ_sn2nid("policyConstraints"));
2022 case KMF_X509_EXT_INHIBIT_ANY_POLICY
:
2023 return (OBJ_sn2nid("inhibitAnyPolicy"));
2024 case KMF_X509_EXT_FRESHEST_CRL
:
2025 return (OBJ_sn2nid("freshestCRL"));
2032 OpenSSL_CertGetPrintable(KMF_HANDLE_T handle
, const KMF_DATA
*pcert
,
2033 KMF_PRINTABLE_ITEM flag
, char *resultStr
)
2035 KMF_RETURN ret
= KMF_OK
;
2036 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2038 unsigned char *outbuf
= NULL
;
2039 unsigned char *outbuf_p
;
2041 int ext_index
, nid
, len
;
2043 STACK_OF(OPENSSL_STRING
) *emlst
= NULL
;
2046 if (pcert
== NULL
|| pcert
->Data
== NULL
|| pcert
->Length
== 0) {
2047 return (KMF_ERR_BAD_PARAMETER
);
2050 /* copy cert data to outbuf */
2051 outbuf
= malloc(pcert
->Length
);
2052 if (outbuf
== NULL
) {
2053 return (KMF_ERR_MEMORY
);
2055 (void) memcpy(outbuf
, pcert
->Data
, pcert
->Length
);
2057 outbuf_p
= outbuf
; /* use a temp pointer; required by openssl */
2058 xcert
= d2i_X509(NULL
, (const uchar_t
**)&outbuf_p
, pcert
->Length
);
2059 if (xcert
== NULL
) {
2060 SET_ERROR(kmfh
, ERR_get_error());
2061 ret
= KMF_ERR_ENCODING
;
2065 mem
= BIO_new(BIO_s_mem());
2067 SET_ERROR(kmfh
, ERR_get_error());
2068 ret
= KMF_ERR_MEMORY
;
2073 case KMF_CERT_ISSUER
:
2074 (void) X509_NAME_print_ex(mem
, X509_get_issuer_name(xcert
), 0,
2075 XN_FLAG_SEP_CPLUS_SPC
);
2076 len
= BIO_gets(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2079 case KMF_CERT_SUBJECT
:
2080 (void) X509_NAME_print_ex(mem
, X509_get_subject_name(xcert
), 0,
2081 XN_FLAG_SEP_CPLUS_SPC
);
2082 len
= BIO_gets(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2085 case KMF_CERT_VERSION
:
2086 (void) snprintf(resultStr
, KMF_CERT_PRINTABLE_LEN
,
2087 "%ld", X509_get_version(xcert
));
2088 len
= strlen(resultStr
);
2091 case KMF_CERT_SERIALNUM
:
2092 if (i2a_ASN1_INTEGER(mem
, X509_get_serialNumber(xcert
)) > 0) {
2093 (void) strcpy(resultStr
, "0x");
2094 len
= BIO_gets(mem
, &resultStr
[2],
2095 KMF_CERT_PRINTABLE_LEN
- 2);
2099 case KMF_CERT_NOTBEFORE
:
2100 (void) ASN1_TIME_print(mem
, X509_getm_notBefore(xcert
));
2101 len
= BIO_gets(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2104 case KMF_CERT_NOTAFTER
:
2105 (void) ASN1_TIME_print(mem
, X509_getm_notAfter(xcert
));
2106 len
= BIO_gets(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2109 case KMF_CERT_PUBKEY_DATA
:
2114 EVP_PKEY
*pkey
= X509_get_pubkey(xcert
);
2116 SET_ERROR(kmfh
, ERR_get_error());
2117 ret
= KMF_ERR_ENCODING
;
2121 if ((rsa
= EVP_PKEY_get0_RSA(pkey
)) != NULL
) {
2122 (void) BIO_printf(mem
,
2123 "RSA Public Key: (%d bit)\n",
2125 (void) RSA_print(mem
, rsa
, 0);
2127 } else if ((dsa
= EVP_PKEY_get0_DSA(pkey
)) != NULL
) {
2128 (void) BIO_printf(mem
,
2129 "%12sDSA Public Key:\n", "");
2130 (void) DSA_print(mem
, dsa
, 0);
2132 (void) BIO_printf(mem
,
2133 "%12sUnknown Public Key:\n", "");
2135 (void) BIO_printf(mem
, "\n");
2136 EVP_PKEY_free(pkey
);
2138 len
= BIO_read(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2140 case KMF_CERT_SIGNATURE_ALG
:
2141 case KMF_CERT_PUBKEY_ALG
:
2143 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
2144 ASN1_OBJECT
*alg
= NULL
;
2146 const ASN1_OBJECT
*alg
= NULL
;
2149 if (flag
== KMF_CERT_SIGNATURE_ALG
) {
2150 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
2151 alg
= xcert
->sig_alg
->algorithm
;
2153 const X509_ALGOR
*sig_alg
= NULL
;
2155 X509_get0_signature(NULL
, &sig_alg
, xcert
);
2156 if (sig_alg
!= NULL
)
2157 X509_ALGOR_get0(&alg
, NULL
, NULL
,
2161 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
2162 alg
= xcert
->cert_info
->key
->algor
->algorithm
;
2164 X509_PUBKEY
*key
= X509_get_X509_PUBKEY(xcert
);
2167 (void) X509_PUBKEY_get0_param(
2168 (ASN1_OBJECT
**)&alg
, NULL
, 0,
2175 else if ((len
= i2a_ASN1_OBJECT(mem
, alg
)) > 0)
2176 len
= BIO_read(mem
, resultStr
,
2177 KMF_CERT_PRINTABLE_LEN
);
2181 case KMF_CERT_EMAIL
:
2182 emlst
= X509_get1_email(xcert
);
2183 for (j
= 0; j
< sk_OPENSSL_STRING_num(emlst
); j
++)
2184 (void) BIO_printf(mem
, "%s\n",
2185 sk_OPENSSL_STRING_value(emlst
, j
));
2187 len
= BIO_gets(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2188 X509_email_free(emlst
);
2190 case KMF_X509_EXT_ISSUER_ALTNAME
:
2191 case KMF_X509_EXT_SUBJ_ALTNAME
:
2192 case KMF_X509_EXT_KEY_USAGE
:
2193 case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD
:
2194 case KMF_X509_EXT_CERT_POLICIES
:
2195 case KMF_X509_EXT_BASIC_CONSTRAINTS
:
2196 case KMF_X509_EXT_NAME_CONSTRAINTS
:
2197 case KMF_X509_EXT_POLICY_CONSTRAINTS
:
2198 case KMF_X509_EXT_EXT_KEY_USAGE
:
2199 case KMF_X509_EXT_INHIBIT_ANY_POLICY
:
2200 case KMF_X509_EXT_AUTH_KEY_ID
:
2201 case KMF_X509_EXT_SUBJ_KEY_ID
:
2202 case KMF_X509_EXT_POLICY_MAPPINGS
:
2203 case KMF_X509_EXT_CRL_DIST_POINTS
:
2204 case KMF_X509_EXT_FRESHEST_CRL
:
2205 nid
= ext2NID(flag
);
2206 if (nid
== NID_undef
) {
2207 ret
= KMF_ERR_EXTENSION_NOT_FOUND
;
2211 ext_index
= X509_get_ext_by_NID(xcert
, nid
, -1);
2212 if (ext_index
== -1) {
2213 SET_ERROR(kmfh
, ERR_get_error());
2215 ret
= KMF_ERR_EXTENSION_NOT_FOUND
;
2218 ex
= X509_get_ext(xcert
, ext_index
);
2220 (void) i2a_ASN1_OBJECT(mem
, X509_EXTENSION_get_object(ex
));
2222 if (BIO_printf(mem
, ": %s\n",
2223 X509_EXTENSION_get_critical(ex
) ? "critical" : "") <= 0) {
2224 SET_ERROR(kmfh
, ERR_get_error());
2225 ret
= KMF_ERR_ENCODING
;
2228 if (!X509V3_EXT_print(mem
, ex
, X509V3_EXT_DUMP_UNKNOWN
, 4)) {
2229 (void) BIO_printf(mem
, "%*s", 4, "");
2230 (void) ASN1_STRING_print(mem
,
2231 X509_EXTENSION_get_data(ex
));
2233 if (BIO_write(mem
, "\n", 1) <= 0) {
2234 SET_ERROR(kmfh
, ERR_get_error());
2235 ret
= KMF_ERR_ENCODING
;
2238 len
= BIO_read(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2241 SET_ERROR(kmfh
, ERR_get_error());
2242 ret
= KMF_ERR_ENCODING
;
2246 if (outbuf
!= NULL
) {
2250 if (xcert
!= NULL
) {
2255 (void) BIO_free(mem
);
2263 OpenSSL_FindPrikeyByCert(KMF_HANDLE_T handle
, int numattr
,
2264 KMF_ATTRIBUTE
*attrlist
)
2266 KMF_RETURN rv
= KMF_OK
;
2267 KMF_KEYSTORE_TYPE kstype
= KMF_KEYSTORE_OPENSSL
;
2268 KMF_KEY_CLASS keyclass
= KMF_ASYM_PRI
;
2269 KMF_KEY_HANDLE
*key
= NULL
;
2270 uint32_t numkeys
= 1; /* 1 key only */
2271 char *dirpath
= NULL
;
2272 char *keyfile
= NULL
;
2273 KMF_ATTRIBUTE new_attrlist
[16];
2277 * This is really just a FindKey operation, reuse the
2280 kmf_set_attr_at_index(new_attrlist
, i
,
2281 KMF_KEYSTORE_TYPE_ATTR
, &kstype
, sizeof (kstype
));
2284 kmf_set_attr_at_index(new_attrlist
, i
,
2285 KMF_COUNT_ATTR
, &numkeys
, sizeof (uint32_t));
2288 kmf_set_attr_at_index(new_attrlist
, i
,
2289 KMF_KEYCLASS_ATTR
, &keyclass
, sizeof (keyclass
));
2292 key
= kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR
, attrlist
, numattr
);
2294 return (KMF_ERR_BAD_PARAMETER
);
2296 kmf_set_attr_at_index(new_attrlist
, i
,
2297 KMF_KEY_HANDLE_ATTR
, key
, sizeof (KMF_KEY_HANDLE
));
2301 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
2302 if (dirpath
!= NULL
) {
2303 kmf_set_attr_at_index(new_attrlist
, i
,
2304 KMF_DIRPATH_ATTR
, dirpath
, strlen(dirpath
));
2308 keyfile
= kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
, attrlist
, numattr
);
2309 if (keyfile
== NULL
)
2310 return (KMF_ERR_BAD_PARAMETER
);
2312 kmf_set_attr_at_index(new_attrlist
, i
,
2313 KMF_KEY_FILENAME_ATTR
, keyfile
, strlen(keyfile
));
2317 rv
= OpenSSL_FindKey(handle
, i
, new_attrlist
);
2323 OpenSSL_DecryptData(KMF_HANDLE_T handle
, KMF_KEY_HANDLE
*key
,
2324 KMF_OID
*AlgOID
, KMF_DATA
*ciphertext
,
2327 KMF_RETURN ret
= KMF_OK
;
2329 unsigned int in_len
= 0, out_len
= 0;
2330 unsigned int total_decrypted
= 0, modulus_len
= 0;
2331 uint8_t *in_data
, *out_data
;
2334 if (key
== NULL
|| AlgOID
== NULL
||
2335 ciphertext
== NULL
|| output
== NULL
||
2336 ciphertext
->Data
== NULL
||
2337 output
->Data
== NULL
)
2338 return (KMF_ERR_BAD_PARAMETER
);
2340 if (key
->keyalg
== KMF_RSA
) {
2341 rsa
= EVP_PKEY_get1_RSA((EVP_PKEY
*)key
->keyp
);
2342 modulus_len
= RSA_size(rsa
);
2344 return (KMF_ERR_BAD_PARAMETER
);
2347 blocks
= ciphertext
->Length
/modulus_len
;
2348 out_data
= output
->Data
;
2349 in_data
= ciphertext
->Data
;
2350 out_len
= modulus_len
- 11;
2351 in_len
= modulus_len
;
2353 for (i
= 0; i
< blocks
; i
++) {
2354 out_len
= RSA_private_decrypt(in_len
,
2355 in_data
, out_data
, rsa
, RSA_PKCS1_PADDING
);
2358 ret
= KMF_ERR_INTERNAL
;
2362 out_data
+= out_len
;
2363 total_decrypted
+= out_len
;
2367 output
->Length
= total_decrypted
;
2379 * This function will create a certid from issuer_cert and user_cert.
2380 * The caller should use OCSP_CERTID_free(OCSP_CERTID *) to deallocate
2381 * certid memory after use.
2384 create_certid(KMF_HANDLE_T handle
, const KMF_DATA
*issuer_cert
,
2385 const KMF_DATA
*user_cert
, OCSP_CERTID
**certid
)
2387 KMF_RETURN ret
= KMF_OK
;
2388 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2389 X509
*issuer
= NULL
;
2391 unsigned char *ptmp
;
2393 if (issuer_cert
== NULL
|| user_cert
== NULL
) {
2394 return (KMF_ERR_BAD_PARAMETER
);
2397 /* convert the DER-encoded issuer cert to an internal X509 */
2398 ptmp
= issuer_cert
->Data
;
2399 issuer
= d2i_X509(NULL
, (const uchar_t
**)&ptmp
,
2400 issuer_cert
->Length
);
2401 if (issuer
== NULL
) {
2402 SET_ERROR(kmfh
, ERR_get_error());
2403 ret
= KMF_ERR_OCSP_BAD_ISSUER
;
2407 /* convert the DER-encoded user cert to an internal X509 */
2408 ptmp
= user_cert
->Data
;
2409 cert
= d2i_X509(NULL
, (const uchar_t
**)&ptmp
,
2412 SET_ERROR(kmfh
, ERR_get_error());
2414 ret
= KMF_ERR_OCSP_BAD_CERT
;
2418 /* create a CERTID */
2419 *certid
= OCSP_cert_to_id(NULL
, cert
, issuer
);
2420 if (*certid
== NULL
) {
2421 SET_ERROR(kmfh
, ERR_get_error());
2422 ret
= KMF_ERR_OCSP_CERTID
;
2427 if (issuer
!= NULL
) {
2439 OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle
,
2440 int numattr
, KMF_ATTRIBUTE
*attrlist
)
2442 KMF_RETURN ret
= KMF_OK
;
2443 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2444 OCSP_CERTID
*id
= NULL
;
2445 OCSP_REQUEST
*req
= NULL
;
2448 KMF_DATA
*issuer_cert
;
2449 KMF_DATA
*user_cert
;
2451 user_cert
= kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR
,
2453 if (user_cert
== NULL
)
2454 return (KMF_ERR_BAD_PARAMETER
);
2456 issuer_cert
= kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR
,
2458 if (issuer_cert
== NULL
)
2459 return (KMF_ERR_BAD_PARAMETER
);
2461 reqfile
= kmf_get_attr_ptr(KMF_OCSP_REQUEST_FILENAME_ATTR
,
2463 if (reqfile
== NULL
)
2464 return (KMF_ERR_BAD_PARAMETER
);
2466 ret
= create_certid(handle
, issuer_cert
, user_cert
, &id
);
2467 if (ret
!= KMF_OK
) {
2471 /* Create an OCSP request */
2472 req
= OCSP_REQUEST_new();
2474 SET_ERROR(kmfh
, ERR_get_error());
2475 ret
= KMF_ERR_OCSP_CREATE_REQUEST
;
2479 if (!OCSP_request_add0_id(req
, id
)) {
2480 ret
= KMF_ERR_OCSP_CREATE_REQUEST
;
2484 /* Write the request to the output file with DER encoding */
2485 derbio
= BIO_new_file(reqfile
, "wb");
2487 SET_ERROR(kmfh
, ERR_get_error());
2488 ret
= KMF_ERR_OPEN_FILE
;
2491 if (i2d_OCSP_REQUEST_bio(derbio
, req
) <= 0) {
2492 ret
= KMF_ERR_ENCODING
;
2497 * We don't need to free "id" explicitely, because OCSP_REQUEST_free()
2498 * will also deallocate certid's space.
2501 OCSP_REQUEST_free(req
);
2504 if (derbio
!= NULL
) {
2505 (void) BIO_free(derbio
);
2511 /* ocsp_find_signer_sk() is copied from openssl source */
2512 static X509
*ocsp_find_signer_sk(STACK_OF(X509
) *certs
, OCSP_BASICRESP
*bs
)
2515 unsigned char tmphash
[SHA_DIGEST_LENGTH
], *keyhash
;
2516 const ASN1_OCTET_STRING
*pid
;
2518 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
2519 OCSP_RESPID
*id
= bs
->tbsResponseData
->responderId
;
2521 if (id
->type
== V_OCSP_RESPID_NAME
)
2522 return (X509_find_by_subject(certs
, id
->value
.byName
));
2524 pid
= id
->value
.byKey
;
2526 const X509_NAME
*pname
;
2528 if (OCSP_resp_get0_id(bs
, &pid
, &pname
) == 0)
2532 return (X509_find_by_subject(certs
, (X509_NAME
*)pname
));
2535 /* Lookup by key hash */
2537 /* If key hash isn't SHA1 length then forget it */
2538 if (pid
->length
!= SHA_DIGEST_LENGTH
)
2541 keyhash
= pid
->data
;
2542 /* Calculate hash of each key and compare */
2543 for (i
= 0; i
< sk_X509_num(certs
); i
++) {
2544 /* LINTED E_BAD_PTR_CAST_ALIGN */
2545 X509
*x
= sk_X509_value(certs
, i
);
2546 /* Use pubkey_digest to get the key ID value */
2547 (void) X509_pubkey_digest(x
, EVP_sha1(), tmphash
, NULL
);
2548 if (!memcmp(keyhash
, tmphash
, SHA_DIGEST_LENGTH
))
2554 /* ocsp_find_signer() is copied from openssl source */
2557 ocsp_find_signer(X509
**psigner
, OCSP_BASICRESP
*bs
, STACK_OF(X509
) *certs
,
2558 X509_STORE
*st
, unsigned long flags
)
2561 if ((signer
= ocsp_find_signer_sk(certs
, bs
))) {
2566 if (!(flags
& OCSP_NOINTERN
) &&
2567 (signer
= ocsp_find_signer_sk(
2568 (STACK_OF(X509
) *)OCSP_resp_get0_certs(bs
), bs
))) {
2572 /* Maybe lookup from store if by subject name */
2579 * This function will verify the signature of a basic response, using
2580 * the public key from the OCSP responder certificate.
2583 check_response_signature(KMF_HANDLE_T handle
, OCSP_BASICRESP
*bs
,
2584 KMF_DATA
*signer_cert
, KMF_DATA
*issuer_cert
)
2586 KMF_RETURN ret
= KMF_OK
;
2587 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2588 STACK_OF(X509
) *cert_stack
= NULL
;
2589 X509
*signer
= NULL
;
2590 X509
*issuer
= NULL
;
2591 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
2592 EVP_PKEY
*skey
= NULL
;
2594 STACK_OF(X509
) *cert_stack2
= NULL
;
2596 unsigned char *ptmp
;
2598 if (bs
== NULL
|| issuer_cert
== NULL
)
2599 return (KMF_ERR_BAD_PARAMETER
);
2602 * Find the certificate that signed the basic response.
2604 * If signer_cert is not NULL, we will use that as the signer cert.
2605 * Otherwise, we will check if the issuer cert is actually the signer.
2606 * If we still do not find a signer, we will look for it from the
2607 * certificate list came with the response file.
2609 if (signer_cert
!= NULL
) {
2610 ptmp
= signer_cert
->Data
;
2611 signer
= d2i_X509(NULL
, (const uchar_t
**)&ptmp
,
2612 signer_cert
->Length
);
2613 if (signer
== NULL
) {
2614 SET_ERROR(kmfh
, ERR_get_error());
2615 ret
= KMF_ERR_OCSP_BAD_SIGNER
;
2620 * Convert the issuer cert into X509 and push it into a
2621 * stack to be used by ocsp_find_signer().
2623 ptmp
= issuer_cert
->Data
;
2624 issuer
= d2i_X509(NULL
, (const uchar_t
**)&ptmp
,
2625 issuer_cert
->Length
);
2626 if (issuer
== NULL
) {
2627 SET_ERROR(kmfh
, ERR_get_error());
2628 ret
= KMF_ERR_OCSP_BAD_ISSUER
;
2632 if ((cert_stack
= sk_X509_new_null()) == NULL
) {
2633 ret
= KMF_ERR_INTERNAL
;
2637 if (sk_X509_push(cert_stack
, issuer
) == NULL
) {
2638 ret
= KMF_ERR_INTERNAL
;
2642 ret
= ocsp_find_signer(&signer
, bs
, cert_stack
, NULL
, 0);
2644 /* can not find the signer */
2645 ret
= KMF_ERR_OCSP_BAD_SIGNER
;
2650 /* Verify the signature of the response */
2651 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
2652 skey
= X509_get_pubkey(signer
);
2654 ret
= KMF_ERR_OCSP_BAD_SIGNER
;
2658 ret
= OCSP_BASICRESP_verify(bs
, skey
, 0);
2661 * Technique based on
2662 * https://mta.openssl.org/pipermail/openssl-users/
2663 * 2017-October/006814.html
2665 if ((cert_stack2
= sk_X509_new_null()) == NULL
) {
2666 ret
= KMF_ERR_INTERNAL
;
2670 if (sk_X509_push(cert_stack2
, signer
) == NULL
) {
2671 ret
= KMF_ERR_INTERNAL
;
2675 ret
= OCSP_basic_verify(bs
, cert_stack2
, NULL
, OCSP_NOVERIFY
);
2679 ret
= KMF_ERR_OCSP_RESPONSE_SIGNATURE
;
2684 if (issuer
!= NULL
) {
2688 if (signer
!= NULL
) {
2692 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
2694 EVP_PKEY_free(skey
);
2697 if (cert_stack2
!= NULL
) {
2698 sk_X509_free(cert_stack2
);
2702 if (cert_stack
!= NULL
) {
2703 sk_X509_free(cert_stack
);
2710 OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle
,
2711 int numattr
, KMF_ATTRIBUTE
*attrlist
)
2713 KMF_RETURN ret
= KMF_OK
;
2715 OCSP_RESPONSE
*resp
= NULL
;
2716 OCSP_BASICRESP
*bs
= NULL
;
2717 OCSP_CERTID
*id
= NULL
;
2718 OCSP_SINGLERESP
*single
= NULL
;
2719 ASN1_GENERALIZEDTIME
*rev
, *thisupd
, *nextupd
;
2720 int index
, status
, reason
;
2721 KMF_DATA
*issuer_cert
;
2722 KMF_DATA
*user_cert
;
2723 KMF_DATA
*signer_cert
;
2725 int *response_reason
, *response_status
, *cert_status
;
2726 boolean_t ignore_response_sign
= B_FALSE
; /* default is FALSE */
2727 uint32_t response_lifetime
;
2729 issuer_cert
= kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR
,
2731 if (issuer_cert
== NULL
)
2732 return (KMF_ERR_BAD_PARAMETER
);
2734 user_cert
= kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR
,
2736 if (user_cert
== NULL
)
2737 return (KMF_ERR_BAD_PARAMETER
);
2739 response
= kmf_get_attr_ptr(KMF_OCSP_RESPONSE_DATA_ATTR
,
2741 if (response
== NULL
)
2742 return (KMF_ERR_BAD_PARAMETER
);
2744 response_status
= kmf_get_attr_ptr(KMF_OCSP_RESPONSE_STATUS_ATTR
,
2746 if (response_status
== NULL
)
2747 return (KMF_ERR_BAD_PARAMETER
);
2749 response_reason
= kmf_get_attr_ptr(KMF_OCSP_RESPONSE_REASON_ATTR
,
2751 if (response_reason
== NULL
)
2752 return (KMF_ERR_BAD_PARAMETER
);
2754 cert_status
= kmf_get_attr_ptr(KMF_OCSP_RESPONSE_CERT_STATUS_ATTR
,
2756 if (cert_status
== NULL
)
2757 return (KMF_ERR_BAD_PARAMETER
);
2759 /* Read in the response */
2760 derbio
= BIO_new_mem_buf(response
->Data
, response
->Length
);
2762 ret
= KMF_ERR_MEMORY
;
2766 resp
= d2i_OCSP_RESPONSE_bio(derbio
, NULL
);
2768 ret
= KMF_ERR_OCSP_MALFORMED_RESPONSE
;
2772 /* Check the response status */
2773 status
= OCSP_response_status(resp
);
2774 *response_status
= status
;
2775 if (status
!= OCSP_RESPONSE_STATUS_SUCCESSFUL
) {
2776 ret
= KMF_ERR_OCSP_RESPONSE_STATUS
;
2781 printf("Successfully checked the response file status.\n");
2784 /* Extract basic response */
2785 bs
= OCSP_response_get1_basic(resp
);
2787 ret
= KMF_ERR_OCSP_NO_BASIC_RESPONSE
;
2792 printf("Successfully retrieved the basic response.\n");
2795 /* Check the basic response signature if required */
2796 ret
= kmf_get_attr(KMF_IGNORE_RESPONSE_SIGN_ATTR
, attrlist
, numattr
,
2797 (void *)&ignore_response_sign
, NULL
);
2801 signer_cert
= kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR
,
2804 if (ignore_response_sign
== B_FALSE
) {
2805 ret
= check_response_signature(handle
, bs
,
2806 signer_cert
, issuer_cert
);
2812 printf("Successfully verified the response signature.\n");
2815 /* Create a certid for the certificate in question */
2816 ret
= create_certid(handle
, issuer_cert
, user_cert
, &id
);
2817 if (ret
!= KMF_OK
) {
2818 ret
= KMF_ERR_OCSP_CERTID
;
2823 printf("successfully created a certid for the cert.\n");
2826 /* Find the index of the single response for the certid */
2827 index
= OCSP_resp_find(bs
, id
, -1);
2829 /* cound not find this certificate in the response */
2830 ret
= KMF_ERR_OCSP_UNKNOWN_CERT
;
2835 printf("Successfully found the single response index for the cert.\n");
2838 /* Retrieve the single response and get the cert status */
2839 single
= OCSP_resp_get0(bs
, index
);
2840 status
= OCSP_single_get0_status(single
, &reason
, &rev
, &thisupd
,
2842 if (status
== V_OCSP_CERTSTATUS_GOOD
) {
2843 *cert_status
= OCSP_GOOD
;
2844 } else if (status
== V_OCSP_CERTSTATUS_UNKNOWN
) {
2845 *cert_status
= OCSP_UNKNOWN
;
2846 } else { /* revoked */
2847 *cert_status
= OCSP_REVOKED
;
2848 *response_reason
= reason
;
2852 /* resp. time is optional, so we don't care about the return code. */
2853 (void) kmf_get_attr(KMF_RESPONSE_LIFETIME_ATTR
, attrlist
, numattr
,
2854 (void *)&response_lifetime
, NULL
);
2856 if (!OCSP_check_validity(thisupd
, nextupd
, 300,
2857 response_lifetime
)) {
2858 ret
= KMF_ERR_OCSP_STATUS_TIME_INVALID
;
2863 printf("Successfully verify the time.\n");
2868 (void) BIO_free(derbio
);
2871 OCSP_RESPONSE_free(resp
);
2874 OCSP_BASICRESP_free(bs
);
2877 OCSP_CERTID_free(id
);
2883 fetch_key(KMF_HANDLE_T handle
, char *path
,
2884 KMF_KEY_CLASS keyclass
, KMF_KEY_HANDLE
*key
)
2886 KMF_RETURN rv
= KMF_OK
;
2887 EVP_PKEY
*pkey
= NULL
;
2888 KMF_RAW_SYM_KEY
*rkey
= NULL
;
2890 if (keyclass
== KMF_ASYM_PRI
||
2891 keyclass
== KMF_ASYM_PUB
) {
2892 pkey
= openssl_load_key(handle
, path
);
2894 return (KMF_ERR_KEY_NOT_FOUND
);
2897 if (EVP_PKEY_get0_RSA(pkey
) != NULL
)
2898 key
->keyalg
= KMF_RSA
;
2899 else if (EVP_PKEY_get0_DSA(pkey
) != NULL
)
2900 key
->keyalg
= KMF_DSA
;
2902 key
->kstype
= KMF_KEYSTORE_OPENSSL
;
2903 key
->keyclass
= keyclass
;
2904 key
->keyp
= (void *)pkey
;
2907 ((key
->keylabel
= strdup(path
)) == NULL
)) {
2908 EVP_PKEY_free(pkey
);
2909 return (KMF_ERR_MEMORY
);
2912 EVP_PKEY_free(pkey
);
2915 } else if (keyclass
== KMF_SYMMETRIC
) {
2916 KMF_ENCODE_FORMAT fmt
;
2918 * If the file is a recognized format,
2919 * then it is NOT a symmetric key.
2921 rv
= kmf_get_file_format(path
, &fmt
);
2922 if (rv
== KMF_OK
|| fmt
!= 0) {
2923 return (KMF_ERR_KEY_NOT_FOUND
);
2924 } else if (rv
== KMF_ERR_ENCODING
) {
2926 * If we don't know the encoding,
2927 * it is probably a symmetric key.
2930 } else if (rv
== KMF_ERR_OPEN_FILE
) {
2931 return (KMF_ERR_KEY_NOT_FOUND
);
2936 rkey
= malloc(sizeof (KMF_RAW_SYM_KEY
));
2938 rv
= KMF_ERR_MEMORY
;
2942 (void) memset(rkey
, 0, sizeof (KMF_RAW_SYM_KEY
));
2943 rv
= kmf_read_input_file(handle
, path
, &keyvalue
);
2947 rkey
->keydata
.len
= keyvalue
.Length
;
2948 rkey
->keydata
.val
= keyvalue
.Data
;
2950 key
->kstype
= KMF_KEYSTORE_OPENSSL
;
2951 key
->keyclass
= keyclass
;
2953 key
->keyp
= (void *)rkey
;
2955 ((key
->keylabel
= strdup(path
)) == NULL
)) {
2956 rv
= KMF_ERR_MEMORY
;
2963 kmf_free_raw_sym_key(rkey
);
2966 EVP_PKEY_free(pkey
);
2969 key
->keyalg
= KMF_KEYALG_NONE
;
2970 key
->keyclass
= KMF_KEYCLASS_NONE
;
2979 OpenSSL_FindKey(KMF_HANDLE_T handle
,
2980 int numattr
, KMF_ATTRIBUTE
*attrlist
)
2982 KMF_RETURN rv
= KMF_OK
;
2983 char *fullpath
= NULL
;
2985 KMF_KEY_HANDLE
*key
;
2987 KMF_KEY_CLASS keyclass
;
2988 KMF_RAW_KEY_DATA
*rawkey
;
2993 return (KMF_ERR_BAD_PARAMETER
);
2995 numkeys
= kmf_get_attr_ptr(KMF_COUNT_ATTR
, attrlist
, numattr
);
2996 if (numkeys
== NULL
)
2997 return (KMF_ERR_BAD_PARAMETER
);
2999 rv
= kmf_get_attr(KMF_KEYCLASS_ATTR
, attrlist
, numattr
,
3000 (void *)&keyclass
, NULL
);
3002 return (KMF_ERR_BAD_PARAMETER
);
3004 if (keyclass
!= KMF_ASYM_PUB
&&
3005 keyclass
!= KMF_ASYM_PRI
&&
3006 keyclass
!= KMF_SYMMETRIC
)
3007 return (KMF_ERR_BAD_KEY_CLASS
);
3009 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
3010 keyfile
= kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
, attrlist
, numattr
);
3012 fullpath
= get_fullpath(dirpath
, keyfile
);
3014 if (fullpath
== NULL
)
3015 return (KMF_ERR_BAD_PARAMETER
);
3019 maxkeys
= 0xFFFFFFFF;
3022 key
= kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR
, attrlist
, numattr
);
3023 /* it is okay to have "keys" contains NULL */
3026 * The caller may want a list of the raw key data as well.
3027 * Useful for importing keys from a file into other keystores.
3029 rawkey
= kmf_get_attr_ptr(KMF_RAW_KEY_ATTR
, attrlist
, numattr
);
3031 if (isdir(fullpath
)) {
3036 /* open all files in the directory and attempt to read them */
3037 if ((dirp
= opendir(fullpath
)) == NULL
) {
3038 return (KMF_ERR_BAD_PARAMETER
);
3041 while ((dp
= readdir(dirp
)) != NULL
&& n
< maxkeys
) {
3042 if (strcmp(dp
->d_name
, ".") &&
3043 strcmp(dp
->d_name
, "..")) {
3046 fname
= get_fullpath(fullpath
,
3047 (char *)&dp
->d_name
);
3049 rv
= fetch_key(handle
, fname
,
3050 keyclass
, key
? &key
[n
] : NULL
);
3053 if (key
!= NULL
&& rawkey
!= NULL
)
3054 rv
= convertToRawKey(
3055 key
[n
].keyp
, &rawkey
[n
]);
3059 if (rv
!= KMF_OK
|| key
== NULL
)
3063 (void) closedir(dirp
);
3067 rv
= fetch_key(handle
, fullpath
, keyclass
, key
);
3071 if (rv
!= KMF_OK
|| key
== NULL
)
3074 if (rv
== KMF_OK
&& key
!= NULL
&& rawkey
!= NULL
) {
3075 rv
= convertToRawKey(key
->keyp
, rawkey
);
3079 if (rv
== KMF_OK
&& (*numkeys
) == 0)
3080 rv
= KMF_ERR_KEY_NOT_FOUND
;
3081 else if (rv
== KMF_ERR_KEY_NOT_FOUND
&& (*numkeys
) > 0)
3087 #define HANDLE_PK12_ERROR { \
3088 SET_ERROR(kmfh, ERR_get_error()); \
3089 rv = KMF_ERR_ENCODING; \
3094 add_alias_to_bag(PKCS12_SAFEBAG
*bag
, X509
*xcert
)
3096 unsigned char *alias
;
3099 if (xcert
!= NULL
&& (alias
= X509_alias_get0(xcert
, &len
)) != NULL
) {
3100 if (PKCS12_add_friendlyname_asc(bag
,
3101 (const char *)alias
, len
) == 0)
3108 add_cert_to_safe(X509
*sslcert
, KMF_CREDENTIAL
*cred
,
3109 uchar_t
*keyid
, unsigned int keyidlen
)
3111 PKCS12_SAFEBAG
*bag
= NULL
;
3112 PKCS7
*cert_authsafe
= NULL
;
3113 STACK_OF(PKCS12_SAFEBAG
) *bag_stack
;
3115 bag_stack
= sk_PKCS12_SAFEBAG_new_null();
3116 if (bag_stack
== NULL
)
3119 /* Convert cert from X509 struct to PKCS#12 bag */
3120 bag
= PKCS12_SAFEBAG_create_cert(sslcert
);
3125 /* Add the key id to the certificate bag. */
3126 if (keyidlen
> 0 && !PKCS12_add_localkeyid(bag
, keyid
, keyidlen
)) {
3130 if (!add_alias_to_bag(bag
, sslcert
))
3133 /* Pile it on the bag_stack. */
3134 if (!sk_PKCS12_SAFEBAG_push(bag_stack
, bag
)) {
3137 /* Turn bag_stack of certs into encrypted authsafe. */
3138 cert_authsafe
= PKCS12_pack_p7encdata(
3139 NID_pbe_WithSHA1And40BitRC2_CBC
,
3140 cred
->cred
, cred
->credlen
, NULL
, 0,
3141 PKCS12_DEFAULT_ITER
, bag_stack
);
3144 if (bag_stack
!= NULL
)
3145 sk_PKCS12_SAFEBAG_pop_free(bag_stack
, PKCS12_SAFEBAG_free
);
3147 return (cert_authsafe
);
3151 add_key_to_safe(EVP_PKEY
*pkey
, KMF_CREDENTIAL
*cred
,
3152 uchar_t
*keyid
, unsigned int keyidlen
,
3153 char *label
, int label_len
)
3155 PKCS8_PRIV_KEY_INFO
*p8
= NULL
;
3156 STACK_OF(PKCS12_SAFEBAG
) *bag_stack
= NULL
;
3157 PKCS12_SAFEBAG
*bag
= NULL
;
3158 PKCS7
*key_authsafe
= NULL
;
3160 p8
= EVP_PKEY2PKCS8(pkey
);
3164 /* Put the shrouded key into a PKCS#12 bag. */
3165 bag
= PKCS12_SAFEBAG_create_pkcs8_encrypt(
3166 NID_pbe_WithSHA1And3_Key_TripleDES_CBC
,
3167 cred
->cred
, cred
->credlen
,
3168 NULL
, 0, PKCS12_DEFAULT_ITER
, p8
);
3170 /* Clean up the PKCS#8 shrouded key, don't need it now. */
3171 PKCS8_PRIV_KEY_INFO_free(p8
);
3177 if (keyidlen
&& !PKCS12_add_localkeyid(bag
, keyid
, keyidlen
))
3179 if (label
!= NULL
&& !PKCS12_add_friendlyname(bag
, label
, label_len
))
3182 /* Start a PKCS#12 safebag container for the private key. */
3183 bag_stack
= sk_PKCS12_SAFEBAG_new_null();
3184 if (bag_stack
== NULL
)
3187 /* Pile on the private key on the bag_stack. */
3188 if (!sk_PKCS12_SAFEBAG_push(bag_stack
, bag
))
3191 key_authsafe
= PKCS12_pack_p7data(bag_stack
);
3194 if (bag_stack
!= NULL
)
3195 sk_PKCS12_SAFEBAG_pop_free(bag_stack
, PKCS12_SAFEBAG_free
);
3197 return (key_authsafe
);
3201 ImportRawRSAKey(KMF_RAW_RSA_KEY
*key
)
3204 EVP_PKEY
*newkey
= NULL
;
3205 BIGNUM
*n
= NULL
, *e
= NULL
, *d
= NULL
,
3206 *p
= NULL
, *q
= NULL
,
3207 *dmp1
= NULL
, *dmq1
= NULL
, *iqmp
= NULL
;
3209 if ((rsa
= RSA_new()) == NULL
)
3212 if ((n
= BN_bin2bn(key
->mod
.val
, key
->mod
.len
, NULL
)) == NULL
)
3215 if ((e
= BN_bin2bn(key
->pubexp
.val
, key
->pubexp
.len
, NULL
)) == NULL
)
3218 if (key
->priexp
.val
!= NULL
&&
3219 (d
= BN_bin2bn(key
->priexp
.val
, key
->priexp
.len
, NULL
)) == NULL
)
3222 if (key
->prime1
.val
!= NULL
&&
3223 (p
= BN_bin2bn(key
->prime1
.val
, key
->prime1
.len
, NULL
)) == NULL
)
3226 if (key
->prime2
.val
!= NULL
&&
3227 (q
= BN_bin2bn(key
->prime2
.val
, key
->prime2
.len
, NULL
)) == NULL
)
3230 if (key
->exp1
.val
!= NULL
&&
3231 (dmp1
= BN_bin2bn(key
->exp1
.val
, key
->exp1
.len
, NULL
)) == NULL
)
3234 if (key
->exp2
.val
!= NULL
&&
3235 (dmq1
= BN_bin2bn(key
->exp2
.val
, key
->exp2
.len
, NULL
)) == NULL
)
3238 if (key
->coef
.val
!= NULL
&&
3239 (iqmp
= BN_bin2bn(key
->coef
.val
, key
->coef
.len
, NULL
)) == NULL
)
3242 if (RSA_set0_key(rsa
, n
, e
, d
) == 0)
3245 if (RSA_set0_factors(rsa
, p
, q
) == 0)
3248 if (RSA_set0_crt_params(rsa
, dmp1
, dmq1
, iqmp
) == 0)
3250 dmp1
= dmq1
= iqmp
= NULL
;
3252 if ((newkey
= EVP_PKEY_new()) == NULL
)
3255 (void) EVP_PKEY_set1_RSA(newkey
, rsa
);
3258 /* The original key must be freed once here or it leaks memory */
3274 ImportRawDSAKey(KMF_RAW_DSA_KEY
*key
)
3277 EVP_PKEY
*newkey
= NULL
;
3278 BIGNUM
*p
= NULL
, *q
= NULL
, *g
= NULL
,
3279 *priv_key
= NULL
, *pub_key
= NULL
;
3281 if ((dsa
= DSA_new()) == NULL
)
3284 if ((p
= BN_bin2bn(key
->prime
.val
, key
->prime
.len
, NULL
)) == NULL
)
3287 if ((q
= BN_bin2bn(key
->subprime
.val
, key
->subprime
.len
, NULL
)) == NULL
)
3290 if ((g
= BN_bin2bn(key
->base
.val
, key
->base
.len
, NULL
)) == NULL
)
3293 if ((priv_key
= BN_bin2bn(key
->value
.val
, key
->value
.len
,
3297 if (key
->pubvalue
.val
!= NULL
&& (pub_key
=
3298 BN_bin2bn(key
->pubvalue
.val
, key
->pubvalue
.len
, NULL
)) == NULL
)
3301 if (DSA_set0_pqg(dsa
, p
, q
, g
) == 0)
3304 if (DSA_set0_key(dsa
, pub_key
, priv_key
) == 0)
3306 pub_key
= priv_key
= 0;
3308 if ((newkey
= EVP_PKEY_new()) == NULL
)
3311 (void) EVP_PKEY_set1_DSA(newkey
, dsa
);
3314 /* The original key must be freed once here or it leaks memory */
3327 raw_key_to_pkey(KMF_KEY_HANDLE
*key
)
3329 EVP_PKEY
*pkey
= NULL
;
3330 KMF_RAW_KEY_DATA
*rawkey
;
3331 ASN1_TYPE
*attr
= NULL
;
3334 if (key
== NULL
|| !key
->israw
)
3337 rawkey
= (KMF_RAW_KEY_DATA
*)key
->keyp
;
3338 if (rawkey
->keytype
== KMF_RSA
) {
3339 pkey
= ImportRawRSAKey(&rawkey
->rawdata
.rsa
);
3340 } else if (rawkey
->keytype
== KMF_DSA
) {
3341 pkey
= ImportRawDSAKey(&rawkey
->rawdata
.dsa
);
3342 } else if (rawkey
->keytype
== KMF_ECDSA
) {
3344 * OpenSSL in Solaris does not support EC for
3349 /* wrong kind of key */
3353 if (rawkey
->label
!= NULL
) {
3354 if ((attr
= ASN1_TYPE_new()) == NULL
) {
3355 EVP_PKEY_free(pkey
);
3358 attr
->value
.bmpstring
= ASN1_STRING_type_new(V_ASN1_BMPSTRING
);
3359 (void) ASN1_STRING_set(attr
->value
.bmpstring
, rawkey
->label
,
3360 strlen(rawkey
->label
));
3361 attr
->type
= V_ASN1_BMPSTRING
;
3362 attr
->value
.ptr
= (char *)attr
->value
.bmpstring
;
3363 ret
= set_pkey_attrib(pkey
, attr
, NID_friendlyName
);
3364 if (ret
!= KMF_OK
) {
3365 EVP_PKEY_free(pkey
);
3366 ASN1_TYPE_free(attr
);
3370 if (rawkey
->id
.Data
!= NULL
) {
3371 if ((attr
= ASN1_TYPE_new()) == NULL
) {
3372 EVP_PKEY_free(pkey
);
3375 attr
->value
.octet_string
=
3376 ASN1_STRING_type_new(V_ASN1_OCTET_STRING
);
3377 attr
->type
= V_ASN1_OCTET_STRING
;
3378 (void) ASN1_STRING_set(attr
->value
.octet_string
,
3379 rawkey
->id
.Data
, rawkey
->id
.Length
);
3380 attr
->value
.ptr
= (char *)attr
->value
.octet_string
;
3381 ret
= set_pkey_attrib(pkey
, attr
, NID_localKeyID
);
3382 if (ret
!= KMF_OK
) {
3383 EVP_PKEY_free(pkey
);
3384 ASN1_TYPE_free(attr
);
3392 * Search a list of private keys to find one that goes with the certificate.
3395 find_matching_key(X509
*xcert
, int numkeys
, KMF_KEY_HANDLE
*keylist
)
3398 EVP_PKEY
*pkey
= NULL
;
3400 if (numkeys
== 0 || keylist
== NULL
|| xcert
== NULL
)
3402 for (i
= 0; i
< numkeys
; i
++) {
3403 if (keylist
[i
].israw
)
3404 pkey
= raw_key_to_pkey(&keylist
[i
]);
3406 pkey
= (EVP_PKEY
*)keylist
[i
].keyp
;
3408 if (X509_check_private_key(xcert
, pkey
)) {
3411 EVP_PKEY_free(pkey
);
3420 local_export_pk12(KMF_HANDLE_T handle
,
3421 KMF_CREDENTIAL
*cred
,
3422 int numcerts
, KMF_X509_DER_CERT
*certlist
,
3423 int numkeys
, KMF_KEY_HANDLE
*keylist
,
3426 KMF_RETURN rv
= KMF_OK
;
3427 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
3429 PKCS7
*cert_authsafe
= NULL
;
3430 PKCS7
*key_authsafe
= NULL
;
3431 STACK_OF(PKCS7
) *authsafe_stack
= NULL
;
3432 PKCS12
*p12_elem
= NULL
;
3435 if (numcerts
== 0 && numkeys
== 0)
3436 return (KMF_ERR_BAD_PARAMETER
);
3439 * Open the output file.
3441 if ((bio
= BIO_new_file(filename
, "wb")) == NULL
) {
3442 SET_ERROR(kmfh
, ERR_get_error());
3443 rv
= KMF_ERR_OPEN_FILE
;
3447 /* Start a PKCS#7 stack. */
3448 authsafe_stack
= sk_PKCS7_new_null();
3449 if (authsafe_stack
== NULL
) {
3450 rv
= KMF_ERR_MEMORY
;
3454 for (i
= 0; rv
== KMF_OK
&& i
< numcerts
; i
++) {
3455 const uchar_t
*p
= certlist
[i
].certificate
.Data
;
3456 long len
= certlist
[i
].certificate
.Length
;
3458 EVP_PKEY
*pkey
= NULL
;
3459 unsigned char keyid
[EVP_MAX_MD_SIZE
];
3460 unsigned int keyidlen
= 0;
3462 xcert
= d2i_X509(NULL
, &p
, len
);
3463 if (xcert
== NULL
) {
3464 SET_ERROR(kmfh
, ERR_get_error());
3465 rv
= KMF_ERR_ENCODING
;
3467 if (certlist
[i
].kmf_private
.label
!= NULL
) {
3468 /* Set alias attribute */
3469 (void) X509_alias_set1(xcert
,
3470 (uchar_t
*)certlist
[i
].kmf_private
.label
,
3471 strlen(certlist
[i
].kmf_private
.label
));
3473 /* Check if there is a key corresponding to this cert */
3474 pkey
= find_matching_key(xcert
, numkeys
, keylist
);
3477 * If key is found, get fingerprint and create a
3481 (void) X509_digest(xcert
, EVP_sha1(),
3483 key_authsafe
= add_key_to_safe(pkey
, cred
,
3485 certlist
[i
].kmf_private
.label
,
3486 (certlist
[i
].kmf_private
.label
?
3487 strlen(certlist
[i
].kmf_private
.label
) : 0));
3489 if (key_authsafe
== NULL
) {
3491 EVP_PKEY_free(pkey
);
3494 /* Put the key safe into the Auth Safe */
3495 if (!sk_PKCS7_push(authsafe_stack
,
3498 EVP_PKEY_free(pkey
);
3503 /* create a certificate safebag */
3504 cert_authsafe
= add_cert_to_safe(xcert
, cred
, keyid
,
3506 if (cert_authsafe
== NULL
) {
3508 EVP_PKEY_free(pkey
);
3511 if (!sk_PKCS7_push(authsafe_stack
, cert_authsafe
)) {
3513 EVP_PKEY_free(pkey
);
3519 EVP_PKEY_free(pkey
);
3521 } else if (numcerts
== 0 && numkeys
> 0) {
3523 * If only adding keys to the file.
3525 for (i
= 0; i
< numkeys
; i
++) {
3526 EVP_PKEY
*pkey
= NULL
;
3528 if (keylist
[i
].israw
)
3529 pkey
= raw_key_to_pkey(&keylist
[i
]);
3531 pkey
= (EVP_PKEY
*)keylist
[i
].keyp
;
3536 key_authsafe
= add_key_to_safe(pkey
, cred
,
3539 if (key_authsafe
== NULL
) {
3540 EVP_PKEY_free(pkey
);
3543 if (!sk_PKCS7_push(authsafe_stack
, key_authsafe
)) {
3544 EVP_PKEY_free(pkey
);
3549 p12_elem
= PKCS12_init(NID_pkcs7_data
);
3550 if (p12_elem
== NULL
) {
3554 /* Put the PKCS#7 stack into the PKCS#12 element. */
3555 if (!PKCS12_pack_authsafes(p12_elem
, authsafe_stack
)) {
3559 /* Set the integrity MAC on the PKCS#12 element. */
3560 if (!PKCS12_set_mac(p12_elem
, cred
->cred
, cred
->credlen
,
3561 NULL
, 0, PKCS12_DEFAULT_ITER
, NULL
)) {
3565 /* Write the PKCS#12 element to the export file. */
3566 if (!i2d_PKCS12_bio(bio
, p12_elem
)) {
3569 PKCS12_free(p12_elem
);
3572 /* Clear away the PKCS#7 stack, we're done with it. */
3574 sk_PKCS7_pop_free(authsafe_stack
, PKCS7_free
);
3577 (void) BIO_free_all(bio
);
3583 openssl_build_pk12(KMF_HANDLE_T handle
, int numcerts
,
3584 KMF_X509_DER_CERT
*certlist
, int numkeys
, KMF_KEY_HANDLE
*keylist
,
3585 KMF_CREDENTIAL
*p12cred
, char *filename
)
3589 if (certlist
== NULL
&& keylist
== NULL
)
3590 return (KMF_ERR_BAD_PARAMETER
);
3592 rv
= local_export_pk12(handle
, p12cred
, numcerts
, certlist
,
3593 numkeys
, keylist
, filename
);
3599 OpenSSL_ExportPK12(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
3602 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
3603 char *fullpath
= NULL
;
3604 char *dirpath
= NULL
;
3605 char *certfile
= NULL
;
3606 char *keyfile
= NULL
;
3607 char *filename
= NULL
;
3608 KMF_CREDENTIAL
*p12cred
= NULL
;
3609 KMF_X509_DER_CERT certdata
;
3615 return (KMF_ERR_BAD_PARAMETER
);
3618 * First, find the certificate.
3620 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
3621 certfile
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
, numattr
);
3622 if (certfile
!= NULL
) {
3623 fullpath
= get_fullpath(dirpath
, certfile
);
3624 if (fullpath
== NULL
)
3625 return (KMF_ERR_BAD_PARAMETER
);
3627 if (isdir(fullpath
)) {
3629 return (KMF_ERR_AMBIGUOUS_PATHNAME
);
3632 (void) memset(&certdata
, 0, sizeof (certdata
));
3633 rv
= kmf_load_cert(kmfh
, NULL
, NULL
, NULL
, NULL
,
3634 fullpath
, &certdata
.certificate
);
3639 certdata
.kmf_private
.keystore_type
= KMF_KEYSTORE_OPENSSL
;
3644 * Now find the private key.
3646 keyfile
= kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
, attrlist
, numattr
);
3647 if (keyfile
!= NULL
) {
3648 fullpath
= get_fullpath(dirpath
, keyfile
);
3649 if (fullpath
== NULL
)
3650 return (KMF_ERR_BAD_PARAMETER
);
3652 if (isdir(fullpath
)) {
3654 return (KMF_ERR_AMBIGUOUS_PATHNAME
);
3657 (void) memset(&key
, 0, sizeof (KMF_KEY_HANDLE
));
3658 rv
= fetch_key(handle
, fullpath
, KMF_ASYM_PRI
, &key
);
3665 * Open the output file.
3667 filename
= kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR
, attrlist
,
3669 if (filename
== NULL
) {
3670 rv
= KMF_ERR_BAD_PARAMETER
;
3674 /* Stick the key and the cert into a PKCS#12 file */
3675 p12cred
= kmf_get_attr_ptr(KMF_PK12CRED_ATTR
, attrlist
, numattr
);
3676 if (p12cred
== NULL
) {
3677 rv
= KMF_ERR_BAD_PARAMETER
;
3681 rv
= local_export_pk12(handle
, p12cred
, 1, &certdata
,
3689 kmf_free_kmf_cert(handle
, &certdata
);
3691 kmf_free_kmf_key(handle
, &key
);
3696 * Helper function to extract keys and certificates from
3697 * a single PEM file. Typically the file should contain a
3698 * private key and an associated public key wrapped in an x509 cert.
3699 * However, the file may be just a list of X509 certs with no keys.
3702 extract_pem(KMF_HANDLE
*kmfh
,
3703 char *issuer
, char *subject
, KMF_BIGINT
*serial
,
3704 char *filename
, CK_UTF8CHAR
*pin
,
3705 CK_ULONG pinlen
, EVP_PKEY
**priv_key
, KMF_DATA
**certs
,
3709 KMF_RETURN rv
= KMF_OK
;
3711 STACK_OF(X509_INFO
) *x509_info_stack
= NULL
;
3712 int i
, ncerts
= 0, matchcerts
= 0;
3713 EVP_PKEY
*pkey
= NULL
;
3716 X509_INFO
**cert_infos
= NULL
;
3717 KMF_DATA
*certlist
= NULL
;
3723 fp
= fopen(filename
, "r");
3725 return (KMF_ERR_OPEN_FILE
);
3727 x509_info_stack
= PEM_X509_INFO_read(fp
, NULL
, NULL
, pin
);
3728 if (x509_info_stack
== NULL
) {
3730 return (KMF_ERR_ENCODING
);
3732 cert_infos
= (X509_INFO
**)malloc(sk_X509_INFO_num(x509_info_stack
) *
3733 sizeof (X509_INFO
*));
3734 if (cert_infos
== NULL
) {
3736 rv
= KMF_ERR_MEMORY
;
3740 for (i
= 0; i
< sk_X509_INFO_num(x509_info_stack
); i
++) {
3741 /* LINTED E_BAD_PTR_CAST_ALIGN */
3742 cert_infos
[ncerts
] = sk_X509_INFO_value(x509_info_stack
, i
);
3748 rv
= KMF_ERR_CERT_NOT_FOUND
;
3752 if (priv_key
!= NULL
) {
3754 pkey
= PEM_read_PrivateKey(fp
, NULL
, NULL
, pin
);
3758 x
= cert_infos
[ncerts
- 1]->x509
;
3760 * Make sure the private key matchs the last cert in the file.
3762 if (pkey
!= NULL
&& !X509_check_private_key(x
, pkey
)) {
3763 EVP_PKEY_free(pkey
);
3764 rv
= KMF_ERR_KEY_MISMATCH
;
3768 certlist
= (KMF_DATA
*)calloc(ncerts
, sizeof (KMF_DATA
));
3769 if (certlist
== NULL
) {
3771 EVP_PKEY_free(pkey
);
3772 rv
= KMF_ERR_MEMORY
;
3777 * Convert all of the certs to DER format.
3780 for (i
= 0; rv
== KMF_OK
&& certs
!= NULL
&& i
< ncerts
; i
++) {
3781 boolean_t match
= FALSE
;
3782 info
= cert_infos
[ncerts
- 1 - i
];
3784 rv
= check_cert(info
->x509
, issuer
, subject
, serial
, &match
);
3785 if (rv
!= KMF_OK
|| match
!= TRUE
) {
3790 rv
= ssl_cert2KMFDATA(kmfh
, info
->x509
,
3791 &certlist
[matchcerts
++]);
3795 for (j
= 0; j
< matchcerts
; j
++)
3796 kmf_free_data(&certlist
[j
]);
3799 ncerts
= matchcerts
= 0;
3803 if (numcerts
!= NULL
)
3804 *numcerts
= matchcerts
;
3808 else if (certlist
!= NULL
) {
3809 for (i
= 0; i
< ncerts
; i
++)
3810 kmf_free_data(&certlist
[i
]);
3815 if (priv_key
== NULL
&& pkey
!= NULL
)
3816 EVP_PKEY_free(pkey
);
3817 else if (priv_key
!= NULL
&& pkey
!= NULL
)
3821 /* Cleanup the stack of X509 info records */
3822 for (i
= 0; i
< sk_X509_INFO_num(x509_info_stack
); i
++) {
3823 /* LINTED E_BAD_PTR_CAST_ALIGN */
3824 info
= (X509_INFO
*)sk_X509_INFO_value(x509_info_stack
, i
);
3825 X509_INFO_free(info
);
3827 if (x509_info_stack
)
3828 sk_X509_INFO_free(x509_info_stack
);
3830 if (cert_infos
!= NULL
)
3837 openssl_parse_bags(const STACK_OF(PKCS12_SAFEBAG
) *bags
, char *pin
,
3838 STACK_OF(EVP_PKEY
) *keys
, STACK_OF(X509
) *certs
)
3843 for (i
= 0; i
< sk_PKCS12_SAFEBAG_num(bags
); i
++) {
3844 /* LINTED E_BAD_PTR_CAST_ALIGN */
3845 PKCS12_SAFEBAG
*bag
= sk_PKCS12_SAFEBAG_value(bags
, i
);
3846 ret
= openssl_parse_bag(bag
, pin
, (pin
? strlen(pin
) : 0),
3857 set_pkey_attrib(EVP_PKEY
*pkey
, ASN1_TYPE
*attrib
, int nid
)
3859 X509_ATTRIBUTE
*attr
= NULL
;
3861 if (pkey
== NULL
|| attrib
== NULL
)
3862 return (KMF_ERR_BAD_PARAMETER
);
3864 attr
= X509_ATTRIBUTE_create(nid
, attrib
->type
, attrib
->value
.ptr
);
3868 if ((i
= EVP_PKEY_get_attr_by_NID(pkey
, nid
, -1)) != -1)
3869 (void) EVP_PKEY_delete_attr(pkey
, i
);
3870 if (EVP_PKEY_add1_attr(pkey
, attr
) == 0) {
3871 X509_ATTRIBUTE_free(attr
);
3872 return (KMF_ERR_MEMORY
);
3875 return (KMF_ERR_MEMORY
);
3882 openssl_parse_bag(PKCS12_SAFEBAG
*bag
, char *pass
, int passlen
,
3883 STACK_OF(EVP_PKEY
) *keylist
, STACK_OF(X509
) *certlist
)
3885 KMF_RETURN ret
= KMF_OK
;
3886 PKCS8_PRIV_KEY_INFO
*p8
= NULL
;
3887 EVP_PKEY
*pkey
= NULL
;
3889 const ASN1_TYPE
*keyid
= NULL
;
3890 const ASN1_TYPE
*fname
= NULL
;
3891 uchar_t
*data
= NULL
;
3893 keyid
= PKCS12_SAFEBAG_get0_attr(bag
, NID_localKeyID
);
3894 fname
= PKCS12_SAFEBAG_get0_attr(bag
, NID_friendlyName
);
3896 switch (PKCS12_SAFEBAG_get_nid(bag
)) {
3898 if (keylist
== NULL
)
3900 pkey
= EVP_PKCS82PKEY(
3901 PKCS12_SAFEBAG_get0_p8inf(bag
));
3903 ret
= KMF_ERR_PKCS12_FORMAT
;
3906 case NID_pkcs8ShroudedKeyBag
:
3907 if (keylist
== NULL
)
3909 p8
= PKCS12_decrypt_skey(bag
, pass
, passlen
);
3911 return (KMF_ERR_AUTH_FAILED
);
3912 pkey
= EVP_PKCS82PKEY(p8
);
3913 PKCS8_PRIV_KEY_INFO_free(p8
);
3915 ret
= KMF_ERR_PKCS12_FORMAT
;
3918 if (certlist
== NULL
)
3920 if (PKCS12_SAFEBAG_get_bag_nid(bag
) !=
3921 NID_x509Certificate
)
3922 return (KMF_ERR_PKCS12_FORMAT
);
3923 xcert
= PKCS12_SAFEBAG_get1_cert(bag
);
3924 if (xcert
== NULL
) {
3925 ret
= KMF_ERR_PKCS12_FORMAT
;
3928 if (keyid
!= NULL
) {
3929 if (X509_keyid_set1(xcert
,
3930 keyid
->value
.octet_string
->data
,
3931 keyid
->value
.octet_string
->length
) == 0) {
3932 ret
= KMF_ERR_PKCS12_FORMAT
;
3936 if (fname
!= NULL
) {
3938 len
= ASN1_STRING_to_UTF8(&data
,
3939 fname
->value
.asn1_string
);
3940 if (len
> 0 && data
!= NULL
) {
3941 r
= X509_alias_set1(xcert
, data
, len
);
3943 ret
= KMF_ERR_PKCS12_FORMAT
;
3947 ret
= KMF_ERR_PKCS12_FORMAT
;
3951 if (sk_X509_push(certlist
, xcert
) == 0)
3952 ret
= KMF_ERR_MEMORY
;
3956 case NID_safeContentsBag
:
3957 return (openssl_parse_bags(
3958 PKCS12_SAFEBAG_get0_safes(bag
),
3959 pass
, keylist
, certlist
));
3961 ret
= KMF_ERR_PKCS12_FORMAT
;
3966 * Set the ID and/or FriendlyName attributes on the key.
3967 * If converting to PKCS11 objects, these can translate to CKA_ID
3968 * and CKA_LABEL values.
3970 if (pkey
!= NULL
&& ret
== KMF_OK
) {
3971 ASN1_TYPE
*attr
= NULL
;
3972 if (keyid
!= NULL
&& keyid
->type
== V_ASN1_OCTET_STRING
) {
3973 if ((attr
= ASN1_TYPE_new()) == NULL
)
3974 return (KMF_ERR_MEMORY
);
3975 attr
->value
.octet_string
=
3976 ASN1_STRING_dup(keyid
->value
.octet_string
);
3977 attr
->type
= V_ASN1_OCTET_STRING
;
3978 attr
->value
.ptr
= (char *)attr
->value
.octet_string
;
3979 ret
= set_pkey_attrib(pkey
, attr
, NID_localKeyID
);
3983 if (ret
== KMF_OK
&& fname
!= NULL
&&
3984 fname
->type
== V_ASN1_BMPSTRING
) {
3985 if ((attr
= ASN1_TYPE_new()) == NULL
)
3986 return (KMF_ERR_MEMORY
);
3987 attr
->value
.bmpstring
=
3988 ASN1_STRING_dup(fname
->value
.bmpstring
);
3989 attr
->type
= V_ASN1_BMPSTRING
;
3990 attr
->value
.ptr
= (char *)attr
->value
.bmpstring
;
3991 ret
= set_pkey_attrib(pkey
, attr
, NID_friendlyName
);
3995 if (ret
== KMF_OK
&& keylist
!= NULL
&&
3996 sk_EVP_PKEY_push(keylist
, pkey
) == 0)
3997 ret
= KMF_ERR_MEMORY
;
3999 if (ret
== KMF_OK
&& keylist
!= NULL
)
4003 EVP_PKEY_free(pkey
);
4013 openssl_pkcs12_parse(PKCS12
*p12
, char *pin
,
4014 STACK_OF(EVP_PKEY
) *keys
,
4015 STACK_OF(X509
) *certs
,
4019 KMF_RETURN ret
= KMF_OK
;
4020 STACK_OF(PKCS7
) *asafes
= NULL
;
4021 STACK_OF(PKCS12_SAFEBAG
) *bags
= NULL
;
4025 if (p12
== NULL
|| (keys
== NULL
&& certs
== NULL
))
4026 return (KMF_ERR_BAD_PARAMETER
);
4028 if (pin
== NULL
|| *pin
== NULL
) {
4029 if (PKCS12_verify_mac(p12
, NULL
, 0)) {
4031 } else if (PKCS12_verify_mac(p12
, "", 0)) {
4034 return (KMF_ERR_AUTH_FAILED
);
4036 } else if (!PKCS12_verify_mac(p12
, pin
, -1)) {
4037 return (KMF_ERR_AUTH_FAILED
);
4040 if ((asafes
= PKCS12_unpack_authsafes(p12
)) == NULL
)
4041 return (KMF_ERR_PKCS12_FORMAT
);
4043 for (i
= 0; ret
== KMF_OK
&& i
< sk_PKCS7_num(asafes
); i
++) {
4045 /* LINTED E_BAD_PTR_CAST_ALIGN */
4046 p7
= sk_PKCS7_value(asafes
, i
);
4047 bagnid
= OBJ_obj2nid(p7
->type
);
4049 if (bagnid
== NID_pkcs7_data
) {
4050 bags
= PKCS12_unpack_p7data(p7
);
4051 } else if (bagnid
== NID_pkcs7_encrypted
) {
4052 bags
= PKCS12_unpack_p7encdata(p7
, pin
,
4053 (pin
? strlen(pin
) : 0));
4058 ret
= KMF_ERR_PKCS12_FORMAT
;
4062 if (openssl_parse_bags(bags
, pin
, keys
, certs
) != KMF_OK
)
4063 ret
= KMF_ERR_PKCS12_FORMAT
;
4065 sk_PKCS12_SAFEBAG_pop_free(bags
, PKCS12_SAFEBAG_free
);
4069 sk_PKCS7_pop_free(asafes
, PKCS7_free
);
4075 * Helper function to decrypt and parse PKCS#12 import file.
4078 extract_pkcs12(BIO
*fbio
, CK_UTF8CHAR
*pin
, CK_ULONG pinlen
,
4079 STACK_OF(EVP_PKEY
) **priv_key
, STACK_OF(X509
) **certs
,
4080 STACK_OF(X509
) **ca
)
4083 PKCS12
*pk12
, *pk12_tmp
;
4084 STACK_OF(EVP_PKEY
) *pkeylist
= NULL
;
4085 STACK_OF(X509
) *xcertlist
= NULL
;
4086 STACK_OF(X509
) *cacertlist
= NULL
;
4088 if ((pk12
= PKCS12_new()) == NULL
) {
4089 return (KMF_ERR_MEMORY
);
4092 if ((pk12_tmp
= d2i_PKCS12_bio(fbio
, &pk12
)) == NULL
) {
4093 /* This is ok; it seems to mean there is no more to read. */
4094 if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_ASN1
&&
4095 ERR_GET_REASON(ERR_peek_error()) == ASN1_R_HEADER_TOO_LONG
)
4096 goto end_extract_pkcs12
;
4099 return (KMF_ERR_PKCS12_FORMAT
);
4103 xcertlist
= sk_X509_new_null();
4104 if (xcertlist
== NULL
) {
4106 return (KMF_ERR_MEMORY
);
4108 pkeylist
= sk_EVP_PKEY_new_null();
4109 if (pkeylist
== NULL
) {
4110 sk_X509_pop_free(xcertlist
, X509_free
);
4112 return (KMF_ERR_MEMORY
);
4115 if (openssl_pkcs12_parse(pk12
, (char *)pin
, pkeylist
, xcertlist
,
4116 cacertlist
) != KMF_OK
) {
4117 sk_X509_pop_free(xcertlist
, X509_free
);
4118 sk_EVP_PKEY_pop_free(pkeylist
, EVP_PKEY_free
);
4120 return (KMF_ERR_PKCS12_FORMAT
);
4123 if (priv_key
&& pkeylist
)
4124 *priv_key
= pkeylist
;
4126 sk_EVP_PKEY_pop_free(pkeylist
, EVP_PKEY_free
);
4127 if (certs
&& xcertlist
)
4130 sk_X509_pop_free(xcertlist
, X509_free
);
4131 if (ca
&& cacertlist
)
4133 else if (cacertlist
)
4134 sk_X509_pop_free(cacertlist
, X509_free
);
4143 sslBN2KMFBN(BIGNUM
*from
, KMF_BIGINT
*to
)
4145 KMF_RETURN rv
= KMF_OK
;
4148 sz
= BN_num_bytes(from
);
4149 to
->val
= (uchar_t
*)malloc(sz
);
4150 if (to
->val
== NULL
)
4151 return (KMF_ERR_MEMORY
);
4153 if ((to
->len
= BN_bn2bin(from
, to
->val
)) != sz
) {
4157 rv
= KMF_ERR_MEMORY
;
4164 exportRawRSAKey(RSA
*rsa
, KMF_RAW_KEY_DATA
*key
)
4167 KMF_RAW_RSA_KEY
*kmfkey
= &key
->rawdata
.rsa
;
4169 const BIGNUM
*n
, *e
, *d
, *p
, *q
, *dmp1
, *dmpq
, *iqmp
;
4171 RSA_get0_key(rsa
, &n
, &e
, &d
);
4172 RSA_get0_factors(rsa
, &p
, &q
);
4173 RSA_get0_crt_params(rsa
, &dmp1
, &dmpq
, &iqmp
);
4175 (void) memset(kmfkey
, 0, sizeof (KMF_RAW_RSA_KEY
));
4176 if ((rv
= sslBN2KMFBN((BIGNUM
*)n
, &kmfkey
->mod
)) != KMF_OK
)
4179 if ((rv
= sslBN2KMFBN((BIGNUM
*)e
, &kmfkey
->pubexp
)) != KMF_OK
)
4183 if ((rv
= sslBN2KMFBN((BIGNUM
*)d
, &kmfkey
->priexp
)) != KMF_OK
)
4187 if ((rv
= sslBN2KMFBN((BIGNUM
*)p
, &kmfkey
->prime1
)) != KMF_OK
)
4191 if ((rv
= sslBN2KMFBN((BIGNUM
*)q
, &kmfkey
->prime2
)) != KMF_OK
)
4195 if ((rv
= sslBN2KMFBN((BIGNUM
*)dmp1
, &kmfkey
->exp1
)) != KMF_OK
)
4199 if ((rv
= sslBN2KMFBN((BIGNUM
*)dmpq
, &kmfkey
->exp2
)) != KMF_OK
)
4203 if ((rv
= sslBN2KMFBN((BIGNUM
*)iqmp
, &kmfkey
->coef
)) != KMF_OK
)
4207 kmf_free_raw_key(key
);
4209 key
->keytype
= KMF_RSA
;
4212 * Free the reference to this key, SSL will not actually free
4213 * the memory until the refcount == 0, so this is safe.
4221 exportRawDSAKey(DSA
*dsa
, KMF_RAW_KEY_DATA
*key
)
4224 KMF_RAW_DSA_KEY
*kmfkey
= &key
->rawdata
.dsa
;
4225 const BIGNUM
*p
, *q
, *g
, *priv_key
;
4227 DSA_get0_pqg(dsa
, &p
, &q
, &g
);
4228 DSA_get0_key(dsa
, NULL
, &priv_key
);
4230 (void) memset(kmfkey
, 0, sizeof (KMF_RAW_DSA_KEY
));
4231 if ((rv
= sslBN2KMFBN((BIGNUM
*)p
, &kmfkey
->prime
)) != KMF_OK
)
4234 if ((rv
= sslBN2KMFBN((BIGNUM
*)q
, &kmfkey
->subprime
)) != KMF_OK
)
4237 if ((rv
= sslBN2KMFBN((BIGNUM
*)g
, &kmfkey
->base
)) != KMF_OK
)
4240 if ((rv
= sslBN2KMFBN((BIGNUM
*)priv_key
, &kmfkey
->value
)) != KMF_OK
)
4245 kmf_free_raw_key(key
);
4247 key
->keytype
= KMF_DSA
;
4250 * Free the reference to this key, SSL will not actually free
4251 * the memory until the refcount == 0, so this is safe.
4259 add_cert_to_list(KMF_HANDLE
*kmfh
, X509
*sslcert
,
4260 KMF_X509_DER_CERT
**certlist
, int *ncerts
)
4262 KMF_RETURN rv
= KMF_OK
;
4263 KMF_X509_DER_CERT
*list
= (*certlist
);
4264 KMF_X509_DER_CERT cert
;
4268 list
= (KMF_X509_DER_CERT
*)malloc(sizeof (KMF_X509_DER_CERT
));
4270 list
= (KMF_X509_DER_CERT
*)realloc(list
,
4271 sizeof (KMF_X509_DER_CERT
) * (n
+ 1));
4275 return (KMF_ERR_MEMORY
);
4277 (void) memset(&cert
, 0, sizeof (cert
));
4278 rv
= ssl_cert2KMFDATA(kmfh
, sslcert
, &cert
.certificate
);
4281 /* Get the alias name for the cert if there is one */
4282 char *a
= (char *)X509_alias_get0(sslcert
, &len
);
4284 cert
.kmf_private
.label
= strdup(a
);
4285 cert
.kmf_private
.keystore_type
= KMF_KEYSTORE_OPENSSL
;
4299 add_key_to_list(KMF_RAW_KEY_DATA
**keylist
,
4300 KMF_RAW_KEY_DATA
*newkey
, int *nkeys
)
4302 KMF_RAW_KEY_DATA
*list
= (*keylist
);
4306 list
= (KMF_RAW_KEY_DATA
*)malloc(sizeof (KMF_RAW_KEY_DATA
));
4308 list
= (KMF_RAW_KEY_DATA
*)realloc(list
,
4309 sizeof (KMF_RAW_KEY_DATA
) * (n
+ 1));
4313 return (KMF_ERR_MEMORY
);
4324 convertToRawKey(EVP_PKEY
*pkey
, KMF_RAW_KEY_DATA
*key
)
4326 KMF_RETURN rv
= KMF_OK
;
4327 X509_ATTRIBUTE
*attr
;
4332 if (pkey
== NULL
|| key
== NULL
)
4333 return (KMF_ERR_BAD_PARAMETER
);
4334 /* Convert SSL key to raw key */
4335 if ((rsa
= EVP_PKEY_get1_RSA(pkey
)) != NULL
) {
4336 rv
= exportRawRSAKey(rsa
, key
);
4339 } else if ((dsa
= EVP_PKEY_get1_DSA(pkey
)) != NULL
) {
4340 rv
= exportRawDSAKey(dsa
, key
);
4344 return (KMF_ERR_BAD_PARAMETER
);
4347 * If friendlyName, add it to record.
4350 if ((loc
= EVP_PKEY_get_attr_by_NID(pkey
,
4351 NID_friendlyName
, -1)) != -1 &&
4352 (attr
= EVP_PKEY_get_attr(pkey
, loc
))) {
4353 ASN1_TYPE
*ty
= NULL
;
4354 int numattr
= X509_ATTRIBUTE_count(attr
);
4356 ty
= X509_ATTRIBUTE_get0_type(attr
, 0);
4359 key
->label
= OPENSSL_uni2asc(ty
->value
.bmpstring
->data
,
4360 ty
->value
.bmpstring
->length
);
4367 * If KeyID, add it to record as a KMF_DATA object.
4369 if ((loc
= EVP_PKEY_get_attr_by_NID(pkey
,
4370 NID_localKeyID
, -1)) != -1 &&
4371 (attr
= EVP_PKEY_get_attr(pkey
, loc
)) != NULL
) {
4372 ASN1_TYPE
*ty
= NULL
;
4373 int numattr
= X509_ATTRIBUTE_count(attr
);
4375 ty
= X509_ATTRIBUTE_get0_type(attr
, 0);
4376 key
->id
.Data
= (uchar_t
*)malloc(
4377 ty
->value
.octet_string
->length
);
4378 if (key
->id
.Data
== NULL
)
4379 return (KMF_ERR_MEMORY
);
4380 (void) memcpy(key
->id
.Data
, ty
->value
.octet_string
->data
,
4381 ty
->value
.octet_string
->length
);
4382 key
->id
.Length
= ty
->value
.octet_string
->length
;
4384 (void) memset(&key
->id
, 0, sizeof (KMF_DATA
));
4393 STACK_OF(EVP_PKEY
) *sslkeys
,
4394 STACK_OF(X509
) *sslcert
,
4395 STACK_OF(X509
) *sslcacerts
,
4396 KMF_RAW_KEY_DATA
**keylist
, int *nkeys
,
4397 KMF_X509_DER_CERT
**certlist
, int *ncerts
)
4399 KMF_RETURN rv
= KMF_OK
;
4400 KMF_RAW_KEY_DATA key
;
4403 for (i
= 0; sslkeys
!= NULL
&& i
< sk_EVP_PKEY_num(sslkeys
); i
++) {
4404 /* LINTED E_BAD_PTR_CAST_ALIGN */
4405 EVP_PKEY
*pkey
= sk_EVP_PKEY_value(sslkeys
, i
);
4406 rv
= convertToRawKey(pkey
, &key
);
4408 rv
= add_key_to_list(keylist
, &key
, nkeys
);
4414 /* Now add the certificate to the certlist */
4415 for (i
= 0; sslcert
!= NULL
&& i
< sk_X509_num(sslcert
); i
++) {
4416 /* LINTED E_BAD_PTR_CAST_ALIGN */
4417 X509
*cert
= sk_X509_value(sslcert
, i
);
4418 rv
= add_cert_to_list(kmfh
, cert
, certlist
, ncerts
);
4423 /* Also add any included CA certs to the list */
4424 for (i
= 0; sslcacerts
!= NULL
&& i
< sk_X509_num(sslcacerts
); i
++) {
4427 * sk_X509_value() is macro that embeds a cast to (X509 *).
4428 * Here it translates into ((X509 *)sk_value((ca), (i))).
4429 * Lint is complaining about the embedded casting, and
4430 * to fix it, you need to fix openssl header files.
4432 /* LINTED E_BAD_PTR_CAST_ALIGN */
4433 c
= sk_X509_value(sslcacerts
, i
);
4435 /* Now add the ca cert to the certlist */
4436 rv
= add_cert_to_list(kmfh
, c
, certlist
, ncerts
);
4444 openssl_import_objects(KMF_HANDLE
*kmfh
,
4445 char *filename
, KMF_CREDENTIAL
*cred
,
4446 KMF_X509_DER_CERT
**certlist
, int *ncerts
,
4447 KMF_RAW_KEY_DATA
**keylist
, int *nkeys
)
4449 KMF_RETURN rv
= KMF_OK
;
4450 KMF_ENCODE_FORMAT format
;
4452 STACK_OF(EVP_PKEY
) *privkeys
= NULL
;
4453 STACK_OF(X509
) *certs
= NULL
;
4454 STACK_OF(X509
) *cacerts
= NULL
;
4457 * auto-detect the file format, regardless of what
4458 * the 'format' parameters in the params say.
4460 rv
= kmf_get_file_format(filename
, &format
);
4465 /* This function only works for PEM or PKCS#12 files */
4466 if (format
!= KMF_FORMAT_PEM
&&
4467 format
!= KMF_FORMAT_PEM_KEYPAIR
&&
4468 format
!= KMF_FORMAT_PKCS12
)
4469 return (KMF_ERR_ENCODING
);
4476 if (format
== KMF_FORMAT_PKCS12
) {
4477 bio
= BIO_new_file(filename
, "rb");
4479 SET_ERROR(kmfh
, ERR_get_error());
4480 rv
= KMF_ERR_OPEN_FILE
;
4484 rv
= extract_pkcs12(bio
, (uchar_t
*)cred
->cred
,
4485 (uint32_t)cred
->credlen
, &privkeys
, &certs
, &cacerts
);
4488 /* Convert keys and certs to exportable format */
4489 rv
= convertPK12Objects(kmfh
, privkeys
, certs
, cacerts
,
4490 keylist
, nkeys
, certlist
, ncerts
);
4493 KMF_DATA
*certdata
= NULL
;
4494 KMF_X509_DER_CERT
*kmfcerts
= NULL
;
4496 rv
= extract_pem(kmfh
, NULL
, NULL
, NULL
, filename
,
4497 (uchar_t
*)cred
->cred
, (uint32_t)cred
->credlen
,
4498 &pkey
, &certdata
, ncerts
);
4500 /* Reached end of import file? */
4501 if (rv
== KMF_OK
&& pkey
!= NULL
) {
4502 privkeys
= sk_EVP_PKEY_new_null();
4503 if (privkeys
== NULL
) {
4504 rv
= KMF_ERR_MEMORY
;
4507 (void) sk_EVP_PKEY_push(privkeys
, pkey
);
4508 /* convert the certificate list here */
4509 if (*ncerts
> 0 && certlist
!= NULL
) {
4510 kmfcerts
= (KMF_X509_DER_CERT
*)calloc(*ncerts
,
4511 sizeof (KMF_X509_DER_CERT
));
4512 if (kmfcerts
== NULL
) {
4513 rv
= KMF_ERR_MEMORY
;
4516 for (i
= 0; i
< *ncerts
; i
++) {
4517 kmfcerts
[i
].certificate
= certdata
[i
];
4518 kmfcerts
[i
].kmf_private
.keystore_type
=
4519 KMF_KEYSTORE_OPENSSL
;
4521 *certlist
= kmfcerts
;
4524 * Convert keys to exportable format, the certs
4527 rv
= convertPK12Objects(kmfh
, privkeys
, NULL
, NULL
,
4528 keylist
, nkeys
, NULL
, NULL
);
4533 (void) BIO_free(bio
);
4536 sk_EVP_PKEY_pop_free(privkeys
, EVP_PKEY_free
);
4538 sk_X509_pop_free(certs
, X509_free
);
4540 sk_X509_pop_free(cacerts
, X509_free
);
4546 create_deskey(DES_cblock
**deskey
)
4550 key
= (DES_cblock
*) malloc(sizeof (DES_cblock
));
4552 return (KMF_ERR_MEMORY
);
4555 if (DES_random_key(key
) == 0) {
4557 return (KMF_ERR_KEYGEN_FAILED
);
4564 #define KEYGEN_RETRY 3
4565 #define DES3_KEY_SIZE 24
4568 create_des3key(unsigned char **des3key
)
4570 KMF_RETURN ret
= KMF_OK
;
4571 DES_cblock
*deskey1
= NULL
;
4572 DES_cblock
*deskey2
= NULL
;
4573 DES_cblock
*deskey3
= NULL
;
4574 unsigned char *newkey
= NULL
;
4577 if ((newkey
= malloc(DES3_KEY_SIZE
)) == NULL
) {
4578 return (KMF_ERR_MEMORY
);
4581 /* create the 1st DES key */
4582 if ((ret
= create_deskey(&deskey1
)) != KMF_OK
) {
4587 * Create the 2nd DES key and make sure its value is different
4588 * from the 1st DES key.
4592 if (deskey2
!= NULL
) {
4597 if ((ret
= create_deskey(&deskey2
)) != KMF_OK
) {
4601 if (memcmp((const void *) deskey1
, (const void *) deskey2
, 8)
4603 ret
= KMF_ERR_KEYGEN_FAILED
;
4606 } while (ret
== KMF_ERR_KEYGEN_FAILED
&& retry
< KEYGEN_RETRY
);
4608 if (ret
!= KMF_OK
) {
4613 * Create the 3rd DES key and make sure its value is different
4614 * from the 2nd DES key.
4618 if (deskey3
!= NULL
) {
4623 if ((ret
= create_deskey(&deskey3
)) != KMF_OK
) {
4627 if (memcmp((const void *)deskey2
, (const void *)deskey3
, 8)
4629 ret
= KMF_ERR_KEYGEN_FAILED
;
4632 } while (ret
== KMF_ERR_KEYGEN_FAILED
&& retry
< KEYGEN_RETRY
);
4634 if (ret
!= KMF_OK
) {
4638 /* Concatenate 3 DES keys into a DES3 key */
4639 (void) memcpy((void *)newkey
, (const void *)deskey1
, 8);
4640 (void) memcpy((void *)(newkey
+ 8), (const void *)deskey2
, 8);
4641 (void) memcpy((void *)(newkey
+ 16), (const void *)deskey3
, 8);
4645 if (deskey1
!= NULL
)
4648 if (deskey2
!= NULL
)
4651 if (deskey3
!= NULL
)
4654 if (ret
!= KMF_OK
&& newkey
!= NULL
)
4661 OpenSSL_CreateSymKey(KMF_HANDLE_T handle
,
4662 int numattr
, KMF_ATTRIBUTE
*attrlist
)
4664 KMF_RETURN ret
= KMF_OK
;
4665 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
4666 char *fullpath
= NULL
;
4667 KMF_RAW_SYM_KEY
*rkey
= NULL
;
4668 DES_cblock
*deskey
= NULL
;
4669 unsigned char *des3key
= NULL
;
4670 unsigned char *random
= NULL
;
4672 KMF_KEY_HANDLE
*symkey
;
4673 KMF_KEY_ALG keytype
;
4675 uint32_t keylen_size
= sizeof (keylen
);
4680 return (KMF_ERR_UNINITIALIZED
);
4682 symkey
= kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR
, attrlist
, numattr
);
4684 return (KMF_ERR_BAD_PARAMETER
);
4686 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
4688 keyfile
= kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
, attrlist
, numattr
);
4689 if (keyfile
== NULL
)
4690 return (KMF_ERR_BAD_PARAMETER
);
4692 ret
= kmf_get_attr(KMF_KEYALG_ATTR
, attrlist
, numattr
,
4693 (void *)&keytype
, NULL
);
4695 return (KMF_ERR_BAD_PARAMETER
);
4697 ret
= kmf_get_attr(KMF_KEYLENGTH_ATTR
, attrlist
, numattr
,
4698 &keylen
, &keylen_size
);
4699 if (ret
== KMF_ERR_ATTR_NOT_FOUND
&&
4700 (keytype
== KMF_DES
|| keytype
== KMF_DES3
))
4701 /* keylength is not required for DES and 3DES */
4704 return (KMF_ERR_BAD_PARAMETER
);
4706 fullpath
= get_fullpath(dirpath
, keyfile
);
4707 if (fullpath
== NULL
)
4708 return (KMF_ERR_BAD_PARAMETER
);
4710 /* If the requested file exists, return an error */
4711 if (test_for_file(fullpath
, 0400) == 1) {
4713 return (KMF_ERR_DUPLICATE_KEYFILE
);
4716 fd
= open(fullpath
, O_CREAT
|O_TRUNC
|O_RDWR
, 0400);
4718 ret
= KMF_ERR_OPEN_FILE
;
4722 rkey
= malloc(sizeof (KMF_RAW_SYM_KEY
));
4724 ret
= KMF_ERR_MEMORY
;
4727 (void) memset(rkey
, 0, sizeof (KMF_RAW_SYM_KEY
));
4729 if (keytype
== KMF_DES
) {
4730 if ((ret
= create_deskey(&deskey
)) != KMF_OK
) {
4733 rkey
->keydata
.val
= (uchar_t
*)deskey
;
4734 rkey
->keydata
.len
= 8;
4736 symkey
->keyalg
= KMF_DES
;
4738 } else if (keytype
== KMF_DES3
) {
4739 if ((ret
= create_des3key(&des3key
)) != KMF_OK
) {
4742 rkey
->keydata
.val
= (uchar_t
*)des3key
;
4743 rkey
->keydata
.len
= DES3_KEY_SIZE
;
4744 symkey
->keyalg
= KMF_DES3
;
4746 } else if (keytype
== KMF_AES
|| keytype
== KMF_RC4
||
4747 keytype
== KMF_GENERIC_SECRET
) {
4750 if (keylen
% 8 != 0) {
4751 ret
= KMF_ERR_BAD_KEY_SIZE
;
4755 if (keytype
== KMF_AES
) {
4756 if (keylen
!= 128 &&
4759 ret
= KMF_ERR_BAD_KEY_SIZE
;
4765 random
= malloc(bytes
);
4766 if (random
== NULL
) {
4767 ret
= KMF_ERR_MEMORY
;
4770 if (RAND_bytes(random
, bytes
) != 1) {
4771 ret
= KMF_ERR_KEYGEN_FAILED
;
4775 rkey
->keydata
.val
= (uchar_t
*)random
;
4776 rkey
->keydata
.len
= bytes
;
4777 symkey
->keyalg
= keytype
;
4780 ret
= KMF_ERR_BAD_KEY_TYPE
;
4784 (void) write(fd
, (const void *) rkey
->keydata
.val
, rkey
->keydata
.len
);
4786 symkey
->kstype
= KMF_KEYSTORE_OPENSSL
;
4787 symkey
->keyclass
= KMF_SYMMETRIC
;
4788 symkey
->keylabel
= (char *)fullpath
;
4789 symkey
->israw
= TRUE
;
4790 symkey
->keyp
= rkey
;
4796 if (ret
!= KMF_OK
&& fullpath
!= NULL
) {
4799 if (ret
!= KMF_OK
) {
4800 kmf_free_raw_sym_key(rkey
);
4801 symkey
->keyp
= NULL
;
4802 symkey
->keyalg
= KMF_KEYALG_NONE
;
4809 * Check a file to see if it is a CRL file with PEM or DER format.
4810 * If success, return its format in the "pformat" argument.
4813 OpenSSL_IsCRLFile(KMF_HANDLE_T handle
, char *filename
, int *pformat
)
4815 KMF_RETURN ret
= KMF_OK
;
4816 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
4818 X509_CRL
*xcrl
= NULL
;
4820 if (filename
== NULL
) {
4821 return (KMF_ERR_BAD_PARAMETER
);
4824 bio
= BIO_new_file(filename
, "rb");
4826 SET_ERROR(kmfh
, ERR_get_error());
4827 ret
= KMF_ERR_OPEN_FILE
;
4831 if ((xcrl
= PEM_read_bio_X509_CRL(bio
, NULL
, NULL
, NULL
)) != NULL
) {
4832 *pformat
= KMF_FORMAT_PEM
;
4835 (void) BIO_free(bio
);
4838 * Now try to read it as raw DER data.
4840 bio
= BIO_new_file(filename
, "rb");
4842 SET_ERROR(kmfh
, ERR_get_error());
4843 ret
= KMF_ERR_OPEN_FILE
;
4847 if ((xcrl
= d2i_X509_CRL_bio(bio
, NULL
)) != NULL
) {
4848 *pformat
= KMF_FORMAT_ASN1
;
4850 ret
= KMF_ERR_BAD_CRLFILE
;
4855 (void) BIO_free(bio
);
4858 X509_CRL_free(xcrl
);
4864 OpenSSL_GetSymKeyValue(KMF_HANDLE_T handle
, KMF_KEY_HANDLE
*symkey
,
4865 KMF_RAW_SYM_KEY
*rkey
)
4867 KMF_RETURN rv
= KMF_OK
;
4868 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
4872 return (KMF_ERR_UNINITIALIZED
);
4874 if (symkey
== NULL
|| rkey
== NULL
)
4875 return (KMF_ERR_BAD_PARAMETER
);
4876 else if (symkey
->keyclass
!= KMF_SYMMETRIC
)
4877 return (KMF_ERR_BAD_KEY_CLASS
);
4879 if (symkey
->israw
) {
4880 KMF_RAW_SYM_KEY
*rawkey
= (KMF_RAW_SYM_KEY
*)symkey
->keyp
;
4882 if (rawkey
== NULL
||
4883 rawkey
->keydata
.val
== NULL
||
4884 rawkey
->keydata
.len
== 0)
4885 return (KMF_ERR_BAD_KEYHANDLE
);
4887 rkey
->keydata
.len
= rawkey
->keydata
.len
;
4888 if ((rkey
->keydata
.val
= malloc(rkey
->keydata
.len
)) == NULL
)
4889 return (KMF_ERR_MEMORY
);
4890 (void) memcpy(rkey
->keydata
.val
, rawkey
->keydata
.val
,
4893 rv
= kmf_read_input_file(handle
, symkey
->keylabel
, &keyvalue
);
4896 rkey
->keydata
.len
= keyvalue
.Length
;
4897 rkey
->keydata
.val
= keyvalue
.Data
;
4904 * substitute for the unsafe access(2) function.
4905 * If the file in question already exists, return 1.
4906 * else 0. If an error occurs during testing (other
4907 * than EEXIST), return -1.
4910 test_for_file(char *filename
, mode_t mode
)
4915 * Try to create the file with the EXCL flag.
4916 * The call should fail if the file exists.
4918 fd
= open(filename
, O_WRONLY
|O_CREAT
|O_EXCL
, mode
);
4919 if (fd
== -1 && errno
== EEXIST
)
4921 else if (fd
== -1) /* some other error */
4924 /* The file did NOT exist. Delete the testcase. */
4926 (void) unlink(filename
);
4931 OpenSSL_StoreKey(KMF_HANDLE_T handle
, int numattr
,
4932 KMF_ATTRIBUTE
*attrlist
)
4934 KMF_RETURN rv
= KMF_OK
;
4935 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
4936 KMF_KEY_HANDLE
*pubkey
= NULL
, *prikey
= NULL
;
4937 KMF_RAW_KEY_DATA
*rawkey
;
4938 EVP_PKEY
*pkey
= NULL
;
4939 KMF_ENCODE_FORMAT format
= KMF_FORMAT_PEM
;
4940 KMF_CREDENTIAL cred
= { NULL
, 0 };
4943 char *fullpath
= NULL
;
4944 char *keyfile
= NULL
;
4945 char *dirpath
= NULL
;
4947 pubkey
= kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR
, attrlist
, numattr
);
4951 prikey
= kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR
, attrlist
, numattr
);
4955 rawkey
= kmf_get_attr_ptr(KMF_RAW_KEY_ATTR
, attrlist
, numattr
);
4960 * Exactly 1 type of key must be passed to this function.
4963 return (KMF_ERR_BAD_PARAMETER
);
4965 keyfile
= (char *)kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
, attrlist
,
4967 if (keyfile
== NULL
)
4968 return (KMF_ERR_BAD_PARAMETER
);
4970 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
4972 fullpath
= get_fullpath(dirpath
, keyfile
);
4974 /* Once we have the full path, we don't need the pieces */
4975 if (fullpath
== NULL
)
4976 return (KMF_ERR_BAD_PARAMETER
);
4978 /* If the requested file exists, return an error */
4979 if (test_for_file(fullpath
, 0400) == 1) {
4981 return (KMF_ERR_DUPLICATE_KEYFILE
);
4984 rv
= kmf_get_attr(KMF_ENCODE_FORMAT_ATTR
, attrlist
, numattr
,
4987 /* format is optional. */
4990 /* CRED is not required for OpenSSL files */
4991 (void) kmf_get_attr(KMF_CREDENTIAL_ATTR
, attrlist
, numattr
,
4994 /* Store the private key to the keyfile */
4995 out
= BIO_new_file(fullpath
, "wb");
4997 SET_ERROR(kmfh
, ERR_get_error());
4998 rv
= KMF_ERR_OPEN_FILE
;
5002 if (prikey
!= NULL
&& prikey
->keyp
!= NULL
) {
5003 if (prikey
->keyalg
== KMF_RSA
||
5004 prikey
->keyalg
== KMF_DSA
) {
5005 pkey
= (EVP_PKEY
*)prikey
->keyp
;
5007 rv
= ssl_write_key(kmfh
, format
,
5008 out
, &cred
, pkey
, TRUE
);
5010 if (rv
== KMF_OK
&& prikey
->keylabel
== NULL
) {
5011 prikey
->keylabel
= strdup(fullpath
);
5012 if (prikey
->keylabel
== NULL
)
5013 rv
= KMF_ERR_MEMORY
;
5016 } else if (pubkey
!= NULL
&& pubkey
->keyp
!= NULL
) {
5017 if (pubkey
->keyalg
== KMF_RSA
||
5018 pubkey
->keyalg
== KMF_DSA
) {
5019 pkey
= (EVP_PKEY
*)pubkey
->keyp
;
5021 rv
= ssl_write_key(kmfh
, format
,
5022 out
, &cred
, pkey
, FALSE
);
5024 if (rv
== KMF_OK
&& pubkey
->keylabel
== NULL
) {
5025 pubkey
->keylabel
= strdup(fullpath
);
5026 if (pubkey
->keylabel
== NULL
)
5027 rv
= KMF_ERR_MEMORY
;
5030 } else if (rawkey
!= NULL
) {
5031 if (rawkey
->keytype
== KMF_RSA
) {
5032 pkey
= ImportRawRSAKey(&rawkey
->rawdata
.rsa
);
5033 } else if (rawkey
->keytype
== KMF_DSA
) {
5034 pkey
= ImportRawDSAKey(&rawkey
->rawdata
.dsa
);
5036 rv
= KMF_ERR_BAD_PARAMETER
;
5039 KMF_KEY_CLASS kclass
= KMF_ASYM_PRI
;
5041 rv
= kmf_get_attr(KMF_KEYCLASS_ATTR
, attrlist
, numattr
,
5042 (void *)&kclass
, NULL
);
5045 rv
= ssl_write_key(kmfh
, format
, out
,
5046 &cred
, pkey
, (kclass
== KMF_ASYM_PRI
));
5047 EVP_PKEY_free(pkey
);
5054 (void) BIO_free(out
);
5058 (void) chmod(fullpath
, 0400);
5065 OpenSSL_ImportCRL(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
5067 KMF_RETURN ret
= KMF_OK
;
5068 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
5069 X509_CRL
*xcrl
= NULL
;
5072 KMF_ENCODE_FORMAT format
;
5073 BIO
*in
= NULL
, *out
= NULL
;
5074 int openssl_ret
= 0;
5075 KMF_ENCODE_FORMAT outformat
;
5076 boolean_t crlcheck
= FALSE
;
5077 char *certfile
, *dirpath
, *crlfile
, *incrl
, *outcrl
, *outcrlfile
;
5079 if (numattr
== 0 || attrlist
== NULL
) {
5080 return (KMF_ERR_BAD_PARAMETER
);
5083 /* CRL check is optional */
5084 (void) kmf_get_attr(KMF_CRL_CHECK_ATTR
, attrlist
, numattr
,
5087 certfile
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
, numattr
);
5088 if (crlcheck
== B_TRUE
&& certfile
== NULL
) {
5089 return (KMF_ERR_BAD_CERTFILE
);
5092 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
5093 incrl
= kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR
, attrlist
, numattr
);
5094 outcrl
= kmf_get_attr_ptr(KMF_CRL_OUTFILE_ATTR
, attrlist
, numattr
);
5096 crlfile
= get_fullpath(dirpath
, incrl
);
5098 if (crlfile
== NULL
)
5099 return (KMF_ERR_BAD_CRLFILE
);
5101 outcrlfile
= get_fullpath(dirpath
, outcrl
);
5102 if (outcrlfile
== NULL
)
5103 return (KMF_ERR_BAD_CRLFILE
);
5105 if (isdir(outcrlfile
)) {
5107 return (KMF_ERR_BAD_CRLFILE
);
5110 ret
= kmf_is_crl_file(handle
, crlfile
, &format
);
5111 if (ret
!= KMF_OK
) {
5116 in
= BIO_new_file(crlfile
, "rb");
5118 SET_ERROR(kmfh
, ERR_get_error());
5119 ret
= KMF_ERR_OPEN_FILE
;
5123 if (format
== KMF_FORMAT_ASN1
) {
5124 xcrl
= d2i_X509_CRL_bio(in
, NULL
);
5125 } else if (format
== KMF_FORMAT_PEM
) {
5126 xcrl
= PEM_read_bio_X509_CRL(in
, NULL
, NULL
, NULL
);
5130 SET_ERROR(kmfh
, ERR_get_error());
5131 ret
= KMF_ERR_BAD_CRLFILE
;
5135 /* If bypasscheck is specified, no need to verify. */
5136 if (crlcheck
== B_FALSE
)
5139 ret
= kmf_is_cert_file(handle
, certfile
, &format
);
5143 /* Read in the CA cert file and convert to X509 */
5144 if (BIO_read_filename(in
, certfile
) <= 0) {
5145 SET_ERROR(kmfh
, ERR_get_error());
5146 ret
= KMF_ERR_OPEN_FILE
;
5150 if (format
== KMF_FORMAT_ASN1
) {
5151 xcert
= d2i_X509_bio(in
, NULL
);
5152 } else if (format
== KMF_FORMAT_PEM
) {
5153 xcert
= PEM_read_bio_X509(in
, NULL
, NULL
, NULL
);
5155 ret
= KMF_ERR_BAD_CERT_FORMAT
;
5159 if (xcert
== NULL
) {
5160 SET_ERROR(kmfh
, ERR_get_error());
5161 ret
= KMF_ERR_BAD_CERT_FORMAT
;
5164 /* Now get the public key from the CA cert */
5165 pkey
= X509_get_pubkey(xcert
);
5167 SET_ERROR(kmfh
, ERR_get_error());
5168 ret
= KMF_ERR_BAD_CERTFILE
;
5172 /* Verify the CRL with the CA's public key */
5173 openssl_ret
= X509_CRL_verify(xcrl
, pkey
);
5174 EVP_PKEY_free(pkey
);
5175 if (openssl_ret
> 0) {
5176 ret
= KMF_OK
; /* verify succeed */
5178 SET_ERROR(kmfh
, openssl_ret
);
5179 ret
= KMF_ERR_BAD_CRLFILE
;
5183 ret
= kmf_get_attr(KMF_ENCODE_FORMAT_ATTR
, attrlist
, numattr
,
5185 if (ret
!= KMF_OK
) {
5187 outformat
= KMF_FORMAT_PEM
;
5190 out
= BIO_new_file(outcrlfile
, "wb");
5192 SET_ERROR(kmfh
, ERR_get_error());
5193 ret
= KMF_ERR_OPEN_FILE
;
5197 if (outformat
== KMF_FORMAT_ASN1
) {
5198 openssl_ret
= (int)i2d_X509_CRL_bio(out
, xcrl
);
5199 } else if (outformat
== KMF_FORMAT_PEM
) {
5200 openssl_ret
= PEM_write_bio_X509_CRL(out
, xcrl
);
5202 ret
= KMF_ERR_BAD_PARAMETER
;
5206 if (openssl_ret
<= 0) {
5207 SET_ERROR(kmfh
, ERR_get_error());
5208 ret
= KMF_ERR_WRITE_FILE
;
5215 X509_CRL_free(xcrl
);
5221 (void) BIO_free(in
);
5224 (void) BIO_free(out
);
5226 if (outcrlfile
!= NULL
)
5233 OpenSSL_ListCRL(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
5235 KMF_RETURN ret
= KMF_OK
;
5236 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
5238 KMF_ENCODE_FORMAT format
;
5239 char *crlfile
= NULL
;
5246 char *crlfilename
, *dirpath
;
5248 if (numattr
== 0 || attrlist
== NULL
) {
5249 return (KMF_ERR_BAD_PARAMETER
);
5251 crlfilename
= kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR
,
5253 if (crlfilename
== NULL
)
5254 return (KMF_ERR_BAD_CRLFILE
);
5256 crldata
= (char **)kmf_get_attr_ptr(KMF_CRL_DATA_ATTR
,
5259 if (crldata
== NULL
)
5260 return (KMF_ERR_BAD_PARAMETER
);
5262 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
5264 crlfile
= get_fullpath(dirpath
, crlfilename
);
5266 if (crlfile
== NULL
)
5267 return (KMF_ERR_BAD_CRLFILE
);
5269 if (isdir(crlfile
)) {
5271 return (KMF_ERR_BAD_CRLFILE
);
5274 ret
= kmf_is_crl_file(handle
, crlfile
, &format
);
5275 if (ret
!= KMF_OK
) {
5280 if (bio_err
== NULL
)
5281 bio_err
= BIO_new_fp(stderr
, BIO_NOCLOSE
);
5283 in
= BIO_new_file(crlfile
, "rb");
5285 SET_ERROR(kmfh
, ERR_get_error());
5286 ret
= KMF_ERR_OPEN_FILE
;
5290 if (format
== KMF_FORMAT_ASN1
) {
5291 x
= d2i_X509_CRL_bio(in
, NULL
);
5292 } else if (format
== KMF_FORMAT_PEM
) {
5293 x
= PEM_read_bio_X509_CRL(in
, NULL
, NULL
, NULL
);
5296 if (x
== NULL
) { /* should not happen */
5297 SET_ERROR(kmfh
, ERR_get_error());
5298 ret
= KMF_ERR_OPEN_FILE
;
5302 mem
= BIO_new(BIO_s_mem());
5304 SET_ERROR(kmfh
, ERR_get_error());
5305 ret
= KMF_ERR_MEMORY
;
5309 (void) X509_CRL_print(mem
, x
);
5310 len
= BIO_get_mem_data(mem
, &memptr
);
5312 SET_ERROR(kmfh
, ERR_get_error());
5313 ret
= KMF_ERR_MEMORY
;
5317 data
= malloc(len
+ 1);
5319 ret
= KMF_ERR_MEMORY
;
5323 (void) memcpy(data
, memptr
, len
);
5331 if (crlfile
!= NULL
)
5335 (void) BIO_free(in
);
5338 (void) BIO_free(mem
);
5344 OpenSSL_DeleteCRL(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
5346 KMF_RETURN ret
= KMF_OK
;
5347 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
5348 KMF_ENCODE_FORMAT format
;
5349 char *crlfile
= NULL
;
5351 char *crlfilename
, *dirpath
;
5353 if (numattr
== 0 || attrlist
== NULL
) {
5354 return (KMF_ERR_BAD_PARAMETER
);
5357 crlfilename
= kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR
,
5360 if (crlfilename
== NULL
)
5361 return (KMF_ERR_BAD_CRLFILE
);
5363 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
5365 crlfile
= get_fullpath(dirpath
, crlfilename
);
5367 if (crlfile
== NULL
)
5368 return (KMF_ERR_BAD_CRLFILE
);
5370 if (isdir(crlfile
)) {
5371 ret
= KMF_ERR_BAD_CRLFILE
;
5375 ret
= kmf_is_crl_file(handle
, crlfile
, &format
);
5379 if (unlink(crlfile
) != 0) {
5380 SET_SYS_ERROR(kmfh
, errno
);
5381 ret
= KMF_ERR_INTERNAL
;
5387 (void) BIO_free(in
);
5388 if (crlfile
!= NULL
)
5395 OpenSSL_FindCertInCRL(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
5397 KMF_RETURN ret
= KMF_OK
;
5398 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
5399 KMF_ENCODE_FORMAT format
;
5402 X509_CRL
*xcrl
= NULL
;
5403 STACK_OF(X509_REVOKED
) *revoke_stack
= NULL
;
5404 X509_REVOKED
*revoke
;
5406 char *crlfilename
, *crlfile
, *dirpath
, *certfile
;
5408 if (numattr
== 0 || attrlist
== NULL
) {
5409 return (KMF_ERR_BAD_PARAMETER
);
5412 crlfilename
= kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR
,
5415 if (crlfilename
== NULL
)
5416 return (KMF_ERR_BAD_CRLFILE
);
5418 certfile
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
, numattr
);
5419 if (certfile
== NULL
)
5420 return (KMF_ERR_BAD_CRLFILE
);
5422 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
5424 crlfile
= get_fullpath(dirpath
, crlfilename
);
5426 if (crlfile
== NULL
)
5427 return (KMF_ERR_BAD_CRLFILE
);
5429 if (isdir(crlfile
)) {
5430 ret
= KMF_ERR_BAD_CRLFILE
;
5434 ret
= kmf_is_crl_file(handle
, crlfile
, &format
);
5438 /* Read the CRL file and load it into a X509_CRL structure */
5439 in
= BIO_new_file(crlfilename
, "rb");
5441 SET_ERROR(kmfh
, ERR_get_error());
5442 ret
= KMF_ERR_OPEN_FILE
;
5446 if (format
== KMF_FORMAT_ASN1
) {
5447 xcrl
= d2i_X509_CRL_bio(in
, NULL
);
5448 } else if (format
== KMF_FORMAT_PEM
) {
5449 xcrl
= PEM_read_bio_X509_CRL(in
, NULL
, NULL
, NULL
);
5453 SET_ERROR(kmfh
, ERR_get_error());
5454 ret
= KMF_ERR_BAD_CRLFILE
;
5457 (void) BIO_free(in
);
5459 /* Read the Certificate file and load it into a X509 structure */
5460 ret
= kmf_is_cert_file(handle
, certfile
, &format
);
5464 in
= BIO_new_file(certfile
, "rb");
5466 SET_ERROR(kmfh
, ERR_get_error());
5467 ret
= KMF_ERR_OPEN_FILE
;
5471 if (format
== KMF_FORMAT_ASN1
) {
5472 xcert
= d2i_X509_bio(in
, NULL
);
5473 } else if (format
== KMF_FORMAT_PEM
) {
5474 xcert
= PEM_read_bio_X509(in
, NULL
, NULL
, NULL
);
5477 if (xcert
== NULL
) {
5478 SET_ERROR(kmfh
, ERR_get_error());
5479 ret
= KMF_ERR_BAD_CERTFILE
;
5483 /* Check if the certificate and the CRL have same issuer */
5484 if (X509_NAME_cmp(X509_get_issuer_name(xcert
),
5485 X509_CRL_get_issuer(xcrl
)) != 0) {
5486 ret
= KMF_ERR_ISSUER
;
5490 /* Check to see if the certificate serial number is revoked */
5491 revoke_stack
= X509_CRL_get_REVOKED(xcrl
);
5492 if (sk_X509_REVOKED_num(revoke_stack
) <= 0) {
5493 /* No revoked certificates in the CRL file */
5494 SET_ERROR(kmfh
, ERR_get_error());
5495 ret
= KMF_ERR_EMPTY_CRL
;
5499 for (i
= 0; i
< sk_X509_REVOKED_num(revoke_stack
); i
++) {
5500 /* LINTED E_BAD_PTR_CAST_ALIGN */
5501 revoke
= sk_X509_REVOKED_value(revoke_stack
, i
);
5502 if (ASN1_INTEGER_cmp(X509_get_serialNumber(xcert
),
5503 X509_REVOKED_get0_serialNumber(revoke
)) == 0) {
5508 if (i
< sk_X509_REVOKED_num(revoke_stack
)) {
5511 ret
= KMF_ERR_NOT_REVOKED
;
5516 (void) BIO_free(in
);
5518 X509_CRL_free(xcrl
);
5526 OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle
, char *crlname
, KMF_DATA
*tacert
)
5528 KMF_RETURN ret
= KMF_OK
;
5529 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
5531 X509_CRL
*xcrl
= NULL
;
5535 KMF_ENCODE_FORMAT crl_format
;
5539 if (handle
== NULL
|| crlname
== NULL
|| tacert
== NULL
) {
5540 return (KMF_ERR_BAD_PARAMETER
);
5543 ret
= kmf_get_file_format(crlname
, &crl_format
);
5547 bcrl
= BIO_new_file(crlname
, "rb");
5549 SET_ERROR(kmfh
, ERR_get_error());
5550 ret
= KMF_ERR_OPEN_FILE
;
5554 if (crl_format
== KMF_FORMAT_ASN1
) {
5555 xcrl
= d2i_X509_CRL_bio(bcrl
, NULL
);
5556 } else if (crl_format
== KMF_FORMAT_PEM
) {
5557 xcrl
= PEM_read_bio_X509_CRL(bcrl
, NULL
, NULL
, NULL
);
5559 ret
= KMF_ERR_BAD_PARAMETER
;
5564 SET_ERROR(kmfh
, ERR_get_error());
5565 ret
= KMF_ERR_BAD_CRLFILE
;
5570 len
= tacert
->Length
;
5571 xcert
= d2i_X509(NULL
, (const uchar_t
**)&p
, len
);
5573 if (xcert
== NULL
) {
5574 SET_ERROR(kmfh
, ERR_get_error());
5575 ret
= KMF_ERR_BAD_CERTFILE
;
5579 /* Get issuer certificate public key */
5580 pkey
= X509_get_pubkey(xcert
);
5582 SET_ERROR(kmfh
, ERR_get_error());
5583 ret
= KMF_ERR_BAD_CERT_FORMAT
;
5587 /* Verify CRL signature */
5588 sslret
= X509_CRL_verify(xcrl
, pkey
);
5589 EVP_PKEY_free(pkey
);
5593 SET_ERROR(kmfh
, sslret
);
5594 ret
= KMF_ERR_BAD_CRLFILE
;
5599 (void) BIO_free(bcrl
);
5602 X509_CRL_free(xcrl
);
5612 OpenSSL_CheckCRLDate(KMF_HANDLE_T handle
, char *crlname
)
5614 KMF_RETURN ret
= KMF_OK
;
5615 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
5616 KMF_ENCODE_FORMAT crl_format
;
5618 X509_CRL
*xcrl
= NULL
;
5621 if (handle
== NULL
|| crlname
== NULL
) {
5622 return (KMF_ERR_BAD_PARAMETER
);
5625 ret
= kmf_is_crl_file(handle
, crlname
, &crl_format
);
5629 bcrl
= BIO_new_file(crlname
, "rb");
5631 SET_ERROR(kmfh
, ERR_get_error());
5632 ret
= KMF_ERR_OPEN_FILE
;
5636 if (crl_format
== KMF_FORMAT_ASN1
)
5637 xcrl
= d2i_X509_CRL_bio(bcrl
, NULL
);
5638 else if (crl_format
== KMF_FORMAT_PEM
)
5639 xcrl
= PEM_read_bio_X509_CRL(bcrl
, NULL
, NULL
, NULL
);
5642 SET_ERROR(kmfh
, ERR_get_error());
5643 ret
= KMF_ERR_BAD_CRLFILE
;
5646 i
= X509_cmp_time(X509_CRL_get0_lastUpdate(xcrl
), NULL
);
5648 ret
= KMF_ERR_VALIDITY_PERIOD
;
5651 if (X509_CRL_get0_nextUpdate(xcrl
)) {
5652 i
= X509_cmp_time(X509_CRL_get0_nextUpdate(xcrl
), NULL
);
5655 ret
= KMF_ERR_VALIDITY_PERIOD
;
5664 (void) BIO_free(bcrl
);
5667 X509_CRL_free(xcrl
);