2 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
4 * Use is subject to license terms.
7 * Copyright (c) 2012, OmniTI Computer Consulting, Inc. All rights reserved.
10 * Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
14 * ====================================================================
15 * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved.
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
21 * 1. Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
24 * 2. Redistributions in binary form must reproduce the above copyright
25 * notice, this list of conditions and the following disclaimer in
26 * the documentation and/or other materials provided with the
29 * 3. All advertising materials mentioning features or use of this
30 * software must display the following acknowledgment:
31 * "This product includes software developed by the OpenSSL Project
32 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
34 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
35 * endorse or promote products derived from this software without
36 * prior written permission. For written permission, please contact
37 * licensing@OpenSSL.org.
39 * 5. Products derived from this software may not be called "OpenSSL"
40 * nor may "OpenSSL" appear in their names without prior written
41 * permission of the OpenSSL Project.
43 * 6. Redistributions of any form whatsoever must retain the following
45 * "This product includes software developed by the OpenSSL Project
46 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
48 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
49 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
51 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
52 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
53 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
54 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
55 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
57 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
58 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
59 * OF THE POSSIBILITY OF SUCH DAMAGE.
60 * ====================================================================
62 * This product includes cryptographic software written by Eric Young
63 * (eay@cryptsoft.com). This product includes software written by Tim
64 * Hudson (tjh@cryptsoft.com).
74 #include <cryptoutil.h>
78 /* OPENSSL related headers */
79 #include <openssl/bio.h>
80 #include <openssl/bn.h>
81 #include <openssl/asn1.h>
82 #include <openssl/err.h>
83 #include <openssl/bn.h>
84 #include <openssl/x509.h>
85 #include <openssl/rsa.h>
86 #include <openssl/dsa.h>
87 #include <openssl/x509v3.h>
88 #include <openssl/objects.h>
89 #include <openssl/pem.h>
90 #include <openssl/pkcs12.h>
91 #include <openssl/ocsp.h>
92 #include <openssl/des.h>
93 #include <openssl/rand.h>
95 #define PRINT_ANY_EXTENSION (\
96 KMF_X509_EXT_KEY_USAGE |\
97 KMF_X509_EXT_CERT_POLICIES |\
98 KMF_X509_EXT_SUBJALTNAME |\
99 KMF_X509_EXT_BASIC_CONSTRAINTS |\
100 KMF_X509_EXT_NAME_CONSTRAINTS |\
101 KMF_X509_EXT_POLICY_CONSTRAINTS |\
102 KMF_X509_EXT_EXT_KEY_USAGE |\
103 KMF_X509_EXT_INHIBIT_ANY_POLICY |\
104 KMF_X509_EXT_AUTH_KEY_ID |\
105 KMF_X509_EXT_SUBJ_KEY_ID |\
106 KMF_X509_EXT_POLICY_MAPPING)
108 static uchar_t P
[] = { 0x00, 0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76,
109 0xaa, 0x3d, 0x25, 0x75, 0x9b, 0xb0, 0x68, 0x69,
110 0xcb, 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d, 0x0c,
111 0xf7, 0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82,
112 0xe5, 0xd0, 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e,
113 0xaf, 0xc2, 0xe9, 0xad, 0xac, 0x32, 0xab, 0x7a,
114 0xac, 0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24,
115 0xc2, 0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02,
118 static uchar_t Q
[] = { 0x00, 0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8,
119 0xee, 0x99, 0x3b, 0x4f, 0x2d, 0xed, 0x30, 0xf4,
120 0x8e, 0xda, 0xce, 0x91, 0x5f };
122 static uchar_t G
[] = { 0x00, 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a,
123 0x13, 0x41, 0x31, 0x63, 0xa5, 0x5b, 0x4c, 0xb5,
124 0x00, 0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c, 0xef,
125 0xcb, 0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c,
126 0x2e, 0x71, 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba,
127 0xbf, 0x58, 0xe5, 0xb7, 0x95, 0x21, 0x92, 0x5c,
128 0x9c, 0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08,
129 0x8c, 0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88,
132 #define SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_OPENSSL; \
133 h->lasterr.errcode = c;
135 #define SET_SYS_ERROR(h, c) h->lasterr.kstype = -1; h->lasterr.errcode = c;
138 * Declare some new macros for managing stacks of EVP_PKEYS.
140 DECLARE_STACK_OF(EVP_PKEY
)
142 #define sk_EVP_PKEY_new_null() SKM_sk_new_null(EVP_PKEY)
143 #define sk_EVP_PKEY_free(st) SKM_sk_free(EVP_PKEY, (st))
144 #define sk_EVP_PKEY_num(st) SKM_sk_num(EVP_PKEY, (st))
145 #define sk_EVP_PKEY_value(st, i) SKM_sk_value(EVP_PKEY, (st), (i))
146 #define sk_EVP_PKEY_push(st, val) SKM_sk_push(EVP_PKEY, (st), (val))
147 #define sk_EVP_PKEY_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY, (st), \
150 mutex_t init_lock
= DEFAULTMUTEX
;
151 static int ssl_initialized
= 0;
152 static BIO
*bio_err
= NULL
;
155 test_for_file(char *, mode_t
);
157 openssl_parse_bag(PKCS12_SAFEBAG
*, char *, int,
158 STACK_OF(EVP_PKEY
) *, STACK_OF(X509
) *);
161 local_export_pk12(KMF_HANDLE_T
, KMF_CREDENTIAL
*, int, KMF_X509_DER_CERT
*,
162 int, KMF_KEY_HANDLE
*, char *);
164 static KMF_RETURN
set_pkey_attrib(EVP_PKEY
*, ASN1_TYPE
*, int);
167 extract_pem(KMF_HANDLE
*, char *, char *, KMF_BIGINT
*, char *,
168 CK_UTF8CHAR
*, CK_ULONG
, EVP_PKEY
**, KMF_DATA
**, int *);
171 kmf_load_cert(KMF_HANDLE
*, char *, char *, KMF_BIGINT
*, KMF_CERT_VALIDITY
,
175 load_certs(KMF_HANDLE
*, char *, char *, KMF_BIGINT
*, KMF_CERT_VALIDITY
,
176 char *, KMF_DATA
**, uint32_t *);
179 sslBN2KMFBN(BIGNUM
*, KMF_BIGINT
*);
182 ImportRawRSAKey(KMF_RAW_RSA_KEY
*);
185 convertToRawKey(EVP_PKEY
*, KMF_RAW_KEY_DATA
*);
188 OpenSSL_FindCert(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
191 OpenSSL_FreeKMFCert(KMF_HANDLE_T
, KMF_X509_DER_CERT
*);
194 OpenSSL_StoreCert(KMF_HANDLE_T handle
, int, KMF_ATTRIBUTE
*);
197 OpenSSL_DeleteCert(KMF_HANDLE_T handle
, int, KMF_ATTRIBUTE
*);
200 OpenSSL_CreateKeypair(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
203 OpenSSL_StoreKey(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
206 OpenSSL_EncodePubKeyData(KMF_HANDLE_T
, KMF_KEY_HANDLE
*, KMF_DATA
*);
209 OpenSSL_SignData(KMF_HANDLE_T
, KMF_KEY_HANDLE
*, KMF_OID
*,
210 KMF_DATA
*, KMF_DATA
*);
213 OpenSSL_DeleteKey(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
216 OpenSSL_ImportCRL(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
219 OpenSSL_DeleteCRL(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
222 OpenSSL_ListCRL(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
225 OpenSSL_FindCertInCRL(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
228 OpenSSL_CertGetPrintable(KMF_HANDLE_T
, const KMF_DATA
*,
229 KMF_PRINTABLE_ITEM
, char *);
232 OpenSSL_GetErrorString(KMF_HANDLE_T
, char **);
235 OpenSSL_FindPrikeyByCert(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
238 OpenSSL_DecryptData(KMF_HANDLE_T
, KMF_KEY_HANDLE
*, KMF_OID
*,
239 KMF_DATA
*, KMF_DATA
*);
242 OpenSSL_CreateOCSPRequest(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
245 OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
248 OpenSSL_FindKey(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
251 OpenSSL_ExportPK12(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
254 OpenSSL_CreateSymKey(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
257 OpenSSL_GetSymKeyValue(KMF_HANDLE_T
, KMF_KEY_HANDLE
*, KMF_RAW_SYM_KEY
*);
260 OpenSSL_VerifyCRLFile(KMF_HANDLE_T
, char *, KMF_DATA
*);
263 OpenSSL_CheckCRLDate(KMF_HANDLE_T
, char *);
266 KMF_PLUGIN_FUNCLIST openssl_plugin_table
=
269 NULL
, /* ConfigureKeystore */
273 NULL
, /* ImportCert */
277 OpenSSL_CreateKeypair
,
279 OpenSSL_EncodePubKeyData
,
284 OpenSSL_FindCertInCRL
,
285 OpenSSL_GetErrorString
,
286 OpenSSL_FindPrikeyByCert
,
289 OpenSSL_CreateSymKey
,
290 OpenSSL_GetSymKeyValue
,
291 NULL
, /* SetTokenPin */
296 static mutex_t
*lock_cs
;
297 static long *lock_count
;
301 locking_cb(int mode
, int type
, char *file
, int line
)
303 if (mode
& CRYPTO_LOCK
) {
304 (void) mutex_lock(&(lock_cs
[type
]));
307 (void) mutex_unlock(&(lock_cs
[type
]));
314 return ((unsigned long)thr_self());
317 KMF_PLUGIN_FUNCLIST
*
318 KMF_Plugin_Initialize()
322 (void) mutex_lock(&init_lock
);
323 if (!ssl_initialized
) {
325 * Add support for extension OIDs that are not yet in the
326 * openssl default set.
328 (void) OBJ_create("2.5.29.30", "nameConstraints",
329 "X509v3 Name Constraints");
330 (void) OBJ_create("2.5.29.33", "policyMappings",
331 "X509v3 Policy Mappings");
332 (void) OBJ_create("2.5.29.36", "policyConstraints",
333 "X509v3 Policy Constraints");
334 (void) OBJ_create("2.5.29.46", "freshestCRL",
335 "X509v3 Freshest CRL");
336 (void) OBJ_create("2.5.29.54", "inhibitAnyPolicy",
337 "X509v3 Inhibit Any-Policy");
339 * Set up for thread-safe operation.
341 lock_cs
= OPENSSL_malloc(CRYPTO_num_locks() * sizeof (mutex_t
));
342 if (lock_cs
== NULL
) {
343 (void) mutex_unlock(&init_lock
);
347 lock_count
= OPENSSL_malloc(CRYPTO_num_locks() * sizeof (long));
348 if (lock_count
== NULL
) {
349 OPENSSL_free(lock_cs
);
350 (void) mutex_unlock(&init_lock
);
354 for (i
= 0; i
< CRYPTO_num_locks(); i
++) {
356 (void) mutex_init(&lock_cs
[i
], USYNC_THREAD
, NULL
);
359 CRYPTO_set_id_callback((unsigned long (*)())thread_id
);
360 if (CRYPTO_get_locking_callback() == NULL
)
361 CRYPTO_set_locking_callback((void (*)())locking_cb
);
363 OpenSSL_add_all_algorithms();
365 /* Enable error strings for reporting */
366 ERR_load_crypto_strings();
370 (void) mutex_unlock(&init_lock
);
372 return (&openssl_plugin_table
);
375 * Convert an SSL DN to a KMF DN.
378 get_x509_dn(X509_NAME
*sslDN
, KMF_X509_NAME
*kmfDN
)
381 KMF_RETURN rv
= KMF_OK
;
384 /* Convert to raw DER format */
385 derdata
.Length
= i2d_X509_NAME(sslDN
, NULL
);
386 if ((tmp
= derdata
.Data
= (uchar_t
*)OPENSSL_malloc(derdata
.Length
))
388 return (KMF_ERR_MEMORY
);
390 (void) i2d_X509_NAME(sslDN
, &tmp
);
392 /* Decode to KMF format */
393 rv
= DerDecodeName(&derdata
, kmfDN
);
395 rv
= KMF_ERR_BAD_CERT_FORMAT
;
397 OPENSSL_free(derdata
.Data
);
407 if (stat(path
, &s
) == -1)
410 return ((s
.st_mode
& S_IFMT
) == S_IFDIR
);
414 ssl_cert2KMFDATA(KMF_HANDLE
*kmfh
, X509
*x509cert
, KMF_DATA
*cert
)
416 KMF_RETURN rv
= KMF_OK
;
417 unsigned char *buf
= NULL
, *p
;
421 * Convert the X509 internal struct to DER encoded data
423 if ((len
= i2d_X509(x509cert
, NULL
)) < 0) {
424 SET_ERROR(kmfh
, ERR_get_error());
425 rv
= KMF_ERR_BAD_CERT_FORMAT
;
428 if ((buf
= malloc(len
)) == NULL
) {
429 SET_SYS_ERROR(kmfh
, errno
);
435 * i2d_X509 will increment the buf pointer so that we need to
439 if ((len
= i2d_X509(x509cert
, &p
)) < 0) {
440 SET_ERROR(kmfh
, ERR_get_error());
442 rv
= KMF_ERR_BAD_CERT_FORMAT
;
446 /* caller's responsibility to free it */
462 check_cert(X509
*xcert
, char *issuer
, char *subject
, KMF_BIGINT
*serial
,
465 KMF_RETURN rv
= KMF_OK
;
466 boolean_t findIssuer
= FALSE
;
467 boolean_t findSubject
= FALSE
;
468 boolean_t findSerial
= FALSE
;
469 KMF_X509_NAME issuerDN
, subjectDN
;
470 KMF_X509_NAME certIssuerDN
, certSubjectDN
;
474 return (KMF_ERR_BAD_PARAMETER
);
477 (void) memset(&issuerDN
, 0, sizeof (KMF_X509_NAME
));
478 (void) memset(&subjectDN
, 0, sizeof (KMF_X509_NAME
));
479 (void) memset(&certIssuerDN
, 0, sizeof (KMF_X509_NAME
));
480 (void) memset(&certSubjectDN
, 0, sizeof (KMF_X509_NAME
));
482 if (issuer
!= NULL
&& strlen(issuer
)) {
483 rv
= kmf_dn_parser(issuer
, &issuerDN
);
485 return (KMF_ERR_BAD_PARAMETER
);
487 rv
= get_x509_dn(xcert
->cert_info
->issuer
, &certIssuerDN
);
489 kmf_free_dn(&issuerDN
);
490 return (KMF_ERR_BAD_PARAMETER
);
495 if (subject
!= NULL
&& strlen(subject
)) {
496 rv
= kmf_dn_parser(subject
, &subjectDN
);
498 rv
= KMF_ERR_BAD_PARAMETER
;
502 rv
= get_x509_dn(xcert
->cert_info
->subject
, &certSubjectDN
);
504 rv
= KMF_ERR_BAD_PARAMETER
;
509 if (serial
!= NULL
&& serial
->val
!= NULL
)
515 /* Comparing BIGNUMs is a pain! */
516 bn
= ASN1_INTEGER_to_BN(xcert
->cert_info
->serialNumber
, NULL
);
518 int bnlen
= BN_num_bytes(bn
);
520 if (bnlen
== serial
->len
) {
521 uchar_t
*a
= malloc(bnlen
);
527 bnlen
= BN_bn2bin(bn
, a
);
528 *match
= (memcmp(a
, serial
->val
, serial
->len
) ==
542 *match
= (kmf_compare_rdns(&issuerDN
, &certIssuerDN
) == 0);
543 if ((*match
) == B_FALSE
) {
544 /* stop checking and bail */
550 *match
= (kmf_compare_rdns(&subjectDN
, &certSubjectDN
) == 0);
551 if ((*match
) == B_FALSE
) {
552 /* stop checking and bail */
561 kmf_free_dn(&issuerDN
);
562 kmf_free_dn(&certIssuerDN
);
565 kmf_free_dn(&subjectDN
);
566 kmf_free_dn(&certSubjectDN
);
574 * This function loads a certificate file into an X509 data structure, and
575 * checks if its issuer, subject or the serial number matches with those
576 * values. If it matches, then return the X509 data structure.
579 load_X509cert(KMF_HANDLE
*kmfh
,
580 char *issuer
, char *subject
, KMF_BIGINT
*serial
,
581 char *pathname
, X509
**outcert
)
583 KMF_RETURN rv
= KMF_OK
;
586 boolean_t match
= FALSE
;
587 KMF_ENCODE_FORMAT format
;
590 * auto-detect the file format, regardless of what
591 * the 'format' parameters in the params say.
593 rv
= kmf_get_file_format(pathname
, &format
);
595 if (rv
== KMF_ERR_OPEN_FILE
)
596 rv
= KMF_ERR_CERT_NOT_FOUND
;
600 /* Not ASN1(DER) format */
601 if ((bcert
= BIO_new_file(pathname
, "rb")) == NULL
) {
602 SET_ERROR(kmfh
, ERR_get_error());
603 rv
= KMF_ERR_OPEN_FILE
;
607 if (format
== KMF_FORMAT_PEM
)
608 xcert
= PEM_read_bio_X509_AUX(bcert
, NULL
, NULL
, NULL
);
609 else if (format
== KMF_FORMAT_ASN1
)
610 xcert
= d2i_X509_bio(bcert
, NULL
);
611 else if (format
== KMF_FORMAT_PKCS12
) {
612 PKCS12
*p12
= d2i_PKCS12_bio(bcert
, NULL
);
614 (void) PKCS12_parse(p12
, NULL
, NULL
, &xcert
, NULL
);
618 SET_ERROR(kmfh
, ERR_get_error());
619 rv
= KMF_ERR_BAD_CERT_FORMAT
;
622 rv
= KMF_ERR_BAD_PARAMETER
;
627 SET_ERROR(kmfh
, ERR_get_error());
628 rv
= KMF_ERR_BAD_CERT_FORMAT
;
632 if (check_cert(xcert
, issuer
, subject
, serial
, &match
) != KMF_OK
||
634 rv
= KMF_ERR_CERT_NOT_FOUND
;
638 if (outcert
!= NULL
) {
643 if (bcert
!= NULL
) (void) BIO_free(bcert
);
644 if (rv
!= KMF_OK
&& xcert
!= NULL
)
651 datacmp(const void *a
, const void *b
)
653 KMF_DATA
*adata
= (KMF_DATA
*)a
;
654 KMF_DATA
*bdata
= (KMF_DATA
*)b
;
655 if (adata
->Length
> bdata
->Length
)
657 if (adata
->Length
< bdata
->Length
)
663 load_certs(KMF_HANDLE
*kmfh
, char *issuer
, char *subject
, KMF_BIGINT
*serial
,
664 KMF_CERT_VALIDITY validity
, char *pathname
,
665 KMF_DATA
**certlist
, uint32_t *numcerts
)
667 KMF_RETURN rv
= KMF_OK
;
669 KMF_DATA
*certs
= NULL
;
672 KMF_ENCODE_FORMAT format
;
674 rv
= kmf_get_file_format(pathname
, &format
);
676 if (rv
== KMF_ERR_OPEN_FILE
)
677 rv
= KMF_ERR_CERT_NOT_FOUND
;
680 if (format
== KMF_FORMAT_ASN1
) {
681 /* load a single certificate */
682 certs
= (KMF_DATA
*)malloc(sizeof (KMF_DATA
));
684 return (KMF_ERR_MEMORY
);
687 rv
= kmf_load_cert(kmfh
, issuer
, subject
, serial
, validity
,
693 kmf_free_data(certs
);
698 } else if (format
== KMF_FORMAT_PKCS12
) {
699 /* We need a credential to access a PKCS#12 file */
700 rv
= KMF_ERR_BAD_CERT_FORMAT
;
701 } else if (format
== KMF_FORMAT_PEM
||
702 format
!= KMF_FORMAT_PEM_KEYPAIR
) {
704 /* This function only works on PEM files */
705 rv
= extract_pem(kmfh
, issuer
, subject
, serial
, pathname
,
706 NULL
, 0, NULL
, &certs
, &nc
);
708 return (KMF_ERR_ENCODING
);
714 for (i
= 0; i
< nc
; i
++) {
715 if (validity
== KMF_NONEXPIRED_CERTS
) {
716 rv
= kmf_check_cert_date(kmfh
, &certs
[i
]);
717 } else if (validity
== KMF_EXPIRED_CERTS
) {
718 rv
= kmf_check_cert_date(kmfh
, &certs
[i
]);
720 rv
= KMF_ERR_CERT_NOT_FOUND
;
721 if (rv
== KMF_ERR_VALIDITY_PERIOD
)
725 /* Remove this cert from the list by clearing it. */
726 kmf_free_data(&certs
[i
]);
728 hits
++; /* count valid certs found */
732 if (rv
== KMF_OK
&& hits
> 0) {
734 * Sort the list of certs by length to put the cleared ones
735 * at the end so they don't get accessed by the caller.
737 qsort((void *)certs
, nc
, sizeof (KMF_DATA
), datacmp
);
740 /* since we sorted the list, just return the number of hits */
743 if (rv
== KMF_OK
&& hits
== 0)
744 rv
= KMF_ERR_CERT_NOT_FOUND
;
754 kmf_load_cert(KMF_HANDLE
*kmfh
,
755 char *issuer
, char *subject
, KMF_BIGINT
*serial
,
756 KMF_CERT_VALIDITY validity
,
760 KMF_RETURN rv
= KMF_OK
;
761 X509
*x509cert
= NULL
;
763 rv
= load_X509cert(kmfh
, issuer
, subject
, serial
, pathname
, &x509cert
);
764 if (rv
== KMF_OK
&& x509cert
!= NULL
&& cert
!= NULL
) {
765 rv
= ssl_cert2KMFDATA(kmfh
, x509cert
, cert
);
769 if (validity
== KMF_NONEXPIRED_CERTS
) {
770 rv
= kmf_check_cert_date(kmfh
, cert
);
771 } else if (validity
== KMF_EXPIRED_CERTS
) {
772 rv
= kmf_check_cert_date(kmfh
, cert
);
775 * This is a valid cert so skip it.
777 rv
= KMF_ERR_CERT_NOT_FOUND
;
779 if (rv
== KMF_ERR_VALIDITY_PERIOD
) {
781 * We want to return success when we
782 * find an invalid cert.
790 if (x509cert
!= NULL
)
797 readAltFormatPrivateKey(KMF_DATA
*filedata
, EVP_PKEY
**pkey
)
799 KMF_RETURN ret
= KMF_OK
;
801 BerElement
*asn1
= NULL
;
803 BerValue OID
= { 0, NULL
};
804 BerValue
*Mod
= NULL
, *PubExp
= NULL
;
805 BerValue
*PriExp
= NULL
, *Prime1
= NULL
, *Prime2
= NULL
;
806 BerValue
*Coef
= NULL
;
807 BIGNUM
*D
= NULL
, *P
= NULL
, *Q
= NULL
, *COEF
= NULL
;
808 BIGNUM
*Exp1
= NULL
, *Exp2
= NULL
, *pminus1
= NULL
;
809 BIGNUM
*qminus1
= NULL
;
814 filebuf
.bv_val
= (char *)filedata
->Data
;
815 filebuf
.bv_len
= filedata
->Length
;
817 asn1
= kmfder_init(&filebuf
);
819 ret
= KMF_ERR_MEMORY
;
823 if (kmfber_scanf(asn1
, "{{Dn{IIIIII}}}",
824 &OID
, &Mod
, &PubExp
, &PriExp
, &Prime1
,
825 &Prime2
, &Coef
) == -1) {
826 ret
= KMF_ERR_ENCODING
;
831 * We have to derive the 2 Exponents using Bignumber math.
832 * Exp1 = PriExp mod (Prime1 - 1)
833 * Exp2 = PriExp mod (Prime2 - 1)
836 /* D = PrivateExponent */
837 D
= BN_bin2bn((const uchar_t
*)PriExp
->bv_val
, PriExp
->bv_len
, D
);
839 ret
= KMF_ERR_MEMORY
;
843 /* P = Prime1 (first prime factor of Modulus) */
844 P
= BN_bin2bn((const uchar_t
*)Prime1
->bv_val
, Prime1
->bv_len
, P
);
846 ret
= KMF_ERR_MEMORY
;
850 /* Q = Prime2 (second prime factor of Modulus) */
851 Q
= BN_bin2bn((const uchar_t
*)Prime2
->bv_val
, Prime2
->bv_len
, Q
);
853 if ((ctx
= BN_CTX_new()) == NULL
) {
854 ret
= KMF_ERR_MEMORY
;
858 /* Compute (P - 1) */
860 (void) BN_sub(pminus1
, P
, BN_value_one());
862 /* Exponent1 = D mod (P - 1) */
864 (void) BN_mod(Exp1
, D
, pminus1
, ctx
);
866 /* Compute (Q - 1) */
868 (void) BN_sub(qminus1
, Q
, BN_value_one());
870 /* Exponent2 = D mod (Q - 1) */
872 (void) BN_mod(Exp2
, D
, qminus1
, ctx
);
874 /* Coef = (Inverse Q) mod P */
876 (void) BN_mod_inverse(COEF
, Q
, P
, ctx
);
878 /* Convert back to KMF format */
879 (void) memset(&rsa
, 0, sizeof (rsa
));
881 if ((ret
= sslBN2KMFBN(Exp1
, &rsa
.exp1
)) != KMF_OK
)
883 if ((ret
= sslBN2KMFBN(Exp2
, &rsa
.exp2
)) != KMF_OK
)
885 if ((ret
= sslBN2KMFBN(COEF
, &rsa
.coef
)) != KMF_OK
)
888 rsa
.mod
.val
= (uchar_t
*)Mod
->bv_val
;
889 rsa
.mod
.len
= Mod
->bv_len
;
891 rsa
.pubexp
.val
= (uchar_t
*)PubExp
->bv_val
;
892 rsa
.pubexp
.len
= PubExp
->bv_len
;
894 rsa
.priexp
.val
= (uchar_t
*)PriExp
->bv_val
;
895 rsa
.priexp
.len
= PriExp
->bv_len
;
897 rsa
.prime1
.val
= (uchar_t
*)Prime1
->bv_val
;
898 rsa
.prime1
.len
= Prime1
->bv_len
;
900 rsa
.prime2
.val
= (uchar_t
*)Prime2
->bv_val
;
901 rsa
.prime2
.len
= Prime2
->bv_len
;
903 *pkey
= ImportRawRSAKey(&rsa
);
906 kmfber_free(asn1
, 1);
918 (void) memset(Coef
->bv_val
, 0, Coef
->bv_len
);
935 BN_clear_free(pminus1
);
937 BN_clear_free(qminus1
);
948 openssl_load_key(KMF_HANDLE_T handle
, const char *file
)
951 EVP_PKEY
*pkey
= NULL
;
952 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
953 KMF_ENCODE_FORMAT format
;
961 if (kmf_get_file_format((char *)file
, &format
) != KMF_OK
)
964 keyfile
= BIO_new_file(file
, "rb");
965 if (keyfile
== NULL
) {
969 if (format
== KMF_FORMAT_ASN1
) {
970 pkey
= d2i_PrivateKey_bio(keyfile
, NULL
);
973 (void) BIO_free(keyfile
);
975 /* Try odd ASN.1 variations */
976 rv
= kmf_read_input_file(kmfh
, (char *)file
,
979 (void) readAltFormatPrivateKey(&filedata
,
981 kmf_free_data(&filedata
);
984 } else if (format
== KMF_FORMAT_PEM
||
985 format
== KMF_FORMAT_PEM_KEYPAIR
) {
986 pkey
= PEM_read_bio_PrivateKey(keyfile
, NULL
, NULL
, NULL
);
990 * Check if this is the alt. format
991 * RSA private key file.
993 rv
= kmf_read_input_file(kmfh
, (char *)file
,
998 rv
= kmf_pem_to_der(filedata
.Data
,
999 filedata
.Length
, &d
, &len
);
1000 if (rv
== KMF_OK
&& d
!= NULL
) {
1002 derdata
.Length
= (size_t)len
;
1003 (void) readAltFormatPrivateKey(
1007 kmf_free_data(&filedata
);
1014 SET_ERROR(kmfh
, ERR_get_error());
1016 if (keyfile
!= NULL
)
1017 (void) BIO_free(keyfile
);
1023 OpenSSL_FindCert(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
1025 KMF_RETURN rv
= KMF_OK
;
1026 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1028 uint32_t maxcerts
= 0;
1029 uint32_t *num_certs
;
1030 KMF_X509_DER_CERT
*kmf_cert
= NULL
;
1031 char *dirpath
= NULL
;
1032 char *filename
= NULL
;
1033 char *fullpath
= NULL
;
1034 char *issuer
= NULL
;
1035 char *subject
= NULL
;
1036 KMF_BIGINT
*serial
= NULL
;
1037 KMF_CERT_VALIDITY validity
;
1039 num_certs
= kmf_get_attr_ptr(KMF_COUNT_ATTR
, attrlist
, numattr
);
1040 if (num_certs
== NULL
)
1041 return (KMF_ERR_BAD_PARAMETER
);
1043 /* num_certs should reference the size of kmf_cert */
1044 maxcerts
= *num_certs
;
1046 maxcerts
= 0xFFFFFFFF;
1049 /* Get the optional returned certificate list */
1050 kmf_cert
= kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR
, attrlist
,
1054 * The dirpath attribute and the filename attribute can not be NULL
1057 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
1058 filename
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
,
1061 fullpath
= get_fullpath(dirpath
, filename
);
1062 if (fullpath
== NULL
)
1063 return (KMF_ERR_BAD_PARAMETER
);
1065 /* Get optional search criteria attributes */
1066 issuer
= kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR
, attrlist
, numattr
);
1067 subject
= kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR
, attrlist
, numattr
);
1068 serial
= kmf_get_attr_ptr(KMF_BIGINT_ATTR
, attrlist
, numattr
);
1069 rv
= kmf_get_attr(KMF_CERT_VALIDITY_ATTR
, attrlist
, numattr
,
1072 validity
= KMF_ALL_CERTS
;
1076 if (isdir(fullpath
)) {
1081 /* open all files in the directory and attempt to read them */
1082 if ((dirp
= opendir(fullpath
)) == NULL
) {
1083 return (KMF_ERR_BAD_PARAMETER
);
1085 while ((dp
= readdir(dirp
)) != NULL
) {
1087 KMF_DATA
*certlist
= NULL
;
1088 uint32_t loaded_certs
= 0;
1090 if (strcmp(dp
->d_name
, ".") == 0 ||
1091 strcmp(dp
->d_name
, "..") == 0)
1094 fname
= get_fullpath(fullpath
, (char *)&dp
->d_name
);
1096 rv
= load_certs(kmfh
, issuer
, subject
, serial
,
1097 validity
, fname
, &certlist
, &loaded_certs
);
1101 if (certlist
!= NULL
) {
1102 for (i
= 0; i
< loaded_certs
; i
++)
1103 kmf_free_data(&certlist
[i
]);
1109 /* If load succeeds, add certdata to the list */
1110 if (kmf_cert
!= NULL
) {
1111 for (i
= 0; i
< loaded_certs
&&
1112 n
< maxcerts
; i
++) {
1113 kmf_cert
[n
].certificate
.Data
=
1115 kmf_cert
[n
].certificate
.Length
=
1118 kmf_cert
[n
].kmf_private
.keystore_type
=
1119 KMF_KEYSTORE_OPENSSL
;
1120 kmf_cert
[n
].kmf_private
.flags
=
1121 KMF_FLAG_CERT_VALID
;
1122 kmf_cert
[n
].kmf_private
.label
=
1127 * If maxcerts < loaded_certs, clean up the
1128 * certs that were not used.
1130 for (; i
< loaded_certs
; i
++)
1131 kmf_free_data(&certlist
[i
]);
1133 for (i
= 0; i
< loaded_certs
; i
++)
1134 kmf_free_data(&certlist
[i
]);
1141 if (*num_certs
== 0)
1142 rv
= KMF_ERR_CERT_NOT_FOUND
;
1146 (void) closedir(dirp
);
1148 KMF_DATA
*certlist
= NULL
;
1149 uint32_t loaded_certs
= 0;
1151 rv
= load_certs(kmfh
, issuer
, subject
, serial
, validity
,
1152 fullpath
, &certlist
, &loaded_certs
);
1159 if (kmf_cert
!= NULL
&& certlist
!= NULL
) {
1160 for (i
= 0; i
< loaded_certs
&& i
< maxcerts
; i
++) {
1161 kmf_cert
[n
].certificate
.Data
=
1163 kmf_cert
[n
].certificate
.Length
=
1165 kmf_cert
[n
].kmf_private
.keystore_type
=
1166 KMF_KEYSTORE_OPENSSL
;
1167 kmf_cert
[n
].kmf_private
.flags
=
1168 KMF_FLAG_CERT_VALID
;
1169 kmf_cert
[n
].kmf_private
.label
=
1173 /* If maxcerts < loaded_certs, clean up */
1174 for (; i
< loaded_certs
; i
++)
1175 kmf_free_data(&certlist
[i
]);
1176 } else if (certlist
!= NULL
) {
1177 for (i
= 0; i
< loaded_certs
; i
++)
1178 kmf_free_data(&certlist
[i
]);
1192 OpenSSL_FreeKMFCert(KMF_HANDLE_T handle
,
1193 KMF_X509_DER_CERT
*kmf_cert
)
1195 if (kmf_cert
!= NULL
) {
1196 if (kmf_cert
->certificate
.Data
!= NULL
) {
1197 kmf_free_data(&kmf_cert
->certificate
);
1199 free(kmf_cert
->kmf_private
.label
);
1205 OpenSSL_StoreCert(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
1207 KMF_RETURN ret
= KMF_OK
;
1208 KMF_DATA
*cert
= NULL
;
1209 char *outfilename
= NULL
;
1210 char *dirpath
= NULL
;
1211 char *fullpath
= NULL
;
1212 KMF_ENCODE_FORMAT format
;
1214 /* Get the cert data */
1215 cert
= kmf_get_attr_ptr(KMF_CERT_DATA_ATTR
, attrlist
, numattr
);
1216 if (cert
== NULL
|| cert
->Data
== NULL
)
1217 return (KMF_ERR_BAD_PARAMETER
);
1219 /* Check the output filename and directory attributes. */
1220 outfilename
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
,
1222 if (outfilename
== NULL
)
1223 return (KMF_ERR_BAD_PARAMETER
);
1225 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
1226 fullpath
= get_fullpath(dirpath
, outfilename
);
1227 if (fullpath
== NULL
)
1228 return (KMF_ERR_BAD_CERTFILE
);
1230 /* Check the optional format attribute */
1231 ret
= kmf_get_attr(KMF_ENCODE_FORMAT_ATTR
, attrlist
, numattr
,
1233 if (ret
!= KMF_OK
) {
1234 /* If there is no format attribute, then default to PEM */
1235 format
= KMF_FORMAT_PEM
;
1237 } else if (format
!= KMF_FORMAT_ASN1
&& format
!= KMF_FORMAT_PEM
) {
1238 ret
= KMF_ERR_BAD_CERT_FORMAT
;
1242 /* Store the certificate in the file with the specified format */
1243 ret
= kmf_create_cert_file(cert
, format
, fullpath
);
1253 OpenSSL_DeleteCert(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
1256 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1257 KMF_DATA certdata
= { 0, NULL
};
1258 char *dirpath
= NULL
;
1259 char *filename
= NULL
;
1260 char *fullpath
= NULL
;
1261 char *issuer
= NULL
;
1262 char *subject
= NULL
;
1263 KMF_BIGINT
*serial
= NULL
;
1264 KMF_CERT_VALIDITY validity
;
1267 * Get the DIRPATH and CERT_FILENAME attributes. They can not be
1268 * NULL at the same time.
1270 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
1271 filename
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
,
1273 fullpath
= get_fullpath(dirpath
, filename
);
1274 if (fullpath
== NULL
)
1275 return (KMF_ERR_BAD_PARAMETER
);
1277 /* Get optional search criteria attributes */
1278 issuer
= kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR
, attrlist
, numattr
);
1279 subject
= kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR
, attrlist
, numattr
);
1280 serial
= kmf_get_attr_ptr(KMF_BIGINT_ATTR
, attrlist
, numattr
);
1281 rv
= kmf_get_attr(KMF_CERT_VALIDITY_ATTR
, attrlist
, numattr
,
1284 validity
= KMF_ALL_CERTS
;
1288 if (isdir(fullpath
)) {
1292 /* open all files in the directory and attempt to read them */
1293 if ((dirp
= opendir(fullpath
)) == NULL
) {
1294 return (KMF_ERR_BAD_PARAMETER
);
1297 while ((dp
= readdir(dirp
)) != NULL
) {
1298 if (strcmp(dp
->d_name
, ".") != 0 &&
1299 strcmp(dp
->d_name
, "..") != 0) {
1302 fname
= get_fullpath(fullpath
,
1303 (char *)&dp
->d_name
);
1305 if (fname
== NULL
) {
1306 rv
= KMF_ERR_MEMORY
;
1310 rv
= kmf_load_cert(kmfh
, issuer
, subject
,
1311 serial
, validity
, fname
, &certdata
);
1313 if (rv
== KMF_ERR_CERT_NOT_FOUND
) {
1315 kmf_free_data(&certdata
);
1318 } else if (rv
!= KMF_OK
) {
1323 if (unlink(fname
) != 0) {
1324 SET_SYS_ERROR(kmfh
, errno
);
1325 rv
= KMF_ERR_INTERNAL
;
1330 kmf_free_data(&certdata
);
1333 (void) closedir(dirp
);
1335 /* Just try to load a single certificate */
1336 rv
= kmf_load_cert(kmfh
, issuer
, subject
, serial
, validity
,
1337 fullpath
, &certdata
);
1339 if (unlink(fullpath
) != 0) {
1340 SET_SYS_ERROR(kmfh
, errno
);
1341 rv
= KMF_ERR_INTERNAL
;
1349 kmf_free_data(&certdata
);
1355 OpenSSL_EncodePubKeyData(KMF_HANDLE_T handle
, KMF_KEY_HANDLE
*key
,
1358 KMF_RETURN rv
= KMF_OK
;
1359 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1362 if (key
== NULL
|| keydata
== NULL
||
1364 return (KMF_ERR_BAD_PARAMETER
);
1366 if (key
->keyalg
== KMF_RSA
) {
1367 RSA
*pubkey
= EVP_PKEY_get1_RSA(key
->keyp
);
1369 if (!(n
= i2d_RSA_PUBKEY(pubkey
, &keydata
->Data
))) {
1370 SET_ERROR(kmfh
, ERR_get_error());
1371 return (KMF_ERR_ENCODING
);
1374 } else if (key
->keyalg
== KMF_DSA
) {
1375 DSA
*pubkey
= EVP_PKEY_get1_DSA(key
->keyp
);
1377 if (!(n
= i2d_DSA_PUBKEY(pubkey
, &keydata
->Data
))) {
1378 SET_ERROR(kmfh
, ERR_get_error());
1379 return (KMF_ERR_ENCODING
);
1383 return (KMF_ERR_BAD_PARAMETER
);
1385 keydata
->Length
= n
;
1389 free(keydata
->Data
);
1390 keydata
->Data
= NULL
;
1391 keydata
->Length
= 0;
1398 ssl_write_key(KMF_HANDLE
*kmfh
, KMF_ENCODE_FORMAT format
, BIO
*out
,
1399 KMF_CREDENTIAL
*cred
, EVP_PKEY
*pkey
, boolean_t
private)
1405 if (pkey
== NULL
|| out
== NULL
)
1406 return (KMF_ERR_BAD_PARAMETER
);
1409 case KMF_FORMAT_RAWKEY
:
1411 case KMF_FORMAT_ASN1
:
1412 if (pkey
->type
== EVP_PKEY_RSA
) {
1413 rsa
= EVP_PKEY_get1_RSA(pkey
);
1415 rv
= i2d_RSAPrivateKey_bio(out
, rsa
);
1417 rv
= i2d_RSAPublicKey_bio(out
, rsa
);
1419 } else if (pkey
->type
== EVP_PKEY_DSA
) {
1420 dsa
= EVP_PKEY_get1_DSA(pkey
);
1421 rv
= i2d_DSAPrivateKey_bio(out
, dsa
);
1427 SET_ERROR(kmfh
, rv
);
1430 case KMF_FORMAT_PEM
:
1431 if (pkey
->type
== EVP_PKEY_RSA
) {
1432 rsa
= EVP_PKEY_get1_RSA(pkey
);
1434 rv
= PEM_write_bio_RSAPrivateKey(out
,
1435 rsa
, NULL
, NULL
, 0, NULL
,
1436 (cred
!= NULL
? cred
->cred
: NULL
));
1438 rv
= PEM_write_bio_RSAPublicKey(out
,
1441 } else if (pkey
->type
== EVP_PKEY_DSA
) {
1442 dsa
= EVP_PKEY_get1_DSA(pkey
);
1443 rv
= PEM_write_bio_DSAPrivateKey(out
,
1444 dsa
, NULL
, NULL
, 0, NULL
,
1445 (cred
!= NULL
? cred
->cred
: NULL
));
1452 SET_ERROR(kmfh
, rv
);
1457 rv
= KMF_ERR_BAD_PARAMETER
;
1464 OpenSSL_CreateKeypair(KMF_HANDLE_T handle
, int numattr
,
1465 KMF_ATTRIBUTE
*attrlist
)
1467 KMF_RETURN rv
= KMF_OK
;
1468 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1469 uint32_t eValue
= 0x010001;
1470 RSA
*sslPrivKey
= NULL
;
1471 DSA
*sslDSAKey
= NULL
;
1472 EVP_PKEY
*eprikey
= NULL
;
1473 EVP_PKEY
*epubkey
= NULL
;
1475 KMF_KEY_HANDLE
*pubkey
= NULL
, *privkey
= NULL
;
1476 uint32_t keylen
= 1024;
1477 uint32_t keylen_size
= sizeof (uint32_t);
1478 boolean_t storekey
= TRUE
;
1479 KMF_KEY_ALG keytype
= KMF_RSA
;
1481 rv
= kmf_get_attr(KMF_STOREKEY_BOOL_ATTR
, attrlist
, numattr
,
1484 /* "storekey" is optional. Default is TRUE */
1488 rv
= kmf_get_attr(KMF_KEYALG_ATTR
, attrlist
, numattr
,
1489 (void *)&keytype
, NULL
);
1491 /* keytype is optional. KMF_RSA is default */
1494 pubkey
= kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR
, attrlist
, numattr
);
1496 return (KMF_ERR_BAD_PARAMETER
);
1498 privkey
= kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR
, attrlist
, numattr
);
1499 if (privkey
== NULL
)
1500 return (KMF_ERR_BAD_PARAMETER
);
1502 (void) memset(pubkey
, 0, sizeof (KMF_KEY_HANDLE
));
1503 (void) memset(privkey
, 0, sizeof (KMF_KEY_HANDLE
));
1505 eprikey
= EVP_PKEY_new();
1506 if (eprikey
== NULL
) {
1507 SET_ERROR(kmfh
, ERR_get_error());
1508 rv
= KMF_ERR_KEYGEN_FAILED
;
1511 epubkey
= EVP_PKEY_new();
1512 if (epubkey
== NULL
) {
1513 SET_ERROR(kmfh
, ERR_get_error());
1514 rv
= KMF_ERR_KEYGEN_FAILED
;
1517 if (keytype
== KMF_RSA
) {
1518 KMF_BIGINT
*rsaexp
= NULL
;
1520 rsaexp
= kmf_get_attr_ptr(KMF_RSAEXP_ATTR
, attrlist
, numattr
);
1521 if (rsaexp
!= NULL
) {
1522 if (rsaexp
->len
> 0 &&
1523 rsaexp
->len
<= sizeof (eValue
) &&
1524 rsaexp
->val
!= NULL
) {
1525 /* LINTED E_BAD_PTR_CAST_ALIGN */
1526 eValue
= *(uint32_t *)rsaexp
->val
;
1528 rv
= KMF_ERR_BAD_PARAMETER
;
1532 /* RSA Exponent is optional. Default is 0x10001 */
1536 rv
= kmf_get_attr(KMF_KEYLENGTH_ATTR
, attrlist
, numattr
,
1537 &keylen
, &keylen_size
);
1538 if (rv
== KMF_ERR_ATTR_NOT_FOUND
)
1539 /* keylen is optional, default is 1024 */
1542 rv
= KMF_ERR_BAD_PARAMETER
;
1546 sslPrivKey
= RSA_generate_key(keylen
, eValue
, NULL
, NULL
);
1547 if (sslPrivKey
== NULL
) {
1548 SET_ERROR(kmfh
, ERR_get_error());
1549 rv
= KMF_ERR_KEYGEN_FAILED
;
1551 (void) EVP_PKEY_set1_RSA(eprikey
, sslPrivKey
);
1552 privkey
->kstype
= KMF_KEYSTORE_OPENSSL
;
1553 privkey
->keyalg
= KMF_RSA
;
1554 privkey
->keyclass
= KMF_ASYM_PRI
;
1555 privkey
->israw
= FALSE
;
1556 privkey
->keyp
= (void *)eprikey
;
1558 /* OpenSSL derives the public key from the private */
1559 (void) EVP_PKEY_set1_RSA(epubkey
, sslPrivKey
);
1560 pubkey
->kstype
= KMF_KEYSTORE_OPENSSL
;
1561 pubkey
->keyalg
= KMF_RSA
;
1562 pubkey
->israw
= FALSE
;
1563 pubkey
->keyclass
= KMF_ASYM_PUB
;
1564 pubkey
->keyp
= (void *)epubkey
;
1566 } else if (keytype
== KMF_DSA
) {
1568 sslDSAKey
= DSA_new();
1569 if (sslDSAKey
== NULL
) {
1570 SET_ERROR(kmfh
, ERR_get_error());
1571 return (KMF_ERR_MEMORY
);
1574 if ((sslDSAKey
->p
= BN_bin2bn(P
, sizeof (P
), sslDSAKey
->p
)) ==
1576 SET_ERROR(kmfh
, ERR_get_error());
1577 rv
= KMF_ERR_KEYGEN_FAILED
;
1580 if ((sslDSAKey
->q
= BN_bin2bn(Q
, sizeof (Q
), sslDSAKey
->q
)) ==
1582 SET_ERROR(kmfh
, ERR_get_error());
1583 rv
= KMF_ERR_KEYGEN_FAILED
;
1586 if ((sslDSAKey
->g
= BN_bin2bn(G
, sizeof (G
), sslDSAKey
->g
)) ==
1588 SET_ERROR(kmfh
, ERR_get_error());
1589 rv
= KMF_ERR_KEYGEN_FAILED
;
1593 if (!DSA_generate_key(sslDSAKey
)) {
1594 SET_ERROR(kmfh
, ERR_get_error());
1595 rv
= KMF_ERR_KEYGEN_FAILED
;
1599 privkey
->kstype
= KMF_KEYSTORE_OPENSSL
;
1600 privkey
->keyalg
= KMF_DSA
;
1601 privkey
->keyclass
= KMF_ASYM_PRI
;
1602 privkey
->israw
= FALSE
;
1603 if (EVP_PKEY_set1_DSA(eprikey
, sslDSAKey
)) {
1604 privkey
->keyp
= (void *)eprikey
;
1606 SET_ERROR(kmfh
, ERR_get_error());
1607 rv
= KMF_ERR_KEYGEN_FAILED
;
1611 /* Make a copy for the public key */
1613 if ((dp
->p
= BN_new()) == NULL
) {
1614 SET_ERROR(kmfh
, ERR_get_error());
1615 rv
= KMF_ERR_MEMORY
;
1619 if ((dp
->q
= BN_new()) == NULL
) {
1620 SET_ERROR(kmfh
, ERR_get_error());
1621 rv
= KMF_ERR_MEMORY
;
1626 if ((dp
->g
= BN_new()) == NULL
) {
1627 SET_ERROR(kmfh
, ERR_get_error());
1628 rv
= KMF_ERR_MEMORY
;
1634 if ((dp
->pub_key
= BN_new()) == NULL
) {
1635 SET_ERROR(kmfh
, ERR_get_error());
1636 rv
= KMF_ERR_MEMORY
;
1643 (void) BN_copy(dp
->p
, sslDSAKey
->p
);
1644 (void) BN_copy(dp
->q
, sslDSAKey
->q
);
1645 (void) BN_copy(dp
->g
, sslDSAKey
->g
);
1646 (void) BN_copy(dp
->pub_key
, sslDSAKey
->pub_key
);
1648 pubkey
->kstype
= KMF_KEYSTORE_OPENSSL
;
1649 pubkey
->keyalg
= KMF_DSA
;
1650 pubkey
->keyclass
= KMF_ASYM_PUB
;
1651 pubkey
->israw
= FALSE
;
1653 if (EVP_PKEY_set1_DSA(epubkey
, sslDSAKey
)) {
1654 pubkey
->keyp
= (void *)epubkey
;
1656 SET_ERROR(kmfh
, ERR_get_error());
1657 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
);
1712 if (eprikey
!= NULL
)
1713 EVP_PKEY_free(eprikey
);
1715 if (epubkey
!= NULL
)
1716 EVP_PKEY_free(epubkey
);
1718 if (pubkey
->keylabel
) {
1719 free(pubkey
->keylabel
);
1720 pubkey
->keylabel
= NULL
;
1723 if (privkey
->keylabel
) {
1724 free(privkey
->keylabel
);
1725 privkey
->keylabel
= NULL
;
1728 pubkey
->keyp
= NULL
;
1729 privkey
->keyp
= NULL
;
1733 RSA_free(sslPrivKey
);
1736 DSA_free(sslDSAKey
);
1739 (void) BIO_free(out
);
1745 * Make sure the BN conversion is properly padded with 0x00
1746 * bytes. If not, signature verification for DSA signatures
1747 * may fail in the case where the bignum value does not use
1751 fixbnlen(BIGNUM
*bn
, unsigned char *buf
, int len
) {
1752 int bytes
= len
- BN_num_bytes(bn
);
1754 /* prepend with leading 0x00 if necessary */
1758 (void) BN_bn2bin(bn
, buf
);
1760 * Return the desired length since we prepended it
1761 * with the necessary 0x00 padding.
1767 OpenSSL_SignData(KMF_HANDLE_T handle
, KMF_KEY_HANDLE
*key
,
1768 KMF_OID
*AlgOID
, KMF_DATA
*tobesigned
, KMF_DATA
*output
)
1770 KMF_RETURN ret
= KMF_OK
;
1771 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1772 KMF_ALGORITHM_INDEX AlgId
;
1776 if (key
== NULL
|| AlgOID
== NULL
||
1777 tobesigned
== NULL
|| output
== NULL
||
1778 tobesigned
->Data
== NULL
||
1779 output
->Data
== NULL
)
1780 return (KMF_ERR_BAD_PARAMETER
);
1782 /* Map the OID to an OpenSSL algorithm */
1783 AlgId
= x509_algoid_to_algid(AlgOID
);
1784 if (AlgId
== KMF_ALGID_NONE
)
1785 return (KMF_ERR_BAD_ALGORITHM
);
1787 if (key
->keyalg
== KMF_RSA
) {
1788 EVP_PKEY
*pkey
= (EVP_PKEY
*)key
->keyp
;
1791 if (AlgId
== KMF_ALGID_MD5WithRSA
)
1793 else if (AlgId
== KMF_ALGID_SHA1WithRSA
)
1795 else if (AlgId
== KMF_ALGID_SHA256WithRSA
)
1797 else if (AlgId
== KMF_ALGID_SHA384WithRSA
)
1799 else if (AlgId
== KMF_ALGID_SHA512WithRSA
)
1801 else if (AlgId
== KMF_ALGID_RSA
)
1804 return (KMF_ERR_BAD_ALGORITHM
);
1806 if ((md
== NULL
) && (AlgId
== KMF_ALGID_RSA
)) {
1807 RSA
*rsa
= EVP_PKEY_get1_RSA((EVP_PKEY
*)pkey
);
1810 if ((len
= RSA_private_encrypt(tobesigned
->Length
,
1811 tobesigned
->Data
, p
, rsa
,
1812 RSA_PKCS1_PADDING
)) <= 0) {
1813 SET_ERROR(kmfh
, ERR_get_error());
1814 ret
= KMF_ERR_INTERNAL
;
1816 output
->Length
= len
;
1818 (void) EVP_MD_CTX_init(&ctx
);
1819 (void) EVP_SignInit_ex(&ctx
, md
, NULL
);
1820 (void) EVP_SignUpdate(&ctx
, tobesigned
->Data
,
1821 (uint32_t)tobesigned
->Length
);
1822 len
= (uint32_t)output
->Length
;
1824 if (!EVP_SignFinal(&ctx
, p
, (uint32_t *)&len
, pkey
)) {
1825 SET_ERROR(kmfh
, ERR_get_error());
1827 ret
= KMF_ERR_INTERNAL
;
1829 output
->Length
= len
;
1830 (void) EVP_MD_CTX_cleanup(&ctx
);
1832 } else if (key
->keyalg
== KMF_DSA
) {
1833 DSA
*dsa
= EVP_PKEY_get1_DSA(key
->keyp
);
1835 uchar_t hash
[EVP_MAX_MD_SIZE
];
1839 if (AlgId
== KMF_ALGID_DSA
||
1840 AlgId
== KMF_ALGID_SHA1WithDSA
)
1842 else if (AlgId
== KMF_ALGID_SHA256WithDSA
)
1844 else /* Bad algorithm */
1845 return (KMF_ERR_BAD_ALGORITHM
);
1848 * OpenSSL EVP_Sign operation automatically converts to
1849 * ASN.1 output so we do the operations separately so we
1850 * are assured of NOT getting ASN.1 output returned.
1851 * KMF does not want ASN.1 encoded results because
1852 * not all mechanisms return ASN.1 encodings (PKCS#11
1853 * and NSS return raw signature data).
1855 EVP_MD_CTX_init(&ctx
);
1856 (void) EVP_DigestInit_ex(&ctx
, md
, NULL
);
1857 (void) EVP_DigestUpdate(&ctx
, tobesigned
->Data
,
1858 tobesigned
->Length
);
1859 (void) EVP_DigestFinal_ex(&ctx
, hash
, &hashlen
);
1861 /* Only sign first 20 bytes for SHA2 */
1862 if (AlgId
== KMF_ALGID_SHA256WithDSA
)
1864 dsasig
= DSA_do_sign(hash
, hashlen
, dsa
);
1865 if (dsasig
!= NULL
) {
1867 output
->Length
= i
= fixbnlen(dsasig
->r
, output
->Data
,
1870 output
->Length
+= fixbnlen(dsasig
->s
, &output
->Data
[i
],
1873 DSA_SIG_free(dsasig
);
1875 SET_ERROR(kmfh
, ERR_get_error());
1877 (void) EVP_MD_CTX_cleanup(&ctx
);
1879 return (KMF_ERR_BAD_PARAMETER
);
1887 OpenSSL_DeleteKey(KMF_HANDLE_T handle
,
1888 int numattr
, KMF_ATTRIBUTE
*attrlist
)
1890 KMF_RETURN rv
= KMF_OK
;
1891 KMF_KEY_HANDLE
*key
;
1892 boolean_t destroy
= B_TRUE
;
1894 key
= kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR
, attrlist
, numattr
);
1895 if (key
== NULL
|| key
->keyp
== NULL
)
1896 return (KMF_ERR_BAD_PARAMETER
);
1898 rv
= kmf_get_attr(KMF_DESTROY_BOOL_ATTR
, attrlist
, numattr
,
1899 (void *)&destroy
, NULL
);
1901 /* "destroy" is optional. Default is TRUE */
1905 if (key
->keyclass
!= KMF_ASYM_PUB
&&
1906 key
->keyclass
!= KMF_ASYM_PRI
&&
1907 key
->keyclass
!= KMF_SYMMETRIC
)
1908 return (KMF_ERR_BAD_KEY_CLASS
);
1910 if (key
->keyclass
== KMF_SYMMETRIC
) {
1911 kmf_free_raw_sym_key((KMF_RAW_SYM_KEY
*)key
->keyp
);
1914 if (key
->keyp
!= NULL
) {
1915 EVP_PKEY_free(key
->keyp
);
1920 if (key
->keylabel
!= NULL
) {
1921 EVP_PKEY
*pkey
= NULL
;
1922 /* If the file exists, make sure it is a proper key. */
1923 pkey
= openssl_load_key(handle
, key
->keylabel
);
1925 if (key
->keylabel
!= NULL
) {
1926 free(key
->keylabel
);
1927 key
->keylabel
= NULL
;
1929 return (KMF_ERR_KEY_NOT_FOUND
);
1931 EVP_PKEY_free(pkey
);
1934 if (unlink(key
->keylabel
) != 0) {
1935 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1936 SET_SYS_ERROR(kmfh
, errno
);
1937 rv
= KMF_ERR_INTERNAL
;
1940 if (key
->keylabel
!= NULL
) {
1941 free(key
->keylabel
);
1942 key
->keylabel
= NULL
;
1949 OpenSSL_GetErrorString(KMF_HANDLE_T handle
, char **msgstr
)
1951 KMF_RETURN ret
= KMF_OK
;
1952 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1953 char str
[256]; /* OpenSSL needs at least 120 byte buffer */
1955 ERR_error_string_n(kmfh
->lasterr
.errcode
, str
, sizeof (str
));
1957 *msgstr
= (char *)strdup(str
);
1958 if ((*msgstr
) == NULL
)
1959 ret
= KMF_ERR_MEMORY
;
1971 case KMF_X509_EXT_KEY_USAGE
:
1972 return (NID_key_usage
);
1973 case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD
:
1974 return (NID_private_key_usage_period
);
1975 case KMF_X509_EXT_CERT_POLICIES
:
1976 return (NID_certificate_policies
);
1977 case KMF_X509_EXT_SUBJ_ALTNAME
:
1978 return (NID_subject_alt_name
);
1979 case KMF_X509_EXT_ISSUER_ALTNAME
:
1980 return (NID_issuer_alt_name
);
1981 case KMF_X509_EXT_BASIC_CONSTRAINTS
:
1982 return (NID_basic_constraints
);
1983 case KMF_X509_EXT_EXT_KEY_USAGE
:
1984 return (NID_ext_key_usage
);
1985 case KMF_X509_EXT_AUTH_KEY_ID
:
1986 return (NID_authority_key_identifier
);
1987 case KMF_X509_EXT_CRL_DIST_POINTS
:
1988 return (NID_crl_distribution_points
);
1989 case KMF_X509_EXT_SUBJ_KEY_ID
:
1990 return (NID_subject_key_identifier
);
1991 case KMF_X509_EXT_POLICY_MAPPINGS
:
1992 return (OBJ_sn2nid("policyMappings"));
1993 case KMF_X509_EXT_NAME_CONSTRAINTS
:
1994 return (OBJ_sn2nid("nameConstraints"));
1995 case KMF_X509_EXT_POLICY_CONSTRAINTS
:
1996 return (OBJ_sn2nid("policyConstraints"));
1997 case KMF_X509_EXT_INHIBIT_ANY_POLICY
:
1998 return (OBJ_sn2nid("inhibitAnyPolicy"));
1999 case KMF_X509_EXT_FRESHEST_CRL
:
2000 return (OBJ_sn2nid("freshestCRL"));
2007 OpenSSL_CertGetPrintable(KMF_HANDLE_T handle
, const KMF_DATA
*pcert
,
2008 KMF_PRINTABLE_ITEM flag
, char *resultStr
)
2010 KMF_RETURN ret
= KMF_OK
;
2011 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2013 unsigned char *outbuf
= NULL
;
2014 unsigned char *outbuf_p
;
2015 char *tmpstr
= NULL
;
2017 int ext_index
, nid
, len
;
2019 #if OPENSSL_VERSION_NUMBER < 0x10000000L
2020 STACK
*emlst
= NULL
;
2022 STACK_OF(OPENSSL_STRING
) *emlst
= NULL
;
2027 if (pcert
== NULL
|| pcert
->Data
== NULL
|| pcert
->Length
== 0) {
2028 return (KMF_ERR_BAD_PARAMETER
);
2031 /* copy cert data to outbuf */
2032 outbuf
= malloc(pcert
->Length
);
2033 if (outbuf
== NULL
) {
2034 return (KMF_ERR_MEMORY
);
2036 (void) memcpy(outbuf
, pcert
->Data
, pcert
->Length
);
2038 outbuf_p
= outbuf
; /* use a temp pointer; required by openssl */
2039 xcert
= d2i_X509(NULL
, (const uchar_t
**)&outbuf_p
, pcert
->Length
);
2040 if (xcert
== NULL
) {
2041 SET_ERROR(kmfh
, ERR_get_error());
2042 ret
= KMF_ERR_ENCODING
;
2046 mem
= BIO_new(BIO_s_mem());
2048 SET_ERROR(kmfh
, ERR_get_error());
2049 ret
= KMF_ERR_MEMORY
;
2054 case KMF_CERT_ISSUER
:
2055 (void) X509_NAME_print_ex(mem
, X509_get_issuer_name(xcert
), 0,
2056 XN_FLAG_SEP_CPLUS_SPC
);
2057 len
= BIO_gets(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2060 case KMF_CERT_SUBJECT
:
2061 (void) X509_NAME_print_ex(mem
, X509_get_subject_name(xcert
), 0,
2062 XN_FLAG_SEP_CPLUS_SPC
);
2063 len
= BIO_gets(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2066 case KMF_CERT_VERSION
:
2067 tmpstr
= i2s_ASN1_INTEGER(NULL
, xcert
->cert_info
->version
);
2068 (void) strncpy(resultStr
, tmpstr
, KMF_CERT_PRINTABLE_LEN
);
2069 OPENSSL_free(tmpstr
);
2070 len
= strlen(resultStr
);
2073 case KMF_CERT_SERIALNUM
:
2074 if (i2a_ASN1_INTEGER(mem
, X509_get_serialNumber(xcert
)) > 0) {
2075 (void) strcpy(resultStr
, "0x");
2076 len
= BIO_gets(mem
, &resultStr
[2],
2077 KMF_CERT_PRINTABLE_LEN
- 2);
2081 case KMF_CERT_NOTBEFORE
:
2082 (void) ASN1_TIME_print(mem
, X509_get_notBefore(xcert
));
2083 len
= BIO_gets(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2086 case KMF_CERT_NOTAFTER
:
2087 (void) ASN1_TIME_print(mem
, X509_get_notAfter(xcert
));
2088 len
= BIO_gets(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2091 case KMF_CERT_PUBKEY_DATA
:
2093 EVP_PKEY
*pkey
= X509_get_pubkey(xcert
);
2095 SET_ERROR(kmfh
, ERR_get_error());
2096 ret
= KMF_ERR_ENCODING
;
2100 if (pkey
->type
== EVP_PKEY_RSA
) {
2101 (void) BIO_printf(mem
,
2102 "RSA Public Key: (%d bit)\n",
2103 BN_num_bits(pkey
->pkey
.rsa
->n
));
2104 (void) RSA_print(mem
, pkey
->pkey
.rsa
, 0);
2105 } else if (pkey
->type
== EVP_PKEY_DSA
) {
2106 (void) BIO_printf(mem
,
2107 "%12sDSA Public Key:\n", "");
2108 (void) DSA_print(mem
, pkey
->pkey
.dsa
, 0);
2110 (void) BIO_printf(mem
,
2111 "%12sUnknown Public Key:\n", "");
2113 (void) BIO_printf(mem
, "\n");
2114 EVP_PKEY_free(pkey
);
2116 len
= BIO_read(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2118 case KMF_CERT_SIGNATURE_ALG
:
2119 case KMF_CERT_PUBKEY_ALG
:
2120 if (flag
== KMF_CERT_SIGNATURE_ALG
) {
2121 len
= i2a_ASN1_OBJECT(mem
,
2122 xcert
->sig_alg
->algorithm
);
2124 len
= i2a_ASN1_OBJECT(mem
,
2125 xcert
->cert_info
->key
->algor
->algorithm
);
2129 len
= BIO_read(mem
, resultStr
,
2130 KMF_CERT_PRINTABLE_LEN
);
2134 case KMF_CERT_EMAIL
:
2135 emlst
= X509_get1_email(xcert
);
2136 #if OPENSSL_VERSION_NUMBER < 0x10000000L
2137 for (j
= 0; j
< sk_num(emlst
); j
++)
2138 (void) BIO_printf(mem
, "%s\n", sk_value(emlst
, j
));
2140 for (j
= 0; j
< sk_OPENSSL_STRING_num(emlst
); j
++)
2141 (void) BIO_printf(mem
, "%s\n",
2142 sk_OPENSSL_STRING_value(emlst
, j
));
2145 len
= BIO_gets(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2146 X509_email_free(emlst
);
2148 case KMF_X509_EXT_ISSUER_ALTNAME
:
2149 case KMF_X509_EXT_SUBJ_ALTNAME
:
2150 case KMF_X509_EXT_KEY_USAGE
:
2151 case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD
:
2152 case KMF_X509_EXT_CERT_POLICIES
:
2153 case KMF_X509_EXT_BASIC_CONSTRAINTS
:
2154 case KMF_X509_EXT_NAME_CONSTRAINTS
:
2155 case KMF_X509_EXT_POLICY_CONSTRAINTS
:
2156 case KMF_X509_EXT_EXT_KEY_USAGE
:
2157 case KMF_X509_EXT_INHIBIT_ANY_POLICY
:
2158 case KMF_X509_EXT_AUTH_KEY_ID
:
2159 case KMF_X509_EXT_SUBJ_KEY_ID
:
2160 case KMF_X509_EXT_POLICY_MAPPINGS
:
2161 case KMF_X509_EXT_CRL_DIST_POINTS
:
2162 case KMF_X509_EXT_FRESHEST_CRL
:
2163 nid
= ext2NID(flag
);
2164 if (nid
== NID_undef
) {
2165 ret
= KMF_ERR_EXTENSION_NOT_FOUND
;
2168 ci
= xcert
->cert_info
;
2170 ext_index
= X509v3_get_ext_by_NID(ci
->extensions
, nid
, -1);
2171 if (ext_index
== -1) {
2172 SET_ERROR(kmfh
, ERR_get_error());
2174 ret
= KMF_ERR_EXTENSION_NOT_FOUND
;
2177 ex
= X509v3_get_ext(ci
->extensions
, ext_index
);
2179 (void) i2a_ASN1_OBJECT(mem
, X509_EXTENSION_get_object(ex
));
2181 if (BIO_printf(mem
, ": %s\n",
2182 X509_EXTENSION_get_critical(ex
) ? "critical" : "") <= 0) {
2183 SET_ERROR(kmfh
, ERR_get_error());
2184 ret
= KMF_ERR_ENCODING
;
2187 if (!X509V3_EXT_print(mem
, ex
, X509V3_EXT_DUMP_UNKNOWN
, 4)) {
2188 (void) BIO_printf(mem
, "%*s", 4, "");
2189 (void) M_ASN1_OCTET_STRING_print(mem
, ex
->value
);
2191 if (BIO_write(mem
, "\n", 1) <= 0) {
2192 SET_ERROR(kmfh
, ERR_get_error());
2193 ret
= KMF_ERR_ENCODING
;
2196 len
= BIO_read(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2199 SET_ERROR(kmfh
, ERR_get_error());
2200 ret
= KMF_ERR_ENCODING
;
2204 if (outbuf
!= NULL
) {
2208 if (xcert
!= NULL
) {
2213 (void) BIO_free(mem
);
2221 OpenSSL_FindPrikeyByCert(KMF_HANDLE_T handle
, int numattr
,
2222 KMF_ATTRIBUTE
*attrlist
)
2224 KMF_RETURN rv
= KMF_OK
;
2225 KMF_KEYSTORE_TYPE kstype
= KMF_KEYSTORE_OPENSSL
;
2226 KMF_KEY_CLASS keyclass
= KMF_ASYM_PRI
;
2227 KMF_KEY_HANDLE
*key
= NULL
;
2228 uint32_t numkeys
= 1; /* 1 key only */
2229 char *dirpath
= NULL
;
2230 char *keyfile
= NULL
;
2231 KMF_ATTRIBUTE new_attrlist
[16];
2235 * This is really just a FindKey operation, reuse the
2238 kmf_set_attr_at_index(new_attrlist
, i
,
2239 KMF_KEYSTORE_TYPE_ATTR
, &kstype
, sizeof (kstype
));
2242 kmf_set_attr_at_index(new_attrlist
, i
,
2243 KMF_COUNT_ATTR
, &numkeys
, sizeof (uint32_t));
2246 kmf_set_attr_at_index(new_attrlist
, i
,
2247 KMF_KEYCLASS_ATTR
, &keyclass
, sizeof (keyclass
));
2250 key
= kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR
, attrlist
, numattr
);
2252 return (KMF_ERR_BAD_PARAMETER
);
2254 kmf_set_attr_at_index(new_attrlist
, i
,
2255 KMF_KEY_HANDLE_ATTR
, key
, sizeof (KMF_KEY_HANDLE
));
2259 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
2260 if (dirpath
!= NULL
) {
2261 kmf_set_attr_at_index(new_attrlist
, i
,
2262 KMF_DIRPATH_ATTR
, dirpath
, strlen(dirpath
));
2266 keyfile
= kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
, attrlist
, numattr
);
2267 if (keyfile
== NULL
)
2268 return (KMF_ERR_BAD_PARAMETER
);
2270 kmf_set_attr_at_index(new_attrlist
, i
,
2271 KMF_KEY_FILENAME_ATTR
, keyfile
, strlen(keyfile
));
2275 rv
= OpenSSL_FindKey(handle
, i
, new_attrlist
);
2281 OpenSSL_DecryptData(KMF_HANDLE_T handle
, KMF_KEY_HANDLE
*key
,
2282 KMF_OID
*AlgOID
, KMF_DATA
*ciphertext
,
2285 KMF_RETURN ret
= KMF_OK
;
2287 unsigned int in_len
= 0, out_len
= 0;
2288 unsigned int total_decrypted
= 0, modulus_len
= 0;
2289 uint8_t *in_data
, *out_data
;
2292 if (key
== NULL
|| AlgOID
== NULL
||
2293 ciphertext
== NULL
|| output
== NULL
||
2294 ciphertext
->Data
== NULL
||
2295 output
->Data
== NULL
)
2296 return (KMF_ERR_BAD_PARAMETER
);
2298 if (key
->keyalg
== KMF_RSA
) {
2299 rsa
= EVP_PKEY_get1_RSA((EVP_PKEY
*)key
->keyp
);
2300 modulus_len
= RSA_size(rsa
);
2302 return (KMF_ERR_BAD_PARAMETER
);
2305 blocks
= ciphertext
->Length
/modulus_len
;
2306 out_data
= output
->Data
;
2307 in_data
= ciphertext
->Data
;
2308 out_len
= modulus_len
- 11;
2309 in_len
= modulus_len
;
2311 for (i
= 0; i
< blocks
; i
++) {
2312 out_len
= RSA_private_decrypt(in_len
,
2313 in_data
, out_data
, rsa
, RSA_PKCS1_PADDING
);
2316 ret
= KMF_ERR_INTERNAL
;
2320 out_data
+= out_len
;
2321 total_decrypted
+= out_len
;
2325 output
->Length
= total_decrypted
;
2337 * This function will create a certid from issuer_cert and user_cert.
2338 * The caller should use OCSP_CERTID_free(OCSP_CERTID *) to deallocate
2339 * certid memory after use.
2342 create_certid(KMF_HANDLE_T handle
, const KMF_DATA
*issuer_cert
,
2343 const KMF_DATA
*user_cert
, OCSP_CERTID
**certid
)
2345 KMF_RETURN ret
= KMF_OK
;
2346 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2347 X509
*issuer
= NULL
;
2349 unsigned char *ptmp
;
2351 if (issuer_cert
== NULL
|| user_cert
== NULL
) {
2352 return (KMF_ERR_BAD_PARAMETER
);
2355 /* convert the DER-encoded issuer cert to an internal X509 */
2356 ptmp
= issuer_cert
->Data
;
2357 issuer
= d2i_X509(NULL
, (const uchar_t
**)&ptmp
,
2358 issuer_cert
->Length
);
2359 if (issuer
== NULL
) {
2360 SET_ERROR(kmfh
, ERR_get_error());
2361 ret
= KMF_ERR_OCSP_BAD_ISSUER
;
2365 /* convert the DER-encoded user cert to an internal X509 */
2366 ptmp
= user_cert
->Data
;
2367 cert
= d2i_X509(NULL
, (const uchar_t
**)&ptmp
,
2370 SET_ERROR(kmfh
, ERR_get_error());
2372 ret
= KMF_ERR_OCSP_BAD_CERT
;
2376 /* create a CERTID */
2377 *certid
= OCSP_cert_to_id(NULL
, cert
, issuer
);
2378 if (*certid
== NULL
) {
2379 SET_ERROR(kmfh
, ERR_get_error());
2380 ret
= KMF_ERR_OCSP_CERTID
;
2385 if (issuer
!= NULL
) {
2397 OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle
,
2398 int numattr
, KMF_ATTRIBUTE
*attrlist
)
2400 KMF_RETURN ret
= KMF_OK
;
2401 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2402 OCSP_CERTID
*id
= NULL
;
2403 OCSP_REQUEST
*req
= NULL
;
2406 KMF_DATA
*issuer_cert
;
2407 KMF_DATA
*user_cert
;
2409 user_cert
= kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR
,
2411 if (user_cert
== NULL
)
2412 return (KMF_ERR_BAD_PARAMETER
);
2414 issuer_cert
= kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR
,
2416 if (issuer_cert
== NULL
)
2417 return (KMF_ERR_BAD_PARAMETER
);
2419 reqfile
= kmf_get_attr_ptr(KMF_OCSP_REQUEST_FILENAME_ATTR
,
2421 if (reqfile
== NULL
)
2422 return (KMF_ERR_BAD_PARAMETER
);
2424 ret
= create_certid(handle
, issuer_cert
, user_cert
, &id
);
2425 if (ret
!= KMF_OK
) {
2429 /* Create an OCSP request */
2430 req
= OCSP_REQUEST_new();
2432 SET_ERROR(kmfh
, ERR_get_error());
2433 ret
= KMF_ERR_OCSP_CREATE_REQUEST
;
2437 if (!OCSP_request_add0_id(req
, id
)) {
2438 ret
= KMF_ERR_OCSP_CREATE_REQUEST
;
2442 /* Write the request to the output file with DER encoding */
2443 derbio
= BIO_new_file(reqfile
, "wb");
2445 SET_ERROR(kmfh
, ERR_get_error());
2446 ret
= KMF_ERR_OPEN_FILE
;
2449 if (i2d_OCSP_REQUEST_bio(derbio
, req
) <= 0) {
2450 ret
= KMF_ERR_ENCODING
;
2455 * We don't need to free "id" explicitely, because OCSP_REQUEST_free()
2456 * will also deallocate certid's space.
2459 OCSP_REQUEST_free(req
);
2462 if (derbio
!= NULL
) {
2463 (void) BIO_free(derbio
);
2469 /* ocsp_find_signer_sk() is copied from openssl source */
2470 static X509
*ocsp_find_signer_sk(STACK_OF(X509
) *certs
, OCSP_RESPID
*id
)
2473 unsigned char tmphash
[SHA_DIGEST_LENGTH
], *keyhash
;
2475 /* Easy if lookup by name */
2476 if (id
->type
== V_OCSP_RESPID_NAME
)
2477 return (X509_find_by_subject(certs
, id
->value
.byName
));
2479 /* Lookup by key hash */
2481 /* If key hash isn't SHA1 length then forget it */
2482 if (id
->value
.byKey
->length
!= SHA_DIGEST_LENGTH
)
2485 keyhash
= id
->value
.byKey
->data
;
2486 /* Calculate hash of each key and compare */
2487 for (i
= 0; i
< sk_X509_num(certs
); i
++) {
2488 /* LINTED E_BAD_PTR_CAST_ALIGN */
2489 X509
*x
= sk_X509_value(certs
, i
);
2490 /* Use pubkey_digest to get the key ID value */
2491 (void) X509_pubkey_digest(x
, EVP_sha1(), tmphash
, NULL
);
2492 if (!memcmp(keyhash
, tmphash
, SHA_DIGEST_LENGTH
))
2498 /* ocsp_find_signer() is copied from openssl source */
2501 ocsp_find_signer(X509
**psigner
, OCSP_BASICRESP
*bs
, STACK_OF(X509
) *certs
,
2502 X509_STORE
*st
, unsigned long flags
)
2505 OCSP_RESPID
*rid
= bs
->tbsResponseData
->responderId
;
2506 if ((signer
= ocsp_find_signer_sk(certs
, rid
))) {
2510 if (!(flags
& OCSP_NOINTERN
) &&
2511 (signer
= ocsp_find_signer_sk(bs
->certs
, rid
))) {
2515 /* Maybe lookup from store if by subject name */
2522 * This function will verify the signature of a basic response, using
2523 * the public key from the OCSP responder certificate.
2526 check_response_signature(KMF_HANDLE_T handle
, OCSP_BASICRESP
*bs
,
2527 KMF_DATA
*signer_cert
, KMF_DATA
*issuer_cert
)
2529 KMF_RETURN ret
= KMF_OK
;
2530 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2531 STACK_OF(X509
) *cert_stack
= NULL
;
2532 X509
*signer
= NULL
;
2533 X509
*issuer
= NULL
;
2534 EVP_PKEY
*skey
= NULL
;
2535 unsigned char *ptmp
;
2538 if (bs
== NULL
|| issuer_cert
== NULL
)
2539 return (KMF_ERR_BAD_PARAMETER
);
2542 * Find the certificate that signed the basic response.
2544 * If signer_cert is not NULL, we will use that as the signer cert.
2545 * Otherwise, we will check if the issuer cert is actually the signer.
2546 * If we still do not find a signer, we will look for it from the
2547 * certificate list came with the response file.
2549 if (signer_cert
!= NULL
) {
2550 ptmp
= signer_cert
->Data
;
2551 signer
= d2i_X509(NULL
, (const uchar_t
**)&ptmp
,
2552 signer_cert
->Length
);
2553 if (signer
== NULL
) {
2554 SET_ERROR(kmfh
, ERR_get_error());
2555 ret
= KMF_ERR_OCSP_BAD_SIGNER
;
2560 * Convert the issuer cert into X509 and push it into a
2561 * stack to be used by ocsp_find_signer().
2563 ptmp
= issuer_cert
->Data
;
2564 issuer
= d2i_X509(NULL
, (const uchar_t
**)&ptmp
,
2565 issuer_cert
->Length
);
2566 if (issuer
== NULL
) {
2567 SET_ERROR(kmfh
, ERR_get_error());
2568 ret
= KMF_ERR_OCSP_BAD_ISSUER
;
2572 if ((cert_stack
= sk_X509_new_null()) == NULL
) {
2573 ret
= KMF_ERR_INTERNAL
;
2577 if (sk_X509_push(cert_stack
, issuer
) == 0) {
2578 ret
= KMF_ERR_INTERNAL
;
2582 ret
= ocsp_find_signer(&signer
, bs
, cert_stack
, NULL
, 0);
2584 /* can not find the signer */
2585 ret
= KMF_ERR_OCSP_BAD_SIGNER
;
2590 /* Verify the signature of the response */
2591 skey
= X509_get_pubkey(signer
);
2593 ret
= KMF_ERR_OCSP_BAD_SIGNER
;
2597 ret
= OCSP_BASICRESP_verify(bs
, skey
, 0);
2599 ret
= KMF_ERR_OCSP_RESPONSE_SIGNATURE
;
2604 if (issuer
!= NULL
) {
2608 if (signer
!= NULL
) {
2613 EVP_PKEY_free(skey
);
2616 if (cert_stack
!= NULL
) {
2617 sk_X509_free(cert_stack
);
2626 OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle
,
2627 int numattr
, KMF_ATTRIBUTE
*attrlist
)
2629 KMF_RETURN ret
= KMF_OK
;
2631 OCSP_RESPONSE
*resp
= NULL
;
2632 OCSP_BASICRESP
*bs
= NULL
;
2633 OCSP_CERTID
*id
= NULL
;
2634 OCSP_SINGLERESP
*single
= NULL
;
2635 ASN1_GENERALIZEDTIME
*rev
, *thisupd
, *nextupd
;
2636 int index
, status
, reason
;
2637 KMF_DATA
*issuer_cert
;
2638 KMF_DATA
*user_cert
;
2639 KMF_DATA
*signer_cert
;
2641 int *response_reason
, *response_status
, *cert_status
;
2642 boolean_t ignore_response_sign
= B_FALSE
; /* default is FALSE */
2643 uint32_t response_lifetime
;
2645 issuer_cert
= kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR
,
2647 if (issuer_cert
== NULL
)
2648 return (KMF_ERR_BAD_PARAMETER
);
2650 user_cert
= kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR
,
2652 if (user_cert
== NULL
)
2653 return (KMF_ERR_BAD_PARAMETER
);
2655 response
= kmf_get_attr_ptr(KMF_OCSP_RESPONSE_DATA_ATTR
,
2657 if (response
== NULL
)
2658 return (KMF_ERR_BAD_PARAMETER
);
2660 response_status
= kmf_get_attr_ptr(KMF_OCSP_RESPONSE_STATUS_ATTR
,
2662 if (response_status
== NULL
)
2663 return (KMF_ERR_BAD_PARAMETER
);
2665 response_reason
= kmf_get_attr_ptr(KMF_OCSP_RESPONSE_REASON_ATTR
,
2667 if (response_reason
== NULL
)
2668 return (KMF_ERR_BAD_PARAMETER
);
2670 cert_status
= kmf_get_attr_ptr(KMF_OCSP_RESPONSE_CERT_STATUS_ATTR
,
2672 if (cert_status
== NULL
)
2673 return (KMF_ERR_BAD_PARAMETER
);
2675 /* Read in the response */
2676 derbio
= BIO_new_mem_buf(response
->Data
, response
->Length
);
2678 ret
= KMF_ERR_MEMORY
;
2682 resp
= d2i_OCSP_RESPONSE_bio(derbio
, NULL
);
2684 ret
= KMF_ERR_OCSP_MALFORMED_RESPONSE
;
2688 /* Check the response status */
2689 status
= OCSP_response_status(resp
);
2690 *response_status
= status
;
2691 if (status
!= OCSP_RESPONSE_STATUS_SUCCESSFUL
) {
2692 ret
= KMF_ERR_OCSP_RESPONSE_STATUS
;
2697 printf("Successfully checked the response file status.\n");
2700 /* Extract basic response */
2701 bs
= OCSP_response_get1_basic(resp
);
2703 ret
= KMF_ERR_OCSP_NO_BASIC_RESPONSE
;
2708 printf("Successfully retrieved the basic response.\n");
2711 /* Check the basic response signature if required */
2712 ret
= kmf_get_attr(KMF_IGNORE_RESPONSE_SIGN_ATTR
, attrlist
, numattr
,
2713 (void *)&ignore_response_sign
, NULL
);
2717 signer_cert
= kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR
,
2720 if (ignore_response_sign
== B_FALSE
) {
2721 ret
= check_response_signature(handle
, bs
,
2722 signer_cert
, issuer_cert
);
2728 printf("Successfully verified the response signature.\n");
2731 /* Create a certid for the certificate in question */
2732 ret
= create_certid(handle
, issuer_cert
, user_cert
, &id
);
2733 if (ret
!= KMF_OK
) {
2734 ret
= KMF_ERR_OCSP_CERTID
;
2739 printf("successfully created a certid for the cert.\n");
2742 /* Find the index of the single response for the certid */
2743 index
= OCSP_resp_find(bs
, id
, -1);
2745 /* cound not find this certificate in the response */
2746 ret
= KMF_ERR_OCSP_UNKNOWN_CERT
;
2751 printf("Successfully found the single response index for the cert.\n");
2754 /* Retrieve the single response and get the cert status */
2755 single
= OCSP_resp_get0(bs
, index
);
2756 status
= OCSP_single_get0_status(single
, &reason
, &rev
, &thisupd
,
2758 if (status
== V_OCSP_CERTSTATUS_GOOD
) {
2759 *cert_status
= OCSP_GOOD
;
2760 } else if (status
== V_OCSP_CERTSTATUS_UNKNOWN
) {
2761 *cert_status
= OCSP_UNKNOWN
;
2762 } else { /* revoked */
2763 *cert_status
= OCSP_REVOKED
;
2764 *response_reason
= reason
;
2768 /* resp. time is optional, so we don't care about the return code. */
2769 (void) kmf_get_attr(KMF_RESPONSE_LIFETIME_ATTR
, attrlist
, numattr
,
2770 (void *)&response_lifetime
, NULL
);
2772 if (!OCSP_check_validity(thisupd
, nextupd
, 300,
2773 response_lifetime
)) {
2774 ret
= KMF_ERR_OCSP_STATUS_TIME_INVALID
;
2779 printf("Successfully verify the time.\n");
2784 (void) BIO_free(derbio
);
2787 OCSP_RESPONSE_free(resp
);
2790 OCSP_BASICRESP_free(bs
);
2793 OCSP_CERTID_free(id
);
2799 fetch_key(KMF_HANDLE_T handle
, char *path
,
2800 KMF_KEY_CLASS keyclass
, KMF_KEY_HANDLE
*key
)
2802 KMF_RETURN rv
= KMF_OK
;
2803 EVP_PKEY
*pkey
= NULL
;
2804 KMF_RAW_SYM_KEY
*rkey
= NULL
;
2806 if (keyclass
== KMF_ASYM_PRI
||
2807 keyclass
== KMF_ASYM_PUB
) {
2808 pkey
= openssl_load_key(handle
, path
);
2810 return (KMF_ERR_KEY_NOT_FOUND
);
2813 if (pkey
->type
== EVP_PKEY_RSA
)
2814 key
->keyalg
= KMF_RSA
;
2815 else if (pkey
->type
== EVP_PKEY_DSA
)
2816 key
->keyalg
= KMF_DSA
;
2818 key
->kstype
= KMF_KEYSTORE_OPENSSL
;
2819 key
->keyclass
= keyclass
;
2820 key
->keyp
= (void *)pkey
;
2823 ((key
->keylabel
= strdup(path
)) == NULL
)) {
2824 EVP_PKEY_free(pkey
);
2825 return (KMF_ERR_MEMORY
);
2828 EVP_PKEY_free(pkey
);
2831 } else if (keyclass
== KMF_SYMMETRIC
) {
2832 KMF_ENCODE_FORMAT fmt
;
2834 * If the file is a recognized format,
2835 * then it is NOT a symmetric key.
2837 rv
= kmf_get_file_format(path
, &fmt
);
2838 if (rv
== KMF_OK
|| fmt
!= 0) {
2839 return (KMF_ERR_KEY_NOT_FOUND
);
2840 } else if (rv
== KMF_ERR_ENCODING
) {
2842 * If we don't know the encoding,
2843 * it is probably a symmetric key.
2846 } else if (rv
== KMF_ERR_OPEN_FILE
) {
2847 return (KMF_ERR_KEY_NOT_FOUND
);
2852 rkey
= malloc(sizeof (KMF_RAW_SYM_KEY
));
2854 rv
= KMF_ERR_MEMORY
;
2858 (void) memset(rkey
, 0, sizeof (KMF_RAW_SYM_KEY
));
2859 rv
= kmf_read_input_file(handle
, path
, &keyvalue
);
2863 rkey
->keydata
.len
= keyvalue
.Length
;
2864 rkey
->keydata
.val
= keyvalue
.Data
;
2866 key
->kstype
= KMF_KEYSTORE_OPENSSL
;
2867 key
->keyclass
= keyclass
;
2869 key
->keyp
= (void *)rkey
;
2871 ((key
->keylabel
= strdup(path
)) == NULL
)) {
2872 rv
= KMF_ERR_MEMORY
;
2879 kmf_free_raw_sym_key(rkey
);
2882 EVP_PKEY_free(pkey
);
2885 key
->keyalg
= KMF_KEYALG_NONE
;
2886 key
->keyclass
= KMF_KEYCLASS_NONE
;
2895 OpenSSL_FindKey(KMF_HANDLE_T handle
,
2896 int numattr
, KMF_ATTRIBUTE
*attrlist
)
2898 KMF_RETURN rv
= KMF_OK
;
2899 char *fullpath
= NULL
;
2901 KMF_KEY_HANDLE
*key
;
2903 KMF_KEY_CLASS keyclass
;
2904 KMF_RAW_KEY_DATA
*rawkey
;
2909 return (KMF_ERR_BAD_PARAMETER
);
2911 numkeys
= kmf_get_attr_ptr(KMF_COUNT_ATTR
, attrlist
, numattr
);
2912 if (numkeys
== NULL
)
2913 return (KMF_ERR_BAD_PARAMETER
);
2915 rv
= kmf_get_attr(KMF_KEYCLASS_ATTR
, attrlist
, numattr
,
2916 (void *)&keyclass
, NULL
);
2918 return (KMF_ERR_BAD_PARAMETER
);
2920 if (keyclass
!= KMF_ASYM_PUB
&&
2921 keyclass
!= KMF_ASYM_PRI
&&
2922 keyclass
!= KMF_SYMMETRIC
)
2923 return (KMF_ERR_BAD_KEY_CLASS
);
2925 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
2926 keyfile
= kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
, attrlist
, numattr
);
2928 fullpath
= get_fullpath(dirpath
, keyfile
);
2930 if (fullpath
== NULL
)
2931 return (KMF_ERR_BAD_PARAMETER
);
2935 maxkeys
= 0xFFFFFFFF;
2938 key
= kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR
, attrlist
, numattr
);
2939 /* it is okay to have "keys" contains NULL */
2942 * The caller may want a list of the raw key data as well.
2943 * Useful for importing keys from a file into other keystores.
2945 rawkey
= kmf_get_attr_ptr(KMF_RAW_KEY_ATTR
, attrlist
, numattr
);
2947 if (isdir(fullpath
)) {
2952 /* open all files in the directory and attempt to read them */
2953 if ((dirp
= opendir(fullpath
)) == NULL
) {
2954 return (KMF_ERR_BAD_PARAMETER
);
2957 while ((dp
= readdir(dirp
)) != NULL
&& n
< maxkeys
) {
2958 if (strcmp(dp
->d_name
, ".") &&
2959 strcmp(dp
->d_name
, "..")) {
2962 fname
= get_fullpath(fullpath
,
2963 (char *)&dp
->d_name
);
2965 rv
= fetch_key(handle
, fname
,
2966 keyclass
, key
? &key
[n
] : NULL
);
2969 if (key
!= NULL
&& rawkey
!= NULL
)
2970 rv
= convertToRawKey(
2971 key
[n
].keyp
, &rawkey
[n
]);
2975 if (rv
!= KMF_OK
|| key
== NULL
)
2979 (void) closedir(dirp
);
2983 rv
= fetch_key(handle
, fullpath
, keyclass
, key
);
2987 if (rv
!= KMF_OK
|| key
== NULL
)
2990 if (rv
== KMF_OK
&& key
!= NULL
&& rawkey
!= NULL
) {
2991 rv
= convertToRawKey(key
->keyp
, rawkey
);
2995 if (rv
== KMF_OK
&& (*numkeys
) == 0)
2996 rv
= KMF_ERR_KEY_NOT_FOUND
;
2997 else if (rv
== KMF_ERR_KEY_NOT_FOUND
&& (*numkeys
) > 0)
3003 #define HANDLE_PK12_ERROR { \
3004 SET_ERROR(kmfh, ERR_get_error()); \
3005 rv = KMF_ERR_ENCODING; \
3010 add_alias_to_bag(PKCS12_SAFEBAG
*bag
, X509
*xcert
)
3012 if (xcert
!= NULL
&& xcert
->aux
!= NULL
&&
3013 xcert
->aux
->alias
!= NULL
) {
3014 if (PKCS12_add_friendlyname_asc(bag
,
3015 (const char *)xcert
->aux
->alias
->data
,
3016 xcert
->aux
->alias
->length
) == 0)
3023 add_cert_to_safe(X509
*sslcert
, KMF_CREDENTIAL
*cred
,
3024 uchar_t
*keyid
, unsigned int keyidlen
)
3026 PKCS12_SAFEBAG
*bag
= NULL
;
3027 PKCS7
*cert_authsafe
= NULL
;
3028 STACK_OF(PKCS12_SAFEBAG
) *bag_stack
;
3030 bag_stack
= sk_PKCS12_SAFEBAG_new_null();
3031 if (bag_stack
== NULL
)
3034 /* Convert cert from X509 struct to PKCS#12 bag */
3035 bag
= PKCS12_x5092certbag(sslcert
);
3040 /* Add the key id to the certificate bag. */
3041 if (keyidlen
> 0 && !PKCS12_add_localkeyid(bag
, keyid
, keyidlen
)) {
3045 if (!add_alias_to_bag(bag
, sslcert
))
3048 /* Pile it on the bag_stack. */
3049 if (!sk_PKCS12_SAFEBAG_push(bag_stack
, bag
)) {
3052 /* Turn bag_stack of certs into encrypted authsafe. */
3053 cert_authsafe
= PKCS12_pack_p7encdata(
3054 NID_pbe_WithSHA1And40BitRC2_CBC
,
3055 cred
->cred
, cred
->credlen
, NULL
, 0,
3056 PKCS12_DEFAULT_ITER
, bag_stack
);
3059 if (bag_stack
!= NULL
)
3060 sk_PKCS12_SAFEBAG_pop_free(bag_stack
, PKCS12_SAFEBAG_free
);
3062 return (cert_authsafe
);
3066 add_key_to_safe(EVP_PKEY
*pkey
, KMF_CREDENTIAL
*cred
,
3067 uchar_t
*keyid
, unsigned int keyidlen
,
3068 char *label
, int label_len
)
3070 PKCS8_PRIV_KEY_INFO
*p8
= NULL
;
3071 STACK_OF(PKCS12_SAFEBAG
) *bag_stack
= NULL
;
3072 PKCS12_SAFEBAG
*bag
= NULL
;
3073 PKCS7
*key_authsafe
= NULL
;
3075 p8
= EVP_PKEY2PKCS8(pkey
);
3079 /* Put the shrouded key into a PKCS#12 bag. */
3080 bag
= PKCS12_MAKE_SHKEYBAG(
3081 NID_pbe_WithSHA1And3_Key_TripleDES_CBC
,
3082 cred
->cred
, cred
->credlen
,
3083 NULL
, 0, PKCS12_DEFAULT_ITER
, p8
);
3085 /* Clean up the PKCS#8 shrouded key, don't need it now. */
3086 PKCS8_PRIV_KEY_INFO_free(p8
);
3092 if (keyidlen
&& !PKCS12_add_localkeyid(bag
, keyid
, keyidlen
))
3094 if (label
!= NULL
&& !PKCS12_add_friendlyname(bag
, label
, label_len
))
3097 /* Start a PKCS#12 safebag container for the private key. */
3098 bag_stack
= sk_PKCS12_SAFEBAG_new_null();
3099 if (bag_stack
== NULL
)
3102 /* Pile on the private key on the bag_stack. */
3103 if (!sk_PKCS12_SAFEBAG_push(bag_stack
, bag
))
3106 key_authsafe
= PKCS12_pack_p7data(bag_stack
);
3109 if (bag_stack
!= NULL
)
3110 sk_PKCS12_SAFEBAG_pop_free(bag_stack
, PKCS12_SAFEBAG_free
);
3112 return (key_authsafe
);
3116 ImportRawRSAKey(KMF_RAW_RSA_KEY
*key
)
3119 EVP_PKEY
*newkey
= NULL
;
3121 if ((rsa
= RSA_new()) == NULL
)
3124 if ((rsa
->n
= BN_bin2bn(key
->mod
.val
, key
->mod
.len
, rsa
->n
)) == NULL
)
3127 if ((rsa
->e
= BN_bin2bn(key
->pubexp
.val
, key
->pubexp
.len
, rsa
->e
)) ==
3131 if (key
->priexp
.val
!= NULL
)
3132 if ((rsa
->d
= BN_bin2bn(key
->priexp
.val
, key
->priexp
.len
,
3136 if (key
->prime1
.val
!= NULL
)
3137 if ((rsa
->p
= BN_bin2bn(key
->prime1
.val
, key
->prime1
.len
,
3141 if (key
->prime2
.val
!= NULL
)
3142 if ((rsa
->q
= BN_bin2bn(key
->prime2
.val
, key
->prime2
.len
,
3146 if (key
->exp1
.val
!= NULL
)
3147 if ((rsa
->dmp1
= BN_bin2bn(key
->exp1
.val
, key
->exp1
.len
,
3148 rsa
->dmp1
)) == NULL
)
3151 if (key
->exp2
.val
!= NULL
)
3152 if ((rsa
->dmq1
= BN_bin2bn(key
->exp2
.val
, key
->exp2
.len
,
3153 rsa
->dmq1
)) == NULL
)
3156 if (key
->coef
.val
!= NULL
)
3157 if ((rsa
->iqmp
= BN_bin2bn(key
->coef
.val
, key
->coef
.len
,
3158 rsa
->iqmp
)) == NULL
)
3161 if ((newkey
= EVP_PKEY_new()) == NULL
)
3164 (void) EVP_PKEY_set1_RSA(newkey
, rsa
);
3166 /* The original key must be freed once here or it leaks memory */
3173 ImportRawDSAKey(KMF_RAW_DSA_KEY
*key
)
3176 EVP_PKEY
*newkey
= NULL
;
3178 if ((dsa
= DSA_new()) == NULL
)
3181 if ((dsa
->p
= BN_bin2bn(key
->prime
.val
, key
->prime
.len
,
3185 if ((dsa
->q
= BN_bin2bn(key
->subprime
.val
, key
->subprime
.len
,
3189 if ((dsa
->g
= BN_bin2bn(key
->base
.val
, key
->base
.len
,
3193 if ((dsa
->priv_key
= BN_bin2bn(key
->value
.val
, key
->value
.len
,
3194 dsa
->priv_key
)) == NULL
)
3197 if (key
->pubvalue
.val
!= NULL
) {
3198 if ((dsa
->pub_key
= BN_bin2bn(key
->pubvalue
.val
,
3199 key
->pubvalue
.len
, dsa
->pub_key
)) == NULL
)
3203 if ((newkey
= EVP_PKEY_new()) == NULL
)
3206 (void) EVP_PKEY_set1_DSA(newkey
, dsa
);
3208 /* The original key must be freed once here or it leaks memory */
3214 raw_key_to_pkey(KMF_KEY_HANDLE
*key
)
3216 EVP_PKEY
*pkey
= NULL
;
3217 KMF_RAW_KEY_DATA
*rawkey
;
3218 ASN1_TYPE
*attr
= NULL
;
3221 if (key
== NULL
|| !key
->israw
)
3224 rawkey
= (KMF_RAW_KEY_DATA
*)key
->keyp
;
3225 if (rawkey
->keytype
== KMF_RSA
) {
3226 pkey
= ImportRawRSAKey(&rawkey
->rawdata
.rsa
);
3227 } else if (rawkey
->keytype
== KMF_DSA
) {
3228 pkey
= ImportRawDSAKey(&rawkey
->rawdata
.dsa
);
3229 } else if (rawkey
->keytype
== KMF_ECDSA
) {
3231 * OpenSSL in Solaris does not support EC for
3236 /* wrong kind of key */
3240 if (rawkey
->label
!= NULL
) {
3241 if ((attr
= ASN1_TYPE_new()) == NULL
) {
3242 EVP_PKEY_free(pkey
);
3245 attr
->value
.bmpstring
= ASN1_STRING_type_new(V_ASN1_BMPSTRING
);
3246 (void) ASN1_STRING_set(attr
->value
.bmpstring
, rawkey
->label
,
3247 strlen(rawkey
->label
));
3248 attr
->type
= V_ASN1_BMPSTRING
;
3249 attr
->value
.ptr
= (char *)attr
->value
.bmpstring
;
3250 ret
= set_pkey_attrib(pkey
, attr
, NID_friendlyName
);
3251 if (ret
!= KMF_OK
) {
3252 EVP_PKEY_free(pkey
);
3253 ASN1_TYPE_free(attr
);
3257 if (rawkey
->id
.Data
!= NULL
) {
3258 if ((attr
= ASN1_TYPE_new()) == NULL
) {
3259 EVP_PKEY_free(pkey
);
3262 attr
->value
.octet_string
=
3263 ASN1_STRING_type_new(V_ASN1_OCTET_STRING
);
3264 attr
->type
= V_ASN1_OCTET_STRING
;
3265 (void) ASN1_STRING_set(attr
->value
.octet_string
,
3266 rawkey
->id
.Data
, rawkey
->id
.Length
);
3267 attr
->value
.ptr
= (char *)attr
->value
.octet_string
;
3268 ret
= set_pkey_attrib(pkey
, attr
, NID_localKeyID
);
3269 if (ret
!= KMF_OK
) {
3270 EVP_PKEY_free(pkey
);
3271 ASN1_TYPE_free(attr
);
3279 * Search a list of private keys to find one that goes with the certificate.
3282 find_matching_key(X509
*xcert
, int numkeys
, KMF_KEY_HANDLE
*keylist
)
3285 EVP_PKEY
*pkey
= NULL
;
3287 if (numkeys
== 0 || keylist
== NULL
|| xcert
== NULL
)
3289 for (i
= 0; i
< numkeys
; i
++) {
3290 if (keylist
[i
].israw
)
3291 pkey
= raw_key_to_pkey(&keylist
[i
]);
3293 pkey
= (EVP_PKEY
*)keylist
[i
].keyp
;
3295 if (X509_check_private_key(xcert
, pkey
)) {
3298 EVP_PKEY_free(pkey
);
3307 local_export_pk12(KMF_HANDLE_T handle
,
3308 KMF_CREDENTIAL
*cred
,
3309 int numcerts
, KMF_X509_DER_CERT
*certlist
,
3310 int numkeys
, KMF_KEY_HANDLE
*keylist
,
3313 KMF_RETURN rv
= KMF_OK
;
3314 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
3316 PKCS7
*cert_authsafe
= NULL
;
3317 PKCS7
*key_authsafe
= NULL
;
3318 STACK_OF(PKCS7
) *authsafe_stack
= NULL
;
3319 PKCS12
*p12_elem
= NULL
;
3322 if (numcerts
== 0 && numkeys
== 0)
3323 return (KMF_ERR_BAD_PARAMETER
);
3326 * Open the output file.
3328 if ((bio
= BIO_new_file(filename
, "wb")) == NULL
) {
3329 SET_ERROR(kmfh
, ERR_get_error());
3330 rv
= KMF_ERR_OPEN_FILE
;
3334 /* Start a PKCS#7 stack. */
3335 authsafe_stack
= sk_PKCS7_new_null();
3336 if (authsafe_stack
== NULL
) {
3337 rv
= KMF_ERR_MEMORY
;
3341 for (i
= 0; rv
== KMF_OK
&& i
< numcerts
; i
++) {
3342 const uchar_t
*p
= certlist
[i
].certificate
.Data
;
3343 long len
= certlist
[i
].certificate
.Length
;
3345 EVP_PKEY
*pkey
= NULL
;
3346 unsigned char keyid
[EVP_MAX_MD_SIZE
];
3347 unsigned int keyidlen
= 0;
3349 xcert
= d2i_X509(NULL
, &p
, len
);
3350 if (xcert
== NULL
) {
3351 SET_ERROR(kmfh
, ERR_get_error());
3352 rv
= KMF_ERR_ENCODING
;
3354 if (certlist
[i
].kmf_private
.label
!= NULL
) {
3355 /* Set alias attribute */
3356 (void) X509_alias_set1(xcert
,
3357 (uchar_t
*)certlist
[i
].kmf_private
.label
,
3358 strlen(certlist
[i
].kmf_private
.label
));
3360 /* Check if there is a key corresponding to this cert */
3361 pkey
= find_matching_key(xcert
, numkeys
, keylist
);
3364 * If key is found, get fingerprint and create a
3368 (void) X509_digest(xcert
, EVP_sha1(),
3370 key_authsafe
= add_key_to_safe(pkey
, cred
,
3372 certlist
[i
].kmf_private
.label
,
3373 (certlist
[i
].kmf_private
.label
?
3374 strlen(certlist
[i
].kmf_private
.label
) : 0));
3376 if (key_authsafe
== NULL
) {
3378 EVP_PKEY_free(pkey
);
3381 /* Put the key safe into the Auth Safe */
3382 if (!sk_PKCS7_push(authsafe_stack
,
3385 EVP_PKEY_free(pkey
);
3390 /* create a certificate safebag */
3391 cert_authsafe
= add_cert_to_safe(xcert
, cred
, keyid
,
3393 if (cert_authsafe
== NULL
) {
3395 EVP_PKEY_free(pkey
);
3398 if (!sk_PKCS7_push(authsafe_stack
, cert_authsafe
)) {
3400 EVP_PKEY_free(pkey
);
3406 EVP_PKEY_free(pkey
);
3408 } else if (numcerts
== 0 && numkeys
> 0) {
3410 * If only adding keys to the file.
3412 for (i
= 0; i
< numkeys
; i
++) {
3413 EVP_PKEY
*pkey
= NULL
;
3415 if (keylist
[i
].israw
)
3416 pkey
= raw_key_to_pkey(&keylist
[i
]);
3418 pkey
= (EVP_PKEY
*)keylist
[i
].keyp
;
3423 key_authsafe
= add_key_to_safe(pkey
, cred
,
3426 if (key_authsafe
== NULL
) {
3427 EVP_PKEY_free(pkey
);
3430 if (!sk_PKCS7_push(authsafe_stack
, key_authsafe
)) {
3431 EVP_PKEY_free(pkey
);
3436 p12_elem
= PKCS12_init(NID_pkcs7_data
);
3437 if (p12_elem
== NULL
) {
3441 /* Put the PKCS#7 stack into the PKCS#12 element. */
3442 if (!PKCS12_pack_authsafes(p12_elem
, authsafe_stack
)) {
3446 /* Set the integrity MAC on the PKCS#12 element. */
3447 if (!PKCS12_set_mac(p12_elem
, cred
->cred
, cred
->credlen
,
3448 NULL
, 0, PKCS12_DEFAULT_ITER
, NULL
)) {
3452 /* Write the PKCS#12 element to the export file. */
3453 if (!i2d_PKCS12_bio(bio
, p12_elem
)) {
3456 PKCS12_free(p12_elem
);
3459 /* Clear away the PKCS#7 stack, we're done with it. */
3461 sk_PKCS7_pop_free(authsafe_stack
, PKCS7_free
);
3464 (void) BIO_free_all(bio
);
3470 openssl_build_pk12(KMF_HANDLE_T handle
, int numcerts
,
3471 KMF_X509_DER_CERT
*certlist
, int numkeys
, KMF_KEY_HANDLE
*keylist
,
3472 KMF_CREDENTIAL
*p12cred
, char *filename
)
3476 if (certlist
== NULL
&& keylist
== NULL
)
3477 return (KMF_ERR_BAD_PARAMETER
);
3479 rv
= local_export_pk12(handle
, p12cred
, numcerts
, certlist
,
3480 numkeys
, keylist
, filename
);
3486 OpenSSL_ExportPK12(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
3489 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
3490 char *fullpath
= NULL
;
3491 char *dirpath
= NULL
;
3492 char *certfile
= NULL
;
3493 char *keyfile
= NULL
;
3494 char *filename
= NULL
;
3495 KMF_CREDENTIAL
*p12cred
= NULL
;
3496 KMF_X509_DER_CERT certdata
;
3502 return (KMF_ERR_BAD_PARAMETER
);
3505 * First, find the certificate.
3507 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
3508 certfile
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
, numattr
);
3509 if (certfile
!= NULL
) {
3510 fullpath
= get_fullpath(dirpath
, certfile
);
3511 if (fullpath
== NULL
)
3512 return (KMF_ERR_BAD_PARAMETER
);
3514 if (isdir(fullpath
)) {
3516 return (KMF_ERR_AMBIGUOUS_PATHNAME
);
3519 (void) memset(&certdata
, 0, sizeof (certdata
));
3520 rv
= kmf_load_cert(kmfh
, NULL
, NULL
, NULL
, KMF_ALL_CERTS
,
3521 fullpath
, &certdata
.certificate
);
3526 certdata
.kmf_private
.keystore_type
= KMF_KEYSTORE_OPENSSL
;
3531 * Now find the private key.
3533 keyfile
= kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
, attrlist
, numattr
);
3534 if (keyfile
!= NULL
) {
3535 fullpath
= get_fullpath(dirpath
, keyfile
);
3536 if (fullpath
== NULL
)
3537 return (KMF_ERR_BAD_PARAMETER
);
3539 if (isdir(fullpath
)) {
3541 return (KMF_ERR_AMBIGUOUS_PATHNAME
);
3544 (void) memset(&key
, 0, sizeof (KMF_KEY_HANDLE
));
3545 rv
= fetch_key(handle
, fullpath
, KMF_ASYM_PRI
, &key
);
3552 * Open the output file.
3554 filename
= kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR
, attrlist
,
3556 if (filename
== NULL
) {
3557 rv
= KMF_ERR_BAD_PARAMETER
;
3561 /* Stick the key and the cert into a PKCS#12 file */
3562 p12cred
= kmf_get_attr_ptr(KMF_PK12CRED_ATTR
, attrlist
, numattr
);
3563 if (p12cred
== NULL
) {
3564 rv
= KMF_ERR_BAD_PARAMETER
;
3568 rv
= local_export_pk12(handle
, p12cred
, 1, &certdata
,
3575 kmf_free_kmf_cert(handle
, &certdata
);
3577 kmf_free_kmf_key(handle
, &key
);
3582 * Helper function to extract keys and certificates from
3583 * a single PEM file. Typically the file should contain a
3584 * private key and an associated public key wrapped in an x509 cert.
3585 * However, the file may be just a list of X509 certs with no keys.
3588 extract_pem(KMF_HANDLE
*kmfh
,
3589 char *issuer
, char *subject
, KMF_BIGINT
*serial
,
3590 char *filename
, CK_UTF8CHAR
*pin
,
3591 CK_ULONG pinlen
, EVP_PKEY
**priv_key
, KMF_DATA
**certs
,
3595 KMF_RETURN rv
= KMF_OK
;
3597 STACK_OF(X509_INFO
) *x509_info_stack
= NULL
;
3598 int i
, ncerts
= 0, matchcerts
= 0;
3599 EVP_PKEY
*pkey
= NULL
;
3602 X509_INFO
**cert_infos
= NULL
;
3603 KMF_DATA
*certlist
= NULL
;
3609 fp
= fopen(filename
, "r");
3611 return (KMF_ERR_OPEN_FILE
);
3613 x509_info_stack
= PEM_X509_INFO_read(fp
, NULL
, NULL
, pin
);
3614 if (x509_info_stack
== NULL
) {
3616 return (KMF_ERR_ENCODING
);
3618 cert_infos
= (X509_INFO
**)malloc(sk_X509_INFO_num(x509_info_stack
) *
3619 sizeof (X509_INFO
*));
3620 if (cert_infos
== NULL
) {
3622 rv
= KMF_ERR_MEMORY
;
3626 for (i
= 0; i
< sk_X509_INFO_num(x509_info_stack
); i
++) {
3627 /* LINTED E_BAD_PTR_CAST_ALIGN */
3628 cert_infos
[ncerts
] = sk_X509_INFO_value(x509_info_stack
, i
);
3634 rv
= KMF_ERR_CERT_NOT_FOUND
;
3638 if (priv_key
!= NULL
) {
3640 pkey
= PEM_read_PrivateKey(fp
, NULL
, NULL
, pin
);
3644 x
= cert_infos
[ncerts
- 1]->x509
;
3646 * Make sure the private key matchs the last cert in the file.
3648 if (pkey
!= NULL
&& !X509_check_private_key(x
, pkey
)) {
3649 EVP_PKEY_free(pkey
);
3650 rv
= KMF_ERR_KEY_MISMATCH
;
3654 certlist
= (KMF_DATA
*)calloc(ncerts
, sizeof (KMF_DATA
));
3655 if (certlist
== NULL
) {
3657 EVP_PKEY_free(pkey
);
3658 rv
= KMF_ERR_MEMORY
;
3663 * Convert all of the certs to DER format.
3666 for (i
= 0; rv
== KMF_OK
&& certs
!= NULL
&& i
< ncerts
; i
++) {
3667 boolean_t match
= FALSE
;
3668 info
= cert_infos
[ncerts
- 1 - i
];
3670 rv
= check_cert(info
->x509
, issuer
, subject
, serial
, &match
);
3671 if (rv
!= KMF_OK
|| match
!= TRUE
) {
3676 rv
= ssl_cert2KMFDATA(kmfh
, info
->x509
,
3677 &certlist
[matchcerts
++]);
3681 for (j
= 0; j
< matchcerts
; j
++)
3682 kmf_free_data(&certlist
[j
]);
3685 ncerts
= matchcerts
= 0;
3689 if (numcerts
!= NULL
)
3690 *numcerts
= matchcerts
;
3694 else if (certlist
!= NULL
) {
3695 for (i
= 0; i
< ncerts
; i
++)
3696 kmf_free_data(&certlist
[i
]);
3701 if (priv_key
== NULL
&& pkey
!= NULL
)
3702 EVP_PKEY_free(pkey
);
3703 else if (priv_key
!= NULL
&& pkey
!= NULL
)
3707 /* Cleanup the stack of X509 info records */
3708 for (i
= 0; i
< sk_X509_INFO_num(x509_info_stack
); i
++) {
3709 /* LINTED E_BAD_PTR_CAST_ALIGN */
3710 info
= (X509_INFO
*)sk_X509_INFO_value(x509_info_stack
, i
);
3711 X509_INFO_free(info
);
3713 if (x509_info_stack
)
3714 sk_X509_INFO_free(x509_info_stack
);
3716 if (cert_infos
!= NULL
)
3723 openssl_parse_bags(STACK_OF(PKCS12_SAFEBAG
) *bags
, char *pin
,
3724 STACK_OF(EVP_PKEY
) *keys
, STACK_OF(X509
) *certs
)
3729 for (i
= 0; i
< sk_PKCS12_SAFEBAG_num(bags
); i
++) {
3730 /* LINTED E_BAD_PTR_CAST_ALIGN */
3731 PKCS12_SAFEBAG
*bag
= sk_PKCS12_SAFEBAG_value(bags
, i
);
3732 ret
= openssl_parse_bag(bag
, pin
, (pin
? strlen(pin
) : 0),
3743 set_pkey_attrib(EVP_PKEY
*pkey
, ASN1_TYPE
*attrib
, int nid
)
3745 X509_ATTRIBUTE
*attr
= NULL
;
3747 if (pkey
== NULL
|| attrib
== NULL
)
3748 return (KMF_ERR_BAD_PARAMETER
);
3750 if (pkey
->attributes
== NULL
) {
3751 pkey
->attributes
= sk_X509_ATTRIBUTE_new_null();
3752 if (pkey
->attributes
== NULL
)
3753 return (KMF_ERR_MEMORY
);
3755 attr
= X509_ATTRIBUTE_create(nid
, attrib
->type
, attrib
->value
.ptr
);
3760 i
< sk_X509_ATTRIBUTE_num(pkey
->attributes
); i
++) {
3761 /* LINTED E_BAD_PTR_CASE_ALIGN */
3762 a
= sk_X509_ATTRIBUTE_value(pkey
->attributes
, i
);
3763 if (OBJ_obj2nid(a
->object
) == nid
) {
3764 X509_ATTRIBUTE_free(a
);
3765 /* LINTED E_BAD_PTR_CAST_ALIGN */
3766 (void) sk_X509_ATTRIBUTE_set(pkey
->attributes
,
3771 if (sk_X509_ATTRIBUTE_push(pkey
->attributes
, attr
) == 0) {
3772 X509_ATTRIBUTE_free(attr
);
3773 return (KMF_ERR_MEMORY
);
3776 return (KMF_ERR_MEMORY
);
3783 openssl_parse_bag(PKCS12_SAFEBAG
*bag
, char *pass
, int passlen
,
3784 STACK_OF(EVP_PKEY
) *keylist
, STACK_OF(X509
) *certlist
)
3786 KMF_RETURN ret
= KMF_OK
;
3787 PKCS8_PRIV_KEY_INFO
*p8
= NULL
;
3788 EVP_PKEY
*pkey
= NULL
;
3790 ASN1_TYPE
*keyid
= NULL
;
3791 ASN1_TYPE
*fname
= NULL
;
3792 uchar_t
*data
= NULL
;
3794 keyid
= PKCS12_get_attr(bag
, NID_localKeyID
);
3795 fname
= PKCS12_get_attr(bag
, NID_friendlyName
);
3797 switch (M_PKCS12_bag_type(bag
)) {
3799 if (keylist
== NULL
)
3801 pkey
= EVP_PKCS82PKEY(bag
->value
.keybag
);
3803 ret
= KMF_ERR_PKCS12_FORMAT
;
3806 case NID_pkcs8ShroudedKeyBag
:
3807 if (keylist
== NULL
)
3809 p8
= M_PKCS12_decrypt_skey(bag
, pass
, passlen
);
3811 return (KMF_ERR_AUTH_FAILED
);
3812 pkey
= EVP_PKCS82PKEY(p8
);
3813 PKCS8_PRIV_KEY_INFO_free(p8
);
3815 ret
= KMF_ERR_PKCS12_FORMAT
;
3818 if (certlist
== NULL
)
3820 if (M_PKCS12_cert_bag_type(bag
) != NID_x509Certificate
)
3821 return (KMF_ERR_PKCS12_FORMAT
);
3822 xcert
= M_PKCS12_certbag2x509(bag
);
3823 if (xcert
== NULL
) {
3824 ret
= KMF_ERR_PKCS12_FORMAT
;
3827 if (keyid
!= NULL
) {
3828 if (X509_keyid_set1(xcert
,
3829 keyid
->value
.octet_string
->data
,
3830 keyid
->value
.octet_string
->length
) == 0) {
3831 ret
= KMF_ERR_PKCS12_FORMAT
;
3835 if (fname
!= NULL
) {
3837 len
= ASN1_STRING_to_UTF8(&data
,
3838 fname
->value
.asn1_string
);
3839 if (len
> 0 && data
!= NULL
) {
3840 r
= X509_alias_set1(xcert
, data
, len
);
3842 ret
= KMF_ERR_PKCS12_FORMAT
;
3846 ret
= KMF_ERR_PKCS12_FORMAT
;
3850 if (sk_X509_push(certlist
, xcert
) == 0)
3851 ret
= KMF_ERR_MEMORY
;
3855 case NID_safeContentsBag
:
3856 return (openssl_parse_bags(bag
->value
.safes
, pass
,
3857 keylist
, certlist
));
3859 ret
= KMF_ERR_PKCS12_FORMAT
;
3864 * Set the ID and/or FriendlyName attributes on the key.
3865 * If converting to PKCS11 objects, these can translate to CKA_ID
3866 * and CKA_LABEL values.
3868 if (pkey
!= NULL
&& ret
== KMF_OK
) {
3869 ASN1_TYPE
*attr
= NULL
;
3870 if (keyid
!= NULL
&& keyid
->type
== V_ASN1_OCTET_STRING
) {
3871 if ((attr
= ASN1_TYPE_new()) == NULL
)
3872 return (KMF_ERR_MEMORY
);
3873 attr
->value
.octet_string
=
3874 ASN1_STRING_dup(keyid
->value
.octet_string
);
3875 attr
->type
= V_ASN1_OCTET_STRING
;
3876 attr
->value
.ptr
= (char *)attr
->value
.octet_string
;
3877 ret
= set_pkey_attrib(pkey
, attr
, NID_localKeyID
);
3881 if (ret
== KMF_OK
&& fname
!= NULL
&&
3882 fname
->type
== V_ASN1_BMPSTRING
) {
3883 if ((attr
= ASN1_TYPE_new()) == NULL
)
3884 return (KMF_ERR_MEMORY
);
3885 attr
->value
.bmpstring
=
3886 ASN1_STRING_dup(fname
->value
.bmpstring
);
3887 attr
->type
= V_ASN1_BMPSTRING
;
3888 attr
->value
.ptr
= (char *)attr
->value
.bmpstring
;
3889 ret
= set_pkey_attrib(pkey
, attr
, NID_friendlyName
);
3893 if (ret
== KMF_OK
&& keylist
!= NULL
&&
3894 sk_EVP_PKEY_push(keylist
, pkey
) == 0)
3895 ret
= KMF_ERR_MEMORY
;
3897 if (ret
== KMF_OK
&& keylist
!= NULL
)
3901 EVP_PKEY_free(pkey
);
3911 openssl_pkcs12_parse(PKCS12
*p12
, char *pin
,
3912 STACK_OF(EVP_PKEY
) *keys
,
3913 STACK_OF(X509
) *certs
,
3917 KMF_RETURN ret
= KMF_OK
;
3918 STACK_OF(PKCS7
) *asafes
= NULL
;
3919 STACK_OF(PKCS12_SAFEBAG
) *bags
= NULL
;
3923 if (p12
== NULL
|| (keys
== NULL
&& certs
== NULL
))
3924 return (KMF_ERR_BAD_PARAMETER
);
3926 if (pin
== NULL
|| *pin
== '\0') {
3927 if (PKCS12_verify_mac(p12
, NULL
, 0)) {
3929 } else if (PKCS12_verify_mac(p12
, "", 0)) {
3932 return (KMF_ERR_AUTH_FAILED
);
3934 } else if (!PKCS12_verify_mac(p12
, pin
, -1)) {
3935 return (KMF_ERR_AUTH_FAILED
);
3938 if ((asafes
= PKCS12_unpack_authsafes(p12
)) == NULL
)
3939 return (KMF_ERR_PKCS12_FORMAT
);
3941 for (i
= 0; ret
== KMF_OK
&& i
< sk_PKCS7_num(asafes
); i
++) {
3943 /* LINTED E_BAD_PTR_CAST_ALIGN */
3944 p7
= sk_PKCS7_value(asafes
, i
);
3945 bagnid
= OBJ_obj2nid(p7
->type
);
3947 if (bagnid
== NID_pkcs7_data
) {
3948 bags
= PKCS12_unpack_p7data(p7
);
3949 } else if (bagnid
== NID_pkcs7_encrypted
) {
3950 bags
= PKCS12_unpack_p7encdata(p7
, pin
,
3951 (pin
? strlen(pin
) : 0));
3956 ret
= KMF_ERR_PKCS12_FORMAT
;
3960 if (openssl_parse_bags(bags
, pin
, keys
, certs
) != KMF_OK
)
3961 ret
= KMF_ERR_PKCS12_FORMAT
;
3963 sk_PKCS12_SAFEBAG_pop_free(bags
, PKCS12_SAFEBAG_free
);
3967 sk_PKCS7_pop_free(asafes
, PKCS7_free
);
3973 * Helper function to decrypt and parse PKCS#12 import file.
3976 extract_pkcs12(BIO
*fbio
, CK_UTF8CHAR
*pin
, CK_ULONG pinlen
,
3977 STACK_OF(EVP_PKEY
) **priv_key
, STACK_OF(X509
) **certs
,
3978 STACK_OF(X509
) **ca
)
3981 PKCS12
*pk12
, *pk12_tmp
;
3982 STACK_OF(EVP_PKEY
) *pkeylist
= NULL
;
3983 STACK_OF(X509
) *xcertlist
= NULL
;
3984 STACK_OF(X509
) *cacertlist
= NULL
;
3986 if ((pk12
= PKCS12_new()) == NULL
) {
3987 return (KMF_ERR_MEMORY
);
3990 if ((pk12_tmp
= d2i_PKCS12_bio(fbio
, &pk12
)) == NULL
) {
3991 /* This is ok; it seems to mean there is no more to read. */
3992 if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_ASN1
&&
3993 ERR_GET_REASON(ERR_peek_error()) == ASN1_R_HEADER_TOO_LONG
)
3994 goto end_extract_pkcs12
;
3997 return (KMF_ERR_PKCS12_FORMAT
);
4001 xcertlist
= sk_X509_new_null();
4002 if (xcertlist
== NULL
) {
4004 return (KMF_ERR_MEMORY
);
4006 pkeylist
= sk_EVP_PKEY_new_null();
4007 if (pkeylist
== NULL
) {
4008 sk_X509_pop_free(xcertlist
, X509_free
);
4010 return (KMF_ERR_MEMORY
);
4013 if (openssl_pkcs12_parse(pk12
, (char *)pin
, pkeylist
, xcertlist
,
4014 cacertlist
) != KMF_OK
) {
4015 sk_X509_pop_free(xcertlist
, X509_free
);
4016 sk_EVP_PKEY_pop_free(pkeylist
, EVP_PKEY_free
);
4018 return (KMF_ERR_PKCS12_FORMAT
);
4021 if (priv_key
&& pkeylist
)
4022 *priv_key
= pkeylist
;
4024 sk_EVP_PKEY_pop_free(pkeylist
, EVP_PKEY_free
);
4025 if (certs
&& xcertlist
)
4028 sk_X509_pop_free(xcertlist
, X509_free
);
4029 if (ca
&& cacertlist
)
4031 else if (cacertlist
)
4032 sk_X509_pop_free(cacertlist
, X509_free
);
4041 sslBN2KMFBN(BIGNUM
*from
, KMF_BIGINT
*to
)
4043 KMF_RETURN rv
= KMF_OK
;
4046 sz
= BN_num_bytes(from
);
4047 to
->val
= (uchar_t
*)malloc(sz
);
4048 if (to
->val
== NULL
)
4049 return (KMF_ERR_MEMORY
);
4051 if ((to
->len
= BN_bn2bin(from
, to
->val
)) != sz
) {
4055 rv
= KMF_ERR_MEMORY
;
4062 exportRawRSAKey(RSA
*rsa
, KMF_RAW_KEY_DATA
*key
)
4065 KMF_RAW_RSA_KEY
*kmfkey
= &key
->rawdata
.rsa
;
4067 (void) memset(kmfkey
, 0, sizeof (KMF_RAW_RSA_KEY
));
4068 if ((rv
= sslBN2KMFBN(rsa
->n
, &kmfkey
->mod
)) != KMF_OK
)
4071 if ((rv
= sslBN2KMFBN(rsa
->e
, &kmfkey
->pubexp
)) != KMF_OK
)
4075 if ((rv
= sslBN2KMFBN(rsa
->d
, &kmfkey
->priexp
)) != KMF_OK
)
4079 if ((rv
= sslBN2KMFBN(rsa
->p
, &kmfkey
->prime1
)) != KMF_OK
)
4083 if ((rv
= sslBN2KMFBN(rsa
->q
, &kmfkey
->prime2
)) != KMF_OK
)
4086 if (rsa
->dmp1
!= NULL
)
4087 if ((rv
= sslBN2KMFBN(rsa
->dmp1
, &kmfkey
->exp1
)) != KMF_OK
)
4090 if (rsa
->dmq1
!= NULL
)
4091 if ((rv
= sslBN2KMFBN(rsa
->dmq1
, &kmfkey
->exp2
)) != KMF_OK
)
4094 if (rsa
->iqmp
!= NULL
)
4095 if ((rv
= sslBN2KMFBN(rsa
->iqmp
, &kmfkey
->coef
)) != KMF_OK
)
4099 kmf_free_raw_key(key
);
4101 key
->keytype
= KMF_RSA
;
4104 * Free the reference to this key, SSL will not actually free
4105 * the memory until the refcount == 0, so this is safe.
4113 exportRawDSAKey(DSA
*dsa
, KMF_RAW_KEY_DATA
*key
)
4116 KMF_RAW_DSA_KEY
*kmfkey
= &key
->rawdata
.dsa
;
4118 (void) memset(kmfkey
, 0, sizeof (KMF_RAW_DSA_KEY
));
4119 if ((rv
= sslBN2KMFBN(dsa
->p
, &kmfkey
->prime
)) != KMF_OK
)
4122 if ((rv
= sslBN2KMFBN(dsa
->q
, &kmfkey
->subprime
)) != KMF_OK
)
4125 if ((rv
= sslBN2KMFBN(dsa
->g
, &kmfkey
->base
)) != KMF_OK
)
4128 if ((rv
= sslBN2KMFBN(dsa
->priv_key
, &kmfkey
->value
)) != KMF_OK
)
4133 kmf_free_raw_key(key
);
4135 key
->keytype
= KMF_DSA
;
4138 * Free the reference to this key, SSL will not actually free
4139 * the memory until the refcount == 0, so this is safe.
4147 add_cert_to_list(KMF_HANDLE
*kmfh
, X509
*sslcert
,
4148 KMF_X509_DER_CERT
**certlist
, int *ncerts
)
4150 KMF_RETURN rv
= KMF_OK
;
4151 KMF_X509_DER_CERT
*list
= (*certlist
);
4152 KMF_X509_DER_CERT cert
;
4156 list
= (KMF_X509_DER_CERT
*)malloc(sizeof (KMF_X509_DER_CERT
));
4158 list
= reallocarray(list
, n
+ 1, sizeof (KMF_X509_DER_CERT
));
4162 return (KMF_ERR_MEMORY
);
4164 (void) memset(&cert
, 0, sizeof (cert
));
4165 rv
= ssl_cert2KMFDATA(kmfh
, sslcert
, &cert
.certificate
);
4168 /* Get the alias name for the cert if there is one */
4169 char *a
= (char *)X509_alias_get0(sslcert
, &len
);
4171 cert
.kmf_private
.label
= strdup(a
);
4172 cert
.kmf_private
.keystore_type
= KMF_KEYSTORE_OPENSSL
;
4186 add_key_to_list(KMF_RAW_KEY_DATA
**keylist
,
4187 KMF_RAW_KEY_DATA
*newkey
, int *nkeys
)
4189 KMF_RAW_KEY_DATA
*list
= (*keylist
);
4193 list
= (KMF_RAW_KEY_DATA
*)malloc(sizeof (KMF_RAW_KEY_DATA
));
4195 list
= reallocarray(list
, n
+ 1, sizeof (KMF_RAW_KEY_DATA
));
4199 return (KMF_ERR_MEMORY
);
4209 static X509_ATTRIBUTE
*
4210 find_attr(STACK_OF(X509_ATTRIBUTE
) *attrs
, int nid
)
4218 for (i
= 0; i
< sk_X509_ATTRIBUTE_num(attrs
); i
++) {
4219 /* LINTED E_BAD_PTR_CAST_ALIGN */
4220 a
= sk_X509_ATTRIBUTE_value(attrs
, i
);
4221 if (OBJ_obj2nid(a
->object
) == nid
)
4228 convertToRawKey(EVP_PKEY
*pkey
, KMF_RAW_KEY_DATA
*key
)
4230 KMF_RETURN rv
= KMF_OK
;
4231 X509_ATTRIBUTE
*attr
;
4233 if (pkey
== NULL
|| key
== NULL
)
4234 return (KMF_ERR_BAD_PARAMETER
);
4235 /* Convert SSL key to raw key */
4236 switch (pkey
->type
) {
4238 rv
= exportRawRSAKey(EVP_PKEY_get1_RSA(pkey
),
4244 rv
= exportRawDSAKey(EVP_PKEY_get1_DSA(pkey
),
4250 return (KMF_ERR_BAD_PARAMETER
);
4253 * If friendlyName, add it to record.
4255 attr
= find_attr(pkey
->attributes
, NID_friendlyName
);
4257 ASN1_TYPE
*ty
= NULL
;
4258 int numattr
= sk_ASN1_TYPE_num(attr
->value
.set
);
4259 if (attr
->single
== 0 && numattr
> 0) {
4260 /* LINTED E_BAD_PTR_CAST_ALIGN */
4261 ty
= sk_ASN1_TYPE_value(attr
->value
.set
, 0);
4264 #if OPENSSL_VERSION_NUMBER < 0x10000000L
4265 key
->label
= uni2asc(ty
->value
.bmpstring
->data
,
4266 ty
->value
.bmpstring
->length
);
4268 key
->label
= OPENSSL_uni2asc(ty
->value
.bmpstring
->data
,
4269 ty
->value
.bmpstring
->length
);
4277 * If KeyID, add it to record as a KMF_DATA object.
4279 attr
= find_attr(pkey
->attributes
, NID_localKeyID
);
4281 ASN1_TYPE
*ty
= NULL
;
4282 int numattr
= sk_ASN1_TYPE_num(attr
->value
.set
);
4283 if (attr
->single
== 0 && numattr
> 0) {
4284 /* LINTED E_BAD_PTR_CAST_ALIGN */
4285 ty
= sk_ASN1_TYPE_value(attr
->value
.set
, 0);
4287 key
->id
.Data
= (uchar_t
*)malloc(
4288 ty
->value
.octet_string
->length
);
4289 if (key
->id
.Data
== NULL
)
4290 return (KMF_ERR_MEMORY
);
4291 (void) memcpy(key
->id
.Data
, ty
->value
.octet_string
->data
,
4292 ty
->value
.octet_string
->length
);
4293 key
->id
.Length
= ty
->value
.octet_string
->length
;
4295 (void) memset(&key
->id
, 0, sizeof (KMF_DATA
));
4304 STACK_OF(EVP_PKEY
) *sslkeys
,
4305 STACK_OF(X509
) *sslcert
,
4306 STACK_OF(X509
) *sslcacerts
,
4307 KMF_RAW_KEY_DATA
**keylist
, int *nkeys
,
4308 KMF_X509_DER_CERT
**certlist
, int *ncerts
)
4310 KMF_RETURN rv
= KMF_OK
;
4311 KMF_RAW_KEY_DATA key
;
4314 for (i
= 0; sslkeys
!= NULL
&& i
< sk_EVP_PKEY_num(sslkeys
); i
++) {
4315 /* LINTED E_BAD_PTR_CAST_ALIGN */
4316 EVP_PKEY
*pkey
= sk_EVP_PKEY_value(sslkeys
, i
);
4317 rv
= convertToRawKey(pkey
, &key
);
4319 rv
= add_key_to_list(keylist
, &key
, nkeys
);
4325 /* Now add the certificate to the certlist */
4326 for (i
= 0; sslcert
!= NULL
&& i
< sk_X509_num(sslcert
); i
++) {
4327 /* LINTED E_BAD_PTR_CAST_ALIGN */
4328 X509
*cert
= sk_X509_value(sslcert
, i
);
4329 rv
= add_cert_to_list(kmfh
, cert
, certlist
, ncerts
);
4334 /* Also add any included CA certs to the list */
4335 for (i
= 0; sslcacerts
!= NULL
&& i
< sk_X509_num(sslcacerts
); i
++) {
4338 * sk_X509_value() is macro that embeds a cast to (X509 *).
4339 * Here it translates into ((X509 *)sk_value((ca), (i))).
4340 * Lint is complaining about the embedded casting, and
4341 * to fix it, you need to fix openssl header files.
4343 /* LINTED E_BAD_PTR_CAST_ALIGN */
4344 c
= sk_X509_value(sslcacerts
, i
);
4346 /* Now add the ca cert to the certlist */
4347 rv
= add_cert_to_list(kmfh
, c
, certlist
, ncerts
);
4355 openssl_import_objects(KMF_HANDLE
*kmfh
,
4356 char *filename
, KMF_CREDENTIAL
*cred
,
4357 KMF_X509_DER_CERT
**certlist
, int *ncerts
,
4358 KMF_RAW_KEY_DATA
**keylist
, int *nkeys
)
4360 KMF_RETURN rv
= KMF_OK
;
4361 KMF_ENCODE_FORMAT format
;
4363 STACK_OF(EVP_PKEY
) *privkeys
= NULL
;
4364 STACK_OF(X509
) *certs
= NULL
;
4365 STACK_OF(X509
) *cacerts
= NULL
;
4368 * auto-detect the file format, regardless of what
4369 * the 'format' parameters in the params say.
4371 rv
= kmf_get_file_format(filename
, &format
);
4376 /* This function only works for PEM or PKCS#12 files */
4377 if (format
!= KMF_FORMAT_PEM
&&
4378 format
!= KMF_FORMAT_PEM_KEYPAIR
&&
4379 format
!= KMF_FORMAT_PKCS12
)
4380 return (KMF_ERR_ENCODING
);
4387 if (format
== KMF_FORMAT_PKCS12
) {
4388 bio
= BIO_new_file(filename
, "rb");
4390 SET_ERROR(kmfh
, ERR_get_error());
4391 rv
= KMF_ERR_OPEN_FILE
;
4395 rv
= extract_pkcs12(bio
, (uchar_t
*)cred
->cred
,
4396 (uint32_t)cred
->credlen
, &privkeys
, &certs
, &cacerts
);
4399 /* Convert keys and certs to exportable format */
4400 rv
= convertPK12Objects(kmfh
, privkeys
, certs
, cacerts
,
4401 keylist
, nkeys
, certlist
, ncerts
);
4404 KMF_DATA
*certdata
= NULL
;
4405 KMF_X509_DER_CERT
*kmfcerts
= NULL
;
4407 rv
= extract_pem(kmfh
, NULL
, NULL
, NULL
, filename
,
4408 (uchar_t
*)cred
->cred
, (uint32_t)cred
->credlen
,
4409 &pkey
, &certdata
, ncerts
);
4411 /* Reached end of import file? */
4412 if (rv
== KMF_OK
&& pkey
!= NULL
) {
4413 privkeys
= sk_EVP_PKEY_new_null();
4414 if (privkeys
== NULL
) {
4415 rv
= KMF_ERR_MEMORY
;
4418 (void) sk_EVP_PKEY_push(privkeys
, pkey
);
4419 /* convert the certificate list here */
4420 if (*ncerts
> 0 && certlist
!= NULL
) {
4421 kmfcerts
= (KMF_X509_DER_CERT
*)calloc(*ncerts
,
4422 sizeof (KMF_X509_DER_CERT
));
4423 if (kmfcerts
== NULL
) {
4424 rv
= KMF_ERR_MEMORY
;
4427 for (i
= 0; i
< *ncerts
; i
++) {
4428 kmfcerts
[i
].certificate
= certdata
[i
];
4429 kmfcerts
[i
].kmf_private
.keystore_type
=
4430 KMF_KEYSTORE_OPENSSL
;
4432 *certlist
= kmfcerts
;
4435 * Convert keys to exportable format, the certs
4438 rv
= convertPK12Objects(kmfh
, privkeys
, NULL
, NULL
,
4439 keylist
, nkeys
, NULL
, NULL
);
4444 (void) BIO_free(bio
);
4447 sk_EVP_PKEY_pop_free(privkeys
, EVP_PKEY_free
);
4449 sk_X509_pop_free(certs
, X509_free
);
4451 sk_X509_pop_free(cacerts
, X509_free
);
4457 create_deskey(DES_cblock
**deskey
)
4461 key
= (DES_cblock
*) malloc(sizeof (DES_cblock
));
4463 return (KMF_ERR_MEMORY
);
4466 if (DES_random_key(key
) == 0) {
4468 return (KMF_ERR_KEYGEN_FAILED
);
4475 #define KEYGEN_RETRY 3
4476 #define DES3_KEY_SIZE 24
4479 create_des3key(unsigned char **des3key
)
4481 KMF_RETURN ret
= KMF_OK
;
4482 DES_cblock
*deskey1
= NULL
;
4483 DES_cblock
*deskey2
= NULL
;
4484 DES_cblock
*deskey3
= NULL
;
4485 unsigned char *newkey
= NULL
;
4488 if ((newkey
= malloc(DES3_KEY_SIZE
)) == NULL
) {
4489 return (KMF_ERR_MEMORY
);
4492 /* create the 1st DES key */
4493 if ((ret
= create_deskey(&deskey1
)) != KMF_OK
) {
4498 * Create the 2nd DES key and make sure its value is different
4499 * from the 1st DES key.
4503 if (deskey2
!= NULL
) {
4508 if ((ret
= create_deskey(&deskey2
)) != KMF_OK
) {
4512 if (memcmp((const void *) deskey1
, (const void *) deskey2
, 8)
4514 ret
= KMF_ERR_KEYGEN_FAILED
;
4517 } while (ret
== KMF_ERR_KEYGEN_FAILED
&& retry
< KEYGEN_RETRY
);
4519 if (ret
!= KMF_OK
) {
4524 * Create the 3rd DES key and make sure its value is different
4525 * from the 2nd DES key.
4529 if (deskey3
!= NULL
) {
4534 if ((ret
= create_deskey(&deskey3
)) != KMF_OK
) {
4538 if (memcmp((const void *)deskey2
, (const void *)deskey3
, 8)
4540 ret
= KMF_ERR_KEYGEN_FAILED
;
4543 } while (ret
== KMF_ERR_KEYGEN_FAILED
&& retry
< KEYGEN_RETRY
);
4545 if (ret
!= KMF_OK
) {
4549 /* Concatenate 3 DES keys into a DES3 key */
4550 (void) memcpy((void *)newkey
, (const void *)deskey1
, 8);
4551 (void) memcpy((void *)(newkey
+ 8), (const void *)deskey2
, 8);
4552 (void) memcpy((void *)(newkey
+ 16), (const void *)deskey3
, 8);
4569 OpenSSL_CreateSymKey(KMF_HANDLE_T handle
,
4570 int numattr
, KMF_ATTRIBUTE
*attrlist
)
4572 KMF_RETURN ret
= KMF_OK
;
4573 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
4574 char *fullpath
= NULL
;
4575 KMF_RAW_SYM_KEY
*rkey
= NULL
;
4576 DES_cblock
*deskey
= NULL
;
4577 unsigned char *des3key
= NULL
;
4578 unsigned char *random
= NULL
;
4580 KMF_KEY_HANDLE
*symkey
;
4581 KMF_KEY_ALG keytype
;
4583 uint32_t keylen_size
= sizeof (keylen
);
4588 return (KMF_ERR_UNINITIALIZED
);
4590 symkey
= kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR
, attrlist
, numattr
);
4592 return (KMF_ERR_BAD_PARAMETER
);
4594 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
4596 keyfile
= kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
, attrlist
, numattr
);
4597 if (keyfile
== NULL
)
4598 return (KMF_ERR_BAD_PARAMETER
);
4600 ret
= kmf_get_attr(KMF_KEYALG_ATTR
, attrlist
, numattr
,
4601 (void *)&keytype
, NULL
);
4603 return (KMF_ERR_BAD_PARAMETER
);
4605 ret
= kmf_get_attr(KMF_KEYLENGTH_ATTR
, attrlist
, numattr
,
4606 &keylen
, &keylen_size
);
4607 if (ret
== KMF_ERR_ATTR_NOT_FOUND
&&
4608 (keytype
== KMF_DES
|| keytype
== KMF_DES3
))
4609 /* keylength is not required for DES and 3DES */
4612 return (KMF_ERR_BAD_PARAMETER
);
4614 fullpath
= get_fullpath(dirpath
, keyfile
);
4615 if (fullpath
== NULL
)
4616 return (KMF_ERR_BAD_PARAMETER
);
4618 /* If the requested file exists, return an error */
4619 if (test_for_file(fullpath
, 0400) == 1) {
4621 return (KMF_ERR_DUPLICATE_KEYFILE
);
4624 fd
= open(fullpath
, O_CREAT
|O_TRUNC
|O_RDWR
, 0400);
4626 ret
= KMF_ERR_OPEN_FILE
;
4630 rkey
= malloc(sizeof (KMF_RAW_SYM_KEY
));
4632 ret
= KMF_ERR_MEMORY
;
4635 (void) memset(rkey
, 0, sizeof (KMF_RAW_SYM_KEY
));
4637 if (keytype
== KMF_DES
) {
4638 if ((ret
= create_deskey(&deskey
)) != KMF_OK
) {
4641 rkey
->keydata
.val
= (uchar_t
*)deskey
;
4642 rkey
->keydata
.len
= 8;
4644 symkey
->keyalg
= KMF_DES
;
4646 } else if (keytype
== KMF_DES3
) {
4647 if ((ret
= create_des3key(&des3key
)) != KMF_OK
) {
4650 rkey
->keydata
.val
= (uchar_t
*)des3key
;
4651 rkey
->keydata
.len
= DES3_KEY_SIZE
;
4652 symkey
->keyalg
= KMF_DES3
;
4654 } else if (keytype
== KMF_AES
|| keytype
== KMF_RC4
||
4655 keytype
== KMF_GENERIC_SECRET
) {
4658 if (keylen
% 8 != 0) {
4659 ret
= KMF_ERR_BAD_KEY_SIZE
;
4663 if (keytype
== KMF_AES
) {
4664 if (keylen
!= 128 &&
4667 ret
= KMF_ERR_BAD_KEY_SIZE
;
4673 random
= malloc(bytes
);
4674 if (random
== NULL
) {
4675 ret
= KMF_ERR_MEMORY
;
4678 if (RAND_bytes(random
, bytes
) != 1) {
4679 ret
= KMF_ERR_KEYGEN_FAILED
;
4683 rkey
->keydata
.val
= (uchar_t
*)random
;
4684 rkey
->keydata
.len
= bytes
;
4685 symkey
->keyalg
= keytype
;
4688 ret
= KMF_ERR_BAD_KEY_TYPE
;
4692 (void) write(fd
, (const void *) rkey
->keydata
.val
, rkey
->keydata
.len
);
4694 symkey
->kstype
= KMF_KEYSTORE_OPENSSL
;
4695 symkey
->keyclass
= KMF_SYMMETRIC
;
4696 symkey
->keylabel
= (char *)fullpath
;
4697 symkey
->israw
= TRUE
;
4698 symkey
->keyp
= rkey
;
4704 if (ret
!= KMF_OK
&& fullpath
!= NULL
) {
4707 if (ret
!= KMF_OK
) {
4708 kmf_free_raw_sym_key(rkey
);
4709 symkey
->keyp
= NULL
;
4710 symkey
->keyalg
= KMF_KEYALG_NONE
;
4717 * Check a file to see if it is a CRL file with PEM or DER format.
4718 * If success, return its format in the "pformat" argument.
4721 OpenSSL_IsCRLFile(KMF_HANDLE_T handle
, char *filename
, int *pformat
)
4723 KMF_RETURN ret
= KMF_OK
;
4724 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
4726 X509_CRL
*xcrl
= NULL
;
4728 if (filename
== NULL
) {
4729 return (KMF_ERR_BAD_PARAMETER
);
4732 bio
= BIO_new_file(filename
, "rb");
4734 SET_ERROR(kmfh
, ERR_get_error());
4735 ret
= KMF_ERR_OPEN_FILE
;
4739 if ((xcrl
= PEM_read_bio_X509_CRL(bio
, NULL
, NULL
, NULL
)) != NULL
) {
4740 *pformat
= KMF_FORMAT_PEM
;
4743 (void) BIO_free(bio
);
4746 * Now try to read it as raw DER data.
4748 bio
= BIO_new_file(filename
, "rb");
4750 SET_ERROR(kmfh
, ERR_get_error());
4751 ret
= KMF_ERR_OPEN_FILE
;
4755 if ((xcrl
= d2i_X509_CRL_bio(bio
, NULL
)) != NULL
) {
4756 *pformat
= KMF_FORMAT_ASN1
;
4758 ret
= KMF_ERR_BAD_CRLFILE
;
4763 (void) BIO_free(bio
);
4766 X509_CRL_free(xcrl
);
4772 OpenSSL_GetSymKeyValue(KMF_HANDLE_T handle
, KMF_KEY_HANDLE
*symkey
,
4773 KMF_RAW_SYM_KEY
*rkey
)
4775 KMF_RETURN rv
= KMF_OK
;
4776 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
4780 return (KMF_ERR_UNINITIALIZED
);
4782 if (symkey
== NULL
|| rkey
== NULL
)
4783 return (KMF_ERR_BAD_PARAMETER
);
4784 else if (symkey
->keyclass
!= KMF_SYMMETRIC
)
4785 return (KMF_ERR_BAD_KEY_CLASS
);
4787 if (symkey
->israw
) {
4788 KMF_RAW_SYM_KEY
*rawkey
= (KMF_RAW_SYM_KEY
*)symkey
->keyp
;
4790 if (rawkey
== NULL
||
4791 rawkey
->keydata
.val
== NULL
||
4792 rawkey
->keydata
.len
== 0)
4793 return (KMF_ERR_BAD_KEYHANDLE
);
4795 rkey
->keydata
.len
= rawkey
->keydata
.len
;
4796 if ((rkey
->keydata
.val
= malloc(rkey
->keydata
.len
)) == NULL
)
4797 return (KMF_ERR_MEMORY
);
4798 (void) memcpy(rkey
->keydata
.val
, rawkey
->keydata
.val
,
4801 rv
= kmf_read_input_file(handle
, symkey
->keylabel
, &keyvalue
);
4804 rkey
->keydata
.len
= keyvalue
.Length
;
4805 rkey
->keydata
.val
= keyvalue
.Data
;
4812 * substitute for the unsafe access(2) function.
4813 * If the file in question already exists, return 1.
4814 * else 0. If an error occurs during testing (other
4815 * than EEXIST), return -1.
4818 test_for_file(char *filename
, mode_t mode
)
4823 * Try to create the file with the EXCL flag.
4824 * The call should fail if the file exists.
4826 fd
= open(filename
, O_WRONLY
|O_CREAT
|O_EXCL
, mode
);
4827 if (fd
== -1 && errno
== EEXIST
)
4829 else if (fd
== -1) /* some other error */
4832 /* The file did NOT exist. Delete the testcase. */
4834 (void) unlink(filename
);
4839 OpenSSL_StoreKey(KMF_HANDLE_T handle
, int numattr
,
4840 KMF_ATTRIBUTE
*attrlist
)
4842 KMF_RETURN rv
= KMF_OK
;
4843 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
4844 KMF_KEY_HANDLE
*pubkey
= NULL
, *prikey
= NULL
;
4845 KMF_RAW_KEY_DATA
*rawkey
;
4846 EVP_PKEY
*pkey
= NULL
;
4847 KMF_ENCODE_FORMAT format
= KMF_FORMAT_PEM
;
4848 KMF_CREDENTIAL cred
= { NULL
, 0 };
4851 char *fullpath
= NULL
;
4852 char *keyfile
= NULL
;
4853 char *dirpath
= NULL
;
4855 pubkey
= kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR
, attrlist
, numattr
);
4859 prikey
= kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR
, attrlist
, numattr
);
4863 rawkey
= kmf_get_attr_ptr(KMF_RAW_KEY_ATTR
, attrlist
, numattr
);
4868 * Exactly 1 type of key must be passed to this function.
4871 return (KMF_ERR_BAD_PARAMETER
);
4873 keyfile
= (char *)kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
, attrlist
,
4875 if (keyfile
== NULL
)
4876 return (KMF_ERR_BAD_PARAMETER
);
4878 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
4880 fullpath
= get_fullpath(dirpath
, keyfile
);
4882 /* Once we have the full path, we don't need the pieces */
4883 if (fullpath
== NULL
)
4884 return (KMF_ERR_BAD_PARAMETER
);
4886 /* If the requested file exists, return an error */
4887 if (test_for_file(fullpath
, 0400) == 1) {
4889 return (KMF_ERR_DUPLICATE_KEYFILE
);
4892 rv
= kmf_get_attr(KMF_ENCODE_FORMAT_ATTR
, attrlist
, numattr
,
4895 /* format is optional. */
4898 /* CRED is not required for OpenSSL files */
4899 (void) kmf_get_attr(KMF_CREDENTIAL_ATTR
, attrlist
, numattr
,
4902 /* Store the private key to the keyfile */
4903 out
= BIO_new_file(fullpath
, "wb");
4905 SET_ERROR(kmfh
, ERR_get_error());
4906 rv
= KMF_ERR_OPEN_FILE
;
4910 if (prikey
!= NULL
&& prikey
->keyp
!= NULL
) {
4911 if (prikey
->keyalg
== KMF_RSA
||
4912 prikey
->keyalg
== KMF_DSA
) {
4913 pkey
= (EVP_PKEY
*)prikey
->keyp
;
4915 rv
= ssl_write_key(kmfh
, format
,
4916 out
, &cred
, pkey
, TRUE
);
4918 if (rv
== KMF_OK
&& prikey
->keylabel
== NULL
) {
4919 prikey
->keylabel
= strdup(fullpath
);
4920 if (prikey
->keylabel
== NULL
)
4921 rv
= KMF_ERR_MEMORY
;
4924 } else if (pubkey
!= NULL
&& pubkey
->keyp
!= NULL
) {
4925 if (pubkey
->keyalg
== KMF_RSA
||
4926 pubkey
->keyalg
== KMF_DSA
) {
4927 pkey
= (EVP_PKEY
*)pubkey
->keyp
;
4929 rv
= ssl_write_key(kmfh
, format
,
4930 out
, &cred
, pkey
, FALSE
);
4932 if (rv
== KMF_OK
&& pubkey
->keylabel
== NULL
) {
4933 pubkey
->keylabel
= strdup(fullpath
);
4934 if (pubkey
->keylabel
== NULL
)
4935 rv
= KMF_ERR_MEMORY
;
4938 } else if (rawkey
!= NULL
) {
4939 if (rawkey
->keytype
== KMF_RSA
) {
4940 pkey
= ImportRawRSAKey(&rawkey
->rawdata
.rsa
);
4941 } else if (rawkey
->keytype
== KMF_DSA
) {
4942 pkey
= ImportRawDSAKey(&rawkey
->rawdata
.dsa
);
4944 rv
= KMF_ERR_BAD_PARAMETER
;
4947 KMF_KEY_CLASS kclass
= KMF_ASYM_PRI
;
4949 rv
= kmf_get_attr(KMF_KEYCLASS_ATTR
, attrlist
, numattr
,
4950 (void *)&kclass
, NULL
);
4953 rv
= ssl_write_key(kmfh
, format
, out
,
4954 &cred
, pkey
, (kclass
== KMF_ASYM_PRI
));
4955 EVP_PKEY_free(pkey
);
4962 (void) BIO_free(out
);
4966 (void) chmod(fullpath
, 0400);
4973 OpenSSL_ImportCRL(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
4975 KMF_RETURN ret
= KMF_OK
;
4976 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
4977 X509_CRL
*xcrl
= NULL
;
4980 KMF_ENCODE_FORMAT format
;
4981 BIO
*in
= NULL
, *out
= NULL
;
4982 int openssl_ret
= 0;
4983 KMF_ENCODE_FORMAT outformat
;
4984 boolean_t crlcheck
= FALSE
;
4985 char *certfile
, *dirpath
, *crlfile
, *incrl
, *outcrl
, *outcrlfile
;
4987 if (numattr
== 0 || attrlist
== NULL
) {
4988 return (KMF_ERR_BAD_PARAMETER
);
4991 /* CRL check is optional */
4992 (void) kmf_get_attr(KMF_CRL_CHECK_ATTR
, attrlist
, numattr
,
4995 certfile
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
, numattr
);
4996 if (crlcheck
== B_TRUE
&& certfile
== NULL
) {
4997 return (KMF_ERR_BAD_CERTFILE
);
5000 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
5001 incrl
= kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR
, attrlist
, numattr
);
5002 outcrl
= kmf_get_attr_ptr(KMF_CRL_OUTFILE_ATTR
, attrlist
, numattr
);
5004 crlfile
= get_fullpath(dirpath
, incrl
);
5006 if (crlfile
== NULL
)
5007 return (KMF_ERR_BAD_CRLFILE
);
5009 outcrlfile
= get_fullpath(dirpath
, outcrl
);
5010 if (outcrlfile
== NULL
)
5011 return (KMF_ERR_BAD_CRLFILE
);
5013 if (isdir(outcrlfile
)) {
5015 return (KMF_ERR_BAD_CRLFILE
);
5018 ret
= kmf_is_crl_file(handle
, crlfile
, &format
);
5019 if (ret
!= KMF_OK
) {
5024 in
= BIO_new_file(crlfile
, "rb");
5026 SET_ERROR(kmfh
, ERR_get_error());
5027 ret
= KMF_ERR_OPEN_FILE
;
5031 if (format
== KMF_FORMAT_ASN1
) {
5032 xcrl
= d2i_X509_CRL_bio(in
, NULL
);
5033 } else if (format
== KMF_FORMAT_PEM
) {
5034 xcrl
= PEM_read_bio_X509_CRL(in
, NULL
, NULL
, NULL
);
5038 SET_ERROR(kmfh
, ERR_get_error());
5039 ret
= KMF_ERR_BAD_CRLFILE
;
5043 /* If bypasscheck is specified, no need to verify. */
5044 if (crlcheck
== B_FALSE
)
5047 ret
= kmf_is_cert_file(handle
, certfile
, &format
);
5051 /* Read in the CA cert file and convert to X509 */
5052 if (BIO_read_filename(in
, certfile
) <= 0) {
5053 SET_ERROR(kmfh
, ERR_get_error());
5054 ret
= KMF_ERR_OPEN_FILE
;
5058 if (format
== KMF_FORMAT_ASN1
) {
5059 xcert
= d2i_X509_bio(in
, NULL
);
5060 } else if (format
== KMF_FORMAT_PEM
) {
5061 xcert
= PEM_read_bio_X509(in
, NULL
, NULL
, NULL
);
5063 ret
= KMF_ERR_BAD_CERT_FORMAT
;
5067 if (xcert
== NULL
) {
5068 SET_ERROR(kmfh
, ERR_get_error());
5069 ret
= KMF_ERR_BAD_CERT_FORMAT
;
5072 /* Now get the public key from the CA cert */
5073 pkey
= X509_get_pubkey(xcert
);
5075 SET_ERROR(kmfh
, ERR_get_error());
5076 ret
= KMF_ERR_BAD_CERTFILE
;
5080 /* Verify the CRL with the CA's public key */
5081 openssl_ret
= X509_CRL_verify(xcrl
, pkey
);
5082 EVP_PKEY_free(pkey
);
5083 if (openssl_ret
> 0) {
5084 ret
= KMF_OK
; /* verify succeed */
5086 SET_ERROR(kmfh
, openssl_ret
);
5087 ret
= KMF_ERR_BAD_CRLFILE
;
5091 ret
= kmf_get_attr(KMF_ENCODE_FORMAT_ATTR
, attrlist
, numattr
,
5093 if (ret
!= KMF_OK
) {
5095 outformat
= KMF_FORMAT_PEM
;
5098 out
= BIO_new_file(outcrlfile
, "wb");
5100 SET_ERROR(kmfh
, ERR_get_error());
5101 ret
= KMF_ERR_OPEN_FILE
;
5105 if (outformat
== KMF_FORMAT_ASN1
) {
5106 openssl_ret
= (int)i2d_X509_CRL_bio(out
, xcrl
);
5107 } else if (outformat
== KMF_FORMAT_PEM
) {
5108 openssl_ret
= PEM_write_bio_X509_CRL(out
, xcrl
);
5110 ret
= KMF_ERR_BAD_PARAMETER
;
5114 if (openssl_ret
<= 0) {
5115 SET_ERROR(kmfh
, ERR_get_error());
5116 ret
= KMF_ERR_WRITE_FILE
;
5123 X509_CRL_free(xcrl
);
5129 (void) BIO_free(in
);
5132 (void) BIO_free(out
);
5140 OpenSSL_ListCRL(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
5142 KMF_RETURN ret
= KMF_OK
;
5143 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
5145 KMF_ENCODE_FORMAT format
;
5146 char *crlfile
= NULL
;
5153 char *crlfilename
, *dirpath
;
5155 if (numattr
== 0 || attrlist
== NULL
) {
5156 return (KMF_ERR_BAD_PARAMETER
);
5158 crlfilename
= kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR
,
5160 if (crlfilename
== NULL
)
5161 return (KMF_ERR_BAD_CRLFILE
);
5163 crldata
= (char **)kmf_get_attr_ptr(KMF_CRL_DATA_ATTR
,
5166 if (crldata
== NULL
)
5167 return (KMF_ERR_BAD_PARAMETER
);
5169 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
5171 crlfile
= get_fullpath(dirpath
, crlfilename
);
5173 if (crlfile
== NULL
)
5174 return (KMF_ERR_BAD_CRLFILE
);
5176 if (isdir(crlfile
)) {
5178 return (KMF_ERR_BAD_CRLFILE
);
5181 ret
= kmf_is_crl_file(handle
, crlfile
, &format
);
5182 if (ret
!= KMF_OK
) {
5187 if (bio_err
== NULL
)
5188 bio_err
= BIO_new_fp(stderr
, BIO_NOCLOSE
);
5190 in
= BIO_new_file(crlfile
, "rb");
5192 SET_ERROR(kmfh
, ERR_get_error());
5193 ret
= KMF_ERR_OPEN_FILE
;
5197 if (format
== KMF_FORMAT_ASN1
) {
5198 x
= d2i_X509_CRL_bio(in
, NULL
);
5199 } else if (format
== KMF_FORMAT_PEM
) {
5200 x
= PEM_read_bio_X509_CRL(in
, NULL
, NULL
, NULL
);
5203 if (x
== NULL
) { /* should not happen */
5204 SET_ERROR(kmfh
, ERR_get_error());
5205 ret
= KMF_ERR_OPEN_FILE
;
5209 mem
= BIO_new(BIO_s_mem());
5211 SET_ERROR(kmfh
, ERR_get_error());
5212 ret
= KMF_ERR_MEMORY
;
5216 (void) X509_CRL_print(mem
, x
);
5217 len
= BIO_get_mem_data(mem
, &memptr
);
5219 SET_ERROR(kmfh
, ERR_get_error());
5220 ret
= KMF_ERR_MEMORY
;
5224 data
= malloc(len
+ 1);
5226 ret
= KMF_ERR_MEMORY
;
5230 (void) memcpy(data
, memptr
, len
);
5241 (void) BIO_free(in
);
5244 (void) BIO_free(mem
);
5250 OpenSSL_DeleteCRL(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
5252 KMF_RETURN ret
= KMF_OK
;
5253 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
5254 KMF_ENCODE_FORMAT format
;
5255 char *crlfile
= NULL
;
5257 char *crlfilename
, *dirpath
;
5259 if (numattr
== 0 || attrlist
== NULL
) {
5260 return (KMF_ERR_BAD_PARAMETER
);
5263 crlfilename
= kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR
,
5266 if (crlfilename
== NULL
)
5267 return (KMF_ERR_BAD_CRLFILE
);
5269 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
5271 crlfile
= get_fullpath(dirpath
, crlfilename
);
5273 if (crlfile
== NULL
)
5274 return (KMF_ERR_BAD_CRLFILE
);
5276 if (isdir(crlfile
)) {
5277 ret
= KMF_ERR_BAD_CRLFILE
;
5281 ret
= kmf_is_crl_file(handle
, crlfile
, &format
);
5285 if (unlink(crlfile
) != 0) {
5286 SET_SYS_ERROR(kmfh
, errno
);
5287 ret
= KMF_ERR_INTERNAL
;
5293 (void) BIO_free(in
);
5300 OpenSSL_FindCertInCRL(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
5302 KMF_RETURN ret
= KMF_OK
;
5303 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
5304 KMF_ENCODE_FORMAT format
;
5307 X509_CRL
*xcrl
= NULL
;
5308 STACK_OF(X509_REVOKED
) *revoke_stack
= NULL
;
5309 X509_REVOKED
*revoke
;
5311 char *crlfilename
, *crlfile
, *dirpath
, *certfile
;
5313 if (numattr
== 0 || attrlist
== NULL
) {
5314 return (KMF_ERR_BAD_PARAMETER
);
5317 crlfilename
= kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR
,
5320 if (crlfilename
== NULL
)
5321 return (KMF_ERR_BAD_CRLFILE
);
5323 certfile
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
, numattr
);
5324 if (certfile
== NULL
)
5325 return (KMF_ERR_BAD_CRLFILE
);
5327 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
5329 crlfile
= get_fullpath(dirpath
, crlfilename
);
5331 if (crlfile
== NULL
)
5332 return (KMF_ERR_BAD_CRLFILE
);
5334 if (isdir(crlfile
)) {
5335 ret
= KMF_ERR_BAD_CRLFILE
;
5339 ret
= kmf_is_crl_file(handle
, crlfile
, &format
);
5343 /* Read the CRL file and load it into a X509_CRL structure */
5344 in
= BIO_new_file(crlfilename
, "rb");
5346 SET_ERROR(kmfh
, ERR_get_error());
5347 ret
= KMF_ERR_OPEN_FILE
;
5351 if (format
== KMF_FORMAT_ASN1
) {
5352 xcrl
= d2i_X509_CRL_bio(in
, NULL
);
5353 } else if (format
== KMF_FORMAT_PEM
) {
5354 xcrl
= PEM_read_bio_X509_CRL(in
, NULL
, NULL
, NULL
);
5358 SET_ERROR(kmfh
, ERR_get_error());
5359 ret
= KMF_ERR_BAD_CRLFILE
;
5362 (void) BIO_free(in
);
5364 /* Read the Certificate file and load it into a X509 structure */
5365 ret
= kmf_is_cert_file(handle
, certfile
, &format
);
5369 in
= BIO_new_file(certfile
, "rb");
5371 SET_ERROR(kmfh
, ERR_get_error());
5372 ret
= KMF_ERR_OPEN_FILE
;
5376 if (format
== KMF_FORMAT_ASN1
) {
5377 xcert
= d2i_X509_bio(in
, NULL
);
5378 } else if (format
== KMF_FORMAT_PEM
) {
5379 xcert
= PEM_read_bio_X509(in
, NULL
, NULL
, NULL
);
5382 if (xcert
== NULL
) {
5383 SET_ERROR(kmfh
, ERR_get_error());
5384 ret
= KMF_ERR_BAD_CERTFILE
;
5388 /* Check if the certificate and the CRL have same issuer */
5389 if (X509_NAME_cmp(xcert
->cert_info
->issuer
, xcrl
->crl
->issuer
) != 0) {
5390 ret
= KMF_ERR_ISSUER
;
5394 /* Check to see if the certificate serial number is revoked */
5395 revoke_stack
= X509_CRL_get_REVOKED(xcrl
);
5396 if (sk_X509_REVOKED_num(revoke_stack
) <= 0) {
5397 /* No revoked certificates in the CRL file */
5398 SET_ERROR(kmfh
, ERR_get_error());
5399 ret
= KMF_ERR_EMPTY_CRL
;
5403 for (i
= 0; i
< sk_X509_REVOKED_num(revoke_stack
); i
++) {
5404 /* LINTED E_BAD_PTR_CAST_ALIGN */
5405 revoke
= sk_X509_REVOKED_value(revoke_stack
, i
);
5406 if (ASN1_INTEGER_cmp(xcert
->cert_info
->serialNumber
,
5407 revoke
->serialNumber
) == 0) {
5412 if (i
< sk_X509_REVOKED_num(revoke_stack
)) {
5415 ret
= KMF_ERR_NOT_REVOKED
;
5420 (void) BIO_free(in
);
5422 X509_CRL_free(xcrl
);
5430 OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle
, char *crlname
, KMF_DATA
*tacert
)
5432 KMF_RETURN ret
= KMF_OK
;
5433 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
5435 X509_CRL
*xcrl
= NULL
;
5439 KMF_ENCODE_FORMAT crl_format
;
5443 if (handle
== NULL
|| crlname
== NULL
|| tacert
== NULL
) {
5444 return (KMF_ERR_BAD_PARAMETER
);
5447 ret
= kmf_get_file_format(crlname
, &crl_format
);
5451 bcrl
= BIO_new_file(crlname
, "rb");
5453 SET_ERROR(kmfh
, ERR_get_error());
5454 ret
= KMF_ERR_OPEN_FILE
;
5458 if (crl_format
== KMF_FORMAT_ASN1
) {
5459 xcrl
= d2i_X509_CRL_bio(bcrl
, NULL
);
5460 } else if (crl_format
== KMF_FORMAT_PEM
) {
5461 xcrl
= PEM_read_bio_X509_CRL(bcrl
, NULL
, NULL
, NULL
);
5463 ret
= KMF_ERR_BAD_PARAMETER
;
5468 SET_ERROR(kmfh
, ERR_get_error());
5469 ret
= KMF_ERR_BAD_CRLFILE
;
5474 len
= tacert
->Length
;
5475 xcert
= d2i_X509(NULL
, (const uchar_t
**)&p
, len
);
5477 if (xcert
== NULL
) {
5478 SET_ERROR(kmfh
, ERR_get_error());
5479 ret
= KMF_ERR_BAD_CERTFILE
;
5483 /* Get issuer certificate public key */
5484 pkey
= X509_get_pubkey(xcert
);
5486 SET_ERROR(kmfh
, ERR_get_error());
5487 ret
= KMF_ERR_BAD_CERT_FORMAT
;
5491 /* Verify CRL signature */
5492 sslret
= X509_CRL_verify(xcrl
, pkey
);
5493 EVP_PKEY_free(pkey
);
5497 SET_ERROR(kmfh
, sslret
);
5498 ret
= KMF_ERR_BAD_CRLFILE
;
5503 (void) BIO_free(bcrl
);
5506 X509_CRL_free(xcrl
);
5516 OpenSSL_CheckCRLDate(KMF_HANDLE_T handle
, char *crlname
)
5518 KMF_RETURN ret
= KMF_OK
;
5519 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
5520 KMF_ENCODE_FORMAT crl_format
;
5522 X509_CRL
*xcrl
= NULL
;
5525 if (handle
== NULL
|| crlname
== NULL
) {
5526 return (KMF_ERR_BAD_PARAMETER
);
5529 ret
= kmf_is_crl_file(handle
, crlname
, &crl_format
);
5533 bcrl
= BIO_new_file(crlname
, "rb");
5535 SET_ERROR(kmfh
, ERR_get_error());
5536 ret
= KMF_ERR_OPEN_FILE
;
5540 if (crl_format
== KMF_FORMAT_ASN1
)
5541 xcrl
= d2i_X509_CRL_bio(bcrl
, NULL
);
5542 else if (crl_format
== KMF_FORMAT_PEM
)
5543 xcrl
= PEM_read_bio_X509_CRL(bcrl
, NULL
, NULL
, NULL
);
5546 SET_ERROR(kmfh
, ERR_get_error());
5547 ret
= KMF_ERR_BAD_CRLFILE
;
5550 i
= X509_cmp_time(X509_CRL_get_lastUpdate(xcrl
), NULL
);
5552 ret
= KMF_ERR_VALIDITY_PERIOD
;
5555 if (X509_CRL_get_nextUpdate(xcrl
)) {
5556 i
= X509_cmp_time(X509_CRL_get_nextUpdate(xcrl
), NULL
);
5559 ret
= KMF_ERR_VALIDITY_PERIOD
;
5568 (void) BIO_free(bcrl
);
5571 X509_CRL_free(xcrl
);