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.
11 * Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
15 * ====================================================================
16 * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved.
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
22 * 1. Redistributions of source code must retain the above copyright
23 * notice, this list of conditions and the following disclaimer.
25 * 2. Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in
27 * the documentation and/or other materials provided with the
30 * 3. All advertising materials mentioning features or use of this
31 * software must display the following acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
35 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
36 * endorse or promote products derived from this software without
37 * prior written permission. For written permission, please contact
38 * licensing@OpenSSL.org.
40 * 5. Products derived from this software may not be called "OpenSSL"
41 * nor may "OpenSSL" appear in their names without prior written
42 * permission of the OpenSSL Project.
44 * 6. Redistributions of any form whatsoever must retain the following
46 * "This product includes software developed by the OpenSSL Project
47 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
49 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
50 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
52 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
53 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
54 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
55 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
56 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
58 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
59 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
60 * OF THE POSSIBILITY OF SUCH DAMAGE.
61 * ====================================================================
63 * This product includes cryptographic software written by Eric Young
64 * (eay@cryptsoft.com). This product includes software written by Tim
65 * Hudson (tjh@cryptsoft.com).
75 #include <cryptoutil.h>
79 /* OPENSSL related headers */
80 #include <openssl/bio.h>
81 #include <openssl/bn.h>
82 #include <openssl/asn1.h>
83 #include <openssl/err.h>
84 #include <openssl/x509.h>
85 #include <openssl/rsa.h>
86 #include <openssl/dsa.h>
87 #include <openssl/x509v3.h>
88 #include <openssl/objects.h>
89 #include <openssl/pem.h>
90 #include <openssl/pkcs12.h>
91 #include <openssl/ocsp.h>
92 #include <openssl/des.h>
93 #include <openssl/rand.h>
96 #define PRINT_ANY_EXTENSION (\
97 KMF_X509_EXT_KEY_USAGE |\
98 KMF_X509_EXT_CERT_POLICIES |\
99 KMF_X509_EXT_SUBJALTNAME |\
100 KMF_X509_EXT_BASIC_CONSTRAINTS |\
101 KMF_X509_EXT_NAME_CONSTRAINTS |\
102 KMF_X509_EXT_POLICY_CONSTRAINTS |\
103 KMF_X509_EXT_EXT_KEY_USAGE |\
104 KMF_X509_EXT_INHIBIT_ANY_POLICY |\
105 KMF_X509_EXT_AUTH_KEY_ID |\
106 KMF_X509_EXT_SUBJ_KEY_ID |\
107 KMF_X509_EXT_POLICY_MAPPING)
109 static uchar_t P
[] = { 0x00, 0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76,
110 0xaa, 0x3d, 0x25, 0x75, 0x9b, 0xb0, 0x68, 0x69,
111 0xcb, 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d, 0x0c,
112 0xf7, 0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82,
113 0xe5, 0xd0, 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e,
114 0xaf, 0xc2, 0xe9, 0xad, 0xac, 0x32, 0xab, 0x7a,
115 0xac, 0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24,
116 0xc2, 0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02,
119 static uchar_t Q
[] = { 0x00, 0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8,
120 0xee, 0x99, 0x3b, 0x4f, 0x2d, 0xed, 0x30, 0xf4,
121 0x8e, 0xda, 0xce, 0x91, 0x5f };
123 static uchar_t G
[] = { 0x00, 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a,
124 0x13, 0x41, 0x31, 0x63, 0xa5, 0x5b, 0x4c, 0xb5,
125 0x00, 0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c, 0xef,
126 0xcb, 0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c,
127 0x2e, 0x71, 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba,
128 0xbf, 0x58, 0xe5, 0xb7, 0x95, 0x21, 0x92, 0x5c,
129 0x9c, 0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08,
130 0x8c, 0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88,
133 #define SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_OPENSSL; \
134 h->lasterr.errcode = c;
136 #define SET_SYS_ERROR(h, c) h->lasterr.kstype = -1; h->lasterr.errcode = c;
139 * Declare some new macros for managing stacks of EVP_PKEYS.
141 #if OPENSSL_VERSION_NUMBER < 0x10100000L
142 DECLARE_STACK_OF(EVP_PKEY
)
144 #define sk_EVP_PKEY_new_null() SKM_sk_new_null(EVP_PKEY)
145 #define sk_EVP_PKEY_free(st) SKM_sk_free(EVP_PKEY, (st))
146 #define sk_EVP_PKEY_num(st) SKM_sk_num(EVP_PKEY, (st))
147 #define sk_EVP_PKEY_value(st, i) SKM_sk_value(EVP_PKEY, (st), (i))
148 #define sk_EVP_PKEY_push(st, val) SKM_sk_push(EVP_PKEY, (st), (val))
149 #define sk_EVP_PKEY_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY, (st), \
153 /* LINTED E_STATIC_UNUSED */
154 DEFINE_STACK_OF(EVP_PKEY
)
157 mutex_t init_lock
= DEFAULTMUTEX
;
158 static int ssl_initialized
= 0;
159 static BIO
*bio_err
= NULL
;
162 test_for_file(char *, mode_t
);
164 openssl_parse_bag(PKCS12_SAFEBAG
*, char *, int,
165 STACK_OF(EVP_PKEY
) *, STACK_OF(X509
) *);
168 local_export_pk12(KMF_HANDLE_T
, KMF_CREDENTIAL
*, int, KMF_X509_DER_CERT
*,
169 int, KMF_KEY_HANDLE
*, char *);
171 static KMF_RETURN
set_pkey_attrib(EVP_PKEY
*, ASN1_TYPE
*, int);
174 extract_pem(KMF_HANDLE
*, char *, char *, KMF_BIGINT
*, char *,
175 CK_UTF8CHAR
*, CK_ULONG
, EVP_PKEY
**, KMF_DATA
**, int *);
178 kmf_load_cert(KMF_HANDLE
*, char *, char *, KMF_BIGINT
*, KMF_CERT_VALIDITY
,
182 load_certs(KMF_HANDLE
*, char *, char *, KMF_BIGINT
*, KMF_CERT_VALIDITY
,
183 char *, KMF_DATA
**, uint32_t *);
186 sslBN2KMFBN(BIGNUM
*, KMF_BIGINT
*);
189 ImportRawRSAKey(KMF_RAW_RSA_KEY
*);
192 convertToRawKey(EVP_PKEY
*, KMF_RAW_KEY_DATA
*);
195 OpenSSL_FindCert(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
198 OpenSSL_FreeKMFCert(KMF_HANDLE_T
, KMF_X509_DER_CERT
*);
201 OpenSSL_StoreCert(KMF_HANDLE_T handle
, int, KMF_ATTRIBUTE
*);
204 OpenSSL_DeleteCert(KMF_HANDLE_T handle
, int, KMF_ATTRIBUTE
*);
207 OpenSSL_CreateKeypair(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
210 OpenSSL_StoreKey(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
213 OpenSSL_EncodePubKeyData(KMF_HANDLE_T
, KMF_KEY_HANDLE
*, KMF_DATA
*);
216 OpenSSL_SignData(KMF_HANDLE_T
, KMF_KEY_HANDLE
*, KMF_OID
*,
217 KMF_DATA
*, KMF_DATA
*);
220 OpenSSL_DeleteKey(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
223 OpenSSL_ImportCRL(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
226 OpenSSL_DeleteCRL(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
229 OpenSSL_ListCRL(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
232 OpenSSL_FindCertInCRL(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
235 OpenSSL_CertGetPrintable(KMF_HANDLE_T
, const KMF_DATA
*,
236 KMF_PRINTABLE_ITEM
, char *);
239 OpenSSL_GetErrorString(KMF_HANDLE_T
, char **);
242 OpenSSL_FindPrikeyByCert(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
245 OpenSSL_DecryptData(KMF_HANDLE_T
, KMF_KEY_HANDLE
*, KMF_OID
*,
246 KMF_DATA
*, KMF_DATA
*);
249 OpenSSL_CreateOCSPRequest(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
252 OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
255 OpenSSL_FindKey(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
258 OpenSSL_ExportPK12(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
261 OpenSSL_CreateSymKey(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
264 OpenSSL_GetSymKeyValue(KMF_HANDLE_T
, KMF_KEY_HANDLE
*, KMF_RAW_SYM_KEY
*);
267 OpenSSL_VerifyCRLFile(KMF_HANDLE_T
, char *, KMF_DATA
*);
270 OpenSSL_CheckCRLDate(KMF_HANDLE_T
, char *);
273 KMF_PLUGIN_FUNCLIST openssl_plugin_table
=
276 NULL
, /* ConfigureKeystore */
280 NULL
, /* ImportCert */
284 OpenSSL_CreateKeypair
,
286 OpenSSL_EncodePubKeyData
,
291 OpenSSL_FindCertInCRL
,
292 OpenSSL_GetErrorString
,
293 OpenSSL_FindPrikeyByCert
,
296 OpenSSL_CreateSymKey
,
297 OpenSSL_GetSymKeyValue
,
298 NULL
, /* SetTokenPin */
303 #if OPENSSL_VERSION_NUMBER < 0x10100000L
304 static mutex_t
*lock_cs
;
305 static long *lock_count
;
309 locking_cb(int mode
, int type
, char *file
, int line
)
311 if (mode
& CRYPTO_LOCK
) {
312 (void) mutex_lock(&(lock_cs
[type
]));
315 (void) mutex_unlock(&(lock_cs
[type
]));
322 return ((unsigned long)thr_self());
324 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
326 KMF_PLUGIN_FUNCLIST
*
327 KMF_Plugin_Initialize()
329 #if OPENSSL_VERSION_NUMBER < 0x10100000L
333 (void) mutex_lock(&init_lock
);
334 if (!ssl_initialized
) {
336 * Add support for extension OIDs that are not yet in the
337 * openssl default set.
339 (void) OBJ_create("2.5.29.30", "nameConstraints",
340 "X509v3 Name Constraints");
341 (void) OBJ_create("2.5.29.33", "policyMappings",
342 "X509v3 Policy Mappings");
343 (void) OBJ_create("2.5.29.36", "policyConstraints",
344 "X509v3 Policy Constraints");
345 (void) OBJ_create("2.5.29.46", "freshestCRL",
346 "X509v3 Freshest CRL");
347 (void) OBJ_create("2.5.29.54", "inhibitAnyPolicy",
348 "X509v3 Inhibit Any-Policy");
350 #if OPENSSL_VERSION_NUMBER < 0x10100000L
352 * Set up for thread-safe operation.
353 * This is not required for OpenSSL 1.1
355 lock_cs
= OPENSSL_malloc(CRYPTO_num_locks() * sizeof (mutex_t
));
356 if (lock_cs
== NULL
) {
357 (void) mutex_unlock(&init_lock
);
361 lock_count
= OPENSSL_malloc(CRYPTO_num_locks() * sizeof (long));
362 if (lock_count
== NULL
) {
363 OPENSSL_free(lock_cs
);
364 (void) mutex_unlock(&init_lock
);
368 for (i
= 0; i
< CRYPTO_num_locks(); i
++) {
370 (void) mutex_init(&lock_cs
[i
], USYNC_THREAD
, NULL
);
373 CRYPTO_set_id_callback((unsigned long (*)())thread_id
);
374 if (CRYPTO_get_locking_callback() == NULL
)
375 CRYPTO_set_locking_callback((void (*)())locking_cb
);
377 (void) OpenSSL_add_all_algorithms();
379 /* Enable error strings for reporting */
380 (void) ERR_load_crypto_strings();
385 (void) mutex_unlock(&init_lock
);
387 return (&openssl_plugin_table
);
391 * Convert an SSL DN to a KMF DN.
394 get_x509_dn(X509_NAME
*sslDN
, KMF_X509_NAME
*kmfDN
)
397 KMF_RETURN rv
= KMF_OK
;
400 /* Convert to raw DER format */
401 derdata
.Length
= i2d_X509_NAME(sslDN
, NULL
);
402 if ((tmp
= derdata
.Data
= (uchar_t
*)OPENSSL_malloc(derdata
.Length
))
404 return (KMF_ERR_MEMORY
);
406 (void) i2d_X509_NAME(sslDN
, &tmp
);
408 /* Decode to KMF format */
409 rv
= DerDecodeName(&derdata
, kmfDN
);
411 rv
= KMF_ERR_BAD_CERT_FORMAT
;
413 OPENSSL_free(derdata
.Data
);
423 if (stat(path
, &s
) == -1)
426 return ((s
.st_mode
& S_IFMT
) == S_IFDIR
);
430 ssl_cert2KMFDATA(KMF_HANDLE
*kmfh
, X509
*x509cert
, KMF_DATA
*cert
)
432 KMF_RETURN rv
= KMF_OK
;
433 unsigned char *buf
= NULL
, *p
;
437 * Convert the X509 internal struct to DER encoded data
439 if ((len
= i2d_X509(x509cert
, NULL
)) < 0) {
440 SET_ERROR(kmfh
, ERR_get_error());
441 rv
= KMF_ERR_BAD_CERT_FORMAT
;
444 if ((buf
= malloc(len
)) == NULL
) {
445 SET_SYS_ERROR(kmfh
, errno
);
451 * i2d_X509 will increment the buf pointer so that we need to
455 if ((len
= i2d_X509(x509cert
, &p
)) < 0) {
456 SET_ERROR(kmfh
, ERR_get_error());
458 rv
= KMF_ERR_BAD_CERT_FORMAT
;
462 /* caller's responsibility to free it */
479 check_cert(X509
*xcert
, char *issuer
, char *subject
, KMF_BIGINT
*serial
,
482 KMF_RETURN rv
= KMF_OK
;
483 boolean_t findIssuer
= FALSE
;
484 boolean_t findSubject
= FALSE
;
485 boolean_t findSerial
= FALSE
;
486 KMF_X509_NAME issuerDN
, subjectDN
;
487 KMF_X509_NAME certIssuerDN
, certSubjectDN
;
491 return (KMF_ERR_BAD_PARAMETER
);
494 (void) memset(&issuerDN
, 0, sizeof (KMF_X509_NAME
));
495 (void) memset(&subjectDN
, 0, sizeof (KMF_X509_NAME
));
496 (void) memset(&certIssuerDN
, 0, sizeof (KMF_X509_NAME
));
497 (void) memset(&certSubjectDN
, 0, sizeof (KMF_X509_NAME
));
499 if (issuer
!= NULL
&& strlen(issuer
)) {
500 rv
= kmf_dn_parser(issuer
, &issuerDN
);
502 return (KMF_ERR_BAD_PARAMETER
);
504 rv
= get_x509_dn(X509_get_issuer_name(xcert
), &certIssuerDN
);
506 kmf_free_dn(&issuerDN
);
507 return (KMF_ERR_BAD_PARAMETER
);
512 if (subject
!= NULL
&& strlen(subject
)) {
513 rv
= kmf_dn_parser(subject
, &subjectDN
);
515 rv
= KMF_ERR_BAD_PARAMETER
;
519 rv
= get_x509_dn(X509_get_subject_name(xcert
), &certSubjectDN
);
521 rv
= KMF_ERR_BAD_PARAMETER
;
526 if (serial
!= NULL
&& serial
->val
!= NULL
)
532 /* Comparing BIGNUMs is a pain! */
533 bn
= ASN1_INTEGER_to_BN(X509_get_serialNumber(xcert
), NULL
);
535 int bnlen
= BN_num_bytes(bn
);
537 if (bnlen
== serial
->len
) {
538 uchar_t
*a
= malloc(bnlen
);
544 bnlen
= BN_bn2bin(bn
, a
);
545 *match
= (memcmp(a
, serial
->val
, serial
->len
) ==
559 *match
= (kmf_compare_rdns(&issuerDN
, &certIssuerDN
) == 0);
560 if ((*match
) == B_FALSE
) {
561 /* stop checking and bail */
567 *match
= (kmf_compare_rdns(&subjectDN
, &certSubjectDN
) == 0);
568 if ((*match
) == B_FALSE
) {
569 /* stop checking and bail */
578 kmf_free_dn(&issuerDN
);
579 kmf_free_dn(&certIssuerDN
);
582 kmf_free_dn(&subjectDN
);
583 kmf_free_dn(&certSubjectDN
);
591 * This function loads a certificate file into an X509 data structure, and
592 * checks if its issuer, subject or the serial number matches with those
593 * values. If it matches, then return the X509 data structure.
596 load_X509cert(KMF_HANDLE
*kmfh
,
597 char *issuer
, char *subject
, KMF_BIGINT
*serial
,
598 char *pathname
, X509
**outcert
)
600 KMF_RETURN rv
= KMF_OK
;
603 boolean_t match
= FALSE
;
604 KMF_ENCODE_FORMAT format
;
607 * auto-detect the file format, regardless of what
608 * the 'format' parameters in the params say.
610 rv
= kmf_get_file_format(pathname
, &format
);
612 if (rv
== KMF_ERR_OPEN_FILE
)
613 rv
= KMF_ERR_CERT_NOT_FOUND
;
617 /* Not ASN1(DER) format */
618 if ((bcert
= BIO_new_file(pathname
, "rb")) == NULL
) {
619 SET_ERROR(kmfh
, ERR_get_error());
620 rv
= KMF_ERR_OPEN_FILE
;
624 if (format
== KMF_FORMAT_PEM
)
625 xcert
= PEM_read_bio_X509_AUX(bcert
, NULL
, NULL
, NULL
);
626 else if (format
== KMF_FORMAT_ASN1
)
627 xcert
= d2i_X509_bio(bcert
, NULL
);
628 else if (format
== KMF_FORMAT_PKCS12
) {
629 PKCS12
*p12
= d2i_PKCS12_bio(bcert
, NULL
);
631 (void) PKCS12_parse(p12
, NULL
, NULL
, &xcert
, NULL
);
635 SET_ERROR(kmfh
, ERR_get_error());
636 rv
= KMF_ERR_BAD_CERT_FORMAT
;
639 rv
= KMF_ERR_BAD_PARAMETER
;
644 SET_ERROR(kmfh
, ERR_get_error());
645 rv
= KMF_ERR_BAD_CERT_FORMAT
;
649 if (check_cert(xcert
, issuer
, subject
, serial
, &match
) != KMF_OK
||
651 rv
= KMF_ERR_CERT_NOT_FOUND
;
655 if (outcert
!= NULL
) {
660 if (bcert
!= NULL
) (void) BIO_free(bcert
);
661 if (rv
!= KMF_OK
&& xcert
!= NULL
)
668 datacmp(const void *a
, const void *b
)
670 KMF_DATA
*adata
= (KMF_DATA
*)a
;
671 KMF_DATA
*bdata
= (KMF_DATA
*)b
;
672 if (adata
->Length
> bdata
->Length
)
674 if (adata
->Length
< bdata
->Length
)
680 load_certs(KMF_HANDLE
*kmfh
, char *issuer
, char *subject
, KMF_BIGINT
*serial
,
681 KMF_CERT_VALIDITY validity
, char *pathname
,
682 KMF_DATA
**certlist
, uint32_t *numcerts
)
684 KMF_RETURN rv
= KMF_OK
;
686 KMF_DATA
*certs
= NULL
;
689 KMF_ENCODE_FORMAT format
;
691 rv
= kmf_get_file_format(pathname
, &format
);
693 if (rv
== KMF_ERR_OPEN_FILE
)
694 rv
= KMF_ERR_CERT_NOT_FOUND
;
697 if (format
== KMF_FORMAT_ASN1
) {
698 /* load a single certificate */
699 certs
= (KMF_DATA
*)malloc(sizeof (KMF_DATA
));
701 return (KMF_ERR_MEMORY
);
704 rv
= kmf_load_cert(kmfh
, issuer
, subject
, serial
, validity
,
710 kmf_free_data(certs
);
715 } else if (format
== KMF_FORMAT_PKCS12
) {
716 /* We need a credential to access a PKCS#12 file */
717 rv
= KMF_ERR_BAD_CERT_FORMAT
;
718 } else if (format
== KMF_FORMAT_PEM
||
719 format
!= KMF_FORMAT_PEM_KEYPAIR
) {
721 /* This function only works on PEM files */
722 rv
= extract_pem(kmfh
, issuer
, subject
, serial
, pathname
,
723 (uchar_t
*)NULL
, 0, NULL
, &certs
, &nc
);
725 return (KMF_ERR_ENCODING
);
731 for (i
= 0; i
< nc
; i
++) {
732 if (validity
== KMF_NONEXPIRED_CERTS
) {
733 rv
= kmf_check_cert_date(kmfh
, &certs
[i
]);
734 } else if (validity
== KMF_EXPIRED_CERTS
) {
735 rv
= kmf_check_cert_date(kmfh
, &certs
[i
]);
737 rv
= KMF_ERR_CERT_NOT_FOUND
;
738 if (rv
== KMF_ERR_VALIDITY_PERIOD
)
742 /* Remove this cert from the list by clearing it. */
743 kmf_free_data(&certs
[i
]);
745 hits
++; /* count valid certs found */
749 if (rv
== KMF_OK
&& hits
> 0) {
751 * Sort the list of certs by length to put the cleared ones
752 * at the end so they don't get accessed by the caller.
754 qsort((void *)certs
, nc
, sizeof (KMF_DATA
), datacmp
);
757 /* since we sorted the list, just return the number of hits */
760 if (rv
== KMF_OK
&& hits
== 0)
761 rv
= KMF_ERR_CERT_NOT_FOUND
;
771 kmf_load_cert(KMF_HANDLE
*kmfh
,
772 char *issuer
, char *subject
, KMF_BIGINT
*serial
,
773 KMF_CERT_VALIDITY validity
,
777 KMF_RETURN rv
= KMF_OK
;
778 X509
*x509cert
= NULL
;
780 rv
= load_X509cert(kmfh
, issuer
, subject
, serial
, pathname
, &x509cert
);
781 if (rv
== KMF_OK
&& x509cert
!= NULL
&& cert
!= NULL
) {
782 rv
= ssl_cert2KMFDATA(kmfh
, x509cert
, cert
);
786 if (validity
== KMF_NONEXPIRED_CERTS
) {
787 rv
= kmf_check_cert_date(kmfh
, cert
);
788 } else if (validity
== KMF_EXPIRED_CERTS
) {
789 rv
= kmf_check_cert_date(kmfh
, cert
);
792 * This is a valid cert so skip it.
794 rv
= KMF_ERR_CERT_NOT_FOUND
;
796 if (rv
== KMF_ERR_VALIDITY_PERIOD
) {
798 * We want to return success when we
799 * find an invalid cert.
807 if (x509cert
!= NULL
)
814 readAltFormatPrivateKey(KMF_DATA
*filedata
, EVP_PKEY
**pkey
)
816 KMF_RETURN ret
= KMF_OK
;
818 BerElement
*asn1
= NULL
;
820 BerValue OID
= { NULL
, 0 };
821 BerValue
*Mod
= NULL
, *PubExp
= NULL
;
822 BerValue
*PriExp
= NULL
, *Prime1
= NULL
, *Prime2
= NULL
;
823 BerValue
*Coef
= NULL
;
824 BIGNUM
*D
= NULL
, *P
= NULL
, *Q
= NULL
, *COEF
= NULL
;
825 BIGNUM
*Exp1
= NULL
, *Exp2
= NULL
, *pminus1
= NULL
;
826 BIGNUM
*qminus1
= NULL
;
831 filebuf
.bv_val
= (char *)filedata
->Data
;
832 filebuf
.bv_len
= filedata
->Length
;
834 asn1
= kmfder_init(&filebuf
);
836 ret
= KMF_ERR_MEMORY
;
840 if (kmfber_scanf(asn1
, "{{Dn{IIIIII}}}",
841 &OID
, &Mod
, &PubExp
, &PriExp
, &Prime1
,
842 &Prime2
, &Coef
) == -1) {
843 ret
= KMF_ERR_ENCODING
;
848 * We have to derive the 2 Exponents using Bignumber math.
849 * Exp1 = PriExp mod (Prime1 - 1)
850 * Exp2 = PriExp mod (Prime2 - 1)
853 /* D = PrivateExponent */
854 D
= BN_bin2bn((const uchar_t
*)PriExp
->bv_val
, PriExp
->bv_len
, D
);
856 ret
= KMF_ERR_MEMORY
;
860 /* P = Prime1 (first prime factor of Modulus) */
861 P
= BN_bin2bn((const uchar_t
*)Prime1
->bv_val
, Prime1
->bv_len
, P
);
863 ret
= KMF_ERR_MEMORY
;
867 /* Q = Prime2 (second prime factor of Modulus) */
868 Q
= BN_bin2bn((const uchar_t
*)Prime2
->bv_val
, Prime2
->bv_len
, Q
);
870 if ((ctx
= BN_CTX_new()) == NULL
) {
871 ret
= KMF_ERR_MEMORY
;
875 /* Compute (P - 1) */
877 (void) BN_sub(pminus1
, P
, BN_value_one());
879 /* Exponent1 = D mod (P - 1) */
881 (void) BN_mod(Exp1
, D
, pminus1
, ctx
);
883 /* Compute (Q - 1) */
885 (void) BN_sub(qminus1
, Q
, BN_value_one());
887 /* Exponent2 = D mod (Q - 1) */
889 (void) BN_mod(Exp2
, D
, qminus1
, ctx
);
891 /* Coef = (Inverse Q) mod P */
893 (void) BN_mod_inverse(COEF
, Q
, P
, ctx
);
895 /* Convert back to KMF format */
896 (void) memset(&rsa
, 0, sizeof (rsa
));
898 if ((ret
= sslBN2KMFBN(Exp1
, &rsa
.exp1
)) != KMF_OK
)
900 if ((ret
= sslBN2KMFBN(Exp2
, &rsa
.exp2
)) != KMF_OK
)
902 if ((ret
= sslBN2KMFBN(COEF
, &rsa
.coef
)) != KMF_OK
)
905 rsa
.mod
.val
= (uchar_t
*)Mod
->bv_val
;
906 rsa
.mod
.len
= Mod
->bv_len
;
908 rsa
.pubexp
.val
= (uchar_t
*)PubExp
->bv_val
;
909 rsa
.pubexp
.len
= PubExp
->bv_len
;
911 rsa
.priexp
.val
= (uchar_t
*)PriExp
->bv_val
;
912 rsa
.priexp
.len
= PriExp
->bv_len
;
914 rsa
.prime1
.val
= (uchar_t
*)Prime1
->bv_val
;
915 rsa
.prime1
.len
= Prime1
->bv_len
;
917 rsa
.prime2
.val
= (uchar_t
*)Prime2
->bv_val
;
918 rsa
.prime2
.len
= Prime2
->bv_len
;
920 *pkey
= ImportRawRSAKey(&rsa
);
923 kmfber_free(asn1
, 1);
938 (void) memset(Coef
->bv_val
, 0, Coef
->bv_len
);
957 BN_clear_free(pminus1
);
959 BN_clear_free(qminus1
);
970 openssl_load_key(KMF_HANDLE_T handle
, const char *file
)
973 EVP_PKEY
*pkey
= NULL
;
974 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
975 KMF_ENCODE_FORMAT format
;
983 if (kmf_get_file_format((char *)file
, &format
) != KMF_OK
)
986 keyfile
= BIO_new_file(file
, "rb");
987 if (keyfile
== NULL
) {
991 if (format
== KMF_FORMAT_ASN1
) {
992 pkey
= d2i_PrivateKey_bio(keyfile
, NULL
);
995 (void) BIO_free(keyfile
);
997 /* Try odd ASN.1 variations */
998 rv
= kmf_read_input_file(kmfh
, (char *)file
,
1001 (void) readAltFormatPrivateKey(&filedata
,
1003 kmf_free_data(&filedata
);
1006 } else if (format
== KMF_FORMAT_PEM
||
1007 format
== KMF_FORMAT_PEM_KEYPAIR
) {
1008 pkey
= PEM_read_bio_PrivateKey(keyfile
, NULL
, NULL
, NULL
);
1012 * Check if this is the alt. format
1013 * RSA private key file.
1015 rv
= kmf_read_input_file(kmfh
, (char *)file
,
1020 rv
= kmf_pem_to_der(filedata
.Data
,
1021 filedata
.Length
, &d
, &len
);
1022 if (rv
== KMF_OK
&& d
!= NULL
) {
1024 derdata
.Length
= (size_t)len
;
1025 (void) readAltFormatPrivateKey(
1029 kmf_free_data(&filedata
);
1036 SET_ERROR(kmfh
, ERR_get_error());
1038 if (keyfile
!= NULL
)
1039 (void) BIO_free(keyfile
);
1045 OpenSSL_FindCert(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
1047 KMF_RETURN rv
= KMF_OK
;
1048 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1050 uint32_t maxcerts
= 0;
1051 uint32_t *num_certs
;
1052 KMF_X509_DER_CERT
*kmf_cert
= NULL
;
1053 char *dirpath
= NULL
;
1054 char *filename
= NULL
;
1055 char *fullpath
= NULL
;
1056 char *issuer
= NULL
;
1057 char *subject
= NULL
;
1058 KMF_BIGINT
*serial
= NULL
;
1059 KMF_CERT_VALIDITY validity
;
1061 num_certs
= kmf_get_attr_ptr(KMF_COUNT_ATTR
, attrlist
, numattr
);
1062 if (num_certs
== NULL
)
1063 return (KMF_ERR_BAD_PARAMETER
);
1065 /* num_certs should reference the size of kmf_cert */
1066 maxcerts
= *num_certs
;
1068 maxcerts
= 0xFFFFFFFF;
1071 /* Get the optional returned certificate list */
1072 kmf_cert
= kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR
, attrlist
,
1076 * The dirpath attribute and the filename attribute can not be NULL
1079 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
1080 filename
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
,
1083 fullpath
= get_fullpath(dirpath
, filename
);
1084 if (fullpath
== NULL
)
1085 return (KMF_ERR_BAD_PARAMETER
);
1087 /* Get optional search criteria attributes */
1088 issuer
= kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR
, attrlist
, numattr
);
1089 subject
= kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR
, attrlist
, numattr
);
1090 serial
= kmf_get_attr_ptr(KMF_BIGINT_ATTR
, attrlist
, numattr
);
1091 rv
= kmf_get_attr(KMF_CERT_VALIDITY_ATTR
, attrlist
, numattr
,
1094 validity
= KMF_ALL_CERTS
;
1098 if (isdir(fullpath
)) {
1103 /* open all files in the directory and attempt to read them */
1104 if ((dirp
= opendir(fullpath
)) == NULL
) {
1105 return (KMF_ERR_BAD_PARAMETER
);
1107 while ((dp
= readdir(dirp
)) != NULL
) {
1109 KMF_DATA
*certlist
= NULL
;
1110 uint32_t loaded_certs
= 0;
1112 if (strcmp(dp
->d_name
, ".") == 0 ||
1113 strcmp(dp
->d_name
, "..") == 0)
1116 fname
= get_fullpath(fullpath
, (char *)&dp
->d_name
);
1118 rv
= load_certs(kmfh
, issuer
, subject
, serial
,
1119 validity
, fname
, &certlist
, &loaded_certs
);
1123 if (certlist
!= NULL
) {
1124 for (i
= 0; i
< loaded_certs
; i
++)
1125 kmf_free_data(&certlist
[i
]);
1131 /* If load succeeds, add certdata to the list */
1132 if (kmf_cert
!= NULL
) {
1133 for (i
= 0; i
< loaded_certs
&&
1134 n
< maxcerts
; i
++) {
1135 kmf_cert
[n
].certificate
.Data
=
1137 kmf_cert
[n
].certificate
.Length
=
1140 kmf_cert
[n
].kmf_private
.keystore_type
=
1141 KMF_KEYSTORE_OPENSSL
;
1142 kmf_cert
[n
].kmf_private
.flags
=
1143 KMF_FLAG_CERT_VALID
;
1144 kmf_cert
[n
].kmf_private
.label
=
1149 * If maxcerts < loaded_certs, clean up the
1150 * certs that were not used.
1152 for (; i
< loaded_certs
; i
++)
1153 kmf_free_data(&certlist
[i
]);
1155 for (i
= 0; i
< loaded_certs
; i
++)
1156 kmf_free_data(&certlist
[i
]);
1163 if (*num_certs
== 0)
1164 rv
= KMF_ERR_CERT_NOT_FOUND
;
1168 (void) closedir(dirp
);
1170 KMF_DATA
*certlist
= NULL
;
1171 uint32_t loaded_certs
= 0;
1173 rv
= load_certs(kmfh
, issuer
, subject
, serial
, validity
,
1174 fullpath
, &certlist
, &loaded_certs
);
1181 if (kmf_cert
!= NULL
&& certlist
!= NULL
) {
1182 for (i
= 0; i
< loaded_certs
&& i
< maxcerts
; i
++) {
1183 kmf_cert
[n
].certificate
.Data
=
1185 kmf_cert
[n
].certificate
.Length
=
1187 kmf_cert
[n
].kmf_private
.keystore_type
=
1188 KMF_KEYSTORE_OPENSSL
;
1189 kmf_cert
[n
].kmf_private
.flags
=
1190 KMF_FLAG_CERT_VALID
;
1191 kmf_cert
[n
].kmf_private
.label
=
1195 /* If maxcerts < loaded_certs, clean up */
1196 for (; i
< loaded_certs
; i
++)
1197 kmf_free_data(&certlist
[i
]);
1198 } else if (certlist
!= NULL
) {
1199 for (i
= 0; i
< loaded_certs
; i
++)
1200 kmf_free_data(&certlist
[i
]);
1203 if (certlist
!= NULL
)
1215 OpenSSL_FreeKMFCert(KMF_HANDLE_T handle
,
1216 KMF_X509_DER_CERT
*kmf_cert
)
1218 if (kmf_cert
!= NULL
) {
1219 if (kmf_cert
->certificate
.Data
!= NULL
) {
1220 kmf_free_data(&kmf_cert
->certificate
);
1222 if (kmf_cert
->kmf_private
.label
)
1223 free(kmf_cert
->kmf_private
.label
);
1229 OpenSSL_StoreCert(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
1231 KMF_RETURN ret
= KMF_OK
;
1232 KMF_DATA
*cert
= NULL
;
1233 char *outfilename
= NULL
;
1234 char *dirpath
= NULL
;
1235 char *fullpath
= NULL
;
1236 KMF_ENCODE_FORMAT format
;
1238 /* Get the cert data */
1239 cert
= kmf_get_attr_ptr(KMF_CERT_DATA_ATTR
, attrlist
, numattr
);
1240 if (cert
== NULL
|| cert
->Data
== NULL
)
1241 return (KMF_ERR_BAD_PARAMETER
);
1243 /* Check the output filename and directory attributes. */
1244 outfilename
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
,
1246 if (outfilename
== NULL
)
1247 return (KMF_ERR_BAD_PARAMETER
);
1249 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
1250 fullpath
= get_fullpath(dirpath
, outfilename
);
1251 if (fullpath
== NULL
)
1252 return (KMF_ERR_BAD_CERTFILE
);
1254 /* Check the optional format attribute */
1255 ret
= kmf_get_attr(KMF_ENCODE_FORMAT_ATTR
, attrlist
, numattr
,
1257 if (ret
!= KMF_OK
) {
1258 /* If there is no format attribute, then default to PEM */
1259 format
= KMF_FORMAT_PEM
;
1261 } else if (format
!= KMF_FORMAT_ASN1
&& format
!= KMF_FORMAT_PEM
) {
1262 ret
= KMF_ERR_BAD_CERT_FORMAT
;
1266 /* Store the certificate in the file with the specified format */
1267 ret
= kmf_create_cert_file(cert
, format
, fullpath
);
1270 if (fullpath
!= NULL
)
1278 OpenSSL_DeleteCert(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
1281 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1282 KMF_DATA certdata
= { 0, NULL
};
1283 char *dirpath
= NULL
;
1284 char *filename
= NULL
;
1285 char *fullpath
= NULL
;
1286 char *issuer
= NULL
;
1287 char *subject
= NULL
;
1288 KMF_BIGINT
*serial
= NULL
;
1289 KMF_CERT_VALIDITY validity
;
1292 * Get the DIRPATH and CERT_FILENAME attributes. They can not be
1293 * NULL at the same time.
1295 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
1296 filename
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
,
1298 fullpath
= get_fullpath(dirpath
, filename
);
1299 if (fullpath
== NULL
)
1300 return (KMF_ERR_BAD_PARAMETER
);
1302 /* Get optional search criteria attributes */
1303 issuer
= kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR
, attrlist
, numattr
);
1304 subject
= kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR
, attrlist
, numattr
);
1305 serial
= kmf_get_attr_ptr(KMF_BIGINT_ATTR
, attrlist
, numattr
);
1306 rv
= kmf_get_attr(KMF_CERT_VALIDITY_ATTR
, attrlist
, numattr
,
1309 validity
= KMF_ALL_CERTS
;
1313 if (isdir(fullpath
)) {
1317 /* open all files in the directory and attempt to read them */
1318 if ((dirp
= opendir(fullpath
)) == NULL
) {
1319 return (KMF_ERR_BAD_PARAMETER
);
1322 while ((dp
= readdir(dirp
)) != NULL
) {
1323 if (strcmp(dp
->d_name
, ".") != 0 &&
1324 strcmp(dp
->d_name
, "..") != 0) {
1327 fname
= get_fullpath(fullpath
,
1328 (char *)&dp
->d_name
);
1330 if (fname
== NULL
) {
1331 rv
= KMF_ERR_MEMORY
;
1335 rv
= kmf_load_cert(kmfh
, issuer
, subject
,
1336 serial
, validity
, fname
, &certdata
);
1338 if (rv
== KMF_ERR_CERT_NOT_FOUND
) {
1340 kmf_free_data(&certdata
);
1343 } else if (rv
!= KMF_OK
) {
1348 if (unlink(fname
) != 0) {
1349 SET_SYS_ERROR(kmfh
, errno
);
1350 rv
= KMF_ERR_INTERNAL
;
1355 kmf_free_data(&certdata
);
1358 (void) closedir(dirp
);
1360 /* Just try to load a single certificate */
1361 rv
= kmf_load_cert(kmfh
, issuer
, subject
, serial
, validity
,
1362 fullpath
, &certdata
);
1364 if (unlink(fullpath
) != 0) {
1365 SET_SYS_ERROR(kmfh
, errno
);
1366 rv
= KMF_ERR_INTERNAL
;
1372 if (fullpath
!= NULL
)
1375 kmf_free_data(&certdata
);
1381 OpenSSL_EncodePubKeyData(KMF_HANDLE_T handle
, KMF_KEY_HANDLE
*key
,
1384 KMF_RETURN rv
= KMF_OK
;
1385 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1388 if (key
== NULL
|| keydata
== NULL
||
1390 return (KMF_ERR_BAD_PARAMETER
);
1392 if (key
->keyalg
== KMF_RSA
) {
1393 RSA
*pubkey
= EVP_PKEY_get1_RSA(key
->keyp
);
1395 if (!(n
= i2d_RSA_PUBKEY(pubkey
, &keydata
->Data
))) {
1396 SET_ERROR(kmfh
, ERR_get_error());
1397 return (KMF_ERR_ENCODING
);
1400 } else if (key
->keyalg
== KMF_DSA
) {
1401 DSA
*pubkey
= EVP_PKEY_get1_DSA(key
->keyp
);
1403 if (!(n
= i2d_DSA_PUBKEY(pubkey
, &keydata
->Data
))) {
1404 SET_ERROR(kmfh
, ERR_get_error());
1405 return (KMF_ERR_ENCODING
);
1409 return (KMF_ERR_BAD_PARAMETER
);
1411 keydata
->Length
= n
;
1416 free(keydata
->Data
);
1417 keydata
->Data
= NULL
;
1418 keydata
->Length
= 0;
1425 ssl_write_key(KMF_HANDLE
*kmfh
, KMF_ENCODE_FORMAT format
, BIO
*out
,
1426 KMF_CREDENTIAL
*cred
, EVP_PKEY
*pkey
, boolean_t
private)
1432 if (pkey
== NULL
|| out
== NULL
)
1433 return (KMF_ERR_BAD_PARAMETER
);
1436 case KMF_FORMAT_RAWKEY
:
1438 case KMF_FORMAT_ASN1
:
1439 if ((rsa
= EVP_PKEY_get0_RSA(pkey
)) != NULL
) {
1441 rv
= i2d_RSAPrivateKey_bio(out
, rsa
);
1443 rv
= i2d_RSAPublicKey_bio(out
, rsa
);
1444 } else if ((dsa
= EVP_PKEY_get0_DSA(pkey
)) != NULL
) {
1445 rv
= i2d_DSAPrivateKey_bio(out
, dsa
);
1450 SET_ERROR(kmfh
, rv
);
1453 case KMF_FORMAT_PEM
:
1454 if ((rsa
= EVP_PKEY_get0_RSA(pkey
)) != NULL
) {
1456 rv
= PEM_write_bio_RSAPrivateKey(out
,
1457 rsa
, NULL
, NULL
, 0, NULL
,
1458 (cred
!= NULL
? cred
->cred
: NULL
));
1460 rv
= PEM_write_bio_RSAPublicKey(out
,
1462 } else if ((dsa
= EVP_PKEY_get0_DSA(pkey
)) != NULL
) {
1463 rv
= PEM_write_bio_DSAPrivateKey(out
,
1464 dsa
, NULL
, NULL
, 0, NULL
,
1465 (cred
!= NULL
? cred
->cred
: NULL
));
1471 SET_ERROR(kmfh
, rv
);
1476 rv
= KMF_ERR_BAD_PARAMETER
;
1483 OpenSSL_CreateKeypair(KMF_HANDLE_T handle
, int numattr
,
1484 KMF_ATTRIBUTE
*attrlist
)
1486 KMF_RETURN rv
= KMF_OK
;
1487 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1488 uint32_t eValue
= RSA_F4
;
1489 BIGNUM
*eValue_bn
= NULL
;
1490 RSA
*sslPrivKey
= NULL
;
1491 DSA
*sslDSAKey
= NULL
;
1492 EVP_PKEY
*eprikey
= NULL
;
1493 EVP_PKEY
*epubkey
= NULL
;
1495 KMF_KEY_HANDLE
*pubkey
= NULL
, *privkey
= NULL
;
1496 uint32_t keylen
= 1024;
1497 uint32_t keylen_size
= sizeof (uint32_t);
1498 boolean_t storekey
= TRUE
;
1499 KMF_KEY_ALG keytype
= KMF_RSA
;
1501 eValue_bn
= BN_new();
1502 if (eValue_bn
== NULL
)
1503 return (KMF_ERR_MEMORY
);
1504 if (BN_set_word(eValue_bn
, eValue
) == 0) {
1505 rv
= KMF_ERR_KEYGEN_FAILED
;
1509 rv
= kmf_get_attr(KMF_STOREKEY_BOOL_ATTR
, attrlist
, numattr
,
1512 /* "storekey" is optional. Default is TRUE */
1516 rv
= kmf_get_attr(KMF_KEYALG_ATTR
, attrlist
, numattr
,
1517 (void *)&keytype
, NULL
);
1519 /* keytype is optional. KMF_RSA is default */
1522 pubkey
= kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR
, attrlist
, numattr
);
1523 if (pubkey
== NULL
) {
1524 rv
= KMF_ERR_BAD_PARAMETER
;
1528 privkey
= kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR
, attrlist
, numattr
);
1529 if (privkey
== NULL
) {
1530 rv
= KMF_ERR_BAD_PARAMETER
;
1534 (void) memset(pubkey
, 0, sizeof (KMF_KEY_HANDLE
));
1535 (void) memset(privkey
, 0, sizeof (KMF_KEY_HANDLE
));
1537 eprikey
= EVP_PKEY_new();
1538 if (eprikey
== NULL
) {
1539 SET_ERROR(kmfh
, ERR_get_error());
1540 rv
= KMF_ERR_KEYGEN_FAILED
;
1543 epubkey
= EVP_PKEY_new();
1544 if (epubkey
== NULL
) {
1545 SET_ERROR(kmfh
, ERR_get_error());
1546 rv
= KMF_ERR_KEYGEN_FAILED
;
1549 if (keytype
== KMF_RSA
) {
1550 KMF_BIGINT
*rsaexp
= NULL
;
1552 rsaexp
= kmf_get_attr_ptr(KMF_RSAEXP_ATTR
, attrlist
, numattr
);
1553 if (rsaexp
!= NULL
) {
1554 if (rsaexp
->len
> 0 &&
1555 rsaexp
->len
<= sizeof (eValue
) &&
1556 rsaexp
->val
!= NULL
) {
1557 /* LINTED E_BAD_PTR_CAST_ALIGN */
1558 eValue
= *(uint32_t *)rsaexp
->val
;
1559 if (BN_set_word(eValue_bn
, eValue
) == 0) {
1560 rv
= KMF_ERR_BAD_PARAMETER
;
1564 rv
= KMF_ERR_BAD_PARAMETER
;
1568 /* RSA Exponent is optional. Default is 0x10001 */
1572 rv
= kmf_get_attr(KMF_KEYLENGTH_ATTR
, attrlist
, numattr
,
1573 &keylen
, &keylen_size
);
1574 if (rv
== KMF_ERR_ATTR_NOT_FOUND
)
1575 /* keylen is optional, default is 1024 */
1578 rv
= KMF_ERR_BAD_PARAMETER
;
1582 sslPrivKey
= RSA_new();
1583 if (sslPrivKey
== NULL
||
1584 RSA_generate_key_ex(sslPrivKey
, keylen
, eValue_bn
, NULL
)
1586 SET_ERROR(kmfh
, ERR_get_error());
1587 rv
= KMF_ERR_KEYGEN_FAILED
;
1589 (void) EVP_PKEY_set1_RSA(eprikey
, sslPrivKey
);
1590 privkey
->kstype
= KMF_KEYSTORE_OPENSSL
;
1591 privkey
->keyalg
= KMF_RSA
;
1592 privkey
->keyclass
= KMF_ASYM_PRI
;
1593 privkey
->israw
= FALSE
;
1594 privkey
->keyp
= (void *)eprikey
;
1596 /* OpenSSL derives the public key from the private */
1597 (void) EVP_PKEY_set1_RSA(epubkey
, sslPrivKey
);
1598 pubkey
->kstype
= KMF_KEYSTORE_OPENSSL
;
1599 pubkey
->keyalg
= KMF_RSA
;
1600 pubkey
->israw
= FALSE
;
1601 pubkey
->keyclass
= KMF_ASYM_PUB
;
1602 pubkey
->keyp
= (void *)epubkey
;
1604 } else if (keytype
== KMF_DSA
) {
1607 sslDSAKey
= DSA_new();
1608 if (sslDSAKey
== NULL
) {
1609 SET_ERROR(kmfh
, ERR_get_error());
1610 return (KMF_ERR_MEMORY
);
1613 p
= BN_bin2bn(P
, sizeof (P
), NULL
);
1614 q
= BN_bin2bn(Q
, sizeof (Q
), NULL
);
1615 g
= BN_bin2bn(G
, sizeof (G
), NULL
);
1616 if (p
== NULL
|| q
== NULL
|| g
== NULL
) {
1620 SET_ERROR(kmfh
, ERR_get_error());
1621 rv
= KMF_ERR_KEYGEN_FAILED
;
1625 if (DSA_set0_pqg(sslDSAKey
, p
, q
, g
) == 0) {
1626 SET_ERROR(kmfh
, ERR_get_error());
1627 rv
= KMF_ERR_KEYGEN_FAILED
;
1631 if (!DSA_generate_key(sslDSAKey
)) {
1632 SET_ERROR(kmfh
, ERR_get_error());
1633 rv
= KMF_ERR_KEYGEN_FAILED
;
1637 privkey
->kstype
= KMF_KEYSTORE_OPENSSL
;
1638 privkey
->keyalg
= KMF_DSA
;
1639 privkey
->keyclass
= KMF_ASYM_PRI
;
1640 privkey
->israw
= FALSE
;
1641 if (EVP_PKEY_set1_DSA(eprikey
, sslDSAKey
)) {
1642 privkey
->keyp
= (void *)eprikey
;
1644 SET_ERROR(kmfh
, ERR_get_error());
1645 rv
= KMF_ERR_KEYGEN_FAILED
;
1649 pubkey
->kstype
= KMF_KEYSTORE_OPENSSL
;
1650 pubkey
->keyalg
= KMF_DSA
;
1651 pubkey
->keyclass
= KMF_ASYM_PUB
;
1652 pubkey
->israw
= FALSE
;
1654 if (EVP_PKEY_set1_DSA(epubkey
, sslDSAKey
)) {
1655 pubkey
->keyp
= (void *)epubkey
;
1657 SET_ERROR(kmfh
, ERR_get_error());
1658 rv
= KMF_ERR_KEYGEN_FAILED
;
1668 KMF_ATTRIBUTE storeattrs
[4]; /* max. 4 attributes needed */
1670 char *keyfile
= NULL
, *dirpath
= NULL
;
1671 KMF_ENCODE_FORMAT format
;
1673 * Construct a new attribute arrray and call openssl_store_key
1675 kmf_set_attr_at_index(storeattrs
, i
, KMF_PRIVKEY_HANDLE_ATTR
,
1676 privkey
, sizeof (privkey
));
1679 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
1680 if (dirpath
!= NULL
) {
1681 storeattrs
[i
].type
= KMF_DIRPATH_ATTR
;
1682 storeattrs
[i
].pValue
= dirpath
;
1683 storeattrs
[i
].valueLen
= strlen(dirpath
);
1686 rv
= KMF_OK
; /* DIRPATH is optional */
1688 keyfile
= kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
,
1690 if (keyfile
!= NULL
) {
1691 storeattrs
[i
].type
= KMF_KEY_FILENAME_ATTR
;
1692 storeattrs
[i
].pValue
= keyfile
;
1693 storeattrs
[i
].valueLen
= strlen(keyfile
);
1696 goto cleanup
; /* KEYFILE is required */
1698 rv
= kmf_get_attr(KMF_ENCODE_FORMAT_ATTR
, attrlist
, numattr
,
1699 (void *)&format
, NULL
);
1701 storeattrs
[i
].type
= KMF_ENCODE_FORMAT_ATTR
;
1702 storeattrs
[i
].pValue
= &format
;
1703 storeattrs
[i
].valueLen
= sizeof (format
);
1707 rv
= OpenSSL_StoreKey(handle
, i
, storeattrs
);
1711 if (eValue_bn
!= NULL
)
1715 if (eprikey
!= NULL
)
1716 EVP_PKEY_free(eprikey
);
1718 if (epubkey
!= NULL
)
1719 EVP_PKEY_free(epubkey
);
1721 if (pubkey
->keylabel
) {
1722 free(pubkey
->keylabel
);
1723 pubkey
->keylabel
= NULL
;
1726 if (privkey
->keylabel
) {
1727 free(privkey
->keylabel
);
1728 privkey
->keylabel
= NULL
;
1731 pubkey
->keyp
= NULL
;
1732 privkey
->keyp
= NULL
;
1736 RSA_free(sslPrivKey
);
1739 DSA_free(sslDSAKey
);
1742 (void) BIO_free(out
);
1748 * Make sure the BN conversion is properly padded with 0x00
1749 * bytes. If not, signature verification for DSA signatures
1750 * may fail in the case where the bignum value does not use
1754 fixbnlen(const BIGNUM
*bn
, unsigned char *buf
, int len
) {
1755 int bytes
= len
- BN_num_bytes(bn
);
1757 /* prepend with leading 0x00 if necessary */
1761 (void) BN_bn2bin(bn
, buf
);
1763 * Return the desired length since we prepended it
1764 * with the necessary 0x00 padding.
1770 OpenSSL_SignData(KMF_HANDLE_T handle
, KMF_KEY_HANDLE
*key
,
1771 KMF_OID
*AlgOID
, KMF_DATA
*tobesigned
, KMF_DATA
*output
)
1773 KMF_RETURN ret
= KMF_OK
;
1774 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1775 KMF_ALGORITHM_INDEX AlgId
;
1779 if (key
== NULL
|| AlgOID
== NULL
||
1780 tobesigned
== NULL
|| output
== NULL
||
1781 tobesigned
->Data
== NULL
||
1782 output
->Data
== NULL
)
1783 return (KMF_ERR_BAD_PARAMETER
);
1785 /* Map the OID to an OpenSSL algorithm */
1786 AlgId
= x509_algoid_to_algid(AlgOID
);
1787 if (AlgId
== KMF_ALGID_NONE
)
1788 return (KMF_ERR_BAD_ALGORITHM
);
1790 if (key
->keyalg
== KMF_RSA
) {
1791 EVP_PKEY
*pkey
= (EVP_PKEY
*)key
->keyp
;
1794 if (AlgId
== KMF_ALGID_MD5WithRSA
)
1796 else if (AlgId
== KMF_ALGID_SHA1WithRSA
)
1798 else if (AlgId
== KMF_ALGID_SHA256WithRSA
)
1800 else if (AlgId
== KMF_ALGID_SHA384WithRSA
)
1802 else if (AlgId
== KMF_ALGID_SHA512WithRSA
)
1804 else if (AlgId
== KMF_ALGID_RSA
)
1807 return (KMF_ERR_BAD_ALGORITHM
);
1809 if ((md
== NULL
) && (AlgId
== KMF_ALGID_RSA
)) {
1810 RSA
*rsa
= EVP_PKEY_get1_RSA((EVP_PKEY
*)pkey
);
1813 if ((len
= RSA_private_encrypt(tobesigned
->Length
,
1814 tobesigned
->Data
, p
, rsa
,
1815 RSA_PKCS1_PADDING
)) <= 0) {
1816 SET_ERROR(kmfh
, ERR_get_error());
1817 ret
= KMF_ERR_INTERNAL
;
1819 output
->Length
= len
;
1821 if ((ctx
= EVP_MD_CTX_new()) == NULL
)
1822 return (KMF_ERR_MEMORY
);
1823 (void) EVP_SignInit_ex(ctx
, md
, NULL
);
1824 (void) EVP_SignUpdate(ctx
, tobesigned
->Data
,
1825 (uint32_t)tobesigned
->Length
);
1826 len
= (uint32_t)output
->Length
;
1828 if (!EVP_SignFinal(ctx
, p
, (uint32_t *)&len
, pkey
)) {
1829 SET_ERROR(kmfh
, ERR_get_error());
1831 ret
= KMF_ERR_INTERNAL
;
1833 output
->Length
= len
;
1834 EVP_MD_CTX_free(ctx
);
1836 } else if (key
->keyalg
== KMF_DSA
) {
1837 DSA
*dsa
= EVP_PKEY_get1_DSA(key
->keyp
);
1839 uchar_t hash
[EVP_MAX_MD_SIZE
];
1843 if (AlgId
== KMF_ALGID_DSA
||
1844 AlgId
== KMF_ALGID_SHA1WithDSA
)
1846 else if (AlgId
== KMF_ALGID_SHA256WithDSA
)
1848 else /* Bad algorithm */
1849 return (KMF_ERR_BAD_ALGORITHM
);
1852 * OpenSSL EVP_Sign operation automatically converts to
1853 * ASN.1 output so we do the operations separately so we
1854 * are assured of NOT getting ASN.1 output returned.
1855 * KMF does not want ASN.1 encoded results because
1856 * not all mechanisms return ASN.1 encodings (PKCS#11
1857 * and NSS return raw signature data).
1859 if ((ctx
= EVP_MD_CTX_new()) == NULL
)
1860 return (KMF_ERR_MEMORY
);
1861 (void) EVP_DigestInit_ex(ctx
, md
, NULL
);
1862 (void) EVP_DigestUpdate(ctx
, tobesigned
->Data
,
1863 tobesigned
->Length
);
1864 (void) EVP_DigestFinal_ex(ctx
, hash
, &hashlen
);
1866 /* Only sign first 20 bytes for SHA2 */
1867 if (AlgId
== KMF_ALGID_SHA256WithDSA
)
1869 dsasig
= DSA_do_sign(hash
, hashlen
, dsa
);
1870 if (dsasig
!= NULL
) {
1872 const BIGNUM
*r
, *s
;
1874 DSA_SIG_get0(dsasig
, &r
, &s
);
1875 output
->Length
= i
= fixbnlen(r
, output
->Data
,
1878 output
->Length
+= fixbnlen(s
, &output
->Data
[i
],
1881 DSA_SIG_free(dsasig
);
1883 SET_ERROR(kmfh
, ERR_get_error());
1885 EVP_MD_CTX_free(ctx
);
1887 return (KMF_ERR_BAD_PARAMETER
);
1895 OpenSSL_DeleteKey(KMF_HANDLE_T handle
,
1896 int numattr
, KMF_ATTRIBUTE
*attrlist
)
1898 KMF_RETURN rv
= KMF_OK
;
1899 KMF_KEY_HANDLE
*key
;
1900 boolean_t destroy
= B_TRUE
;
1902 key
= kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR
, attrlist
, numattr
);
1903 if (key
== NULL
|| key
->keyp
== NULL
)
1904 return (KMF_ERR_BAD_PARAMETER
);
1906 rv
= kmf_get_attr(KMF_DESTROY_BOOL_ATTR
, attrlist
, numattr
,
1907 (void *)&destroy
, NULL
);
1909 /* "destroy" is optional. Default is TRUE */
1913 if (key
->keyclass
!= KMF_ASYM_PUB
&&
1914 key
->keyclass
!= KMF_ASYM_PRI
&&
1915 key
->keyclass
!= KMF_SYMMETRIC
)
1916 return (KMF_ERR_BAD_KEY_CLASS
);
1918 if (key
->keyclass
== KMF_SYMMETRIC
) {
1919 kmf_free_raw_sym_key((KMF_RAW_SYM_KEY
*)key
->keyp
);
1922 if (key
->keyp
!= NULL
) {
1923 EVP_PKEY_free(key
->keyp
);
1928 if (key
->keylabel
!= NULL
) {
1929 EVP_PKEY
*pkey
= NULL
;
1930 /* If the file exists, make sure it is a proper key. */
1931 pkey
= openssl_load_key(handle
, key
->keylabel
);
1933 if (key
->keylabel
!= NULL
) {
1934 free(key
->keylabel
);
1935 key
->keylabel
= NULL
;
1937 return (KMF_ERR_KEY_NOT_FOUND
);
1939 EVP_PKEY_free(pkey
);
1942 if (unlink(key
->keylabel
) != 0) {
1943 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1944 SET_SYS_ERROR(kmfh
, errno
);
1945 rv
= KMF_ERR_INTERNAL
;
1948 if (key
->keylabel
!= NULL
) {
1949 free(key
->keylabel
);
1950 key
->keylabel
= NULL
;
1957 OpenSSL_GetErrorString(KMF_HANDLE_T handle
, char **msgstr
)
1959 KMF_RETURN ret
= KMF_OK
;
1960 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1961 char str
[256]; /* OpenSSL needs at least 120 byte buffer */
1963 ERR_error_string_n(kmfh
->lasterr
.errcode
, str
, sizeof (str
));
1965 *msgstr
= (char *)strdup(str
);
1966 if ((*msgstr
) == NULL
)
1967 ret
= KMF_ERR_MEMORY
;
1979 case KMF_X509_EXT_KEY_USAGE
:
1980 return (NID_key_usage
);
1981 case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD
:
1982 return (NID_private_key_usage_period
);
1983 case KMF_X509_EXT_CERT_POLICIES
:
1984 return (NID_certificate_policies
);
1985 case KMF_X509_EXT_SUBJ_ALTNAME
:
1986 return (NID_subject_alt_name
);
1987 case KMF_X509_EXT_ISSUER_ALTNAME
:
1988 return (NID_issuer_alt_name
);
1989 case KMF_X509_EXT_BASIC_CONSTRAINTS
:
1990 return (NID_basic_constraints
);
1991 case KMF_X509_EXT_EXT_KEY_USAGE
:
1992 return (NID_ext_key_usage
);
1993 case KMF_X509_EXT_AUTH_KEY_ID
:
1994 return (NID_authority_key_identifier
);
1995 case KMF_X509_EXT_CRL_DIST_POINTS
:
1996 return (NID_crl_distribution_points
);
1997 case KMF_X509_EXT_SUBJ_KEY_ID
:
1998 return (NID_subject_key_identifier
);
1999 case KMF_X509_EXT_POLICY_MAPPINGS
:
2000 return (OBJ_sn2nid("policyMappings"));
2001 case KMF_X509_EXT_NAME_CONSTRAINTS
:
2002 return (OBJ_sn2nid("nameConstraints"));
2003 case KMF_X509_EXT_POLICY_CONSTRAINTS
:
2004 return (OBJ_sn2nid("policyConstraints"));
2005 case KMF_X509_EXT_INHIBIT_ANY_POLICY
:
2006 return (OBJ_sn2nid("inhibitAnyPolicy"));
2007 case KMF_X509_EXT_FRESHEST_CRL
:
2008 return (OBJ_sn2nid("freshestCRL"));
2015 OpenSSL_CertGetPrintable(KMF_HANDLE_T handle
, const KMF_DATA
*pcert
,
2016 KMF_PRINTABLE_ITEM flag
, char *resultStr
)
2018 KMF_RETURN ret
= KMF_OK
;
2019 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2021 unsigned char *outbuf
= NULL
;
2022 unsigned char *outbuf_p
;
2024 int ext_index
, nid
, len
;
2026 STACK_OF(OPENSSL_STRING
) *emlst
= NULL
;
2029 if (pcert
== NULL
|| pcert
->Data
== NULL
|| pcert
->Length
== 0) {
2030 return (KMF_ERR_BAD_PARAMETER
);
2033 /* copy cert data to outbuf */
2034 outbuf
= malloc(pcert
->Length
);
2035 if (outbuf
== NULL
) {
2036 return (KMF_ERR_MEMORY
);
2038 (void) memcpy(outbuf
, pcert
->Data
, pcert
->Length
);
2040 outbuf_p
= outbuf
; /* use a temp pointer; required by openssl */
2041 xcert
= d2i_X509(NULL
, (const uchar_t
**)&outbuf_p
, pcert
->Length
);
2042 if (xcert
== NULL
) {
2043 SET_ERROR(kmfh
, ERR_get_error());
2044 ret
= KMF_ERR_ENCODING
;
2048 mem
= BIO_new(BIO_s_mem());
2050 SET_ERROR(kmfh
, ERR_get_error());
2051 ret
= KMF_ERR_MEMORY
;
2056 case KMF_CERT_ISSUER
:
2057 (void) X509_NAME_print_ex(mem
, X509_get_issuer_name(xcert
), 0,
2058 XN_FLAG_SEP_CPLUS_SPC
);
2059 len
= BIO_gets(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2062 case KMF_CERT_SUBJECT
:
2063 (void) X509_NAME_print_ex(mem
, X509_get_subject_name(xcert
), 0,
2064 XN_FLAG_SEP_CPLUS_SPC
);
2065 len
= BIO_gets(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2068 case KMF_CERT_VERSION
:
2069 (void) snprintf(resultStr
, KMF_CERT_PRINTABLE_LEN
,
2070 "%ld", X509_get_version(xcert
));
2071 len
= strlen(resultStr
);
2074 case KMF_CERT_SERIALNUM
:
2075 if (i2a_ASN1_INTEGER(mem
, X509_get_serialNumber(xcert
)) > 0) {
2076 (void) strcpy(resultStr
, "0x");
2077 len
= BIO_gets(mem
, &resultStr
[2],
2078 KMF_CERT_PRINTABLE_LEN
- 2);
2082 case KMF_CERT_NOTBEFORE
:
2083 (void) ASN1_TIME_print(mem
, X509_getm_notBefore(xcert
));
2084 len
= BIO_gets(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2087 case KMF_CERT_NOTAFTER
:
2088 (void) ASN1_TIME_print(mem
, X509_getm_notAfter(xcert
));
2089 len
= BIO_gets(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2092 case KMF_CERT_PUBKEY_DATA
:
2097 EVP_PKEY
*pkey
= X509_get_pubkey(xcert
);
2099 SET_ERROR(kmfh
, ERR_get_error());
2100 ret
= KMF_ERR_ENCODING
;
2104 if ((rsa
= EVP_PKEY_get0_RSA(pkey
)) != NULL
) {
2105 (void) BIO_printf(mem
,
2106 "RSA Public Key: (%d bit)\n",
2108 (void) RSA_print(mem
, rsa
, 0);
2110 } else if ((dsa
= EVP_PKEY_get0_DSA(pkey
)) != NULL
) {
2111 (void) BIO_printf(mem
,
2112 "%12sDSA Public Key:\n", "");
2113 (void) DSA_print(mem
, dsa
, 0);
2115 (void) BIO_printf(mem
,
2116 "%12sUnknown Public Key:\n", "");
2118 (void) BIO_printf(mem
, "\n");
2119 EVP_PKEY_free(pkey
);
2121 len
= BIO_read(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2123 case KMF_CERT_SIGNATURE_ALG
:
2124 case KMF_CERT_PUBKEY_ALG
:
2126 #if OPENSSL_VERSION_NUMBER < 0x10100000L
2127 ASN1_OBJECT
*alg
= NULL
;
2129 const ASN1_OBJECT
*alg
= NULL
;
2132 if (flag
== KMF_CERT_SIGNATURE_ALG
) {
2133 #if OPENSSL_VERSION_NUMBER < 0x10100000L
2134 alg
= xcert
->sig_alg
->algorithm
;
2136 const X509_ALGOR
*sig_alg
= NULL
;
2138 X509_get0_signature(NULL
, &sig_alg
, xcert
);
2139 if (sig_alg
!= NULL
)
2140 X509_ALGOR_get0(&alg
, NULL
, NULL
,
2144 #if OPENSSL_VERSION_NUMBER < 0x10100000L
2145 alg
= xcert
->cert_info
->key
->algor
->algorithm
;
2147 X509_PUBKEY
*key
= X509_get_X509_PUBKEY(xcert
);
2150 (void) X509_PUBKEY_get0_param(
2151 (ASN1_OBJECT
**)&alg
, NULL
, 0,
2158 else if ((len
= i2a_ASN1_OBJECT(mem
, alg
)) > 0)
2159 len
= BIO_read(mem
, resultStr
,
2160 KMF_CERT_PRINTABLE_LEN
);
2164 case KMF_CERT_EMAIL
:
2165 emlst
= X509_get1_email(xcert
);
2166 for (j
= 0; j
< sk_OPENSSL_STRING_num(emlst
); j
++)
2167 (void) BIO_printf(mem
, "%s\n",
2168 sk_OPENSSL_STRING_value(emlst
, j
));
2170 len
= BIO_gets(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2171 X509_email_free(emlst
);
2173 case KMF_X509_EXT_ISSUER_ALTNAME
:
2174 case KMF_X509_EXT_SUBJ_ALTNAME
:
2175 case KMF_X509_EXT_KEY_USAGE
:
2176 case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD
:
2177 case KMF_X509_EXT_CERT_POLICIES
:
2178 case KMF_X509_EXT_BASIC_CONSTRAINTS
:
2179 case KMF_X509_EXT_NAME_CONSTRAINTS
:
2180 case KMF_X509_EXT_POLICY_CONSTRAINTS
:
2181 case KMF_X509_EXT_EXT_KEY_USAGE
:
2182 case KMF_X509_EXT_INHIBIT_ANY_POLICY
:
2183 case KMF_X509_EXT_AUTH_KEY_ID
:
2184 case KMF_X509_EXT_SUBJ_KEY_ID
:
2185 case KMF_X509_EXT_POLICY_MAPPINGS
:
2186 case KMF_X509_EXT_CRL_DIST_POINTS
:
2187 case KMF_X509_EXT_FRESHEST_CRL
:
2188 nid
= ext2NID(flag
);
2189 if (nid
== NID_undef
) {
2190 ret
= KMF_ERR_EXTENSION_NOT_FOUND
;
2194 ext_index
= X509_get_ext_by_NID(xcert
, nid
, -1);
2195 if (ext_index
== -1) {
2196 SET_ERROR(kmfh
, ERR_get_error());
2198 ret
= KMF_ERR_EXTENSION_NOT_FOUND
;
2201 ex
= X509_get_ext(xcert
, ext_index
);
2203 (void) i2a_ASN1_OBJECT(mem
, X509_EXTENSION_get_object(ex
));
2205 if (BIO_printf(mem
, ": %s\n",
2206 X509_EXTENSION_get_critical(ex
) ? "critical" : "") <= 0) {
2207 SET_ERROR(kmfh
, ERR_get_error());
2208 ret
= KMF_ERR_ENCODING
;
2211 if (!X509V3_EXT_print(mem
, ex
, X509V3_EXT_DUMP_UNKNOWN
, 4)) {
2212 (void) BIO_printf(mem
, "%*s", 4, "");
2213 (void) ASN1_STRING_print(mem
,
2214 X509_EXTENSION_get_data(ex
));
2216 if (BIO_write(mem
, "\n", 1) <= 0) {
2217 SET_ERROR(kmfh
, ERR_get_error());
2218 ret
= KMF_ERR_ENCODING
;
2221 len
= BIO_read(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2224 SET_ERROR(kmfh
, ERR_get_error());
2225 ret
= KMF_ERR_ENCODING
;
2229 if (outbuf
!= NULL
) {
2233 if (xcert
!= NULL
) {
2238 (void) BIO_free(mem
);
2246 OpenSSL_FindPrikeyByCert(KMF_HANDLE_T handle
, int numattr
,
2247 KMF_ATTRIBUTE
*attrlist
)
2249 KMF_RETURN rv
= KMF_OK
;
2250 KMF_KEYSTORE_TYPE kstype
= KMF_KEYSTORE_OPENSSL
;
2251 KMF_KEY_CLASS keyclass
= KMF_ASYM_PRI
;
2252 KMF_KEY_HANDLE
*key
= NULL
;
2253 uint32_t numkeys
= 1; /* 1 key only */
2254 char *dirpath
= NULL
;
2255 char *keyfile
= NULL
;
2256 KMF_ATTRIBUTE new_attrlist
[16];
2260 * This is really just a FindKey operation, reuse the
2263 kmf_set_attr_at_index(new_attrlist
, i
,
2264 KMF_KEYSTORE_TYPE_ATTR
, &kstype
, sizeof (kstype
));
2267 kmf_set_attr_at_index(new_attrlist
, i
,
2268 KMF_COUNT_ATTR
, &numkeys
, sizeof (uint32_t));
2271 kmf_set_attr_at_index(new_attrlist
, i
,
2272 KMF_KEYCLASS_ATTR
, &keyclass
, sizeof (keyclass
));
2275 key
= kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR
, attrlist
, numattr
);
2277 return (KMF_ERR_BAD_PARAMETER
);
2279 kmf_set_attr_at_index(new_attrlist
, i
,
2280 KMF_KEY_HANDLE_ATTR
, key
, sizeof (KMF_KEY_HANDLE
));
2284 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
2285 if (dirpath
!= NULL
) {
2286 kmf_set_attr_at_index(new_attrlist
, i
,
2287 KMF_DIRPATH_ATTR
, dirpath
, strlen(dirpath
));
2291 keyfile
= kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
, attrlist
, numattr
);
2292 if (keyfile
== NULL
)
2293 return (KMF_ERR_BAD_PARAMETER
);
2295 kmf_set_attr_at_index(new_attrlist
, i
,
2296 KMF_KEY_FILENAME_ATTR
, keyfile
, strlen(keyfile
));
2300 rv
= OpenSSL_FindKey(handle
, i
, new_attrlist
);
2306 OpenSSL_DecryptData(KMF_HANDLE_T handle
, KMF_KEY_HANDLE
*key
,
2307 KMF_OID
*AlgOID
, KMF_DATA
*ciphertext
,
2310 KMF_RETURN ret
= KMF_OK
;
2312 unsigned int in_len
= 0, out_len
= 0;
2313 unsigned int total_decrypted
= 0, modulus_len
= 0;
2314 uint8_t *in_data
, *out_data
;
2317 if (key
== NULL
|| AlgOID
== NULL
||
2318 ciphertext
== NULL
|| output
== NULL
||
2319 ciphertext
->Data
== NULL
||
2320 output
->Data
== NULL
)
2321 return (KMF_ERR_BAD_PARAMETER
);
2323 if (key
->keyalg
== KMF_RSA
) {
2324 rsa
= EVP_PKEY_get1_RSA((EVP_PKEY
*)key
->keyp
);
2325 modulus_len
= RSA_size(rsa
);
2327 return (KMF_ERR_BAD_PARAMETER
);
2330 blocks
= ciphertext
->Length
/modulus_len
;
2331 out_data
= output
->Data
;
2332 in_data
= ciphertext
->Data
;
2333 out_len
= modulus_len
- 11;
2334 in_len
= modulus_len
;
2336 for (i
= 0; i
< blocks
; i
++) {
2337 out_len
= RSA_private_decrypt(in_len
,
2338 in_data
, out_data
, rsa
, RSA_PKCS1_PADDING
);
2341 ret
= KMF_ERR_INTERNAL
;
2345 out_data
+= out_len
;
2346 total_decrypted
+= out_len
;
2350 output
->Length
= total_decrypted
;
2362 * This function will create a certid from issuer_cert and user_cert.
2363 * The caller should use OCSP_CERTID_free(OCSP_CERTID *) to deallocate
2364 * certid memory after use.
2367 create_certid(KMF_HANDLE_T handle
, const KMF_DATA
*issuer_cert
,
2368 const KMF_DATA
*user_cert
, OCSP_CERTID
**certid
)
2370 KMF_RETURN ret
= KMF_OK
;
2371 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2372 X509
*issuer
= NULL
;
2374 unsigned char *ptmp
;
2376 if (issuer_cert
== NULL
|| user_cert
== NULL
) {
2377 return (KMF_ERR_BAD_PARAMETER
);
2380 /* convert the DER-encoded issuer cert to an internal X509 */
2381 ptmp
= issuer_cert
->Data
;
2382 issuer
= d2i_X509(NULL
, (const uchar_t
**)&ptmp
,
2383 issuer_cert
->Length
);
2384 if (issuer
== NULL
) {
2385 SET_ERROR(kmfh
, ERR_get_error());
2386 ret
= KMF_ERR_OCSP_BAD_ISSUER
;
2390 /* convert the DER-encoded user cert to an internal X509 */
2391 ptmp
= user_cert
->Data
;
2392 cert
= d2i_X509(NULL
, (const uchar_t
**)&ptmp
,
2395 SET_ERROR(kmfh
, ERR_get_error());
2397 ret
= KMF_ERR_OCSP_BAD_CERT
;
2401 /* create a CERTID */
2402 *certid
= OCSP_cert_to_id(NULL
, cert
, issuer
);
2403 if (*certid
== NULL
) {
2404 SET_ERROR(kmfh
, ERR_get_error());
2405 ret
= KMF_ERR_OCSP_CERTID
;
2410 if (issuer
!= NULL
) {
2422 OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle
,
2423 int numattr
, KMF_ATTRIBUTE
*attrlist
)
2425 KMF_RETURN ret
= KMF_OK
;
2426 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2427 OCSP_CERTID
*id
= NULL
;
2428 OCSP_REQUEST
*req
= NULL
;
2431 KMF_DATA
*issuer_cert
;
2432 KMF_DATA
*user_cert
;
2434 user_cert
= kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR
,
2436 if (user_cert
== NULL
)
2437 return (KMF_ERR_BAD_PARAMETER
);
2439 issuer_cert
= kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR
,
2441 if (issuer_cert
== NULL
)
2442 return (KMF_ERR_BAD_PARAMETER
);
2444 reqfile
= kmf_get_attr_ptr(KMF_OCSP_REQUEST_FILENAME_ATTR
,
2446 if (reqfile
== NULL
)
2447 return (KMF_ERR_BAD_PARAMETER
);
2449 ret
= create_certid(handle
, issuer_cert
, user_cert
, &id
);
2450 if (ret
!= KMF_OK
) {
2454 /* Create an OCSP request */
2455 req
= OCSP_REQUEST_new();
2457 SET_ERROR(kmfh
, ERR_get_error());
2458 ret
= KMF_ERR_OCSP_CREATE_REQUEST
;
2462 if (!OCSP_request_add0_id(req
, id
)) {
2463 ret
= KMF_ERR_OCSP_CREATE_REQUEST
;
2467 /* Write the request to the output file with DER encoding */
2468 derbio
= BIO_new_file(reqfile
, "wb");
2470 SET_ERROR(kmfh
, ERR_get_error());
2471 ret
= KMF_ERR_OPEN_FILE
;
2474 if (i2d_OCSP_REQUEST_bio(derbio
, req
) <= 0) {
2475 ret
= KMF_ERR_ENCODING
;
2480 * We don't need to free "id" explicitely, because OCSP_REQUEST_free()
2481 * will also deallocate certid's space.
2484 OCSP_REQUEST_free(req
);
2487 if (derbio
!= NULL
) {
2488 (void) BIO_free(derbio
);
2494 /* ocsp_find_signer_sk() is copied from openssl source */
2495 static X509
*ocsp_find_signer_sk(STACK_OF(X509
) *certs
, OCSP_BASICRESP
*bs
)
2498 unsigned char tmphash
[SHA_DIGEST_LENGTH
], *keyhash
;
2499 const ASN1_OCTET_STRING
*pid
;
2501 #if OPENSSL_VERSION_NUMBER < 0x10100000L
2502 OCSP_RESPID
*id
= bs
->tbsResponseData
->responderId
;
2504 if (id
->type
== V_OCSP_RESPID_NAME
)
2505 return (X509_find_by_subject(certs
, id
->value
.byName
));
2507 pid
= id
->value
.byKey
;
2509 const X509_NAME
*pname
;
2511 if (OCSP_resp_get0_id(bs
, &pid
, &pname
) == 0)
2515 return (X509_find_by_subject(certs
, (X509_NAME
*)pname
));
2518 /* Lookup by key hash */
2520 /* If key hash isn't SHA1 length then forget it */
2521 if (pid
->length
!= SHA_DIGEST_LENGTH
)
2524 keyhash
= pid
->data
;
2525 /* Calculate hash of each key and compare */
2526 for (i
= 0; i
< sk_X509_num(certs
); i
++) {
2527 /* LINTED E_BAD_PTR_CAST_ALIGN */
2528 X509
*x
= sk_X509_value(certs
, i
);
2529 /* Use pubkey_digest to get the key ID value */
2530 (void) X509_pubkey_digest(x
, EVP_sha1(), tmphash
, NULL
);
2531 if (!memcmp(keyhash
, tmphash
, SHA_DIGEST_LENGTH
))
2537 /* ocsp_find_signer() is copied from openssl source */
2540 ocsp_find_signer(X509
**psigner
, OCSP_BASICRESP
*bs
, STACK_OF(X509
) *certs
,
2541 X509_STORE
*st
, unsigned long flags
)
2544 if ((signer
= ocsp_find_signer_sk(certs
, bs
))) {
2549 if (!(flags
& OCSP_NOINTERN
) &&
2550 (signer
= ocsp_find_signer_sk(
2551 (STACK_OF(X509
) *)OCSP_resp_get0_certs(bs
), bs
))) {
2555 /* Maybe lookup from store if by subject name */
2562 * This function will verify the signature of a basic response, using
2563 * the public key from the OCSP responder certificate.
2566 check_response_signature(KMF_HANDLE_T handle
, OCSP_BASICRESP
*bs
,
2567 KMF_DATA
*signer_cert
, KMF_DATA
*issuer_cert
)
2569 KMF_RETURN ret
= KMF_OK
;
2570 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2571 STACK_OF(X509
) *cert_stack
= NULL
;
2572 X509
*signer
= NULL
;
2573 X509
*issuer
= NULL
;
2574 #if OPENSSL_VERSION_NUMBER < 0x10100000L
2575 EVP_PKEY
*skey
= NULL
;
2577 STACK_OF(X509
) *cert_stack2
= NULL
;
2579 unsigned char *ptmp
;
2581 if (bs
== NULL
|| issuer_cert
== NULL
)
2582 return (KMF_ERR_BAD_PARAMETER
);
2585 * Find the certificate that signed the basic response.
2587 * If signer_cert is not NULL, we will use that as the signer cert.
2588 * Otherwise, we will check if the issuer cert is actually the signer.
2589 * If we still do not find a signer, we will look for it from the
2590 * certificate list came with the response file.
2592 if (signer_cert
!= NULL
) {
2593 ptmp
= signer_cert
->Data
;
2594 signer
= d2i_X509(NULL
, (const uchar_t
**)&ptmp
,
2595 signer_cert
->Length
);
2596 if (signer
== NULL
) {
2597 SET_ERROR(kmfh
, ERR_get_error());
2598 ret
= KMF_ERR_OCSP_BAD_SIGNER
;
2603 * Convert the issuer cert into X509 and push it into a
2604 * stack to be used by ocsp_find_signer().
2606 ptmp
= issuer_cert
->Data
;
2607 issuer
= d2i_X509(NULL
, (const uchar_t
**)&ptmp
,
2608 issuer_cert
->Length
);
2609 if (issuer
== NULL
) {
2610 SET_ERROR(kmfh
, ERR_get_error());
2611 ret
= KMF_ERR_OCSP_BAD_ISSUER
;
2615 if ((cert_stack
= sk_X509_new_null()) == NULL
) {
2616 ret
= KMF_ERR_INTERNAL
;
2620 if (sk_X509_push(cert_stack
, issuer
) == NULL
) {
2621 ret
= KMF_ERR_INTERNAL
;
2625 ret
= ocsp_find_signer(&signer
, bs
, cert_stack
, NULL
, 0);
2627 /* can not find the signer */
2628 ret
= KMF_ERR_OCSP_BAD_SIGNER
;
2633 /* Verify the signature of the response */
2634 #if OPENSSL_VERSION_NUMBER < 0x10100000L
2635 skey
= X509_get_pubkey(signer
);
2637 ret
= KMF_ERR_OCSP_BAD_SIGNER
;
2641 ret
= OCSP_BASICRESP_verify(bs
, skey
, 0);
2644 * Technique based on
2645 * https://mta.openssl.org/pipermail/openssl-users/
2646 * 2017-October/006814.html
2648 if ((cert_stack2
= sk_X509_new_null()) == NULL
) {
2649 ret
= KMF_ERR_INTERNAL
;
2653 if (sk_X509_push(cert_stack2
, signer
) == NULL
) {
2654 ret
= KMF_ERR_INTERNAL
;
2658 ret
= OCSP_basic_verify(bs
, cert_stack2
, NULL
, OCSP_NOVERIFY
);
2662 ret
= KMF_ERR_OCSP_RESPONSE_SIGNATURE
;
2667 if (issuer
!= NULL
) {
2671 if (signer
!= NULL
) {
2675 #if OPENSSL_VERSION_NUMBER < 0x10100000L
2677 EVP_PKEY_free(skey
);
2680 if (cert_stack2
!= NULL
) {
2681 sk_X509_free(cert_stack2
);
2685 if (cert_stack
!= NULL
) {
2686 sk_X509_free(cert_stack
);
2693 OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle
,
2694 int numattr
, KMF_ATTRIBUTE
*attrlist
)
2696 KMF_RETURN ret
= KMF_OK
;
2698 OCSP_RESPONSE
*resp
= NULL
;
2699 OCSP_BASICRESP
*bs
= NULL
;
2700 OCSP_CERTID
*id
= NULL
;
2701 OCSP_SINGLERESP
*single
= NULL
;
2702 ASN1_GENERALIZEDTIME
*rev
, *thisupd
, *nextupd
;
2703 int index
, status
, reason
;
2704 KMF_DATA
*issuer_cert
;
2705 KMF_DATA
*user_cert
;
2706 KMF_DATA
*signer_cert
;
2708 int *response_reason
, *response_status
, *cert_status
;
2709 boolean_t ignore_response_sign
= B_FALSE
; /* default is FALSE */
2710 uint32_t response_lifetime
;
2712 issuer_cert
= kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR
,
2714 if (issuer_cert
== NULL
)
2715 return (KMF_ERR_BAD_PARAMETER
);
2717 user_cert
= kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR
,
2719 if (user_cert
== NULL
)
2720 return (KMF_ERR_BAD_PARAMETER
);
2722 response
= kmf_get_attr_ptr(KMF_OCSP_RESPONSE_DATA_ATTR
,
2724 if (response
== NULL
)
2725 return (KMF_ERR_BAD_PARAMETER
);
2727 response_status
= kmf_get_attr_ptr(KMF_OCSP_RESPONSE_STATUS_ATTR
,
2729 if (response_status
== NULL
)
2730 return (KMF_ERR_BAD_PARAMETER
);
2732 response_reason
= kmf_get_attr_ptr(KMF_OCSP_RESPONSE_REASON_ATTR
,
2734 if (response_reason
== NULL
)
2735 return (KMF_ERR_BAD_PARAMETER
);
2737 cert_status
= kmf_get_attr_ptr(KMF_OCSP_RESPONSE_CERT_STATUS_ATTR
,
2739 if (cert_status
== NULL
)
2740 return (KMF_ERR_BAD_PARAMETER
);
2742 /* Read in the response */
2743 derbio
= BIO_new_mem_buf(response
->Data
, response
->Length
);
2745 ret
= KMF_ERR_MEMORY
;
2749 resp
= d2i_OCSP_RESPONSE_bio(derbio
, NULL
);
2751 ret
= KMF_ERR_OCSP_MALFORMED_RESPONSE
;
2755 /* Check the response status */
2756 status
= OCSP_response_status(resp
);
2757 *response_status
= status
;
2758 if (status
!= OCSP_RESPONSE_STATUS_SUCCESSFUL
) {
2759 ret
= KMF_ERR_OCSP_RESPONSE_STATUS
;
2764 printf("Successfully checked the response file status.\n");
2767 /* Extract basic response */
2768 bs
= OCSP_response_get1_basic(resp
);
2770 ret
= KMF_ERR_OCSP_NO_BASIC_RESPONSE
;
2775 printf("Successfully retrieved the basic response.\n");
2778 /* Check the basic response signature if required */
2779 ret
= kmf_get_attr(KMF_IGNORE_RESPONSE_SIGN_ATTR
, attrlist
, numattr
,
2780 (void *)&ignore_response_sign
, NULL
);
2784 signer_cert
= kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR
,
2787 if (ignore_response_sign
== B_FALSE
) {
2788 ret
= check_response_signature(handle
, bs
,
2789 signer_cert
, issuer_cert
);
2795 printf("Successfully verified the response signature.\n");
2798 /* Create a certid for the certificate in question */
2799 ret
= create_certid(handle
, issuer_cert
, user_cert
, &id
);
2800 if (ret
!= KMF_OK
) {
2801 ret
= KMF_ERR_OCSP_CERTID
;
2806 printf("successfully created a certid for the cert.\n");
2809 /* Find the index of the single response for the certid */
2810 index
= OCSP_resp_find(bs
, id
, -1);
2812 /* cound not find this certificate in the response */
2813 ret
= KMF_ERR_OCSP_UNKNOWN_CERT
;
2818 printf("Successfully found the single response index for the cert.\n");
2821 /* Retrieve the single response and get the cert status */
2822 single
= OCSP_resp_get0(bs
, index
);
2823 status
= OCSP_single_get0_status(single
, &reason
, &rev
, &thisupd
,
2825 if (status
== V_OCSP_CERTSTATUS_GOOD
) {
2826 *cert_status
= OCSP_GOOD
;
2827 } else if (status
== V_OCSP_CERTSTATUS_UNKNOWN
) {
2828 *cert_status
= OCSP_UNKNOWN
;
2829 } else { /* revoked */
2830 *cert_status
= OCSP_REVOKED
;
2831 *response_reason
= reason
;
2835 /* resp. time is optional, so we don't care about the return code. */
2836 (void) kmf_get_attr(KMF_RESPONSE_LIFETIME_ATTR
, attrlist
, numattr
,
2837 (void *)&response_lifetime
, NULL
);
2839 if (!OCSP_check_validity(thisupd
, nextupd
, 300,
2840 response_lifetime
)) {
2841 ret
= KMF_ERR_OCSP_STATUS_TIME_INVALID
;
2846 printf("Successfully verify the time.\n");
2851 (void) BIO_free(derbio
);
2854 OCSP_RESPONSE_free(resp
);
2857 OCSP_BASICRESP_free(bs
);
2860 OCSP_CERTID_free(id
);
2866 fetch_key(KMF_HANDLE_T handle
, char *path
,
2867 KMF_KEY_CLASS keyclass
, KMF_KEY_HANDLE
*key
)
2869 KMF_RETURN rv
= KMF_OK
;
2870 EVP_PKEY
*pkey
= NULL
;
2871 KMF_RAW_SYM_KEY
*rkey
= NULL
;
2873 if (keyclass
== KMF_ASYM_PRI
||
2874 keyclass
== KMF_ASYM_PUB
) {
2875 pkey
= openssl_load_key(handle
, path
);
2877 return (KMF_ERR_KEY_NOT_FOUND
);
2880 if (EVP_PKEY_get0_RSA(pkey
) != NULL
)
2881 key
->keyalg
= KMF_RSA
;
2882 else if (EVP_PKEY_get0_DSA(pkey
) != NULL
)
2883 key
->keyalg
= KMF_DSA
;
2885 key
->kstype
= KMF_KEYSTORE_OPENSSL
;
2886 key
->keyclass
= keyclass
;
2887 key
->keyp
= (void *)pkey
;
2890 ((key
->keylabel
= strdup(path
)) == NULL
)) {
2891 EVP_PKEY_free(pkey
);
2892 return (KMF_ERR_MEMORY
);
2895 EVP_PKEY_free(pkey
);
2898 } else if (keyclass
== KMF_SYMMETRIC
) {
2899 KMF_ENCODE_FORMAT fmt
;
2901 * If the file is a recognized format,
2902 * then it is NOT a symmetric key.
2904 rv
= kmf_get_file_format(path
, &fmt
);
2905 if (rv
== KMF_OK
|| fmt
!= 0) {
2906 return (KMF_ERR_KEY_NOT_FOUND
);
2907 } else if (rv
== KMF_ERR_ENCODING
) {
2909 * If we don't know the encoding,
2910 * it is probably a symmetric key.
2913 } else if (rv
== KMF_ERR_OPEN_FILE
) {
2914 return (KMF_ERR_KEY_NOT_FOUND
);
2919 rkey
= malloc(sizeof (KMF_RAW_SYM_KEY
));
2921 rv
= KMF_ERR_MEMORY
;
2925 (void) memset(rkey
, 0, sizeof (KMF_RAW_SYM_KEY
));
2926 rv
= kmf_read_input_file(handle
, path
, &keyvalue
);
2930 rkey
->keydata
.len
= keyvalue
.Length
;
2931 rkey
->keydata
.val
= keyvalue
.Data
;
2933 key
->kstype
= KMF_KEYSTORE_OPENSSL
;
2934 key
->keyclass
= keyclass
;
2936 key
->keyp
= (void *)rkey
;
2938 ((key
->keylabel
= strdup(path
)) == NULL
)) {
2939 rv
= KMF_ERR_MEMORY
;
2946 kmf_free_raw_sym_key(rkey
);
2949 EVP_PKEY_free(pkey
);
2952 key
->keyalg
= KMF_KEYALG_NONE
;
2953 key
->keyclass
= KMF_KEYCLASS_NONE
;
2962 OpenSSL_FindKey(KMF_HANDLE_T handle
,
2963 int numattr
, KMF_ATTRIBUTE
*attrlist
)
2965 KMF_RETURN rv
= KMF_OK
;
2966 char *fullpath
= NULL
;
2968 KMF_KEY_HANDLE
*key
;
2970 KMF_KEY_CLASS keyclass
;
2971 KMF_RAW_KEY_DATA
*rawkey
;
2976 return (KMF_ERR_BAD_PARAMETER
);
2978 numkeys
= kmf_get_attr_ptr(KMF_COUNT_ATTR
, attrlist
, numattr
);
2979 if (numkeys
== NULL
)
2980 return (KMF_ERR_BAD_PARAMETER
);
2982 rv
= kmf_get_attr(KMF_KEYCLASS_ATTR
, attrlist
, numattr
,
2983 (void *)&keyclass
, NULL
);
2985 return (KMF_ERR_BAD_PARAMETER
);
2987 if (keyclass
!= KMF_ASYM_PUB
&&
2988 keyclass
!= KMF_ASYM_PRI
&&
2989 keyclass
!= KMF_SYMMETRIC
)
2990 return (KMF_ERR_BAD_KEY_CLASS
);
2992 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
2993 keyfile
= kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
, attrlist
, numattr
);
2995 fullpath
= get_fullpath(dirpath
, keyfile
);
2997 if (fullpath
== NULL
)
2998 return (KMF_ERR_BAD_PARAMETER
);
3002 maxkeys
= 0xFFFFFFFF;
3005 key
= kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR
, attrlist
, numattr
);
3006 /* it is okay to have "keys" contains NULL */
3009 * The caller may want a list of the raw key data as well.
3010 * Useful for importing keys from a file into other keystores.
3012 rawkey
= kmf_get_attr_ptr(KMF_RAW_KEY_ATTR
, attrlist
, numattr
);
3014 if (isdir(fullpath
)) {
3019 /* open all files in the directory and attempt to read them */
3020 if ((dirp
= opendir(fullpath
)) == NULL
) {
3021 return (KMF_ERR_BAD_PARAMETER
);
3024 while ((dp
= readdir(dirp
)) != NULL
&& n
< maxkeys
) {
3025 if (strcmp(dp
->d_name
, ".") &&
3026 strcmp(dp
->d_name
, "..")) {
3029 fname
= get_fullpath(fullpath
,
3030 (char *)&dp
->d_name
);
3032 rv
= fetch_key(handle
, fname
,
3033 keyclass
, key
? &key
[n
] : NULL
);
3036 if (key
!= NULL
&& rawkey
!= NULL
)
3037 rv
= convertToRawKey(
3038 key
[n
].keyp
, &rawkey
[n
]);
3042 if (rv
!= KMF_OK
|| key
== NULL
)
3046 (void) closedir(dirp
);
3050 rv
= fetch_key(handle
, fullpath
, keyclass
, key
);
3054 if (rv
!= KMF_OK
|| key
== NULL
)
3057 if (rv
== KMF_OK
&& key
!= NULL
&& rawkey
!= NULL
) {
3058 rv
= convertToRawKey(key
->keyp
, rawkey
);
3062 if (rv
== KMF_OK
&& (*numkeys
) == 0)
3063 rv
= KMF_ERR_KEY_NOT_FOUND
;
3064 else if (rv
== KMF_ERR_KEY_NOT_FOUND
&& (*numkeys
) > 0)
3070 #define HANDLE_PK12_ERROR { \
3071 SET_ERROR(kmfh, ERR_get_error()); \
3072 rv = KMF_ERR_ENCODING; \
3077 add_alias_to_bag(PKCS12_SAFEBAG
*bag
, X509
*xcert
)
3079 unsigned char *alias
;
3082 if (xcert
!= NULL
&& (alias
= X509_alias_get0(xcert
, &len
)) != NULL
) {
3083 if (PKCS12_add_friendlyname_asc(bag
,
3084 (const char *)alias
, len
) == 0)
3091 add_cert_to_safe(X509
*sslcert
, KMF_CREDENTIAL
*cred
,
3092 uchar_t
*keyid
, unsigned int keyidlen
)
3094 PKCS12_SAFEBAG
*bag
= NULL
;
3095 PKCS7
*cert_authsafe
= NULL
;
3096 STACK_OF(PKCS12_SAFEBAG
) *bag_stack
;
3098 bag_stack
= sk_PKCS12_SAFEBAG_new_null();
3099 if (bag_stack
== NULL
)
3102 /* Convert cert from X509 struct to PKCS#12 bag */
3103 bag
= PKCS12_SAFEBAG_create_cert(sslcert
);
3108 /* Add the key id to the certificate bag. */
3109 if (keyidlen
> 0 && !PKCS12_add_localkeyid(bag
, keyid
, keyidlen
)) {
3113 if (!add_alias_to_bag(bag
, sslcert
))
3116 /* Pile it on the bag_stack. */
3117 if (!sk_PKCS12_SAFEBAG_push(bag_stack
, bag
)) {
3120 /* Turn bag_stack of certs into encrypted authsafe. */
3121 cert_authsafe
= PKCS12_pack_p7encdata(
3122 NID_pbe_WithSHA1And40BitRC2_CBC
,
3123 cred
->cred
, cred
->credlen
, NULL
, 0,
3124 PKCS12_DEFAULT_ITER
, bag_stack
);
3127 if (bag_stack
!= NULL
)
3128 sk_PKCS12_SAFEBAG_pop_free(bag_stack
, PKCS12_SAFEBAG_free
);
3130 return (cert_authsafe
);
3134 add_key_to_safe(EVP_PKEY
*pkey
, KMF_CREDENTIAL
*cred
,
3135 uchar_t
*keyid
, unsigned int keyidlen
,
3136 char *label
, int label_len
)
3138 PKCS8_PRIV_KEY_INFO
*p8
= NULL
;
3139 STACK_OF(PKCS12_SAFEBAG
) *bag_stack
= NULL
;
3140 PKCS12_SAFEBAG
*bag
= NULL
;
3141 PKCS7
*key_authsafe
= NULL
;
3143 p8
= EVP_PKEY2PKCS8(pkey
);
3147 /* Put the shrouded key into a PKCS#12 bag. */
3148 bag
= PKCS12_SAFEBAG_create_pkcs8_encrypt(
3149 NID_pbe_WithSHA1And3_Key_TripleDES_CBC
,
3150 cred
->cred
, cred
->credlen
,
3151 NULL
, 0, PKCS12_DEFAULT_ITER
, p8
);
3153 /* Clean up the PKCS#8 shrouded key, don't need it now. */
3154 PKCS8_PRIV_KEY_INFO_free(p8
);
3160 if (keyidlen
&& !PKCS12_add_localkeyid(bag
, keyid
, keyidlen
))
3162 if (label
!= NULL
&& !PKCS12_add_friendlyname(bag
, label
, label_len
))
3165 /* Start a PKCS#12 safebag container for the private key. */
3166 bag_stack
= sk_PKCS12_SAFEBAG_new_null();
3167 if (bag_stack
== NULL
)
3170 /* Pile on the private key on the bag_stack. */
3171 if (!sk_PKCS12_SAFEBAG_push(bag_stack
, bag
))
3174 key_authsafe
= PKCS12_pack_p7data(bag_stack
);
3177 if (bag_stack
!= NULL
)
3178 sk_PKCS12_SAFEBAG_pop_free(bag_stack
, PKCS12_SAFEBAG_free
);
3180 return (key_authsafe
);
3184 ImportRawRSAKey(KMF_RAW_RSA_KEY
*key
)
3187 EVP_PKEY
*newkey
= NULL
;
3188 BIGNUM
*n
= NULL
, *e
= NULL
, *d
= NULL
,
3189 *p
= NULL
, *q
= NULL
,
3190 *dmp1
= NULL
, *dmq1
= NULL
, *iqmp
= NULL
;
3192 if ((rsa
= RSA_new()) == NULL
)
3195 if ((n
= BN_bin2bn(key
->mod
.val
, key
->mod
.len
, NULL
)) == NULL
)
3198 if ((e
= BN_bin2bn(key
->pubexp
.val
, key
->pubexp
.len
, NULL
)) == NULL
)
3201 if (key
->priexp
.val
!= NULL
&&
3202 (d
= BN_bin2bn(key
->priexp
.val
, key
->priexp
.len
, NULL
)) == NULL
)
3205 if (key
->prime1
.val
!= NULL
&&
3206 (p
= BN_bin2bn(key
->prime1
.val
, key
->prime1
.len
, NULL
)) == NULL
)
3209 if (key
->prime2
.val
!= NULL
&&
3210 (q
= BN_bin2bn(key
->prime2
.val
, key
->prime2
.len
, NULL
)) == NULL
)
3213 if (key
->exp1
.val
!= NULL
&&
3214 (dmp1
= BN_bin2bn(key
->exp1
.val
, key
->exp1
.len
, NULL
)) == NULL
)
3217 if (key
->exp2
.val
!= NULL
&&
3218 (dmq1
= BN_bin2bn(key
->exp2
.val
, key
->exp2
.len
, NULL
)) == NULL
)
3221 if (key
->coef
.val
!= NULL
&&
3222 (iqmp
= BN_bin2bn(key
->coef
.val
, key
->coef
.len
, NULL
)) == NULL
)
3225 if (RSA_set0_key(rsa
, n
, e
, d
) == 0)
3228 if (RSA_set0_factors(rsa
, p
, q
) == 0)
3231 if (RSA_set0_crt_params(rsa
, dmp1
, dmq1
, iqmp
) == 0)
3233 dmp1
= dmq1
= iqmp
= NULL
;
3235 if ((newkey
= EVP_PKEY_new()) == NULL
)
3238 (void) EVP_PKEY_set1_RSA(newkey
, rsa
);
3241 /* The original key must be freed once here or it leaks memory */
3257 ImportRawDSAKey(KMF_RAW_DSA_KEY
*key
)
3260 EVP_PKEY
*newkey
= NULL
;
3261 BIGNUM
*p
= NULL
, *q
= NULL
, *g
= NULL
,
3262 *priv_key
= NULL
, *pub_key
= NULL
;
3264 if ((dsa
= DSA_new()) == NULL
)
3267 if ((p
= BN_bin2bn(key
->prime
.val
, key
->prime
.len
, NULL
)) == NULL
)
3270 if ((q
= BN_bin2bn(key
->subprime
.val
, key
->subprime
.len
, NULL
)) == NULL
)
3273 if ((g
= BN_bin2bn(key
->base
.val
, key
->base
.len
, NULL
)) == NULL
)
3276 if ((priv_key
= BN_bin2bn(key
->value
.val
, key
->value
.len
,
3280 if (key
->pubvalue
.val
!= NULL
&& (pub_key
=
3281 BN_bin2bn(key
->pubvalue
.val
, key
->pubvalue
.len
, NULL
)) == NULL
)
3284 if (DSA_set0_pqg(dsa
, p
, q
, g
) == 0)
3287 if (DSA_set0_key(dsa
, pub_key
, priv_key
) == 0)
3289 pub_key
= priv_key
= 0;
3291 if ((newkey
= EVP_PKEY_new()) == NULL
)
3294 (void) EVP_PKEY_set1_DSA(newkey
, dsa
);
3297 /* The original key must be freed once here or it leaks memory */
3310 raw_key_to_pkey(KMF_KEY_HANDLE
*key
)
3312 EVP_PKEY
*pkey
= NULL
;
3313 KMF_RAW_KEY_DATA
*rawkey
;
3314 ASN1_TYPE
*attr
= NULL
;
3317 if (key
== NULL
|| !key
->israw
)
3320 rawkey
= (KMF_RAW_KEY_DATA
*)key
->keyp
;
3321 if (rawkey
->keytype
== KMF_RSA
) {
3322 pkey
= ImportRawRSAKey(&rawkey
->rawdata
.rsa
);
3323 } else if (rawkey
->keytype
== KMF_DSA
) {
3324 pkey
= ImportRawDSAKey(&rawkey
->rawdata
.dsa
);
3325 } else if (rawkey
->keytype
== KMF_ECDSA
) {
3327 * OpenSSL in Solaris does not support EC for
3332 /* wrong kind of key */
3336 if (rawkey
->label
!= NULL
) {
3337 if ((attr
= ASN1_TYPE_new()) == NULL
) {
3338 EVP_PKEY_free(pkey
);
3341 attr
->value
.bmpstring
= ASN1_STRING_type_new(V_ASN1_BMPSTRING
);
3342 (void) ASN1_STRING_set(attr
->value
.bmpstring
, rawkey
->label
,
3343 strlen(rawkey
->label
));
3344 attr
->type
= V_ASN1_BMPSTRING
;
3345 attr
->value
.ptr
= (char *)attr
->value
.bmpstring
;
3346 ret
= set_pkey_attrib(pkey
, attr
, NID_friendlyName
);
3347 if (ret
!= KMF_OK
) {
3348 EVP_PKEY_free(pkey
);
3349 ASN1_TYPE_free(attr
);
3353 if (rawkey
->id
.Data
!= NULL
) {
3354 if ((attr
= ASN1_TYPE_new()) == NULL
) {
3355 EVP_PKEY_free(pkey
);
3358 attr
->value
.octet_string
=
3359 ASN1_STRING_type_new(V_ASN1_OCTET_STRING
);
3360 attr
->type
= V_ASN1_OCTET_STRING
;
3361 (void) ASN1_STRING_set(attr
->value
.octet_string
,
3362 rawkey
->id
.Data
, rawkey
->id
.Length
);
3363 attr
->value
.ptr
= (char *)attr
->value
.octet_string
;
3364 ret
= set_pkey_attrib(pkey
, attr
, NID_localKeyID
);
3365 if (ret
!= KMF_OK
) {
3366 EVP_PKEY_free(pkey
);
3367 ASN1_TYPE_free(attr
);
3375 * Search a list of private keys to find one that goes with the certificate.
3378 find_matching_key(X509
*xcert
, int numkeys
, KMF_KEY_HANDLE
*keylist
)
3381 EVP_PKEY
*pkey
= NULL
;
3383 if (numkeys
== 0 || keylist
== NULL
|| xcert
== NULL
)
3385 for (i
= 0; i
< numkeys
; i
++) {
3386 if (keylist
[i
].israw
)
3387 pkey
= raw_key_to_pkey(&keylist
[i
]);
3389 pkey
= (EVP_PKEY
*)keylist
[i
].keyp
;
3391 if (X509_check_private_key(xcert
, pkey
)) {
3394 EVP_PKEY_free(pkey
);
3403 local_export_pk12(KMF_HANDLE_T handle
,
3404 KMF_CREDENTIAL
*cred
,
3405 int numcerts
, KMF_X509_DER_CERT
*certlist
,
3406 int numkeys
, KMF_KEY_HANDLE
*keylist
,
3409 KMF_RETURN rv
= KMF_OK
;
3410 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
3412 PKCS7
*cert_authsafe
= NULL
;
3413 PKCS7
*key_authsafe
= NULL
;
3414 STACK_OF(PKCS7
) *authsafe_stack
= NULL
;
3415 PKCS12
*p12_elem
= NULL
;
3418 if (numcerts
== 0 && numkeys
== 0)
3419 return (KMF_ERR_BAD_PARAMETER
);
3422 * Open the output file.
3424 if ((bio
= BIO_new_file(filename
, "wb")) == NULL
) {
3425 SET_ERROR(kmfh
, ERR_get_error());
3426 rv
= KMF_ERR_OPEN_FILE
;
3430 /* Start a PKCS#7 stack. */
3431 authsafe_stack
= sk_PKCS7_new_null();
3432 if (authsafe_stack
== NULL
) {
3433 rv
= KMF_ERR_MEMORY
;
3437 for (i
= 0; rv
== KMF_OK
&& i
< numcerts
; i
++) {
3438 const uchar_t
*p
= certlist
[i
].certificate
.Data
;
3439 long len
= certlist
[i
].certificate
.Length
;
3441 EVP_PKEY
*pkey
= NULL
;
3442 unsigned char keyid
[EVP_MAX_MD_SIZE
];
3443 unsigned int keyidlen
= 0;
3445 xcert
= d2i_X509(NULL
, &p
, len
);
3446 if (xcert
== NULL
) {
3447 SET_ERROR(kmfh
, ERR_get_error());
3448 rv
= KMF_ERR_ENCODING
;
3450 if (certlist
[i
].kmf_private
.label
!= NULL
) {
3451 /* Set alias attribute */
3452 (void) X509_alias_set1(xcert
,
3453 (uchar_t
*)certlist
[i
].kmf_private
.label
,
3454 strlen(certlist
[i
].kmf_private
.label
));
3456 /* Check if there is a key corresponding to this cert */
3457 pkey
= find_matching_key(xcert
, numkeys
, keylist
);
3460 * If key is found, get fingerprint and create a
3464 (void) X509_digest(xcert
, EVP_sha1(),
3466 key_authsafe
= add_key_to_safe(pkey
, cred
,
3468 certlist
[i
].kmf_private
.label
,
3469 (certlist
[i
].kmf_private
.label
?
3470 strlen(certlist
[i
].kmf_private
.label
) : 0));
3472 if (key_authsafe
== NULL
) {
3474 EVP_PKEY_free(pkey
);
3477 /* Put the key safe into the Auth Safe */
3478 if (!sk_PKCS7_push(authsafe_stack
,
3481 EVP_PKEY_free(pkey
);
3486 /* create a certificate safebag */
3487 cert_authsafe
= add_cert_to_safe(xcert
, cred
, keyid
,
3489 if (cert_authsafe
== NULL
) {
3491 EVP_PKEY_free(pkey
);
3494 if (!sk_PKCS7_push(authsafe_stack
, cert_authsafe
)) {
3496 EVP_PKEY_free(pkey
);
3502 EVP_PKEY_free(pkey
);
3504 } else if (numcerts
== 0 && numkeys
> 0) {
3506 * If only adding keys to the file.
3508 for (i
= 0; i
< numkeys
; i
++) {
3509 EVP_PKEY
*pkey
= NULL
;
3511 if (keylist
[i
].israw
)
3512 pkey
= raw_key_to_pkey(&keylist
[i
]);
3514 pkey
= (EVP_PKEY
*)keylist
[i
].keyp
;
3519 key_authsafe
= add_key_to_safe(pkey
, cred
,
3522 if (key_authsafe
== NULL
) {
3523 EVP_PKEY_free(pkey
);
3526 if (!sk_PKCS7_push(authsafe_stack
, key_authsafe
)) {
3527 EVP_PKEY_free(pkey
);
3532 p12_elem
= PKCS12_init(NID_pkcs7_data
);
3533 if (p12_elem
== NULL
) {
3537 /* Put the PKCS#7 stack into the PKCS#12 element. */
3538 if (!PKCS12_pack_authsafes(p12_elem
, authsafe_stack
)) {
3542 /* Set the integrity MAC on the PKCS#12 element. */
3543 if (!PKCS12_set_mac(p12_elem
, cred
->cred
, cred
->credlen
,
3544 NULL
, 0, PKCS12_DEFAULT_ITER
, NULL
)) {
3548 /* Write the PKCS#12 element to the export file. */
3549 if (!i2d_PKCS12_bio(bio
, p12_elem
)) {
3552 PKCS12_free(p12_elem
);
3555 /* Clear away the PKCS#7 stack, we're done with it. */
3557 sk_PKCS7_pop_free(authsafe_stack
, PKCS7_free
);
3560 (void) BIO_free_all(bio
);
3566 openssl_build_pk12(KMF_HANDLE_T handle
, int numcerts
,
3567 KMF_X509_DER_CERT
*certlist
, int numkeys
, KMF_KEY_HANDLE
*keylist
,
3568 KMF_CREDENTIAL
*p12cred
, char *filename
)
3572 if (certlist
== NULL
&& keylist
== NULL
)
3573 return (KMF_ERR_BAD_PARAMETER
);
3575 rv
= local_export_pk12(handle
, p12cred
, numcerts
, certlist
,
3576 numkeys
, keylist
, filename
);
3582 OpenSSL_ExportPK12(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
3585 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
3586 char *fullpath
= NULL
;
3587 char *dirpath
= NULL
;
3588 char *certfile
= NULL
;
3589 char *keyfile
= NULL
;
3590 char *filename
= NULL
;
3591 KMF_CREDENTIAL
*p12cred
= NULL
;
3592 KMF_X509_DER_CERT certdata
;
3598 return (KMF_ERR_BAD_PARAMETER
);
3601 * First, find the certificate.
3603 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
3604 certfile
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
, numattr
);
3605 if (certfile
!= NULL
) {
3606 fullpath
= get_fullpath(dirpath
, certfile
);
3607 if (fullpath
== NULL
)
3608 return (KMF_ERR_BAD_PARAMETER
);
3610 if (isdir(fullpath
)) {
3612 return (KMF_ERR_AMBIGUOUS_PATHNAME
);
3615 (void) memset(&certdata
, 0, sizeof (certdata
));
3616 rv
= kmf_load_cert(kmfh
, NULL
, NULL
, NULL
, NULL
,
3617 fullpath
, &certdata
.certificate
);
3622 certdata
.kmf_private
.keystore_type
= KMF_KEYSTORE_OPENSSL
;
3627 * Now find the private key.
3629 keyfile
= kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
, attrlist
, numattr
);
3630 if (keyfile
!= NULL
) {
3631 fullpath
= get_fullpath(dirpath
, keyfile
);
3632 if (fullpath
== NULL
)
3633 return (KMF_ERR_BAD_PARAMETER
);
3635 if (isdir(fullpath
)) {
3637 return (KMF_ERR_AMBIGUOUS_PATHNAME
);
3640 (void) memset(&key
, 0, sizeof (KMF_KEY_HANDLE
));
3641 rv
= fetch_key(handle
, fullpath
, KMF_ASYM_PRI
, &key
);
3648 * Open the output file.
3650 filename
= kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR
, attrlist
,
3652 if (filename
== NULL
) {
3653 rv
= KMF_ERR_BAD_PARAMETER
;
3657 /* Stick the key and the cert into a PKCS#12 file */
3658 p12cred
= kmf_get_attr_ptr(KMF_PK12CRED_ATTR
, attrlist
, numattr
);
3659 if (p12cred
== NULL
) {
3660 rv
= KMF_ERR_BAD_PARAMETER
;
3664 rv
= local_export_pk12(handle
, p12cred
, 1, &certdata
,
3672 kmf_free_kmf_cert(handle
, &certdata
);
3674 kmf_free_kmf_key(handle
, &key
);
3679 * Helper function to extract keys and certificates from
3680 * a single PEM file. Typically the file should contain a
3681 * private key and an associated public key wrapped in an x509 cert.
3682 * However, the file may be just a list of X509 certs with no keys.
3685 extract_pem(KMF_HANDLE
*kmfh
,
3686 char *issuer
, char *subject
, KMF_BIGINT
*serial
,
3687 char *filename
, CK_UTF8CHAR
*pin
,
3688 CK_ULONG pinlen
, EVP_PKEY
**priv_key
, KMF_DATA
**certs
,
3692 KMF_RETURN rv
= KMF_OK
;
3694 STACK_OF(X509_INFO
) *x509_info_stack
= NULL
;
3695 int i
, ncerts
= 0, matchcerts
= 0;
3696 EVP_PKEY
*pkey
= NULL
;
3699 X509_INFO
**cert_infos
= NULL
;
3700 KMF_DATA
*certlist
= NULL
;
3706 fp
= fopen(filename
, "r");
3708 return (KMF_ERR_OPEN_FILE
);
3710 x509_info_stack
= PEM_X509_INFO_read(fp
, NULL
, NULL
, pin
);
3711 if (x509_info_stack
== NULL
) {
3713 return (KMF_ERR_ENCODING
);
3715 cert_infos
= (X509_INFO
**)malloc(sk_X509_INFO_num(x509_info_stack
) *
3716 sizeof (X509_INFO
*));
3717 if (cert_infos
== NULL
) {
3719 rv
= KMF_ERR_MEMORY
;
3723 for (i
= 0; i
< sk_X509_INFO_num(x509_info_stack
); i
++) {
3724 /* LINTED E_BAD_PTR_CAST_ALIGN */
3725 cert_infos
[ncerts
] = sk_X509_INFO_value(x509_info_stack
, i
);
3731 rv
= KMF_ERR_CERT_NOT_FOUND
;
3735 if (priv_key
!= NULL
) {
3737 pkey
= PEM_read_PrivateKey(fp
, NULL
, NULL
, pin
);
3741 x
= cert_infos
[ncerts
- 1]->x509
;
3743 * Make sure the private key matchs the last cert in the file.
3745 if (pkey
!= NULL
&& !X509_check_private_key(x
, pkey
)) {
3746 EVP_PKEY_free(pkey
);
3747 rv
= KMF_ERR_KEY_MISMATCH
;
3751 certlist
= (KMF_DATA
*)calloc(ncerts
, sizeof (KMF_DATA
));
3752 if (certlist
== NULL
) {
3754 EVP_PKEY_free(pkey
);
3755 rv
= KMF_ERR_MEMORY
;
3760 * Convert all of the certs to DER format.
3763 for (i
= 0; rv
== KMF_OK
&& certs
!= NULL
&& i
< ncerts
; i
++) {
3764 boolean_t match
= FALSE
;
3765 info
= cert_infos
[ncerts
- 1 - i
];
3767 rv
= check_cert(info
->x509
, issuer
, subject
, serial
, &match
);
3768 if (rv
!= KMF_OK
|| match
!= TRUE
) {
3773 rv
= ssl_cert2KMFDATA(kmfh
, info
->x509
,
3774 &certlist
[matchcerts
++]);
3778 for (j
= 0; j
< matchcerts
; j
++)
3779 kmf_free_data(&certlist
[j
]);
3782 ncerts
= matchcerts
= 0;
3786 if (numcerts
!= NULL
)
3787 *numcerts
= matchcerts
;
3791 else if (certlist
!= NULL
) {
3792 for (i
= 0; i
< ncerts
; i
++)
3793 kmf_free_data(&certlist
[i
]);
3798 if (priv_key
== NULL
&& pkey
!= NULL
)
3799 EVP_PKEY_free(pkey
);
3800 else if (priv_key
!= NULL
&& pkey
!= NULL
)
3804 /* Cleanup the stack of X509 info records */
3805 for (i
= 0; i
< sk_X509_INFO_num(x509_info_stack
); i
++) {
3806 /* LINTED E_BAD_PTR_CAST_ALIGN */
3807 info
= (X509_INFO
*)sk_X509_INFO_value(x509_info_stack
, i
);
3808 X509_INFO_free(info
);
3810 if (x509_info_stack
)
3811 sk_X509_INFO_free(x509_info_stack
);
3813 if (cert_infos
!= NULL
)
3820 openssl_parse_bags(const STACK_OF(PKCS12_SAFEBAG
) *bags
, char *pin
,
3821 STACK_OF(EVP_PKEY
) *keys
, STACK_OF(X509
) *certs
)
3826 for (i
= 0; i
< sk_PKCS12_SAFEBAG_num(bags
); i
++) {
3827 /* LINTED E_BAD_PTR_CAST_ALIGN */
3828 PKCS12_SAFEBAG
*bag
= sk_PKCS12_SAFEBAG_value(bags
, i
);
3829 ret
= openssl_parse_bag(bag
, pin
, (pin
? strlen(pin
) : 0),
3840 set_pkey_attrib(EVP_PKEY
*pkey
, ASN1_TYPE
*attrib
, int nid
)
3842 X509_ATTRIBUTE
*attr
= NULL
;
3844 if (pkey
== NULL
|| attrib
== NULL
)
3845 return (KMF_ERR_BAD_PARAMETER
);
3847 attr
= X509_ATTRIBUTE_create(nid
, attrib
->type
, attrib
->value
.ptr
);
3851 if ((i
= EVP_PKEY_get_attr_by_NID(pkey
, nid
, -1)) != -1)
3852 (void) EVP_PKEY_delete_attr(pkey
, i
);
3853 if (EVP_PKEY_add1_attr(pkey
, attr
) == 0) {
3854 X509_ATTRIBUTE_free(attr
);
3855 return (KMF_ERR_MEMORY
);
3858 return (KMF_ERR_MEMORY
);
3865 openssl_parse_bag(PKCS12_SAFEBAG
*bag
, char *pass
, int passlen
,
3866 STACK_OF(EVP_PKEY
) *keylist
, STACK_OF(X509
) *certlist
)
3868 KMF_RETURN ret
= KMF_OK
;
3869 PKCS8_PRIV_KEY_INFO
*p8
= NULL
;
3870 EVP_PKEY
*pkey
= NULL
;
3872 const ASN1_TYPE
*keyid
= NULL
;
3873 const ASN1_TYPE
*fname
= NULL
;
3874 uchar_t
*data
= NULL
;
3876 keyid
= PKCS12_SAFEBAG_get0_attr(bag
, NID_localKeyID
);
3877 fname
= PKCS12_SAFEBAG_get0_attr(bag
, NID_friendlyName
);
3879 switch (PKCS12_SAFEBAG_get_nid(bag
)) {
3881 if (keylist
== NULL
)
3883 pkey
= EVP_PKCS82PKEY(
3884 PKCS12_SAFEBAG_get0_p8inf(bag
));
3886 ret
= KMF_ERR_PKCS12_FORMAT
;
3889 case NID_pkcs8ShroudedKeyBag
:
3890 if (keylist
== NULL
)
3892 p8
= PKCS12_decrypt_skey(bag
, pass
, passlen
);
3894 return (KMF_ERR_AUTH_FAILED
);
3895 pkey
= EVP_PKCS82PKEY(p8
);
3896 PKCS8_PRIV_KEY_INFO_free(p8
);
3898 ret
= KMF_ERR_PKCS12_FORMAT
;
3901 if (certlist
== NULL
)
3903 if (PKCS12_SAFEBAG_get_bag_nid(bag
) !=
3904 NID_x509Certificate
)
3905 return (KMF_ERR_PKCS12_FORMAT
);
3906 xcert
= PKCS12_SAFEBAG_get1_cert(bag
);
3907 if (xcert
== NULL
) {
3908 ret
= KMF_ERR_PKCS12_FORMAT
;
3911 if (keyid
!= NULL
) {
3912 if (X509_keyid_set1(xcert
,
3913 keyid
->value
.octet_string
->data
,
3914 keyid
->value
.octet_string
->length
) == 0) {
3915 ret
= KMF_ERR_PKCS12_FORMAT
;
3919 if (fname
!= NULL
) {
3921 len
= ASN1_STRING_to_UTF8(&data
,
3922 fname
->value
.asn1_string
);
3923 if (len
> 0 && data
!= NULL
) {
3924 r
= X509_alias_set1(xcert
, data
, len
);
3926 ret
= KMF_ERR_PKCS12_FORMAT
;
3930 ret
= KMF_ERR_PKCS12_FORMAT
;
3934 if (sk_X509_push(certlist
, xcert
) == 0)
3935 ret
= KMF_ERR_MEMORY
;
3939 case NID_safeContentsBag
:
3940 return (openssl_parse_bags(
3941 PKCS12_SAFEBAG_get0_safes(bag
),
3942 pass
, keylist
, certlist
));
3944 ret
= KMF_ERR_PKCS12_FORMAT
;
3949 * Set the ID and/or FriendlyName attributes on the key.
3950 * If converting to PKCS11 objects, these can translate to CKA_ID
3951 * and CKA_LABEL values.
3953 if (pkey
!= NULL
&& ret
== KMF_OK
) {
3954 ASN1_TYPE
*attr
= NULL
;
3955 if (keyid
!= NULL
&& keyid
->type
== V_ASN1_OCTET_STRING
) {
3956 if ((attr
= ASN1_TYPE_new()) == NULL
)
3957 return (KMF_ERR_MEMORY
);
3958 attr
->value
.octet_string
=
3959 ASN1_STRING_dup(keyid
->value
.octet_string
);
3960 attr
->type
= V_ASN1_OCTET_STRING
;
3961 attr
->value
.ptr
= (char *)attr
->value
.octet_string
;
3962 ret
= set_pkey_attrib(pkey
, attr
, NID_localKeyID
);
3966 if (ret
== KMF_OK
&& fname
!= NULL
&&
3967 fname
->type
== V_ASN1_BMPSTRING
) {
3968 if ((attr
= ASN1_TYPE_new()) == NULL
)
3969 return (KMF_ERR_MEMORY
);
3970 attr
->value
.bmpstring
=
3971 ASN1_STRING_dup(fname
->value
.bmpstring
);
3972 attr
->type
= V_ASN1_BMPSTRING
;
3973 attr
->value
.ptr
= (char *)attr
->value
.bmpstring
;
3974 ret
= set_pkey_attrib(pkey
, attr
, NID_friendlyName
);
3978 if (ret
== KMF_OK
&& keylist
!= NULL
&&
3979 sk_EVP_PKEY_push(keylist
, pkey
) == 0)
3980 ret
= KMF_ERR_MEMORY
;
3982 if (ret
== KMF_OK
&& keylist
!= NULL
)
3986 EVP_PKEY_free(pkey
);
3996 openssl_pkcs12_parse(PKCS12
*p12
, char *pin
,
3997 STACK_OF(EVP_PKEY
) *keys
,
3998 STACK_OF(X509
) *certs
,
4002 KMF_RETURN ret
= KMF_OK
;
4003 STACK_OF(PKCS7
) *asafes
= NULL
;
4004 STACK_OF(PKCS12_SAFEBAG
) *bags
= NULL
;
4008 if (p12
== NULL
|| (keys
== NULL
&& certs
== NULL
))
4009 return (KMF_ERR_BAD_PARAMETER
);
4011 if (pin
== NULL
|| *pin
== NULL
) {
4012 if (PKCS12_verify_mac(p12
, NULL
, 0)) {
4014 } else if (PKCS12_verify_mac(p12
, "", 0)) {
4017 return (KMF_ERR_AUTH_FAILED
);
4019 } else if (!PKCS12_verify_mac(p12
, pin
, -1)) {
4020 return (KMF_ERR_AUTH_FAILED
);
4023 if ((asafes
= PKCS12_unpack_authsafes(p12
)) == NULL
)
4024 return (KMF_ERR_PKCS12_FORMAT
);
4026 for (i
= 0; ret
== KMF_OK
&& i
< sk_PKCS7_num(asafes
); i
++) {
4028 /* LINTED E_BAD_PTR_CAST_ALIGN */
4029 p7
= sk_PKCS7_value(asafes
, i
);
4030 bagnid
= OBJ_obj2nid(p7
->type
);
4032 if (bagnid
== NID_pkcs7_data
) {
4033 bags
= PKCS12_unpack_p7data(p7
);
4034 } else if (bagnid
== NID_pkcs7_encrypted
) {
4035 bags
= PKCS12_unpack_p7encdata(p7
, pin
,
4036 (pin
? strlen(pin
) : 0));
4041 ret
= KMF_ERR_PKCS12_FORMAT
;
4045 if (openssl_parse_bags(bags
, pin
, keys
, certs
) != KMF_OK
)
4046 ret
= KMF_ERR_PKCS12_FORMAT
;
4048 sk_PKCS12_SAFEBAG_pop_free(bags
, PKCS12_SAFEBAG_free
);
4052 sk_PKCS7_pop_free(asafes
, PKCS7_free
);
4058 * Helper function to decrypt and parse PKCS#12 import file.
4061 extract_pkcs12(BIO
*fbio
, CK_UTF8CHAR
*pin
, CK_ULONG pinlen
,
4062 STACK_OF(EVP_PKEY
) **priv_key
, STACK_OF(X509
) **certs
,
4063 STACK_OF(X509
) **ca
)
4066 PKCS12
*pk12
, *pk12_tmp
;
4067 STACK_OF(EVP_PKEY
) *pkeylist
= NULL
;
4068 STACK_OF(X509
) *xcertlist
= NULL
;
4069 STACK_OF(X509
) *cacertlist
= NULL
;
4071 if ((pk12
= PKCS12_new()) == NULL
) {
4072 return (KMF_ERR_MEMORY
);
4075 if ((pk12_tmp
= d2i_PKCS12_bio(fbio
, &pk12
)) == NULL
) {
4076 /* This is ok; it seems to mean there is no more to read. */
4077 if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_ASN1
&&
4078 ERR_GET_REASON(ERR_peek_error()) == ASN1_R_HEADER_TOO_LONG
)
4079 goto end_extract_pkcs12
;
4082 return (KMF_ERR_PKCS12_FORMAT
);
4086 xcertlist
= sk_X509_new_null();
4087 if (xcertlist
== NULL
) {
4089 return (KMF_ERR_MEMORY
);
4091 pkeylist
= sk_EVP_PKEY_new_null();
4092 if (pkeylist
== NULL
) {
4093 sk_X509_pop_free(xcertlist
, X509_free
);
4095 return (KMF_ERR_MEMORY
);
4098 if (openssl_pkcs12_parse(pk12
, (char *)pin
, pkeylist
, xcertlist
,
4099 cacertlist
) != KMF_OK
) {
4100 sk_X509_pop_free(xcertlist
, X509_free
);
4101 sk_EVP_PKEY_pop_free(pkeylist
, EVP_PKEY_free
);
4103 return (KMF_ERR_PKCS12_FORMAT
);
4106 if (priv_key
&& pkeylist
)
4107 *priv_key
= pkeylist
;
4109 sk_EVP_PKEY_pop_free(pkeylist
, EVP_PKEY_free
);
4110 if (certs
&& xcertlist
)
4113 sk_X509_pop_free(xcertlist
, X509_free
);
4114 if (ca
&& cacertlist
)
4116 else if (cacertlist
)
4117 sk_X509_pop_free(cacertlist
, X509_free
);
4126 sslBN2KMFBN(BIGNUM
*from
, KMF_BIGINT
*to
)
4128 KMF_RETURN rv
= KMF_OK
;
4131 sz
= BN_num_bytes(from
);
4132 to
->val
= (uchar_t
*)malloc(sz
);
4133 if (to
->val
== NULL
)
4134 return (KMF_ERR_MEMORY
);
4136 if ((to
->len
= BN_bn2bin(from
, to
->val
)) != sz
) {
4140 rv
= KMF_ERR_MEMORY
;
4147 exportRawRSAKey(RSA
*rsa
, KMF_RAW_KEY_DATA
*key
)
4150 KMF_RAW_RSA_KEY
*kmfkey
= &key
->rawdata
.rsa
;
4152 const BIGNUM
*n
, *e
, *d
, *p
, *q
, *dmp1
, *dmpq
, *iqmp
;
4154 RSA_get0_key(rsa
, &n
, &e
, &d
);
4155 RSA_get0_factors(rsa
, &p
, &q
);
4156 RSA_get0_crt_params(rsa
, &dmp1
, &dmpq
, &iqmp
);
4158 (void) memset(kmfkey
, 0, sizeof (KMF_RAW_RSA_KEY
));
4159 if ((rv
= sslBN2KMFBN((BIGNUM
*)n
, &kmfkey
->mod
)) != KMF_OK
)
4162 if ((rv
= sslBN2KMFBN((BIGNUM
*)e
, &kmfkey
->pubexp
)) != KMF_OK
)
4166 if ((rv
= sslBN2KMFBN((BIGNUM
*)d
, &kmfkey
->priexp
)) != KMF_OK
)
4170 if ((rv
= sslBN2KMFBN((BIGNUM
*)p
, &kmfkey
->prime1
)) != KMF_OK
)
4174 if ((rv
= sslBN2KMFBN((BIGNUM
*)q
, &kmfkey
->prime2
)) != KMF_OK
)
4178 if ((rv
= sslBN2KMFBN((BIGNUM
*)dmp1
, &kmfkey
->exp1
)) != KMF_OK
)
4182 if ((rv
= sslBN2KMFBN((BIGNUM
*)dmpq
, &kmfkey
->exp2
)) != KMF_OK
)
4186 if ((rv
= sslBN2KMFBN((BIGNUM
*)iqmp
, &kmfkey
->coef
)) != KMF_OK
)
4190 kmf_free_raw_key(key
);
4192 key
->keytype
= KMF_RSA
;
4195 * Free the reference to this key, SSL will not actually free
4196 * the memory until the refcount == 0, so this is safe.
4204 exportRawDSAKey(DSA
*dsa
, KMF_RAW_KEY_DATA
*key
)
4207 KMF_RAW_DSA_KEY
*kmfkey
= &key
->rawdata
.dsa
;
4208 const BIGNUM
*p
, *q
, *g
, *priv_key
;
4210 DSA_get0_pqg(dsa
, &p
, &q
, &g
);
4211 DSA_get0_key(dsa
, NULL
, &priv_key
);
4213 (void) memset(kmfkey
, 0, sizeof (KMF_RAW_DSA_KEY
));
4214 if ((rv
= sslBN2KMFBN((BIGNUM
*)p
, &kmfkey
->prime
)) != KMF_OK
)
4217 if ((rv
= sslBN2KMFBN((BIGNUM
*)q
, &kmfkey
->subprime
)) != KMF_OK
)
4220 if ((rv
= sslBN2KMFBN((BIGNUM
*)g
, &kmfkey
->base
)) != KMF_OK
)
4223 if ((rv
= sslBN2KMFBN((BIGNUM
*)priv_key
, &kmfkey
->value
)) != KMF_OK
)
4228 kmf_free_raw_key(key
);
4230 key
->keytype
= KMF_DSA
;
4233 * Free the reference to this key, SSL will not actually free
4234 * the memory until the refcount == 0, so this is safe.
4242 add_cert_to_list(KMF_HANDLE
*kmfh
, X509
*sslcert
,
4243 KMF_X509_DER_CERT
**certlist
, int *ncerts
)
4245 KMF_RETURN rv
= KMF_OK
;
4246 KMF_X509_DER_CERT
*list
= (*certlist
);
4247 KMF_X509_DER_CERT cert
;
4251 list
= (KMF_X509_DER_CERT
*)malloc(sizeof (KMF_X509_DER_CERT
));
4253 list
= (KMF_X509_DER_CERT
*)realloc(list
,
4254 sizeof (KMF_X509_DER_CERT
) * (n
+ 1));
4258 return (KMF_ERR_MEMORY
);
4260 (void) memset(&cert
, 0, sizeof (cert
));
4261 rv
= ssl_cert2KMFDATA(kmfh
, sslcert
, &cert
.certificate
);
4264 /* Get the alias name for the cert if there is one */
4265 char *a
= (char *)X509_alias_get0(sslcert
, &len
);
4267 cert
.kmf_private
.label
= strdup(a
);
4268 cert
.kmf_private
.keystore_type
= KMF_KEYSTORE_OPENSSL
;
4282 add_key_to_list(KMF_RAW_KEY_DATA
**keylist
,
4283 KMF_RAW_KEY_DATA
*newkey
, int *nkeys
)
4285 KMF_RAW_KEY_DATA
*list
= (*keylist
);
4289 list
= (KMF_RAW_KEY_DATA
*)malloc(sizeof (KMF_RAW_KEY_DATA
));
4291 list
= (KMF_RAW_KEY_DATA
*)realloc(list
,
4292 sizeof (KMF_RAW_KEY_DATA
) * (n
+ 1));
4296 return (KMF_ERR_MEMORY
);
4307 convertToRawKey(EVP_PKEY
*pkey
, KMF_RAW_KEY_DATA
*key
)
4309 KMF_RETURN rv
= KMF_OK
;
4310 X509_ATTRIBUTE
*attr
;
4315 if (pkey
== NULL
|| key
== NULL
)
4316 return (KMF_ERR_BAD_PARAMETER
);
4317 /* Convert SSL key to raw key */
4318 if ((rsa
= EVP_PKEY_get1_RSA(pkey
)) != NULL
) {
4319 rv
= exportRawRSAKey(rsa
, key
);
4322 } else if ((dsa
= EVP_PKEY_get1_DSA(pkey
)) != NULL
) {
4323 rv
= exportRawDSAKey(dsa
, key
);
4327 return (KMF_ERR_BAD_PARAMETER
);
4330 * If friendlyName, add it to record.
4333 if ((loc
= EVP_PKEY_get_attr_by_NID(pkey
,
4334 NID_friendlyName
, -1)) != -1 &&
4335 (attr
= EVP_PKEY_get_attr(pkey
, loc
))) {
4336 ASN1_TYPE
*ty
= NULL
;
4337 int numattr
= X509_ATTRIBUTE_count(attr
);
4339 ty
= X509_ATTRIBUTE_get0_type(attr
, 0);
4342 key
->label
= OPENSSL_uni2asc(ty
->value
.bmpstring
->data
,
4343 ty
->value
.bmpstring
->length
);
4350 * If KeyID, add it to record as a KMF_DATA object.
4352 if ((loc
= EVP_PKEY_get_attr_by_NID(pkey
,
4353 NID_localKeyID
, -1)) != -1 &&
4354 (attr
= EVP_PKEY_get_attr(pkey
, loc
)) != NULL
) {
4355 ASN1_TYPE
*ty
= NULL
;
4356 int numattr
= X509_ATTRIBUTE_count(attr
);
4358 ty
= X509_ATTRIBUTE_get0_type(attr
, 0);
4359 key
->id
.Data
= (uchar_t
*)malloc(
4360 ty
->value
.octet_string
->length
);
4361 if (key
->id
.Data
== NULL
)
4362 return (KMF_ERR_MEMORY
);
4363 (void) memcpy(key
->id
.Data
, ty
->value
.octet_string
->data
,
4364 ty
->value
.octet_string
->length
);
4365 key
->id
.Length
= ty
->value
.octet_string
->length
;
4367 (void) memset(&key
->id
, 0, sizeof (KMF_DATA
));
4376 STACK_OF(EVP_PKEY
) *sslkeys
,
4377 STACK_OF(X509
) *sslcert
,
4378 STACK_OF(X509
) *sslcacerts
,
4379 KMF_RAW_KEY_DATA
**keylist
, int *nkeys
,
4380 KMF_X509_DER_CERT
**certlist
, int *ncerts
)
4382 KMF_RETURN rv
= KMF_OK
;
4383 KMF_RAW_KEY_DATA key
;
4386 for (i
= 0; sslkeys
!= NULL
&& i
< sk_EVP_PKEY_num(sslkeys
); i
++) {
4387 /* LINTED E_BAD_PTR_CAST_ALIGN */
4388 EVP_PKEY
*pkey
= sk_EVP_PKEY_value(sslkeys
, i
);
4389 rv
= convertToRawKey(pkey
, &key
);
4391 rv
= add_key_to_list(keylist
, &key
, nkeys
);
4397 /* Now add the certificate to the certlist */
4398 for (i
= 0; sslcert
!= NULL
&& i
< sk_X509_num(sslcert
); i
++) {
4399 /* LINTED E_BAD_PTR_CAST_ALIGN */
4400 X509
*cert
= sk_X509_value(sslcert
, i
);
4401 rv
= add_cert_to_list(kmfh
, cert
, certlist
, ncerts
);
4406 /* Also add any included CA certs to the list */
4407 for (i
= 0; sslcacerts
!= NULL
&& i
< sk_X509_num(sslcacerts
); i
++) {
4410 * sk_X509_value() is macro that embeds a cast to (X509 *).
4411 * Here it translates into ((X509 *)sk_value((ca), (i))).
4412 * Lint is complaining about the embedded casting, and
4413 * to fix it, you need to fix openssl header files.
4415 /* LINTED E_BAD_PTR_CAST_ALIGN */
4416 c
= sk_X509_value(sslcacerts
, i
);
4418 /* Now add the ca cert to the certlist */
4419 rv
= add_cert_to_list(kmfh
, c
, certlist
, ncerts
);
4427 openssl_import_objects(KMF_HANDLE
*kmfh
,
4428 char *filename
, KMF_CREDENTIAL
*cred
,
4429 KMF_X509_DER_CERT
**certlist
, int *ncerts
,
4430 KMF_RAW_KEY_DATA
**keylist
, int *nkeys
)
4432 KMF_RETURN rv
= KMF_OK
;
4433 KMF_ENCODE_FORMAT format
;
4435 STACK_OF(EVP_PKEY
) *privkeys
= NULL
;
4436 STACK_OF(X509
) *certs
= NULL
;
4437 STACK_OF(X509
) *cacerts
= NULL
;
4440 * auto-detect the file format, regardless of what
4441 * the 'format' parameters in the params say.
4443 rv
= kmf_get_file_format(filename
, &format
);
4448 /* This function only works for PEM or PKCS#12 files */
4449 if (format
!= KMF_FORMAT_PEM
&&
4450 format
!= KMF_FORMAT_PEM_KEYPAIR
&&
4451 format
!= KMF_FORMAT_PKCS12
)
4452 return (KMF_ERR_ENCODING
);
4459 if (format
== KMF_FORMAT_PKCS12
) {
4460 bio
= BIO_new_file(filename
, "rb");
4462 SET_ERROR(kmfh
, ERR_get_error());
4463 rv
= KMF_ERR_OPEN_FILE
;
4467 rv
= extract_pkcs12(bio
, (uchar_t
*)cred
->cred
,
4468 (uint32_t)cred
->credlen
, &privkeys
, &certs
, &cacerts
);
4471 /* Convert keys and certs to exportable format */
4472 rv
= convertPK12Objects(kmfh
, privkeys
, certs
, cacerts
,
4473 keylist
, nkeys
, certlist
, ncerts
);
4476 KMF_DATA
*certdata
= NULL
;
4477 KMF_X509_DER_CERT
*kmfcerts
= NULL
;
4479 rv
= extract_pem(kmfh
, NULL
, NULL
, NULL
, filename
,
4480 (uchar_t
*)cred
->cred
, (uint32_t)cred
->credlen
,
4481 &pkey
, &certdata
, ncerts
);
4483 /* Reached end of import file? */
4484 if (rv
== KMF_OK
&& pkey
!= NULL
) {
4485 privkeys
= sk_EVP_PKEY_new_null();
4486 if (privkeys
== NULL
) {
4487 rv
= KMF_ERR_MEMORY
;
4490 (void) sk_EVP_PKEY_push(privkeys
, pkey
);
4491 /* convert the certificate list here */
4492 if (*ncerts
> 0 && certlist
!= NULL
) {
4493 kmfcerts
= (KMF_X509_DER_CERT
*)calloc(*ncerts
,
4494 sizeof (KMF_X509_DER_CERT
));
4495 if (kmfcerts
== NULL
) {
4496 rv
= KMF_ERR_MEMORY
;
4499 for (i
= 0; i
< *ncerts
; i
++) {
4500 kmfcerts
[i
].certificate
= certdata
[i
];
4501 kmfcerts
[i
].kmf_private
.keystore_type
=
4502 KMF_KEYSTORE_OPENSSL
;
4504 *certlist
= kmfcerts
;
4507 * Convert keys to exportable format, the certs
4510 rv
= convertPK12Objects(kmfh
, privkeys
, NULL
, NULL
,
4511 keylist
, nkeys
, NULL
, NULL
);
4516 (void) BIO_free(bio
);
4519 sk_EVP_PKEY_pop_free(privkeys
, EVP_PKEY_free
);
4521 sk_X509_pop_free(certs
, X509_free
);
4523 sk_X509_pop_free(cacerts
, X509_free
);
4529 create_deskey(DES_cblock
**deskey
)
4533 key
= (DES_cblock
*) malloc(sizeof (DES_cblock
));
4535 return (KMF_ERR_MEMORY
);
4538 if (DES_random_key(key
) == 0) {
4540 return (KMF_ERR_KEYGEN_FAILED
);
4547 #define KEYGEN_RETRY 3
4548 #define DES3_KEY_SIZE 24
4551 create_des3key(unsigned char **des3key
)
4553 KMF_RETURN ret
= KMF_OK
;
4554 DES_cblock
*deskey1
= NULL
;
4555 DES_cblock
*deskey2
= NULL
;
4556 DES_cblock
*deskey3
= NULL
;
4557 unsigned char *newkey
= NULL
;
4560 if ((newkey
= malloc(DES3_KEY_SIZE
)) == NULL
) {
4561 return (KMF_ERR_MEMORY
);
4564 /* create the 1st DES key */
4565 if ((ret
= create_deskey(&deskey1
)) != KMF_OK
) {
4570 * Create the 2nd DES key and make sure its value is different
4571 * from the 1st DES key.
4575 if (deskey2
!= NULL
) {
4580 if ((ret
= create_deskey(&deskey2
)) != KMF_OK
) {
4584 if (memcmp((const void *) deskey1
, (const void *) deskey2
, 8)
4586 ret
= KMF_ERR_KEYGEN_FAILED
;
4589 } while (ret
== KMF_ERR_KEYGEN_FAILED
&& retry
< KEYGEN_RETRY
);
4591 if (ret
!= KMF_OK
) {
4596 * Create the 3rd DES key and make sure its value is different
4597 * from the 2nd DES key.
4601 if (deskey3
!= NULL
) {
4606 if ((ret
= create_deskey(&deskey3
)) != KMF_OK
) {
4610 if (memcmp((const void *)deskey2
, (const void *)deskey3
, 8)
4612 ret
= KMF_ERR_KEYGEN_FAILED
;
4615 } while (ret
== KMF_ERR_KEYGEN_FAILED
&& retry
< KEYGEN_RETRY
);
4617 if (ret
!= KMF_OK
) {
4621 /* Concatenate 3 DES keys into a DES3 key */
4622 (void) memcpy((void *)newkey
, (const void *)deskey1
, 8);
4623 (void) memcpy((void *)(newkey
+ 8), (const void *)deskey2
, 8);
4624 (void) memcpy((void *)(newkey
+ 16), (const void *)deskey3
, 8);
4628 if (deskey1
!= NULL
)
4631 if (deskey2
!= NULL
)
4634 if (deskey3
!= NULL
)
4637 if (ret
!= KMF_OK
&& newkey
!= NULL
)
4644 OpenSSL_CreateSymKey(KMF_HANDLE_T handle
,
4645 int numattr
, KMF_ATTRIBUTE
*attrlist
)
4647 KMF_RETURN ret
= KMF_OK
;
4648 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
4649 char *fullpath
= NULL
;
4650 KMF_RAW_SYM_KEY
*rkey
= NULL
;
4651 DES_cblock
*deskey
= NULL
;
4652 unsigned char *des3key
= NULL
;
4653 unsigned char *random
= NULL
;
4655 KMF_KEY_HANDLE
*symkey
;
4656 KMF_KEY_ALG keytype
;
4658 uint32_t keylen_size
= sizeof (keylen
);
4663 return (KMF_ERR_UNINITIALIZED
);
4665 symkey
= kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR
, attrlist
, numattr
);
4667 return (KMF_ERR_BAD_PARAMETER
);
4669 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
4671 keyfile
= kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
, attrlist
, numattr
);
4672 if (keyfile
== NULL
)
4673 return (KMF_ERR_BAD_PARAMETER
);
4675 ret
= kmf_get_attr(KMF_KEYALG_ATTR
, attrlist
, numattr
,
4676 (void *)&keytype
, NULL
);
4678 return (KMF_ERR_BAD_PARAMETER
);
4680 ret
= kmf_get_attr(KMF_KEYLENGTH_ATTR
, attrlist
, numattr
,
4681 &keylen
, &keylen_size
);
4682 if (ret
== KMF_ERR_ATTR_NOT_FOUND
&&
4683 (keytype
== KMF_DES
|| keytype
== KMF_DES3
))
4684 /* keylength is not required for DES and 3DES */
4687 return (KMF_ERR_BAD_PARAMETER
);
4689 fullpath
= get_fullpath(dirpath
, keyfile
);
4690 if (fullpath
== NULL
)
4691 return (KMF_ERR_BAD_PARAMETER
);
4693 /* If the requested file exists, return an error */
4694 if (test_for_file(fullpath
, 0400) == 1) {
4696 return (KMF_ERR_DUPLICATE_KEYFILE
);
4699 fd
= open(fullpath
, O_CREAT
|O_TRUNC
|O_RDWR
, 0400);
4701 ret
= KMF_ERR_OPEN_FILE
;
4705 rkey
= malloc(sizeof (KMF_RAW_SYM_KEY
));
4707 ret
= KMF_ERR_MEMORY
;
4710 (void) memset(rkey
, 0, sizeof (KMF_RAW_SYM_KEY
));
4712 if (keytype
== KMF_DES
) {
4713 if ((ret
= create_deskey(&deskey
)) != KMF_OK
) {
4716 rkey
->keydata
.val
= (uchar_t
*)deskey
;
4717 rkey
->keydata
.len
= 8;
4719 symkey
->keyalg
= KMF_DES
;
4721 } else if (keytype
== KMF_DES3
) {
4722 if ((ret
= create_des3key(&des3key
)) != KMF_OK
) {
4725 rkey
->keydata
.val
= (uchar_t
*)des3key
;
4726 rkey
->keydata
.len
= DES3_KEY_SIZE
;
4727 symkey
->keyalg
= KMF_DES3
;
4729 } else if (keytype
== KMF_AES
|| keytype
== KMF_RC4
||
4730 keytype
== KMF_GENERIC_SECRET
) {
4733 if (keylen
% 8 != 0) {
4734 ret
= KMF_ERR_BAD_KEY_SIZE
;
4738 if (keytype
== KMF_AES
) {
4739 if (keylen
!= 128 &&
4742 ret
= KMF_ERR_BAD_KEY_SIZE
;
4748 random
= malloc(bytes
);
4749 if (random
== NULL
) {
4750 ret
= KMF_ERR_MEMORY
;
4753 if (RAND_bytes(random
, bytes
) != 1) {
4754 ret
= KMF_ERR_KEYGEN_FAILED
;
4758 rkey
->keydata
.val
= (uchar_t
*)random
;
4759 rkey
->keydata
.len
= bytes
;
4760 symkey
->keyalg
= keytype
;
4763 ret
= KMF_ERR_BAD_KEY_TYPE
;
4767 (void) write(fd
, (const void *) rkey
->keydata
.val
, rkey
->keydata
.len
);
4769 symkey
->kstype
= KMF_KEYSTORE_OPENSSL
;
4770 symkey
->keyclass
= KMF_SYMMETRIC
;
4771 symkey
->keylabel
= (char *)fullpath
;
4772 symkey
->israw
= TRUE
;
4773 symkey
->keyp
= rkey
;
4779 if (ret
!= KMF_OK
&& fullpath
!= NULL
) {
4782 if (ret
!= KMF_OK
) {
4783 kmf_free_raw_sym_key(rkey
);
4784 symkey
->keyp
= NULL
;
4785 symkey
->keyalg
= KMF_KEYALG_NONE
;
4792 * Check a file to see if it is a CRL file with PEM or DER format.
4793 * If success, return its format in the "pformat" argument.
4796 OpenSSL_IsCRLFile(KMF_HANDLE_T handle
, char *filename
, int *pformat
)
4798 KMF_RETURN ret
= KMF_OK
;
4799 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
4801 X509_CRL
*xcrl
= NULL
;
4803 if (filename
== NULL
) {
4804 return (KMF_ERR_BAD_PARAMETER
);
4807 bio
= BIO_new_file(filename
, "rb");
4809 SET_ERROR(kmfh
, ERR_get_error());
4810 ret
= KMF_ERR_OPEN_FILE
;
4814 if ((xcrl
= PEM_read_bio_X509_CRL(bio
, NULL
, NULL
, NULL
)) != NULL
) {
4815 *pformat
= KMF_FORMAT_PEM
;
4818 (void) BIO_free(bio
);
4821 * Now try to read it as raw DER data.
4823 bio
= BIO_new_file(filename
, "rb");
4825 SET_ERROR(kmfh
, ERR_get_error());
4826 ret
= KMF_ERR_OPEN_FILE
;
4830 if ((xcrl
= d2i_X509_CRL_bio(bio
, NULL
)) != NULL
) {
4831 *pformat
= KMF_FORMAT_ASN1
;
4833 ret
= KMF_ERR_BAD_CRLFILE
;
4838 (void) BIO_free(bio
);
4841 X509_CRL_free(xcrl
);
4847 OpenSSL_GetSymKeyValue(KMF_HANDLE_T handle
, KMF_KEY_HANDLE
*symkey
,
4848 KMF_RAW_SYM_KEY
*rkey
)
4850 KMF_RETURN rv
= KMF_OK
;
4851 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
4855 return (KMF_ERR_UNINITIALIZED
);
4857 if (symkey
== NULL
|| rkey
== NULL
)
4858 return (KMF_ERR_BAD_PARAMETER
);
4859 else if (symkey
->keyclass
!= KMF_SYMMETRIC
)
4860 return (KMF_ERR_BAD_KEY_CLASS
);
4862 if (symkey
->israw
) {
4863 KMF_RAW_SYM_KEY
*rawkey
= (KMF_RAW_SYM_KEY
*)symkey
->keyp
;
4865 if (rawkey
== NULL
||
4866 rawkey
->keydata
.val
== NULL
||
4867 rawkey
->keydata
.len
== 0)
4868 return (KMF_ERR_BAD_KEYHANDLE
);
4870 rkey
->keydata
.len
= rawkey
->keydata
.len
;
4871 if ((rkey
->keydata
.val
= malloc(rkey
->keydata
.len
)) == NULL
)
4872 return (KMF_ERR_MEMORY
);
4873 (void) memcpy(rkey
->keydata
.val
, rawkey
->keydata
.val
,
4876 rv
= kmf_read_input_file(handle
, symkey
->keylabel
, &keyvalue
);
4879 rkey
->keydata
.len
= keyvalue
.Length
;
4880 rkey
->keydata
.val
= keyvalue
.Data
;
4887 * substitute for the unsafe access(2) function.
4888 * If the file in question already exists, return 1.
4889 * else 0. If an error occurs during testing (other
4890 * than EEXIST), return -1.
4893 test_for_file(char *filename
, mode_t mode
)
4898 * Try to create the file with the EXCL flag.
4899 * The call should fail if the file exists.
4901 fd
= open(filename
, O_WRONLY
|O_CREAT
|O_EXCL
, mode
);
4902 if (fd
== -1 && errno
== EEXIST
)
4904 else if (fd
== -1) /* some other error */
4907 /* The file did NOT exist. Delete the testcase. */
4909 (void) unlink(filename
);
4914 OpenSSL_StoreKey(KMF_HANDLE_T handle
, int numattr
,
4915 KMF_ATTRIBUTE
*attrlist
)
4917 KMF_RETURN rv
= KMF_OK
;
4918 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
4919 KMF_KEY_HANDLE
*pubkey
= NULL
, *prikey
= NULL
;
4920 KMF_RAW_KEY_DATA
*rawkey
;
4921 EVP_PKEY
*pkey
= NULL
;
4922 KMF_ENCODE_FORMAT format
= KMF_FORMAT_PEM
;
4923 KMF_CREDENTIAL cred
= { NULL
, 0 };
4926 char *fullpath
= NULL
;
4927 char *keyfile
= NULL
;
4928 char *dirpath
= NULL
;
4930 pubkey
= kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR
, attrlist
, numattr
);
4934 prikey
= kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR
, attrlist
, numattr
);
4938 rawkey
= kmf_get_attr_ptr(KMF_RAW_KEY_ATTR
, attrlist
, numattr
);
4943 * Exactly 1 type of key must be passed to this function.
4946 return (KMF_ERR_BAD_PARAMETER
);
4948 keyfile
= (char *)kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
, attrlist
,
4950 if (keyfile
== NULL
)
4951 return (KMF_ERR_BAD_PARAMETER
);
4953 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
4955 fullpath
= get_fullpath(dirpath
, keyfile
);
4957 /* Once we have the full path, we don't need the pieces */
4958 if (fullpath
== NULL
)
4959 return (KMF_ERR_BAD_PARAMETER
);
4961 /* If the requested file exists, return an error */
4962 if (test_for_file(fullpath
, 0400) == 1) {
4964 return (KMF_ERR_DUPLICATE_KEYFILE
);
4967 rv
= kmf_get_attr(KMF_ENCODE_FORMAT_ATTR
, attrlist
, numattr
,
4970 /* format is optional. */
4973 /* CRED is not required for OpenSSL files */
4974 (void) kmf_get_attr(KMF_CREDENTIAL_ATTR
, attrlist
, numattr
,
4977 /* Store the private key to the keyfile */
4978 out
= BIO_new_file(fullpath
, "wb");
4980 SET_ERROR(kmfh
, ERR_get_error());
4981 rv
= KMF_ERR_OPEN_FILE
;
4985 if (prikey
!= NULL
&& prikey
->keyp
!= NULL
) {
4986 if (prikey
->keyalg
== KMF_RSA
||
4987 prikey
->keyalg
== KMF_DSA
) {
4988 pkey
= (EVP_PKEY
*)prikey
->keyp
;
4990 rv
= ssl_write_key(kmfh
, format
,
4991 out
, &cred
, pkey
, TRUE
);
4993 if (rv
== KMF_OK
&& prikey
->keylabel
== NULL
) {
4994 prikey
->keylabel
= strdup(fullpath
);
4995 if (prikey
->keylabel
== NULL
)
4996 rv
= KMF_ERR_MEMORY
;
4999 } else if (pubkey
!= NULL
&& pubkey
->keyp
!= NULL
) {
5000 if (pubkey
->keyalg
== KMF_RSA
||
5001 pubkey
->keyalg
== KMF_DSA
) {
5002 pkey
= (EVP_PKEY
*)pubkey
->keyp
;
5004 rv
= ssl_write_key(kmfh
, format
,
5005 out
, &cred
, pkey
, FALSE
);
5007 if (rv
== KMF_OK
&& pubkey
->keylabel
== NULL
) {
5008 pubkey
->keylabel
= strdup(fullpath
);
5009 if (pubkey
->keylabel
== NULL
)
5010 rv
= KMF_ERR_MEMORY
;
5013 } else if (rawkey
!= NULL
) {
5014 if (rawkey
->keytype
== KMF_RSA
) {
5015 pkey
= ImportRawRSAKey(&rawkey
->rawdata
.rsa
);
5016 } else if (rawkey
->keytype
== KMF_DSA
) {
5017 pkey
= ImportRawDSAKey(&rawkey
->rawdata
.dsa
);
5019 rv
= KMF_ERR_BAD_PARAMETER
;
5022 KMF_KEY_CLASS kclass
= KMF_ASYM_PRI
;
5024 rv
= kmf_get_attr(KMF_KEYCLASS_ATTR
, attrlist
, numattr
,
5025 (void *)&kclass
, NULL
);
5028 rv
= ssl_write_key(kmfh
, format
, out
,
5029 &cred
, pkey
, (kclass
== KMF_ASYM_PRI
));
5030 EVP_PKEY_free(pkey
);
5037 (void) BIO_free(out
);
5041 (void) chmod(fullpath
, 0400);
5048 OpenSSL_ImportCRL(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
5050 KMF_RETURN ret
= KMF_OK
;
5051 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
5052 X509_CRL
*xcrl
= NULL
;
5055 KMF_ENCODE_FORMAT format
;
5056 BIO
*in
= NULL
, *out
= NULL
;
5057 int openssl_ret
= 0;
5058 KMF_ENCODE_FORMAT outformat
;
5059 boolean_t crlcheck
= FALSE
;
5060 char *certfile
, *dirpath
, *crlfile
, *incrl
, *outcrl
, *outcrlfile
;
5062 if (numattr
== 0 || attrlist
== NULL
) {
5063 return (KMF_ERR_BAD_PARAMETER
);
5066 /* CRL check is optional */
5067 (void) kmf_get_attr(KMF_CRL_CHECK_ATTR
, attrlist
, numattr
,
5070 certfile
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
, numattr
);
5071 if (crlcheck
== B_TRUE
&& certfile
== NULL
) {
5072 return (KMF_ERR_BAD_CERTFILE
);
5075 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
5076 incrl
= kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR
, attrlist
, numattr
);
5077 outcrl
= kmf_get_attr_ptr(KMF_CRL_OUTFILE_ATTR
, attrlist
, numattr
);
5079 crlfile
= get_fullpath(dirpath
, incrl
);
5081 if (crlfile
== NULL
)
5082 return (KMF_ERR_BAD_CRLFILE
);
5084 outcrlfile
= get_fullpath(dirpath
, outcrl
);
5085 if (outcrlfile
== NULL
)
5086 return (KMF_ERR_BAD_CRLFILE
);
5088 if (isdir(outcrlfile
)) {
5090 return (KMF_ERR_BAD_CRLFILE
);
5093 ret
= kmf_is_crl_file(handle
, crlfile
, &format
);
5094 if (ret
!= KMF_OK
) {
5099 in
= BIO_new_file(crlfile
, "rb");
5101 SET_ERROR(kmfh
, ERR_get_error());
5102 ret
= KMF_ERR_OPEN_FILE
;
5106 if (format
== KMF_FORMAT_ASN1
) {
5107 xcrl
= d2i_X509_CRL_bio(in
, NULL
);
5108 } else if (format
== KMF_FORMAT_PEM
) {
5109 xcrl
= PEM_read_bio_X509_CRL(in
, NULL
, NULL
, NULL
);
5113 SET_ERROR(kmfh
, ERR_get_error());
5114 ret
= KMF_ERR_BAD_CRLFILE
;
5118 /* If bypasscheck is specified, no need to verify. */
5119 if (crlcheck
== B_FALSE
)
5122 ret
= kmf_is_cert_file(handle
, certfile
, &format
);
5126 /* Read in the CA cert file and convert to X509 */
5127 if (BIO_read_filename(in
, certfile
) <= 0) {
5128 SET_ERROR(kmfh
, ERR_get_error());
5129 ret
= KMF_ERR_OPEN_FILE
;
5133 if (format
== KMF_FORMAT_ASN1
) {
5134 xcert
= d2i_X509_bio(in
, NULL
);
5135 } else if (format
== KMF_FORMAT_PEM
) {
5136 xcert
= PEM_read_bio_X509(in
, NULL
, NULL
, NULL
);
5138 ret
= KMF_ERR_BAD_CERT_FORMAT
;
5142 if (xcert
== NULL
) {
5143 SET_ERROR(kmfh
, ERR_get_error());
5144 ret
= KMF_ERR_BAD_CERT_FORMAT
;
5147 /* Now get the public key from the CA cert */
5148 pkey
= X509_get_pubkey(xcert
);
5150 SET_ERROR(kmfh
, ERR_get_error());
5151 ret
= KMF_ERR_BAD_CERTFILE
;
5155 /* Verify the CRL with the CA's public key */
5156 openssl_ret
= X509_CRL_verify(xcrl
, pkey
);
5157 EVP_PKEY_free(pkey
);
5158 if (openssl_ret
> 0) {
5159 ret
= KMF_OK
; /* verify succeed */
5161 SET_ERROR(kmfh
, openssl_ret
);
5162 ret
= KMF_ERR_BAD_CRLFILE
;
5166 ret
= kmf_get_attr(KMF_ENCODE_FORMAT_ATTR
, attrlist
, numattr
,
5168 if (ret
!= KMF_OK
) {
5170 outformat
= KMF_FORMAT_PEM
;
5173 out
= BIO_new_file(outcrlfile
, "wb");
5175 SET_ERROR(kmfh
, ERR_get_error());
5176 ret
= KMF_ERR_OPEN_FILE
;
5180 if (outformat
== KMF_FORMAT_ASN1
) {
5181 openssl_ret
= (int)i2d_X509_CRL_bio(out
, xcrl
);
5182 } else if (outformat
== KMF_FORMAT_PEM
) {
5183 openssl_ret
= PEM_write_bio_X509_CRL(out
, xcrl
);
5185 ret
= KMF_ERR_BAD_PARAMETER
;
5189 if (openssl_ret
<= 0) {
5190 SET_ERROR(kmfh
, ERR_get_error());
5191 ret
= KMF_ERR_WRITE_FILE
;
5198 X509_CRL_free(xcrl
);
5204 (void) BIO_free(in
);
5207 (void) BIO_free(out
);
5209 if (outcrlfile
!= NULL
)
5216 OpenSSL_ListCRL(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
5218 KMF_RETURN ret
= KMF_OK
;
5219 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
5221 KMF_ENCODE_FORMAT format
;
5222 char *crlfile
= NULL
;
5229 char *crlfilename
, *dirpath
;
5231 if (numattr
== 0 || attrlist
== NULL
) {
5232 return (KMF_ERR_BAD_PARAMETER
);
5234 crlfilename
= kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR
,
5236 if (crlfilename
== NULL
)
5237 return (KMF_ERR_BAD_CRLFILE
);
5239 crldata
= (char **)kmf_get_attr_ptr(KMF_CRL_DATA_ATTR
,
5242 if (crldata
== NULL
)
5243 return (KMF_ERR_BAD_PARAMETER
);
5245 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
5247 crlfile
= get_fullpath(dirpath
, crlfilename
);
5249 if (crlfile
== NULL
)
5250 return (KMF_ERR_BAD_CRLFILE
);
5252 if (isdir(crlfile
)) {
5254 return (KMF_ERR_BAD_CRLFILE
);
5257 ret
= kmf_is_crl_file(handle
, crlfile
, &format
);
5258 if (ret
!= KMF_OK
) {
5263 if (bio_err
== NULL
)
5264 bio_err
= BIO_new_fp(stderr
, BIO_NOCLOSE
);
5266 in
= BIO_new_file(crlfile
, "rb");
5268 SET_ERROR(kmfh
, ERR_get_error());
5269 ret
= KMF_ERR_OPEN_FILE
;
5273 if (format
== KMF_FORMAT_ASN1
) {
5274 x
= d2i_X509_CRL_bio(in
, NULL
);
5275 } else if (format
== KMF_FORMAT_PEM
) {
5276 x
= PEM_read_bio_X509_CRL(in
, NULL
, NULL
, NULL
);
5279 if (x
== NULL
) { /* should not happen */
5280 SET_ERROR(kmfh
, ERR_get_error());
5281 ret
= KMF_ERR_OPEN_FILE
;
5285 mem
= BIO_new(BIO_s_mem());
5287 SET_ERROR(kmfh
, ERR_get_error());
5288 ret
= KMF_ERR_MEMORY
;
5292 (void) X509_CRL_print(mem
, x
);
5293 len
= BIO_get_mem_data(mem
, &memptr
);
5295 SET_ERROR(kmfh
, ERR_get_error());
5296 ret
= KMF_ERR_MEMORY
;
5300 data
= malloc(len
+ 1);
5302 ret
= KMF_ERR_MEMORY
;
5306 (void) memcpy(data
, memptr
, len
);
5314 if (crlfile
!= NULL
)
5318 (void) BIO_free(in
);
5321 (void) BIO_free(mem
);
5327 OpenSSL_DeleteCRL(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
5329 KMF_RETURN ret
= KMF_OK
;
5330 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
5331 KMF_ENCODE_FORMAT format
;
5332 char *crlfile
= NULL
;
5334 char *crlfilename
, *dirpath
;
5336 if (numattr
== 0 || attrlist
== NULL
) {
5337 return (KMF_ERR_BAD_PARAMETER
);
5340 crlfilename
= kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR
,
5343 if (crlfilename
== NULL
)
5344 return (KMF_ERR_BAD_CRLFILE
);
5346 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
5348 crlfile
= get_fullpath(dirpath
, crlfilename
);
5350 if (crlfile
== NULL
)
5351 return (KMF_ERR_BAD_CRLFILE
);
5353 if (isdir(crlfile
)) {
5354 ret
= KMF_ERR_BAD_CRLFILE
;
5358 ret
= kmf_is_crl_file(handle
, crlfile
, &format
);
5362 if (unlink(crlfile
) != 0) {
5363 SET_SYS_ERROR(kmfh
, errno
);
5364 ret
= KMF_ERR_INTERNAL
;
5370 (void) BIO_free(in
);
5371 if (crlfile
!= NULL
)
5378 OpenSSL_FindCertInCRL(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
5380 KMF_RETURN ret
= KMF_OK
;
5381 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
5382 KMF_ENCODE_FORMAT format
;
5385 X509_CRL
*xcrl
= NULL
;
5386 STACK_OF(X509_REVOKED
) *revoke_stack
= NULL
;
5387 X509_REVOKED
*revoke
;
5389 char *crlfilename
, *crlfile
, *dirpath
, *certfile
;
5391 if (numattr
== 0 || attrlist
== NULL
) {
5392 return (KMF_ERR_BAD_PARAMETER
);
5395 crlfilename
= kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR
,
5398 if (crlfilename
== NULL
)
5399 return (KMF_ERR_BAD_CRLFILE
);
5401 certfile
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
, numattr
);
5402 if (certfile
== NULL
)
5403 return (KMF_ERR_BAD_CRLFILE
);
5405 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
5407 crlfile
= get_fullpath(dirpath
, crlfilename
);
5409 if (crlfile
== NULL
)
5410 return (KMF_ERR_BAD_CRLFILE
);
5412 if (isdir(crlfile
)) {
5413 ret
= KMF_ERR_BAD_CRLFILE
;
5417 ret
= kmf_is_crl_file(handle
, crlfile
, &format
);
5421 /* Read the CRL file and load it into a X509_CRL structure */
5422 in
= BIO_new_file(crlfilename
, "rb");
5424 SET_ERROR(kmfh
, ERR_get_error());
5425 ret
= KMF_ERR_OPEN_FILE
;
5429 if (format
== KMF_FORMAT_ASN1
) {
5430 xcrl
= d2i_X509_CRL_bio(in
, NULL
);
5431 } else if (format
== KMF_FORMAT_PEM
) {
5432 xcrl
= PEM_read_bio_X509_CRL(in
, NULL
, NULL
, NULL
);
5436 SET_ERROR(kmfh
, ERR_get_error());
5437 ret
= KMF_ERR_BAD_CRLFILE
;
5440 (void) BIO_free(in
);
5442 /* Read the Certificate file and load it into a X509 structure */
5443 ret
= kmf_is_cert_file(handle
, certfile
, &format
);
5447 in
= BIO_new_file(certfile
, "rb");
5449 SET_ERROR(kmfh
, ERR_get_error());
5450 ret
= KMF_ERR_OPEN_FILE
;
5454 if (format
== KMF_FORMAT_ASN1
) {
5455 xcert
= d2i_X509_bio(in
, NULL
);
5456 } else if (format
== KMF_FORMAT_PEM
) {
5457 xcert
= PEM_read_bio_X509(in
, NULL
, NULL
, NULL
);
5460 if (xcert
== NULL
) {
5461 SET_ERROR(kmfh
, ERR_get_error());
5462 ret
= KMF_ERR_BAD_CERTFILE
;
5466 /* Check if the certificate and the CRL have same issuer */
5467 if (X509_NAME_cmp(X509_get_issuer_name(xcert
),
5468 X509_CRL_get_issuer(xcrl
)) != 0) {
5469 ret
= KMF_ERR_ISSUER
;
5473 /* Check to see if the certificate serial number is revoked */
5474 revoke_stack
= X509_CRL_get_REVOKED(xcrl
);
5475 if (sk_X509_REVOKED_num(revoke_stack
) <= 0) {
5476 /* No revoked certificates in the CRL file */
5477 SET_ERROR(kmfh
, ERR_get_error());
5478 ret
= KMF_ERR_EMPTY_CRL
;
5482 for (i
= 0; i
< sk_X509_REVOKED_num(revoke_stack
); i
++) {
5483 /* LINTED E_BAD_PTR_CAST_ALIGN */
5484 revoke
= sk_X509_REVOKED_value(revoke_stack
, i
);
5485 if (ASN1_INTEGER_cmp(X509_get_serialNumber(xcert
),
5486 X509_REVOKED_get0_serialNumber(revoke
)) == 0) {
5491 if (i
< sk_X509_REVOKED_num(revoke_stack
)) {
5494 ret
= KMF_ERR_NOT_REVOKED
;
5499 (void) BIO_free(in
);
5501 X509_CRL_free(xcrl
);
5509 OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle
, char *crlname
, KMF_DATA
*tacert
)
5511 KMF_RETURN ret
= KMF_OK
;
5512 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
5514 X509_CRL
*xcrl
= NULL
;
5518 KMF_ENCODE_FORMAT crl_format
;
5522 if (handle
== NULL
|| crlname
== NULL
|| tacert
== NULL
) {
5523 return (KMF_ERR_BAD_PARAMETER
);
5526 ret
= kmf_get_file_format(crlname
, &crl_format
);
5530 bcrl
= BIO_new_file(crlname
, "rb");
5532 SET_ERROR(kmfh
, ERR_get_error());
5533 ret
= KMF_ERR_OPEN_FILE
;
5537 if (crl_format
== KMF_FORMAT_ASN1
) {
5538 xcrl
= d2i_X509_CRL_bio(bcrl
, NULL
);
5539 } else if (crl_format
== KMF_FORMAT_PEM
) {
5540 xcrl
= PEM_read_bio_X509_CRL(bcrl
, NULL
, NULL
, NULL
);
5542 ret
= KMF_ERR_BAD_PARAMETER
;
5547 SET_ERROR(kmfh
, ERR_get_error());
5548 ret
= KMF_ERR_BAD_CRLFILE
;
5553 len
= tacert
->Length
;
5554 xcert
= d2i_X509(NULL
, (const uchar_t
**)&p
, len
);
5556 if (xcert
== NULL
) {
5557 SET_ERROR(kmfh
, ERR_get_error());
5558 ret
= KMF_ERR_BAD_CERTFILE
;
5562 /* Get issuer certificate public key */
5563 pkey
= X509_get_pubkey(xcert
);
5565 SET_ERROR(kmfh
, ERR_get_error());
5566 ret
= KMF_ERR_BAD_CERT_FORMAT
;
5570 /* Verify CRL signature */
5571 sslret
= X509_CRL_verify(xcrl
, pkey
);
5572 EVP_PKEY_free(pkey
);
5576 SET_ERROR(kmfh
, sslret
);
5577 ret
= KMF_ERR_BAD_CRLFILE
;
5582 (void) BIO_free(bcrl
);
5585 X509_CRL_free(xcrl
);
5595 OpenSSL_CheckCRLDate(KMF_HANDLE_T handle
, char *crlname
)
5597 KMF_RETURN ret
= KMF_OK
;
5598 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
5599 KMF_ENCODE_FORMAT crl_format
;
5601 X509_CRL
*xcrl
= NULL
;
5604 if (handle
== NULL
|| crlname
== NULL
) {
5605 return (KMF_ERR_BAD_PARAMETER
);
5608 ret
= kmf_is_crl_file(handle
, crlname
, &crl_format
);
5612 bcrl
= BIO_new_file(crlname
, "rb");
5614 SET_ERROR(kmfh
, ERR_get_error());
5615 ret
= KMF_ERR_OPEN_FILE
;
5619 if (crl_format
== KMF_FORMAT_ASN1
)
5620 xcrl
= d2i_X509_CRL_bio(bcrl
, NULL
);
5621 else if (crl_format
== KMF_FORMAT_PEM
)
5622 xcrl
= PEM_read_bio_X509_CRL(bcrl
, NULL
, NULL
, NULL
);
5625 SET_ERROR(kmfh
, ERR_get_error());
5626 ret
= KMF_ERR_BAD_CRLFILE
;
5629 i
= X509_cmp_time(X509_CRL_get0_lastUpdate(xcrl
), NULL
);
5631 ret
= KMF_ERR_VALIDITY_PERIOD
;
5634 if (X509_CRL_get0_nextUpdate(xcrl
)) {
5635 i
= X509_cmp_time(X509_CRL_get0_nextUpdate(xcrl
), NULL
);
5638 ret
= KMF_ERR_VALIDITY_PERIOD
;
5647 (void) BIO_free(bcrl
);
5650 X509_CRL_free(xcrl
);