2 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
4 * Use is subject to license terms.
7 * Copyright (c) 2012, OmniTI Computer Consulting, Inc. All rights reserved.
10 * Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
14 * ====================================================================
15 * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved.
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
21 * 1. Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
24 * 2. Redistributions in binary form must reproduce the above copyright
25 * notice, this list of conditions and the following disclaimer in
26 * the documentation and/or other materials provided with the
29 * 3. All advertising materials mentioning features or use of this
30 * software must display the following acknowledgment:
31 * "This product includes software developed by the OpenSSL Project
32 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
34 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
35 * endorse or promote products derived from this software without
36 * prior written permission. For written permission, please contact
37 * licensing@OpenSSL.org.
39 * 5. Products derived from this software may not be called "OpenSSL"
40 * nor may "OpenSSL" appear in their names without prior written
41 * permission of the OpenSSL Project.
43 * 6. Redistributions of any form whatsoever must retain the following
45 * "This product includes software developed by the OpenSSL Project
46 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
48 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
49 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
51 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
52 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
53 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
54 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
55 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
57 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
58 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
59 * OF THE POSSIBILITY OF SUCH DAMAGE.
60 * ====================================================================
62 * This product includes cryptographic software written by Eric Young
63 * (eay@cryptsoft.com). This product includes software written by Tim
64 * Hudson (tjh@cryptsoft.com).
74 #include <cryptoutil.h>
78 /* OPENSSL related headers */
79 #include <openssl/bio.h>
80 #include <openssl/bn.h>
81 #include <openssl/asn1.h>
82 #include <openssl/err.h>
83 #include <openssl/bn.h>
84 #include <openssl/x509.h>
85 #include <openssl/rsa.h>
86 #include <openssl/dsa.h>
87 #include <openssl/x509v3.h>
88 #include <openssl/objects.h>
89 #include <openssl/pem.h>
90 #include <openssl/pkcs12.h>
91 #include <openssl/ocsp.h>
92 #include <openssl/des.h>
93 #include <openssl/rand.h>
95 #define PRINT_ANY_EXTENSION (\
96 KMF_X509_EXT_KEY_USAGE |\
97 KMF_X509_EXT_CERT_POLICIES |\
98 KMF_X509_EXT_SUBJALTNAME |\
99 KMF_X509_EXT_BASIC_CONSTRAINTS |\
100 KMF_X509_EXT_NAME_CONSTRAINTS |\
101 KMF_X509_EXT_POLICY_CONSTRAINTS |\
102 KMF_X509_EXT_EXT_KEY_USAGE |\
103 KMF_X509_EXT_INHIBIT_ANY_POLICY |\
104 KMF_X509_EXT_AUTH_KEY_ID |\
105 KMF_X509_EXT_SUBJ_KEY_ID |\
106 KMF_X509_EXT_POLICY_MAPPING)
108 static uchar_t P
[] = { 0x00, 0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76,
109 0xaa, 0x3d, 0x25, 0x75, 0x9b, 0xb0, 0x68, 0x69,
110 0xcb, 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d, 0x0c,
111 0xf7, 0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82,
112 0xe5, 0xd0, 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e,
113 0xaf, 0xc2, 0xe9, 0xad, 0xac, 0x32, 0xab, 0x7a,
114 0xac, 0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24,
115 0xc2, 0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02,
118 static uchar_t Q
[] = { 0x00, 0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8,
119 0xee, 0x99, 0x3b, 0x4f, 0x2d, 0xed, 0x30, 0xf4,
120 0x8e, 0xda, 0xce, 0x91, 0x5f };
122 static uchar_t G
[] = { 0x00, 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a,
123 0x13, 0x41, 0x31, 0x63, 0xa5, 0x5b, 0x4c, 0xb5,
124 0x00, 0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c, 0xef,
125 0xcb, 0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c,
126 0x2e, 0x71, 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba,
127 0xbf, 0x58, 0xe5, 0xb7, 0x95, 0x21, 0x92, 0x5c,
128 0x9c, 0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08,
129 0x8c, 0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88,
132 #define SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_OPENSSL; \
133 h->lasterr.errcode = c;
135 #define SET_SYS_ERROR(h, c) h->lasterr.kstype = -1; h->lasterr.errcode = c;
138 * Declare some new macros for managing stacks of EVP_PKEYS, similar to
141 DECLARE_STACK_OF(EVP_PKEY
)
143 #define sk_EVP_PKEY_new_null() SKM_sk_new_null(EVP_PKEY)
144 #define sk_EVP_PKEY_free(st) SKM_sk_free(EVP_PKEY, (st))
145 #define sk_EVP_PKEY_num(st) SKM_sk_num(EVP_PKEY, (st))
146 #define sk_EVP_PKEY_value(st, i) SKM_sk_value(EVP_PKEY, (st), (i))
147 #define sk_EVP_PKEY_push(st, val) SKM_sk_push(EVP_PKEY, (st), (val))
148 #define sk_EVP_PKEY_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY, (st), \
151 mutex_t init_lock
= DEFAULTMUTEX
;
152 static int ssl_initialized
= 0;
153 static BIO
*bio_err
= NULL
;
156 test_for_file(char *, mode_t
);
158 openssl_parse_bag(PKCS12_SAFEBAG
*, char *, int,
159 STACK_OF(EVP_PKEY
) *, STACK_OF(X509
) *);
162 local_export_pk12(KMF_HANDLE_T
, KMF_CREDENTIAL
*, int, KMF_X509_DER_CERT
*,
163 int, KMF_KEY_HANDLE
*, char *);
165 static KMF_RETURN
set_pkey_attrib(EVP_PKEY
*, ASN1_TYPE
*, int);
168 extract_pem(KMF_HANDLE
*, char *, char *, KMF_BIGINT
*, char *,
169 CK_UTF8CHAR
*, CK_ULONG
, EVP_PKEY
**, KMF_DATA
**, int *);
172 kmf_load_cert(KMF_HANDLE
*, char *, char *, KMF_BIGINT
*, KMF_CERT_VALIDITY
,
176 load_certs(KMF_HANDLE
*, char *, char *, KMF_BIGINT
*, KMF_CERT_VALIDITY
,
177 char *, KMF_DATA
**, uint32_t *);
180 sslBN2KMFBN(BIGNUM
*, KMF_BIGINT
*);
183 ImportRawRSAKey(KMF_RAW_RSA_KEY
*);
186 convertToRawKey(EVP_PKEY
*, KMF_RAW_KEY_DATA
*);
189 OpenSSL_FindCert(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
192 OpenSSL_FreeKMFCert(KMF_HANDLE_T
, KMF_X509_DER_CERT
*);
195 OpenSSL_StoreCert(KMF_HANDLE_T handle
, int, KMF_ATTRIBUTE
*);
198 OpenSSL_DeleteCert(KMF_HANDLE_T handle
, int, KMF_ATTRIBUTE
*);
201 OpenSSL_CreateKeypair(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
204 OpenSSL_StoreKey(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
207 OpenSSL_EncodePubKeyData(KMF_HANDLE_T
, KMF_KEY_HANDLE
*, KMF_DATA
*);
210 OpenSSL_SignData(KMF_HANDLE_T
, KMF_KEY_HANDLE
*, KMF_OID
*,
211 KMF_DATA
*, KMF_DATA
*);
214 OpenSSL_DeleteKey(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
217 OpenSSL_ImportCRL(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
220 OpenSSL_DeleteCRL(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
223 OpenSSL_ListCRL(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
226 OpenSSL_FindCertInCRL(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
229 OpenSSL_CertGetPrintable(KMF_HANDLE_T
, const KMF_DATA
*,
230 KMF_PRINTABLE_ITEM
, char *);
233 OpenSSL_GetErrorString(KMF_HANDLE_T
, char **);
236 OpenSSL_FindPrikeyByCert(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
239 OpenSSL_DecryptData(KMF_HANDLE_T
, KMF_KEY_HANDLE
*, KMF_OID
*,
240 KMF_DATA
*, KMF_DATA
*);
243 OpenSSL_CreateOCSPRequest(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
246 OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
249 OpenSSL_FindKey(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
252 OpenSSL_ExportPK12(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
255 OpenSSL_CreateSymKey(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
258 OpenSSL_GetSymKeyValue(KMF_HANDLE_T
, KMF_KEY_HANDLE
*, KMF_RAW_SYM_KEY
*);
261 OpenSSL_VerifyCRLFile(KMF_HANDLE_T
, char *, KMF_DATA
*);
264 OpenSSL_CheckCRLDate(KMF_HANDLE_T
, char *);
267 KMF_PLUGIN_FUNCLIST openssl_plugin_table
=
270 NULL
, /* ConfigureKeystore */
274 NULL
, /* ImportCert */
278 OpenSSL_CreateKeypair
,
280 OpenSSL_EncodePubKeyData
,
285 OpenSSL_FindCertInCRL
,
286 OpenSSL_GetErrorString
,
287 OpenSSL_FindPrikeyByCert
,
290 OpenSSL_CreateSymKey
,
291 OpenSSL_GetSymKeyValue
,
292 NULL
, /* SetTokenPin */
297 static mutex_t
*lock_cs
;
298 static long *lock_count
;
302 locking_cb(int mode
, int type
, char *file
, int line
)
304 if (mode
& CRYPTO_LOCK
) {
305 (void) mutex_lock(&(lock_cs
[type
]));
308 (void) mutex_unlock(&(lock_cs
[type
]));
315 return ((unsigned long)thr_self());
318 KMF_PLUGIN_FUNCLIST
*
319 KMF_Plugin_Initialize()
323 (void) mutex_lock(&init_lock
);
324 if (!ssl_initialized
) {
326 * Add support for extension OIDs that are not yet in the
327 * openssl default set.
329 (void) OBJ_create("2.5.29.30", "nameConstraints",
330 "X509v3 Name Constraints");
331 (void) OBJ_create("2.5.29.33", "policyMappings",
332 "X509v3 Policy Mappings");
333 (void) OBJ_create("2.5.29.36", "policyConstraints",
334 "X509v3 Policy Constraints");
335 (void) OBJ_create("2.5.29.46", "freshestCRL",
336 "X509v3 Freshest CRL");
337 (void) OBJ_create("2.5.29.54", "inhibitAnyPolicy",
338 "X509v3 Inhibit Any-Policy");
340 * Set up for thread-safe operation.
342 lock_cs
= OPENSSL_malloc(CRYPTO_num_locks() * sizeof (mutex_t
));
343 if (lock_cs
== NULL
) {
344 (void) mutex_unlock(&init_lock
);
348 lock_count
= OPENSSL_malloc(CRYPTO_num_locks() * sizeof (long));
349 if (lock_count
== NULL
) {
350 OPENSSL_free(lock_cs
);
351 (void) mutex_unlock(&init_lock
);
355 for (i
= 0; i
< CRYPTO_num_locks(); i
++) {
357 (void) mutex_init(&lock_cs
[i
], USYNC_THREAD
, NULL
);
360 CRYPTO_set_id_callback((unsigned long (*)())thread_id
);
361 if (CRYPTO_get_locking_callback() == NULL
)
362 CRYPTO_set_locking_callback((void (*)())locking_cb
);
364 OpenSSL_add_all_algorithms();
366 /* Enable error strings for reporting */
367 ERR_load_crypto_strings();
371 (void) mutex_unlock(&init_lock
);
373 return (&openssl_plugin_table
);
376 * Convert an SSL DN to a KMF DN.
379 get_x509_dn(X509_NAME
*sslDN
, KMF_X509_NAME
*kmfDN
)
382 KMF_RETURN rv
= KMF_OK
;
385 /* Convert to raw DER format */
386 derdata
.Length
= i2d_X509_NAME(sslDN
, NULL
);
387 if ((tmp
= derdata
.Data
= (uchar_t
*)OPENSSL_malloc(derdata
.Length
))
389 return (KMF_ERR_MEMORY
);
391 (void) i2d_X509_NAME(sslDN
, &tmp
);
393 /* Decode to KMF format */
394 rv
= DerDecodeName(&derdata
, kmfDN
);
396 rv
= KMF_ERR_BAD_CERT_FORMAT
;
398 OPENSSL_free(derdata
.Data
);
408 if (stat(path
, &s
) == -1)
411 return ((s
.st_mode
& S_IFMT
) == S_IFDIR
);
415 ssl_cert2KMFDATA(KMF_HANDLE
*kmfh
, X509
*x509cert
, KMF_DATA
*cert
)
417 KMF_RETURN rv
= KMF_OK
;
418 unsigned char *buf
= NULL
, *p
;
422 * Convert the X509 internal struct to DER encoded data
424 if ((len
= i2d_X509(x509cert
, NULL
)) < 0) {
425 SET_ERROR(kmfh
, ERR_get_error());
426 rv
= KMF_ERR_BAD_CERT_FORMAT
;
429 if ((buf
= malloc(len
)) == NULL
) {
430 SET_SYS_ERROR(kmfh
, errno
);
436 * i2d_X509 will increment the buf pointer so that we need to
440 if ((len
= i2d_X509(x509cert
, &p
)) < 0) {
441 SET_ERROR(kmfh
, ERR_get_error());
443 rv
= KMF_ERR_BAD_CERT_FORMAT
;
447 /* caller's responsibility to free it */
464 check_cert(X509
*xcert
, char *issuer
, char *subject
, KMF_BIGINT
*serial
,
467 KMF_RETURN rv
= KMF_OK
;
468 boolean_t findIssuer
= FALSE
;
469 boolean_t findSubject
= FALSE
;
470 boolean_t findSerial
= FALSE
;
471 KMF_X509_NAME issuerDN
, subjectDN
;
472 KMF_X509_NAME certIssuerDN
, certSubjectDN
;
476 return (KMF_ERR_BAD_PARAMETER
);
479 (void) memset(&issuerDN
, 0, sizeof (KMF_X509_NAME
));
480 (void) memset(&subjectDN
, 0, sizeof (KMF_X509_NAME
));
481 (void) memset(&certIssuerDN
, 0, sizeof (KMF_X509_NAME
));
482 (void) memset(&certSubjectDN
, 0, sizeof (KMF_X509_NAME
));
484 if (issuer
!= NULL
&& strlen(issuer
)) {
485 rv
= kmf_dn_parser(issuer
, &issuerDN
);
487 return (KMF_ERR_BAD_PARAMETER
);
489 rv
= get_x509_dn(xcert
->cert_info
->issuer
, &certIssuerDN
);
491 kmf_free_dn(&issuerDN
);
492 return (KMF_ERR_BAD_PARAMETER
);
497 if (subject
!= NULL
&& strlen(subject
)) {
498 rv
= kmf_dn_parser(subject
, &subjectDN
);
500 rv
= KMF_ERR_BAD_PARAMETER
;
504 rv
= get_x509_dn(xcert
->cert_info
->subject
, &certSubjectDN
);
506 rv
= KMF_ERR_BAD_PARAMETER
;
511 if (serial
!= NULL
&& serial
->val
!= NULL
)
517 /* Comparing BIGNUMs is a pain! */
518 bn
= ASN1_INTEGER_to_BN(xcert
->cert_info
->serialNumber
, NULL
);
520 int bnlen
= BN_num_bytes(bn
);
522 if (bnlen
== serial
->len
) {
523 uchar_t
*a
= malloc(bnlen
);
529 bnlen
= BN_bn2bin(bn
, a
);
530 *match
= (memcmp(a
, serial
->val
, serial
->len
) ==
544 *match
= (kmf_compare_rdns(&issuerDN
, &certIssuerDN
) == 0);
545 if ((*match
) == B_FALSE
) {
546 /* stop checking and bail */
552 *match
= (kmf_compare_rdns(&subjectDN
, &certSubjectDN
) == 0);
553 if ((*match
) == B_FALSE
) {
554 /* stop checking and bail */
563 kmf_free_dn(&issuerDN
);
564 kmf_free_dn(&certIssuerDN
);
567 kmf_free_dn(&subjectDN
);
568 kmf_free_dn(&certSubjectDN
);
576 * This function loads a certificate file into an X509 data structure, and
577 * checks if its issuer, subject or the serial number matches with those
578 * values. If it matches, then return the X509 data structure.
581 load_X509cert(KMF_HANDLE
*kmfh
,
582 char *issuer
, char *subject
, KMF_BIGINT
*serial
,
583 char *pathname
, X509
**outcert
)
585 KMF_RETURN rv
= KMF_OK
;
588 boolean_t match
= FALSE
;
589 KMF_ENCODE_FORMAT format
;
592 * auto-detect the file format, regardless of what
593 * the 'format' parameters in the params say.
595 rv
= kmf_get_file_format(pathname
, &format
);
597 if (rv
== KMF_ERR_OPEN_FILE
)
598 rv
= KMF_ERR_CERT_NOT_FOUND
;
602 /* Not ASN1(DER) format */
603 if ((bcert
= BIO_new_file(pathname
, "rb")) == NULL
) {
604 SET_ERROR(kmfh
, ERR_get_error());
605 rv
= KMF_ERR_OPEN_FILE
;
609 if (format
== KMF_FORMAT_PEM
)
610 xcert
= PEM_read_bio_X509_AUX(bcert
, NULL
, NULL
, NULL
);
611 else if (format
== KMF_FORMAT_ASN1
)
612 xcert
= d2i_X509_bio(bcert
, NULL
);
613 else if (format
== KMF_FORMAT_PKCS12
) {
614 PKCS12
*p12
= d2i_PKCS12_bio(bcert
, NULL
);
616 (void) PKCS12_parse(p12
, NULL
, NULL
, &xcert
, NULL
);
620 SET_ERROR(kmfh
, ERR_get_error());
621 rv
= KMF_ERR_BAD_CERT_FORMAT
;
624 rv
= KMF_ERR_BAD_PARAMETER
;
629 SET_ERROR(kmfh
, ERR_get_error());
630 rv
= KMF_ERR_BAD_CERT_FORMAT
;
634 if (check_cert(xcert
, issuer
, subject
, serial
, &match
) != KMF_OK
||
636 rv
= KMF_ERR_CERT_NOT_FOUND
;
640 if (outcert
!= NULL
) {
645 if (bcert
!= NULL
) (void) BIO_free(bcert
);
646 if (rv
!= KMF_OK
&& xcert
!= NULL
)
653 datacmp(const void *a
, const void *b
)
655 KMF_DATA
*adata
= (KMF_DATA
*)a
;
656 KMF_DATA
*bdata
= (KMF_DATA
*)b
;
657 if (adata
->Length
> bdata
->Length
)
659 if (adata
->Length
< bdata
->Length
)
665 load_certs(KMF_HANDLE
*kmfh
, char *issuer
, char *subject
, KMF_BIGINT
*serial
,
666 KMF_CERT_VALIDITY validity
, char *pathname
,
667 KMF_DATA
**certlist
, uint32_t *numcerts
)
669 KMF_RETURN rv
= KMF_OK
;
671 KMF_DATA
*certs
= NULL
;
674 KMF_ENCODE_FORMAT format
;
676 rv
= kmf_get_file_format(pathname
, &format
);
678 if (rv
== KMF_ERR_OPEN_FILE
)
679 rv
= KMF_ERR_CERT_NOT_FOUND
;
682 if (format
== KMF_FORMAT_ASN1
) {
683 /* load a single certificate */
684 certs
= (KMF_DATA
*)malloc(sizeof (KMF_DATA
));
686 return (KMF_ERR_MEMORY
);
689 rv
= kmf_load_cert(kmfh
, issuer
, subject
, serial
, validity
,
695 kmf_free_data(certs
);
700 } else if (format
== KMF_FORMAT_PKCS12
) {
701 /* We need a credential to access a PKCS#12 file */
702 rv
= KMF_ERR_BAD_CERT_FORMAT
;
703 } else if (format
== KMF_FORMAT_PEM
||
704 format
!= KMF_FORMAT_PEM_KEYPAIR
) {
706 /* This function only works on PEM files */
707 rv
= extract_pem(kmfh
, issuer
, subject
, serial
, pathname
,
708 (uchar_t
*)NULL
, 0, NULL
, &certs
, &nc
);
710 return (KMF_ERR_ENCODING
);
716 for (i
= 0; i
< nc
; i
++) {
717 if (validity
== KMF_NONEXPIRED_CERTS
) {
718 rv
= kmf_check_cert_date(kmfh
, &certs
[i
]);
719 } else if (validity
== KMF_EXPIRED_CERTS
) {
720 rv
= kmf_check_cert_date(kmfh
, &certs
[i
]);
722 rv
= KMF_ERR_CERT_NOT_FOUND
;
723 if (rv
== KMF_ERR_VALIDITY_PERIOD
)
727 /* Remove this cert from the list by clearing it. */
728 kmf_free_data(&certs
[i
]);
730 hits
++; /* count valid certs found */
734 if (rv
== KMF_OK
&& hits
> 0) {
736 * Sort the list of certs by length to put the cleared ones
737 * at the end so they don't get accessed by the caller.
739 qsort((void *)certs
, nc
, sizeof (KMF_DATA
), datacmp
);
742 /* since we sorted the list, just return the number of hits */
745 if (rv
== KMF_OK
&& hits
== 0)
746 rv
= KMF_ERR_CERT_NOT_FOUND
;
756 kmf_load_cert(KMF_HANDLE
*kmfh
,
757 char *issuer
, char *subject
, KMF_BIGINT
*serial
,
758 KMF_CERT_VALIDITY validity
,
762 KMF_RETURN rv
= KMF_OK
;
763 X509
*x509cert
= NULL
;
765 rv
= load_X509cert(kmfh
, issuer
, subject
, serial
, pathname
, &x509cert
);
766 if (rv
== KMF_OK
&& x509cert
!= NULL
&& cert
!= NULL
) {
767 rv
= ssl_cert2KMFDATA(kmfh
, x509cert
, cert
);
771 if (validity
== KMF_NONEXPIRED_CERTS
) {
772 rv
= kmf_check_cert_date(kmfh
, cert
);
773 } else if (validity
== KMF_EXPIRED_CERTS
) {
774 rv
= kmf_check_cert_date(kmfh
, cert
);
777 * This is a valid cert so skip it.
779 rv
= KMF_ERR_CERT_NOT_FOUND
;
781 if (rv
== KMF_ERR_VALIDITY_PERIOD
) {
783 * We want to return success when we
784 * find an invalid cert.
792 if (x509cert
!= NULL
)
799 readAltFormatPrivateKey(KMF_DATA
*filedata
, EVP_PKEY
**pkey
)
801 KMF_RETURN ret
= KMF_OK
;
803 BerElement
*asn1
= NULL
;
805 BerValue OID
= { NULL
, 0 };
806 BerValue
*Mod
= NULL
, *PubExp
= NULL
;
807 BerValue
*PriExp
= NULL
, *Prime1
= NULL
, *Prime2
= NULL
;
808 BerValue
*Coef
= NULL
;
809 BIGNUM
*D
= NULL
, *P
= NULL
, *Q
= NULL
, *COEF
= NULL
;
810 BIGNUM
*Exp1
= NULL
, *Exp2
= NULL
, *pminus1
= NULL
;
811 BIGNUM
*qminus1
= NULL
;
816 filebuf
.bv_val
= (char *)filedata
->Data
;
817 filebuf
.bv_len
= filedata
->Length
;
819 asn1
= kmfder_init(&filebuf
);
821 ret
= KMF_ERR_MEMORY
;
825 if (kmfber_scanf(asn1
, "{{Dn{IIIIII}}}",
826 &OID
, &Mod
, &PubExp
, &PriExp
, &Prime1
,
827 &Prime2
, &Coef
) == -1) {
828 ret
= KMF_ERR_ENCODING
;
833 * We have to derive the 2 Exponents using Bignumber math.
834 * Exp1 = PriExp mod (Prime1 - 1)
835 * Exp2 = PriExp mod (Prime2 - 1)
838 /* D = PrivateExponent */
839 D
= BN_bin2bn((const uchar_t
*)PriExp
->bv_val
, PriExp
->bv_len
, D
);
841 ret
= KMF_ERR_MEMORY
;
845 /* P = Prime1 (first prime factor of Modulus) */
846 P
= BN_bin2bn((const uchar_t
*)Prime1
->bv_val
, Prime1
->bv_len
, P
);
848 ret
= KMF_ERR_MEMORY
;
852 /* Q = Prime2 (second prime factor of Modulus) */
853 Q
= BN_bin2bn((const uchar_t
*)Prime2
->bv_val
, Prime2
->bv_len
, Q
);
855 if ((ctx
= BN_CTX_new()) == NULL
) {
856 ret
= KMF_ERR_MEMORY
;
860 /* Compute (P - 1) */
862 (void) BN_sub(pminus1
, P
, BN_value_one());
864 /* Exponent1 = D mod (P - 1) */
866 (void) BN_mod(Exp1
, D
, pminus1
, ctx
);
868 /* Compute (Q - 1) */
870 (void) BN_sub(qminus1
, Q
, BN_value_one());
872 /* Exponent2 = D mod (Q - 1) */
874 (void) BN_mod(Exp2
, D
, qminus1
, ctx
);
876 /* Coef = (Inverse Q) mod P */
878 (void) BN_mod_inverse(COEF
, Q
, P
, ctx
);
880 /* Convert back to KMF format */
881 (void) memset(&rsa
, 0, sizeof (rsa
));
883 if ((ret
= sslBN2KMFBN(Exp1
, &rsa
.exp1
)) != KMF_OK
)
885 if ((ret
= sslBN2KMFBN(Exp2
, &rsa
.exp2
)) != KMF_OK
)
887 if ((ret
= sslBN2KMFBN(COEF
, &rsa
.coef
)) != KMF_OK
)
890 rsa
.mod
.val
= (uchar_t
*)Mod
->bv_val
;
891 rsa
.mod
.len
= Mod
->bv_len
;
893 rsa
.pubexp
.val
= (uchar_t
*)PubExp
->bv_val
;
894 rsa
.pubexp
.len
= PubExp
->bv_len
;
896 rsa
.priexp
.val
= (uchar_t
*)PriExp
->bv_val
;
897 rsa
.priexp
.len
= PriExp
->bv_len
;
899 rsa
.prime1
.val
= (uchar_t
*)Prime1
->bv_val
;
900 rsa
.prime1
.len
= Prime1
->bv_len
;
902 rsa
.prime2
.val
= (uchar_t
*)Prime2
->bv_val
;
903 rsa
.prime2
.len
= Prime2
->bv_len
;
905 *pkey
= ImportRawRSAKey(&rsa
);
908 kmfber_free(asn1
, 1);
923 (void) memset(Coef
->bv_val
, 0, Coef
->bv_len
);
942 BN_clear_free(pminus1
);
944 BN_clear_free(qminus1
);
955 openssl_load_key(KMF_HANDLE_T handle
, const char *file
)
958 EVP_PKEY
*pkey
= NULL
;
959 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
960 KMF_ENCODE_FORMAT format
;
968 if (kmf_get_file_format((char *)file
, &format
) != KMF_OK
)
971 keyfile
= BIO_new_file(file
, "rb");
972 if (keyfile
== NULL
) {
976 if (format
== KMF_FORMAT_ASN1
) {
977 pkey
= d2i_PrivateKey_bio(keyfile
, NULL
);
980 (void) BIO_free(keyfile
);
982 /* Try odd ASN.1 variations */
983 rv
= kmf_read_input_file(kmfh
, (char *)file
,
986 (void) readAltFormatPrivateKey(&filedata
,
988 kmf_free_data(&filedata
);
991 } else if (format
== KMF_FORMAT_PEM
||
992 format
== KMF_FORMAT_PEM_KEYPAIR
) {
993 pkey
= PEM_read_bio_PrivateKey(keyfile
, NULL
, NULL
, NULL
);
997 * Check if this is the alt. format
998 * RSA private key file.
1000 rv
= kmf_read_input_file(kmfh
, (char *)file
,
1005 rv
= kmf_pem_to_der(filedata
.Data
,
1006 filedata
.Length
, &d
, &len
);
1007 if (rv
== KMF_OK
&& d
!= NULL
) {
1009 derdata
.Length
= (size_t)len
;
1010 (void) readAltFormatPrivateKey(
1014 kmf_free_data(&filedata
);
1021 SET_ERROR(kmfh
, ERR_get_error());
1023 if (keyfile
!= NULL
)
1024 (void) BIO_free(keyfile
);
1030 OpenSSL_FindCert(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
1032 KMF_RETURN rv
= KMF_OK
;
1033 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1035 uint32_t maxcerts
= 0;
1036 uint32_t *num_certs
;
1037 KMF_X509_DER_CERT
*kmf_cert
= NULL
;
1038 char *dirpath
= NULL
;
1039 char *filename
= NULL
;
1040 char *fullpath
= NULL
;
1041 char *issuer
= NULL
;
1042 char *subject
= NULL
;
1043 KMF_BIGINT
*serial
= NULL
;
1044 KMF_CERT_VALIDITY validity
;
1046 num_certs
= kmf_get_attr_ptr(KMF_COUNT_ATTR
, attrlist
, numattr
);
1047 if (num_certs
== NULL
)
1048 return (KMF_ERR_BAD_PARAMETER
);
1050 /* num_certs should reference the size of kmf_cert */
1051 maxcerts
= *num_certs
;
1053 maxcerts
= 0xFFFFFFFF;
1056 /* Get the optional returned certificate list */
1057 kmf_cert
= kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR
, attrlist
,
1061 * The dirpath attribute and the filename attribute can not be NULL
1064 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
1065 filename
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
,
1068 fullpath
= get_fullpath(dirpath
, filename
);
1069 if (fullpath
== NULL
)
1070 return (KMF_ERR_BAD_PARAMETER
);
1072 /* Get optional search criteria attributes */
1073 issuer
= kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR
, attrlist
, numattr
);
1074 subject
= kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR
, attrlist
, numattr
);
1075 serial
= kmf_get_attr_ptr(KMF_BIGINT_ATTR
, attrlist
, numattr
);
1076 rv
= kmf_get_attr(KMF_CERT_VALIDITY_ATTR
, attrlist
, numattr
,
1079 validity
= KMF_ALL_CERTS
;
1083 if (isdir(fullpath
)) {
1088 /* open all files in the directory and attempt to read them */
1089 if ((dirp
= opendir(fullpath
)) == NULL
) {
1090 return (KMF_ERR_BAD_PARAMETER
);
1092 while ((dp
= readdir(dirp
)) != NULL
) {
1094 KMF_DATA
*certlist
= NULL
;
1095 uint32_t loaded_certs
= 0;
1097 if (strcmp(dp
->d_name
, ".") == 0 ||
1098 strcmp(dp
->d_name
, "..") == 0)
1101 fname
= get_fullpath(fullpath
, (char *)&dp
->d_name
);
1103 rv
= load_certs(kmfh
, issuer
, subject
, serial
,
1104 validity
, fname
, &certlist
, &loaded_certs
);
1108 if (certlist
!= NULL
) {
1109 for (i
= 0; i
< loaded_certs
; i
++)
1110 kmf_free_data(&certlist
[i
]);
1116 /* If load succeeds, add certdata to the list */
1117 if (kmf_cert
!= NULL
) {
1118 for (i
= 0; i
< loaded_certs
&&
1119 n
< maxcerts
; i
++) {
1120 kmf_cert
[n
].certificate
.Data
=
1122 kmf_cert
[n
].certificate
.Length
=
1125 kmf_cert
[n
].kmf_private
.keystore_type
=
1126 KMF_KEYSTORE_OPENSSL
;
1127 kmf_cert
[n
].kmf_private
.flags
=
1128 KMF_FLAG_CERT_VALID
;
1129 kmf_cert
[n
].kmf_private
.label
=
1134 * If maxcerts < loaded_certs, clean up the
1135 * certs that were not used.
1137 for (; i
< loaded_certs
; i
++)
1138 kmf_free_data(&certlist
[i
]);
1140 for (i
= 0; i
< loaded_certs
; i
++)
1141 kmf_free_data(&certlist
[i
]);
1148 if (*num_certs
== 0)
1149 rv
= KMF_ERR_CERT_NOT_FOUND
;
1153 (void) closedir(dirp
);
1155 KMF_DATA
*certlist
= NULL
;
1156 uint32_t loaded_certs
= 0;
1158 rv
= load_certs(kmfh
, issuer
, subject
, serial
, validity
,
1159 fullpath
, &certlist
, &loaded_certs
);
1166 if (kmf_cert
!= NULL
&& certlist
!= NULL
) {
1167 for (i
= 0; i
< loaded_certs
&& i
< maxcerts
; i
++) {
1168 kmf_cert
[n
].certificate
.Data
=
1170 kmf_cert
[n
].certificate
.Length
=
1172 kmf_cert
[n
].kmf_private
.keystore_type
=
1173 KMF_KEYSTORE_OPENSSL
;
1174 kmf_cert
[n
].kmf_private
.flags
=
1175 KMF_FLAG_CERT_VALID
;
1176 kmf_cert
[n
].kmf_private
.label
=
1180 /* If maxcerts < loaded_certs, clean up */
1181 for (; i
< loaded_certs
; i
++)
1182 kmf_free_data(&certlist
[i
]);
1183 } else if (certlist
!= NULL
) {
1184 for (i
= 0; i
< loaded_certs
; i
++)
1185 kmf_free_data(&certlist
[i
]);
1188 if (certlist
!= NULL
)
1200 OpenSSL_FreeKMFCert(KMF_HANDLE_T handle
,
1201 KMF_X509_DER_CERT
*kmf_cert
)
1203 if (kmf_cert
!= NULL
) {
1204 if (kmf_cert
->certificate
.Data
!= NULL
) {
1205 kmf_free_data(&kmf_cert
->certificate
);
1207 if (kmf_cert
->kmf_private
.label
)
1208 free(kmf_cert
->kmf_private
.label
);
1214 OpenSSL_StoreCert(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
1216 KMF_RETURN ret
= KMF_OK
;
1217 KMF_DATA
*cert
= NULL
;
1218 char *outfilename
= NULL
;
1219 char *dirpath
= NULL
;
1220 char *fullpath
= NULL
;
1221 KMF_ENCODE_FORMAT format
;
1223 /* Get the cert data */
1224 cert
= kmf_get_attr_ptr(KMF_CERT_DATA_ATTR
, attrlist
, numattr
);
1225 if (cert
== NULL
|| cert
->Data
== NULL
)
1226 return (KMF_ERR_BAD_PARAMETER
);
1228 /* Check the output filename and directory attributes. */
1229 outfilename
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
,
1231 if (outfilename
== NULL
)
1232 return (KMF_ERR_BAD_PARAMETER
);
1234 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
1235 fullpath
= get_fullpath(dirpath
, outfilename
);
1236 if (fullpath
== NULL
)
1237 return (KMF_ERR_BAD_CERTFILE
);
1239 /* Check the optional format attribute */
1240 ret
= kmf_get_attr(KMF_ENCODE_FORMAT_ATTR
, attrlist
, numattr
,
1242 if (ret
!= KMF_OK
) {
1243 /* If there is no format attribute, then default to PEM */
1244 format
= KMF_FORMAT_PEM
;
1246 } else if (format
!= KMF_FORMAT_ASN1
&& format
!= KMF_FORMAT_PEM
) {
1247 ret
= KMF_ERR_BAD_CERT_FORMAT
;
1251 /* Store the certificate in the file with the specified format */
1252 ret
= kmf_create_cert_file(cert
, format
, fullpath
);
1255 if (fullpath
!= NULL
)
1263 OpenSSL_DeleteCert(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
1266 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1267 KMF_DATA certdata
= {NULL
, 0};
1268 char *dirpath
= NULL
;
1269 char *filename
= NULL
;
1270 char *fullpath
= NULL
;
1271 char *issuer
= NULL
;
1272 char *subject
= NULL
;
1273 KMF_BIGINT
*serial
= NULL
;
1274 KMF_CERT_VALIDITY validity
;
1277 * Get the DIRPATH and CERT_FILENAME attributes. They can not be
1278 * NULL at the same time.
1280 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
1281 filename
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
,
1283 fullpath
= get_fullpath(dirpath
, filename
);
1284 if (fullpath
== NULL
)
1285 return (KMF_ERR_BAD_PARAMETER
);
1287 /* Get optional search criteria attributes */
1288 issuer
= kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR
, attrlist
, numattr
);
1289 subject
= kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR
, attrlist
, numattr
);
1290 serial
= kmf_get_attr_ptr(KMF_BIGINT_ATTR
, attrlist
, numattr
);
1291 rv
= kmf_get_attr(KMF_CERT_VALIDITY_ATTR
, attrlist
, numattr
,
1294 validity
= KMF_ALL_CERTS
;
1298 if (isdir(fullpath
)) {
1302 /* open all files in the directory and attempt to read them */
1303 if ((dirp
= opendir(fullpath
)) == NULL
) {
1304 return (KMF_ERR_BAD_PARAMETER
);
1307 while ((dp
= readdir(dirp
)) != NULL
) {
1308 if (strcmp(dp
->d_name
, ".") != 0 &&
1309 strcmp(dp
->d_name
, "..") != 0) {
1312 fname
= get_fullpath(fullpath
,
1313 (char *)&dp
->d_name
);
1315 if (fname
== NULL
) {
1316 rv
= KMF_ERR_MEMORY
;
1320 rv
= kmf_load_cert(kmfh
, issuer
, subject
,
1321 serial
, validity
, fname
, &certdata
);
1323 if (rv
== KMF_ERR_CERT_NOT_FOUND
) {
1325 kmf_free_data(&certdata
);
1328 } else if (rv
!= KMF_OK
) {
1333 if (unlink(fname
) != 0) {
1334 SET_SYS_ERROR(kmfh
, errno
);
1335 rv
= KMF_ERR_INTERNAL
;
1340 kmf_free_data(&certdata
);
1343 (void) closedir(dirp
);
1345 /* Just try to load a single certificate */
1346 rv
= kmf_load_cert(kmfh
, issuer
, subject
, serial
, validity
,
1347 fullpath
, &certdata
);
1349 if (unlink(fullpath
) != 0) {
1350 SET_SYS_ERROR(kmfh
, errno
);
1351 rv
= KMF_ERR_INTERNAL
;
1357 if (fullpath
!= NULL
)
1360 kmf_free_data(&certdata
);
1366 OpenSSL_EncodePubKeyData(KMF_HANDLE_T handle
, KMF_KEY_HANDLE
*key
,
1369 KMF_RETURN rv
= KMF_OK
;
1370 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1373 if (key
== NULL
|| keydata
== NULL
||
1375 return (KMF_ERR_BAD_PARAMETER
);
1377 if (key
->keyalg
== KMF_RSA
) {
1378 RSA
*pubkey
= EVP_PKEY_get1_RSA(key
->keyp
);
1380 if (!(n
= i2d_RSA_PUBKEY(pubkey
, &keydata
->Data
))) {
1381 SET_ERROR(kmfh
, ERR_get_error());
1382 return (KMF_ERR_ENCODING
);
1385 } else if (key
->keyalg
== KMF_DSA
) {
1386 DSA
*pubkey
= EVP_PKEY_get1_DSA(key
->keyp
);
1388 if (!(n
= i2d_DSA_PUBKEY(pubkey
, &keydata
->Data
))) {
1389 SET_ERROR(kmfh
, ERR_get_error());
1390 return (KMF_ERR_ENCODING
);
1394 return (KMF_ERR_BAD_PARAMETER
);
1396 keydata
->Length
= n
;
1401 free(keydata
->Data
);
1402 keydata
->Data
= NULL
;
1403 keydata
->Length
= 0;
1410 ssl_write_key(KMF_HANDLE
*kmfh
, KMF_ENCODE_FORMAT format
, BIO
*out
,
1411 KMF_CREDENTIAL
*cred
, EVP_PKEY
*pkey
, boolean_t
private)
1417 if (pkey
== NULL
|| out
== NULL
)
1418 return (KMF_ERR_BAD_PARAMETER
);
1421 case KMF_FORMAT_RAWKEY
:
1423 case KMF_FORMAT_ASN1
:
1424 if (pkey
->type
== EVP_PKEY_RSA
) {
1425 rsa
= EVP_PKEY_get1_RSA(pkey
);
1427 rv
= i2d_RSAPrivateKey_bio(out
, rsa
);
1429 rv
= i2d_RSAPublicKey_bio(out
, rsa
);
1431 } else if (pkey
->type
== EVP_PKEY_DSA
) {
1432 dsa
= EVP_PKEY_get1_DSA(pkey
);
1433 rv
= i2d_DSAPrivateKey_bio(out
, dsa
);
1439 SET_ERROR(kmfh
, rv
);
1442 case KMF_FORMAT_PEM
:
1443 if (pkey
->type
== EVP_PKEY_RSA
) {
1444 rsa
= EVP_PKEY_get1_RSA(pkey
);
1446 rv
= PEM_write_bio_RSAPrivateKey(out
,
1447 rsa
, NULL
, NULL
, 0, NULL
,
1448 (cred
!= NULL
? cred
->cred
: NULL
));
1450 rv
= PEM_write_bio_RSAPublicKey(out
,
1453 } else if (pkey
->type
== EVP_PKEY_DSA
) {
1454 dsa
= EVP_PKEY_get1_DSA(pkey
);
1455 rv
= PEM_write_bio_DSAPrivateKey(out
,
1456 dsa
, NULL
, NULL
, 0, NULL
,
1457 (cred
!= NULL
? cred
->cred
: NULL
));
1464 SET_ERROR(kmfh
, rv
);
1469 rv
= KMF_ERR_BAD_PARAMETER
;
1476 OpenSSL_CreateKeypair(KMF_HANDLE_T handle
, int numattr
,
1477 KMF_ATTRIBUTE
*attrlist
)
1479 KMF_RETURN rv
= KMF_OK
;
1480 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1481 uint32_t eValue
= 0x010001;
1482 RSA
*sslPrivKey
= NULL
;
1483 DSA
*sslDSAKey
= NULL
;
1484 EVP_PKEY
*eprikey
= NULL
;
1485 EVP_PKEY
*epubkey
= NULL
;
1487 KMF_KEY_HANDLE
*pubkey
= NULL
, *privkey
= NULL
;
1488 uint32_t keylen
= 1024;
1489 uint32_t keylen_size
= sizeof (uint32_t);
1490 boolean_t storekey
= TRUE
;
1491 KMF_KEY_ALG keytype
= KMF_RSA
;
1493 rv
= kmf_get_attr(KMF_STOREKEY_BOOL_ATTR
, attrlist
, numattr
,
1496 /* "storekey" is optional. Default is TRUE */
1500 rv
= kmf_get_attr(KMF_KEYALG_ATTR
, attrlist
, numattr
,
1501 (void *)&keytype
, NULL
);
1503 /* keytype is optional. KMF_RSA is default */
1506 pubkey
= kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR
, attrlist
, numattr
);
1508 return (KMF_ERR_BAD_PARAMETER
);
1510 privkey
= kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR
, attrlist
, numattr
);
1511 if (privkey
== NULL
)
1512 return (KMF_ERR_BAD_PARAMETER
);
1514 (void) memset(pubkey
, 0, sizeof (KMF_KEY_HANDLE
));
1515 (void) memset(privkey
, 0, sizeof (KMF_KEY_HANDLE
));
1517 eprikey
= EVP_PKEY_new();
1518 if (eprikey
== NULL
) {
1519 SET_ERROR(kmfh
, ERR_get_error());
1520 rv
= KMF_ERR_KEYGEN_FAILED
;
1523 epubkey
= EVP_PKEY_new();
1524 if (epubkey
== NULL
) {
1525 SET_ERROR(kmfh
, ERR_get_error());
1526 rv
= KMF_ERR_KEYGEN_FAILED
;
1529 if (keytype
== KMF_RSA
) {
1530 KMF_BIGINT
*rsaexp
= NULL
;
1532 rsaexp
= kmf_get_attr_ptr(KMF_RSAEXP_ATTR
, attrlist
, numattr
);
1533 if (rsaexp
!= NULL
) {
1534 if (rsaexp
->len
> 0 &&
1535 rsaexp
->len
<= sizeof (eValue
) &&
1536 rsaexp
->val
!= NULL
) {
1537 /* LINTED E_BAD_PTR_CAST_ALIGN */
1538 eValue
= *(uint32_t *)rsaexp
->val
;
1540 rv
= KMF_ERR_BAD_PARAMETER
;
1544 /* RSA Exponent is optional. Default is 0x10001 */
1548 rv
= kmf_get_attr(KMF_KEYLENGTH_ATTR
, attrlist
, numattr
,
1549 &keylen
, &keylen_size
);
1550 if (rv
== KMF_ERR_ATTR_NOT_FOUND
)
1551 /* keylen is optional, default is 1024 */
1554 rv
= KMF_ERR_BAD_PARAMETER
;
1558 sslPrivKey
= RSA_generate_key(keylen
, eValue
, NULL
, NULL
);
1559 if (sslPrivKey
== NULL
) {
1560 SET_ERROR(kmfh
, ERR_get_error());
1561 rv
= KMF_ERR_KEYGEN_FAILED
;
1563 (void) EVP_PKEY_set1_RSA(eprikey
, sslPrivKey
);
1564 privkey
->kstype
= KMF_KEYSTORE_OPENSSL
;
1565 privkey
->keyalg
= KMF_RSA
;
1566 privkey
->keyclass
= KMF_ASYM_PRI
;
1567 privkey
->israw
= FALSE
;
1568 privkey
->keyp
= (void *)eprikey
;
1570 /* OpenSSL derives the public key from the private */
1571 (void) EVP_PKEY_set1_RSA(epubkey
, sslPrivKey
);
1572 pubkey
->kstype
= KMF_KEYSTORE_OPENSSL
;
1573 pubkey
->keyalg
= KMF_RSA
;
1574 pubkey
->israw
= FALSE
;
1575 pubkey
->keyclass
= KMF_ASYM_PUB
;
1576 pubkey
->keyp
= (void *)epubkey
;
1578 } else if (keytype
== KMF_DSA
) {
1580 sslDSAKey
= DSA_new();
1581 if (sslDSAKey
== NULL
) {
1582 SET_ERROR(kmfh
, ERR_get_error());
1583 return (KMF_ERR_MEMORY
);
1586 if ((sslDSAKey
->p
= BN_bin2bn(P
, sizeof (P
), sslDSAKey
->p
)) ==
1588 SET_ERROR(kmfh
, ERR_get_error());
1589 rv
= KMF_ERR_KEYGEN_FAILED
;
1592 if ((sslDSAKey
->q
= BN_bin2bn(Q
, sizeof (Q
), sslDSAKey
->q
)) ==
1594 SET_ERROR(kmfh
, ERR_get_error());
1595 rv
= KMF_ERR_KEYGEN_FAILED
;
1598 if ((sslDSAKey
->g
= BN_bin2bn(G
, sizeof (G
), sslDSAKey
->g
)) ==
1600 SET_ERROR(kmfh
, ERR_get_error());
1601 rv
= KMF_ERR_KEYGEN_FAILED
;
1605 if (!DSA_generate_key(sslDSAKey
)) {
1606 SET_ERROR(kmfh
, ERR_get_error());
1607 rv
= KMF_ERR_KEYGEN_FAILED
;
1611 privkey
->kstype
= KMF_KEYSTORE_OPENSSL
;
1612 privkey
->keyalg
= KMF_DSA
;
1613 privkey
->keyclass
= KMF_ASYM_PRI
;
1614 privkey
->israw
= FALSE
;
1615 if (EVP_PKEY_set1_DSA(eprikey
, sslDSAKey
)) {
1616 privkey
->keyp
= (void *)eprikey
;
1618 SET_ERROR(kmfh
, ERR_get_error());
1619 rv
= KMF_ERR_KEYGEN_FAILED
;
1623 /* Make a copy for the public key */
1625 if ((dp
->p
= BN_new()) == NULL
) {
1626 SET_ERROR(kmfh
, ERR_get_error());
1627 rv
= KMF_ERR_MEMORY
;
1631 if ((dp
->q
= BN_new()) == NULL
) {
1632 SET_ERROR(kmfh
, ERR_get_error());
1633 rv
= KMF_ERR_MEMORY
;
1638 if ((dp
->g
= BN_new()) == NULL
) {
1639 SET_ERROR(kmfh
, ERR_get_error());
1640 rv
= KMF_ERR_MEMORY
;
1646 if ((dp
->pub_key
= BN_new()) == NULL
) {
1647 SET_ERROR(kmfh
, ERR_get_error());
1648 rv
= KMF_ERR_MEMORY
;
1655 (void) BN_copy(dp
->p
, sslDSAKey
->p
);
1656 (void) BN_copy(dp
->q
, sslDSAKey
->q
);
1657 (void) BN_copy(dp
->g
, sslDSAKey
->g
);
1658 (void) BN_copy(dp
->pub_key
, sslDSAKey
->pub_key
);
1660 pubkey
->kstype
= KMF_KEYSTORE_OPENSSL
;
1661 pubkey
->keyalg
= KMF_DSA
;
1662 pubkey
->keyclass
= KMF_ASYM_PUB
;
1663 pubkey
->israw
= FALSE
;
1665 if (EVP_PKEY_set1_DSA(epubkey
, sslDSAKey
)) {
1666 pubkey
->keyp
= (void *)epubkey
;
1668 SET_ERROR(kmfh
, ERR_get_error());
1669 rv
= KMF_ERR_KEYGEN_FAILED
;
1680 KMF_ATTRIBUTE storeattrs
[4]; /* max. 4 attributes needed */
1682 char *keyfile
= NULL
, *dirpath
= NULL
;
1683 KMF_ENCODE_FORMAT format
;
1685 * Construct a new attribute arrray and call openssl_store_key
1687 kmf_set_attr_at_index(storeattrs
, i
, KMF_PRIVKEY_HANDLE_ATTR
,
1688 privkey
, sizeof (privkey
));
1691 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
1692 if (dirpath
!= NULL
) {
1693 storeattrs
[i
].type
= KMF_DIRPATH_ATTR
;
1694 storeattrs
[i
].pValue
= dirpath
;
1695 storeattrs
[i
].valueLen
= strlen(dirpath
);
1698 rv
= KMF_OK
; /* DIRPATH is optional */
1700 keyfile
= kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
,
1702 if (keyfile
!= NULL
) {
1703 storeattrs
[i
].type
= KMF_KEY_FILENAME_ATTR
;
1704 storeattrs
[i
].pValue
= keyfile
;
1705 storeattrs
[i
].valueLen
= strlen(keyfile
);
1708 goto cleanup
; /* KEYFILE is required */
1710 rv
= kmf_get_attr(KMF_ENCODE_FORMAT_ATTR
, attrlist
, numattr
,
1711 (void *)&format
, NULL
);
1713 storeattrs
[i
].type
= KMF_ENCODE_FORMAT_ATTR
;
1714 storeattrs
[i
].pValue
= &format
;
1715 storeattrs
[i
].valueLen
= sizeof (format
);
1719 rv
= OpenSSL_StoreKey(handle
, i
, storeattrs
);
1724 if (eprikey
!= NULL
)
1725 EVP_PKEY_free(eprikey
);
1727 if (epubkey
!= NULL
)
1728 EVP_PKEY_free(epubkey
);
1730 if (pubkey
->keylabel
) {
1731 free(pubkey
->keylabel
);
1732 pubkey
->keylabel
= NULL
;
1735 if (privkey
->keylabel
) {
1736 free(privkey
->keylabel
);
1737 privkey
->keylabel
= NULL
;
1740 pubkey
->keyp
= NULL
;
1741 privkey
->keyp
= NULL
;
1745 RSA_free(sslPrivKey
);
1748 DSA_free(sslDSAKey
);
1751 (void) BIO_free(out
);
1757 * Make sure the BN conversion is properly padded with 0x00
1758 * bytes. If not, signature verification for DSA signatures
1759 * may fail in the case where the bignum value does not use
1763 fixbnlen(BIGNUM
*bn
, unsigned char *buf
, int len
) {
1764 int bytes
= len
- BN_num_bytes(bn
);
1766 /* prepend with leading 0x00 if necessary */
1770 (void) BN_bn2bin(bn
, buf
);
1772 * Return the desired length since we prepended it
1773 * with the necessary 0x00 padding.
1779 OpenSSL_SignData(KMF_HANDLE_T handle
, KMF_KEY_HANDLE
*key
,
1780 KMF_OID
*AlgOID
, KMF_DATA
*tobesigned
, KMF_DATA
*output
)
1782 KMF_RETURN ret
= KMF_OK
;
1783 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1784 KMF_ALGORITHM_INDEX AlgId
;
1788 if (key
== NULL
|| AlgOID
== NULL
||
1789 tobesigned
== NULL
|| output
== NULL
||
1790 tobesigned
->Data
== NULL
||
1791 output
->Data
== NULL
)
1792 return (KMF_ERR_BAD_PARAMETER
);
1794 /* Map the OID to an OpenSSL algorithm */
1795 AlgId
= x509_algoid_to_algid(AlgOID
);
1796 if (AlgId
== KMF_ALGID_NONE
)
1797 return (KMF_ERR_BAD_ALGORITHM
);
1799 if (key
->keyalg
== KMF_RSA
) {
1800 EVP_PKEY
*pkey
= (EVP_PKEY
*)key
->keyp
;
1803 if (AlgId
== KMF_ALGID_MD5WithRSA
)
1805 else if (AlgId
== KMF_ALGID_MD2WithRSA
)
1807 else if (AlgId
== KMF_ALGID_SHA1WithRSA
)
1809 else if (AlgId
== KMF_ALGID_SHA256WithRSA
)
1811 else if (AlgId
== KMF_ALGID_SHA384WithRSA
)
1813 else if (AlgId
== KMF_ALGID_SHA512WithRSA
)
1815 else if (AlgId
== KMF_ALGID_RSA
)
1818 return (KMF_ERR_BAD_ALGORITHM
);
1820 if ((md
== NULL
) && (AlgId
== KMF_ALGID_RSA
)) {
1821 RSA
*rsa
= EVP_PKEY_get1_RSA((EVP_PKEY
*)pkey
);
1824 if ((len
= RSA_private_encrypt(tobesigned
->Length
,
1825 tobesigned
->Data
, p
, rsa
,
1826 RSA_PKCS1_PADDING
)) <= 0) {
1827 SET_ERROR(kmfh
, ERR_get_error());
1828 ret
= KMF_ERR_INTERNAL
;
1830 output
->Length
= len
;
1832 (void) EVP_MD_CTX_init(&ctx
);
1833 (void) EVP_SignInit_ex(&ctx
, md
, NULL
);
1834 (void) EVP_SignUpdate(&ctx
, tobesigned
->Data
,
1835 (uint32_t)tobesigned
->Length
);
1836 len
= (uint32_t)output
->Length
;
1838 if (!EVP_SignFinal(&ctx
, p
, (uint32_t *)&len
, pkey
)) {
1839 SET_ERROR(kmfh
, ERR_get_error());
1841 ret
= KMF_ERR_INTERNAL
;
1843 output
->Length
= len
;
1844 (void) EVP_MD_CTX_cleanup(&ctx
);
1846 } else if (key
->keyalg
== KMF_DSA
) {
1847 DSA
*dsa
= EVP_PKEY_get1_DSA(key
->keyp
);
1849 uchar_t hash
[EVP_MAX_MD_SIZE
];
1853 if (AlgId
== KMF_ALGID_DSA
||
1854 AlgId
== KMF_ALGID_SHA1WithDSA
)
1856 else if (AlgId
== KMF_ALGID_SHA256WithDSA
)
1858 else /* Bad algorithm */
1859 return (KMF_ERR_BAD_ALGORITHM
);
1862 * OpenSSL EVP_Sign operation automatically converts to
1863 * ASN.1 output so we do the operations separately so we
1864 * are assured of NOT getting ASN.1 output returned.
1865 * KMF does not want ASN.1 encoded results because
1866 * not all mechanisms return ASN.1 encodings (PKCS#11
1867 * and NSS return raw signature data).
1869 EVP_MD_CTX_init(&ctx
);
1870 (void) EVP_DigestInit_ex(&ctx
, md
, NULL
);
1871 (void) EVP_DigestUpdate(&ctx
, tobesigned
->Data
,
1872 tobesigned
->Length
);
1873 (void) EVP_DigestFinal_ex(&ctx
, hash
, &hashlen
);
1875 /* Only sign first 20 bytes for SHA2 */
1876 if (AlgId
== KMF_ALGID_SHA256WithDSA
)
1878 dsasig
= DSA_do_sign(hash
, hashlen
, dsa
);
1879 if (dsasig
!= NULL
) {
1881 output
->Length
= i
= fixbnlen(dsasig
->r
, output
->Data
,
1884 output
->Length
+= fixbnlen(dsasig
->s
, &output
->Data
[i
],
1887 DSA_SIG_free(dsasig
);
1889 SET_ERROR(kmfh
, ERR_get_error());
1891 (void) EVP_MD_CTX_cleanup(&ctx
);
1893 return (KMF_ERR_BAD_PARAMETER
);
1901 OpenSSL_DeleteKey(KMF_HANDLE_T handle
,
1902 int numattr
, KMF_ATTRIBUTE
*attrlist
)
1904 KMF_RETURN rv
= KMF_OK
;
1905 KMF_KEY_HANDLE
*key
;
1906 boolean_t destroy
= B_TRUE
;
1908 key
= kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR
, attrlist
, numattr
);
1909 if (key
== NULL
|| key
->keyp
== NULL
)
1910 return (KMF_ERR_BAD_PARAMETER
);
1912 rv
= kmf_get_attr(KMF_DESTROY_BOOL_ATTR
, attrlist
, numattr
,
1913 (void *)&destroy
, NULL
);
1915 /* "destroy" is optional. Default is TRUE */
1919 if (key
->keyclass
!= KMF_ASYM_PUB
&&
1920 key
->keyclass
!= KMF_ASYM_PRI
&&
1921 key
->keyclass
!= KMF_SYMMETRIC
)
1922 return (KMF_ERR_BAD_KEY_CLASS
);
1924 if (key
->keyclass
== KMF_SYMMETRIC
) {
1925 kmf_free_raw_sym_key((KMF_RAW_SYM_KEY
*)key
->keyp
);
1928 if (key
->keyp
!= NULL
) {
1929 EVP_PKEY_free(key
->keyp
);
1934 if (key
->keylabel
!= NULL
) {
1935 EVP_PKEY
*pkey
= NULL
;
1936 /* If the file exists, make sure it is a proper key. */
1937 pkey
= openssl_load_key(handle
, key
->keylabel
);
1939 if (key
->keylabel
!= NULL
) {
1940 free(key
->keylabel
);
1941 key
->keylabel
= NULL
;
1943 return (KMF_ERR_KEY_NOT_FOUND
);
1945 EVP_PKEY_free(pkey
);
1948 if (unlink(key
->keylabel
) != 0) {
1949 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1950 SET_SYS_ERROR(kmfh
, errno
);
1951 rv
= KMF_ERR_INTERNAL
;
1954 if (key
->keylabel
!= NULL
) {
1955 free(key
->keylabel
);
1956 key
->keylabel
= NULL
;
1963 OpenSSL_GetErrorString(KMF_HANDLE_T handle
, char **msgstr
)
1965 KMF_RETURN ret
= KMF_OK
;
1966 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1967 char str
[256]; /* OpenSSL needs at least 120 byte buffer */
1969 ERR_error_string_n(kmfh
->lasterr
.errcode
, str
, sizeof (str
));
1971 *msgstr
= (char *)strdup(str
);
1972 if ((*msgstr
) == NULL
)
1973 ret
= KMF_ERR_MEMORY
;
1985 case KMF_X509_EXT_KEY_USAGE
:
1986 return (NID_key_usage
);
1987 case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD
:
1988 return (NID_private_key_usage_period
);
1989 case KMF_X509_EXT_CERT_POLICIES
:
1990 return (NID_certificate_policies
);
1991 case KMF_X509_EXT_SUBJ_ALTNAME
:
1992 return (NID_subject_alt_name
);
1993 case KMF_X509_EXT_ISSUER_ALTNAME
:
1994 return (NID_issuer_alt_name
);
1995 case KMF_X509_EXT_BASIC_CONSTRAINTS
:
1996 return (NID_basic_constraints
);
1997 case KMF_X509_EXT_EXT_KEY_USAGE
:
1998 return (NID_ext_key_usage
);
1999 case KMF_X509_EXT_AUTH_KEY_ID
:
2000 return (NID_authority_key_identifier
);
2001 case KMF_X509_EXT_CRL_DIST_POINTS
:
2002 return (NID_crl_distribution_points
);
2003 case KMF_X509_EXT_SUBJ_KEY_ID
:
2004 return (NID_subject_key_identifier
);
2005 case KMF_X509_EXT_POLICY_MAPPINGS
:
2006 return (OBJ_sn2nid("policyMappings"));
2007 case KMF_X509_EXT_NAME_CONSTRAINTS
:
2008 return (OBJ_sn2nid("nameConstraints"));
2009 case KMF_X509_EXT_POLICY_CONSTRAINTS
:
2010 return (OBJ_sn2nid("policyConstraints"));
2011 case KMF_X509_EXT_INHIBIT_ANY_POLICY
:
2012 return (OBJ_sn2nid("inhibitAnyPolicy"));
2013 case KMF_X509_EXT_FRESHEST_CRL
:
2014 return (OBJ_sn2nid("freshestCRL"));
2021 OpenSSL_CertGetPrintable(KMF_HANDLE_T handle
, const KMF_DATA
*pcert
,
2022 KMF_PRINTABLE_ITEM flag
, char *resultStr
)
2024 KMF_RETURN ret
= KMF_OK
;
2025 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2027 unsigned char *outbuf
= NULL
;
2028 unsigned char *outbuf_p
;
2029 char *tmpstr
= NULL
;
2031 int ext_index
, nid
, len
;
2033 #if OPENSSL_VERSION_NUMBER < 0x10000000L
2034 STACK
*emlst
= NULL
;
2036 STACK_OF(OPENSSL_STRING
) *emlst
= NULL
;
2041 if (pcert
== NULL
|| pcert
->Data
== NULL
|| pcert
->Length
== 0) {
2042 return (KMF_ERR_BAD_PARAMETER
);
2045 /* copy cert data to outbuf */
2046 outbuf
= malloc(pcert
->Length
);
2047 if (outbuf
== NULL
) {
2048 return (KMF_ERR_MEMORY
);
2050 (void) memcpy(outbuf
, pcert
->Data
, pcert
->Length
);
2052 outbuf_p
= outbuf
; /* use a temp pointer; required by openssl */
2053 xcert
= d2i_X509(NULL
, (const uchar_t
**)&outbuf_p
, pcert
->Length
);
2054 if (xcert
== NULL
) {
2055 SET_ERROR(kmfh
, ERR_get_error());
2056 ret
= KMF_ERR_ENCODING
;
2060 mem
= BIO_new(BIO_s_mem());
2062 SET_ERROR(kmfh
, ERR_get_error());
2063 ret
= KMF_ERR_MEMORY
;
2068 case KMF_CERT_ISSUER
:
2069 (void) X509_NAME_print_ex(mem
, X509_get_issuer_name(xcert
), 0,
2070 XN_FLAG_SEP_CPLUS_SPC
);
2071 len
= BIO_gets(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2074 case KMF_CERT_SUBJECT
:
2075 (void) X509_NAME_print_ex(mem
, X509_get_subject_name(xcert
), 0,
2076 XN_FLAG_SEP_CPLUS_SPC
);
2077 len
= BIO_gets(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2080 case KMF_CERT_VERSION
:
2081 tmpstr
= i2s_ASN1_INTEGER(NULL
, xcert
->cert_info
->version
);
2082 (void) strncpy(resultStr
, tmpstr
, KMF_CERT_PRINTABLE_LEN
);
2083 OPENSSL_free(tmpstr
);
2084 len
= strlen(resultStr
);
2087 case KMF_CERT_SERIALNUM
:
2088 if (i2a_ASN1_INTEGER(mem
, X509_get_serialNumber(xcert
)) > 0) {
2089 (void) strcpy(resultStr
, "0x");
2090 len
= BIO_gets(mem
, &resultStr
[2],
2091 KMF_CERT_PRINTABLE_LEN
- 2);
2095 case KMF_CERT_NOTBEFORE
:
2096 (void) ASN1_TIME_print(mem
, X509_get_notBefore(xcert
));
2097 len
= BIO_gets(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2100 case KMF_CERT_NOTAFTER
:
2101 (void) ASN1_TIME_print(mem
, X509_get_notAfter(xcert
));
2102 len
= BIO_gets(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2105 case KMF_CERT_PUBKEY_DATA
:
2107 EVP_PKEY
*pkey
= X509_get_pubkey(xcert
);
2109 SET_ERROR(kmfh
, ERR_get_error());
2110 ret
= KMF_ERR_ENCODING
;
2114 if (pkey
->type
== EVP_PKEY_RSA
) {
2115 (void) BIO_printf(mem
,
2116 "RSA Public Key: (%d bit)\n",
2117 BN_num_bits(pkey
->pkey
.rsa
->n
));
2118 (void) RSA_print(mem
, pkey
->pkey
.rsa
, 0);
2119 } else if (pkey
->type
== EVP_PKEY_DSA
) {
2120 (void) BIO_printf(mem
,
2121 "%12sDSA Public Key:\n", "");
2122 (void) DSA_print(mem
, pkey
->pkey
.dsa
, 0);
2124 (void) BIO_printf(mem
,
2125 "%12sUnknown Public Key:\n", "");
2127 (void) BIO_printf(mem
, "\n");
2128 EVP_PKEY_free(pkey
);
2130 len
= BIO_read(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2132 case KMF_CERT_SIGNATURE_ALG
:
2133 case KMF_CERT_PUBKEY_ALG
:
2134 if (flag
== KMF_CERT_SIGNATURE_ALG
) {
2135 len
= i2a_ASN1_OBJECT(mem
,
2136 xcert
->sig_alg
->algorithm
);
2138 len
= i2a_ASN1_OBJECT(mem
,
2139 xcert
->cert_info
->key
->algor
->algorithm
);
2143 len
= BIO_read(mem
, resultStr
,
2144 KMF_CERT_PRINTABLE_LEN
);
2148 case KMF_CERT_EMAIL
:
2149 emlst
= X509_get1_email(xcert
);
2150 #if OPENSSL_VERSION_NUMBER < 0x10000000L
2151 for (j
= 0; j
< sk_num(emlst
); j
++)
2152 (void) BIO_printf(mem
, "%s\n", sk_value(emlst
, j
));
2154 for (j
= 0; j
< sk_OPENSSL_STRING_num(emlst
); j
++)
2155 (void) BIO_printf(mem
, "%s\n",
2156 sk_OPENSSL_STRING_value(emlst
, j
));
2159 len
= BIO_gets(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2160 X509_email_free(emlst
);
2162 case KMF_X509_EXT_ISSUER_ALTNAME
:
2163 case KMF_X509_EXT_SUBJ_ALTNAME
:
2164 case KMF_X509_EXT_KEY_USAGE
:
2165 case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD
:
2166 case KMF_X509_EXT_CERT_POLICIES
:
2167 case KMF_X509_EXT_BASIC_CONSTRAINTS
:
2168 case KMF_X509_EXT_NAME_CONSTRAINTS
:
2169 case KMF_X509_EXT_POLICY_CONSTRAINTS
:
2170 case KMF_X509_EXT_EXT_KEY_USAGE
:
2171 case KMF_X509_EXT_INHIBIT_ANY_POLICY
:
2172 case KMF_X509_EXT_AUTH_KEY_ID
:
2173 case KMF_X509_EXT_SUBJ_KEY_ID
:
2174 case KMF_X509_EXT_POLICY_MAPPINGS
:
2175 case KMF_X509_EXT_CRL_DIST_POINTS
:
2176 case KMF_X509_EXT_FRESHEST_CRL
:
2177 nid
= ext2NID(flag
);
2178 if (nid
== NID_undef
) {
2179 ret
= KMF_ERR_EXTENSION_NOT_FOUND
;
2182 ci
= xcert
->cert_info
;
2184 ext_index
= X509v3_get_ext_by_NID(ci
->extensions
, nid
, -1);
2185 if (ext_index
== -1) {
2186 SET_ERROR(kmfh
, ERR_get_error());
2188 ret
= KMF_ERR_EXTENSION_NOT_FOUND
;
2191 ex
= X509v3_get_ext(ci
->extensions
, ext_index
);
2193 (void) i2a_ASN1_OBJECT(mem
, X509_EXTENSION_get_object(ex
));
2195 if (BIO_printf(mem
, ": %s\n",
2196 X509_EXTENSION_get_critical(ex
) ? "critical" : "") <= 0) {
2197 SET_ERROR(kmfh
, ERR_get_error());
2198 ret
= KMF_ERR_ENCODING
;
2201 if (!X509V3_EXT_print(mem
, ex
, X509V3_EXT_DUMP_UNKNOWN
, 4)) {
2202 (void) BIO_printf(mem
, "%*s", 4, "");
2203 (void) M_ASN1_OCTET_STRING_print(mem
, ex
->value
);
2205 if (BIO_write(mem
, "\n", 1) <= 0) {
2206 SET_ERROR(kmfh
, ERR_get_error());
2207 ret
= KMF_ERR_ENCODING
;
2210 len
= BIO_read(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2213 SET_ERROR(kmfh
, ERR_get_error());
2214 ret
= KMF_ERR_ENCODING
;
2218 if (outbuf
!= NULL
) {
2222 if (xcert
!= NULL
) {
2227 (void) BIO_free(mem
);
2235 OpenSSL_FindPrikeyByCert(KMF_HANDLE_T handle
, int numattr
,
2236 KMF_ATTRIBUTE
*attrlist
)
2238 KMF_RETURN rv
= KMF_OK
;
2239 KMF_KEYSTORE_TYPE kstype
= KMF_KEYSTORE_OPENSSL
;
2240 KMF_KEY_CLASS keyclass
= KMF_ASYM_PRI
;
2241 KMF_KEY_HANDLE
*key
= NULL
;
2242 uint32_t numkeys
= 1; /* 1 key only */
2243 char *dirpath
= NULL
;
2244 char *keyfile
= NULL
;
2245 KMF_ATTRIBUTE new_attrlist
[16];
2249 * This is really just a FindKey operation, reuse the
2252 kmf_set_attr_at_index(new_attrlist
, i
,
2253 KMF_KEYSTORE_TYPE_ATTR
, &kstype
, sizeof (kstype
));
2256 kmf_set_attr_at_index(new_attrlist
, i
,
2257 KMF_COUNT_ATTR
, &numkeys
, sizeof (uint32_t));
2260 kmf_set_attr_at_index(new_attrlist
, i
,
2261 KMF_KEYCLASS_ATTR
, &keyclass
, sizeof (keyclass
));
2264 key
= kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR
, attrlist
, numattr
);
2266 return (KMF_ERR_BAD_PARAMETER
);
2268 kmf_set_attr_at_index(new_attrlist
, i
,
2269 KMF_KEY_HANDLE_ATTR
, key
, sizeof (KMF_KEY_HANDLE
));
2273 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
2274 if (dirpath
!= NULL
) {
2275 kmf_set_attr_at_index(new_attrlist
, i
,
2276 KMF_DIRPATH_ATTR
, dirpath
, strlen(dirpath
));
2280 keyfile
= kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
, attrlist
, numattr
);
2281 if (keyfile
== NULL
)
2282 return (KMF_ERR_BAD_PARAMETER
);
2284 kmf_set_attr_at_index(new_attrlist
, i
,
2285 KMF_KEY_FILENAME_ATTR
, keyfile
, strlen(keyfile
));
2289 rv
= OpenSSL_FindKey(handle
, i
, new_attrlist
);
2295 OpenSSL_DecryptData(KMF_HANDLE_T handle
, KMF_KEY_HANDLE
*key
,
2296 KMF_OID
*AlgOID
, KMF_DATA
*ciphertext
,
2299 KMF_RETURN ret
= KMF_OK
;
2301 unsigned int in_len
= 0, out_len
= 0;
2302 unsigned int total_decrypted
= 0, modulus_len
= 0;
2303 uint8_t *in_data
, *out_data
;
2306 if (key
== NULL
|| AlgOID
== NULL
||
2307 ciphertext
== NULL
|| output
== NULL
||
2308 ciphertext
->Data
== NULL
||
2309 output
->Data
== NULL
)
2310 return (KMF_ERR_BAD_PARAMETER
);
2312 if (key
->keyalg
== KMF_RSA
) {
2313 rsa
= EVP_PKEY_get1_RSA((EVP_PKEY
*)key
->keyp
);
2314 modulus_len
= RSA_size(rsa
);
2316 return (KMF_ERR_BAD_PARAMETER
);
2319 blocks
= ciphertext
->Length
/modulus_len
;
2320 out_data
= output
->Data
;
2321 in_data
= ciphertext
->Data
;
2322 out_len
= modulus_len
- 11;
2323 in_len
= modulus_len
;
2325 for (i
= 0; i
< blocks
; i
++) {
2326 out_len
= RSA_private_decrypt(in_len
,
2327 in_data
, out_data
, rsa
, RSA_PKCS1_PADDING
);
2330 ret
= KMF_ERR_INTERNAL
;
2334 out_data
+= out_len
;
2335 total_decrypted
+= out_len
;
2339 output
->Length
= total_decrypted
;
2351 * This function will create a certid from issuer_cert and user_cert.
2352 * The caller should use OCSP_CERTID_free(OCSP_CERTID *) to deallocate
2353 * certid memory after use.
2356 create_certid(KMF_HANDLE_T handle
, const KMF_DATA
*issuer_cert
,
2357 const KMF_DATA
*user_cert
, OCSP_CERTID
**certid
)
2359 KMF_RETURN ret
= KMF_OK
;
2360 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2361 X509
*issuer
= NULL
;
2363 unsigned char *ptmp
;
2365 if (issuer_cert
== NULL
|| user_cert
== NULL
) {
2366 return (KMF_ERR_BAD_PARAMETER
);
2369 /* convert the DER-encoded issuer cert to an internal X509 */
2370 ptmp
= issuer_cert
->Data
;
2371 issuer
= d2i_X509(NULL
, (const uchar_t
**)&ptmp
,
2372 issuer_cert
->Length
);
2373 if (issuer
== NULL
) {
2374 SET_ERROR(kmfh
, ERR_get_error());
2375 ret
= KMF_ERR_OCSP_BAD_ISSUER
;
2379 /* convert the DER-encoded user cert to an internal X509 */
2380 ptmp
= user_cert
->Data
;
2381 cert
= d2i_X509(NULL
, (const uchar_t
**)&ptmp
,
2384 SET_ERROR(kmfh
, ERR_get_error());
2386 ret
= KMF_ERR_OCSP_BAD_CERT
;
2390 /* create a CERTID */
2391 *certid
= OCSP_cert_to_id(NULL
, cert
, issuer
);
2392 if (*certid
== NULL
) {
2393 SET_ERROR(kmfh
, ERR_get_error());
2394 ret
= KMF_ERR_OCSP_CERTID
;
2399 if (issuer
!= NULL
) {
2411 OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle
,
2412 int numattr
, KMF_ATTRIBUTE
*attrlist
)
2414 KMF_RETURN ret
= KMF_OK
;
2415 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2416 OCSP_CERTID
*id
= NULL
;
2417 OCSP_REQUEST
*req
= NULL
;
2420 KMF_DATA
*issuer_cert
;
2421 KMF_DATA
*user_cert
;
2423 user_cert
= kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR
,
2425 if (user_cert
== NULL
)
2426 return (KMF_ERR_BAD_PARAMETER
);
2428 issuer_cert
= kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR
,
2430 if (issuer_cert
== NULL
)
2431 return (KMF_ERR_BAD_PARAMETER
);
2433 reqfile
= kmf_get_attr_ptr(KMF_OCSP_REQUEST_FILENAME_ATTR
,
2435 if (reqfile
== NULL
)
2436 return (KMF_ERR_BAD_PARAMETER
);
2438 ret
= create_certid(handle
, issuer_cert
, user_cert
, &id
);
2439 if (ret
!= KMF_OK
) {
2443 /* Create an OCSP request */
2444 req
= OCSP_REQUEST_new();
2446 SET_ERROR(kmfh
, ERR_get_error());
2447 ret
= KMF_ERR_OCSP_CREATE_REQUEST
;
2451 if (!OCSP_request_add0_id(req
, id
)) {
2452 ret
= KMF_ERR_OCSP_CREATE_REQUEST
;
2456 /* Write the request to the output file with DER encoding */
2457 derbio
= BIO_new_file(reqfile
, "wb");
2459 SET_ERROR(kmfh
, ERR_get_error());
2460 ret
= KMF_ERR_OPEN_FILE
;
2463 if (i2d_OCSP_REQUEST_bio(derbio
, req
) <= 0) {
2464 ret
= KMF_ERR_ENCODING
;
2469 * We don't need to free "id" explicitely, because OCSP_REQUEST_free()
2470 * will also deallocate certid's space.
2473 OCSP_REQUEST_free(req
);
2476 if (derbio
!= NULL
) {
2477 (void) BIO_free(derbio
);
2483 /* ocsp_find_signer_sk() is copied from openssl source */
2484 static X509
*ocsp_find_signer_sk(STACK_OF(X509
) *certs
, OCSP_RESPID
*id
)
2487 unsigned char tmphash
[SHA_DIGEST_LENGTH
], *keyhash
;
2489 /* Easy if lookup by name */
2490 if (id
->type
== V_OCSP_RESPID_NAME
)
2491 return (X509_find_by_subject(certs
, id
->value
.byName
));
2493 /* Lookup by key hash */
2495 /* If key hash isn't SHA1 length then forget it */
2496 if (id
->value
.byKey
->length
!= SHA_DIGEST_LENGTH
)
2499 keyhash
= id
->value
.byKey
->data
;
2500 /* Calculate hash of each key and compare */
2501 for (i
= 0; i
< sk_X509_num(certs
); i
++) {
2502 X509
*x
= sk_X509_value(certs
, i
);
2503 /* Use pubkey_digest to get the key ID value */
2504 (void) X509_pubkey_digest(x
, EVP_sha1(), tmphash
, NULL
);
2505 if (!memcmp(keyhash
, tmphash
, SHA_DIGEST_LENGTH
))
2511 /* ocsp_find_signer() is copied from openssl source */
2514 ocsp_find_signer(X509
**psigner
, OCSP_BASICRESP
*bs
, STACK_OF(X509
) *certs
,
2515 X509_STORE
*st
, unsigned long flags
)
2518 OCSP_RESPID
*rid
= bs
->tbsResponseData
->responderId
;
2519 if ((signer
= ocsp_find_signer_sk(certs
, rid
))) {
2523 if (!(flags
& OCSP_NOINTERN
) &&
2524 (signer
= ocsp_find_signer_sk(bs
->certs
, rid
))) {
2528 /* Maybe lookup from store if by subject name */
2535 * This function will verify the signature of a basic response, using
2536 * the public key from the OCSP responder certificate.
2539 check_response_signature(KMF_HANDLE_T handle
, OCSP_BASICRESP
*bs
,
2540 KMF_DATA
*signer_cert
, KMF_DATA
*issuer_cert
)
2542 KMF_RETURN ret
= KMF_OK
;
2543 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2544 STACK_OF(X509
) *cert_stack
= NULL
;
2545 X509
*signer
= NULL
;
2546 X509
*issuer
= NULL
;
2547 EVP_PKEY
*skey
= NULL
;
2548 unsigned char *ptmp
;
2551 if (bs
== NULL
|| issuer_cert
== NULL
)
2552 return (KMF_ERR_BAD_PARAMETER
);
2555 * Find the certificate that signed the basic response.
2557 * If signer_cert is not NULL, we will use that as the signer cert.
2558 * Otherwise, we will check if the issuer cert is actually the signer.
2559 * If we still do not find a signer, we will look for it from the
2560 * certificate list came with the response file.
2562 if (signer_cert
!= NULL
) {
2563 ptmp
= signer_cert
->Data
;
2564 signer
= d2i_X509(NULL
, (const uchar_t
**)&ptmp
,
2565 signer_cert
->Length
);
2566 if (signer
== NULL
) {
2567 SET_ERROR(kmfh
, ERR_get_error());
2568 ret
= KMF_ERR_OCSP_BAD_SIGNER
;
2573 * Convert the issuer cert into X509 and push it into a
2574 * stack to be used by ocsp_find_signer().
2576 ptmp
= issuer_cert
->Data
;
2577 issuer
= d2i_X509(NULL
, (const uchar_t
**)&ptmp
,
2578 issuer_cert
->Length
);
2579 if (issuer
== NULL
) {
2580 SET_ERROR(kmfh
, ERR_get_error());
2581 ret
= KMF_ERR_OCSP_BAD_ISSUER
;
2585 if ((cert_stack
= sk_X509_new_null()) == NULL
) {
2586 ret
= KMF_ERR_INTERNAL
;
2590 if (sk_X509_push(cert_stack
, issuer
) == NULL
) {
2591 ret
= KMF_ERR_INTERNAL
;
2595 ret
= ocsp_find_signer(&signer
, bs
, cert_stack
, NULL
, 0);
2597 /* can not find the signer */
2598 ret
= KMF_ERR_OCSP_BAD_SIGNER
;
2603 /* Verify the signature of the response */
2604 skey
= X509_get_pubkey(signer
);
2606 ret
= KMF_ERR_OCSP_BAD_SIGNER
;
2610 ret
= OCSP_BASICRESP_verify(bs
, skey
, 0);
2612 ret
= KMF_ERR_OCSP_RESPONSE_SIGNATURE
;
2617 if (issuer
!= NULL
) {
2621 if (signer
!= NULL
) {
2626 EVP_PKEY_free(skey
);
2629 if (cert_stack
!= NULL
) {
2630 sk_X509_free(cert_stack
);
2639 OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle
,
2640 int numattr
, KMF_ATTRIBUTE
*attrlist
)
2642 KMF_RETURN ret
= KMF_OK
;
2644 OCSP_RESPONSE
*resp
= NULL
;
2645 OCSP_BASICRESP
*bs
= NULL
;
2646 OCSP_CERTID
*id
= NULL
;
2647 OCSP_SINGLERESP
*single
= NULL
;
2648 ASN1_GENERALIZEDTIME
*rev
, *thisupd
, *nextupd
;
2649 int index
, status
, reason
;
2650 KMF_DATA
*issuer_cert
;
2651 KMF_DATA
*user_cert
;
2652 KMF_DATA
*signer_cert
;
2654 int *response_reason
, *response_status
, *cert_status
;
2655 boolean_t ignore_response_sign
= B_FALSE
; /* default is FALSE */
2656 uint32_t response_lifetime
;
2658 issuer_cert
= kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR
,
2660 if (issuer_cert
== NULL
)
2661 return (KMF_ERR_BAD_PARAMETER
);
2663 user_cert
= kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR
,
2665 if (user_cert
== NULL
)
2666 return (KMF_ERR_BAD_PARAMETER
);
2668 response
= kmf_get_attr_ptr(KMF_OCSP_RESPONSE_DATA_ATTR
,
2670 if (response
== NULL
)
2671 return (KMF_ERR_BAD_PARAMETER
);
2673 response_status
= kmf_get_attr_ptr(KMF_OCSP_RESPONSE_STATUS_ATTR
,
2675 if (response_status
== NULL
)
2676 return (KMF_ERR_BAD_PARAMETER
);
2678 response_reason
= kmf_get_attr_ptr(KMF_OCSP_RESPONSE_REASON_ATTR
,
2680 if (response_reason
== NULL
)
2681 return (KMF_ERR_BAD_PARAMETER
);
2683 cert_status
= kmf_get_attr_ptr(KMF_OCSP_RESPONSE_CERT_STATUS_ATTR
,
2685 if (cert_status
== NULL
)
2686 return (KMF_ERR_BAD_PARAMETER
);
2688 /* Read in the response */
2689 derbio
= BIO_new_mem_buf(response
->Data
, response
->Length
);
2691 ret
= KMF_ERR_MEMORY
;
2695 resp
= d2i_OCSP_RESPONSE_bio(derbio
, NULL
);
2697 ret
= KMF_ERR_OCSP_MALFORMED_RESPONSE
;
2701 /* Check the response status */
2702 status
= OCSP_response_status(resp
);
2703 *response_status
= status
;
2704 if (status
!= OCSP_RESPONSE_STATUS_SUCCESSFUL
) {
2705 ret
= KMF_ERR_OCSP_RESPONSE_STATUS
;
2710 printf("Successfully checked the response file status.\n");
2713 /* Extract basic response */
2714 bs
= OCSP_response_get1_basic(resp
);
2716 ret
= KMF_ERR_OCSP_NO_BASIC_RESPONSE
;
2721 printf("Successfully retrieved the basic response.\n");
2724 /* Check the basic response signature if required */
2725 ret
= kmf_get_attr(KMF_IGNORE_RESPONSE_SIGN_ATTR
, attrlist
, numattr
,
2726 (void *)&ignore_response_sign
, NULL
);
2730 signer_cert
= kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR
,
2733 if (ignore_response_sign
== B_FALSE
) {
2734 ret
= check_response_signature(handle
, bs
,
2735 signer_cert
, issuer_cert
);
2741 printf("Successfully verified the response signature.\n");
2744 /* Create a certid for the certificate in question */
2745 ret
= create_certid(handle
, issuer_cert
, user_cert
, &id
);
2746 if (ret
!= KMF_OK
) {
2747 ret
= KMF_ERR_OCSP_CERTID
;
2752 printf("successfully created a certid for the cert.\n");
2755 /* Find the index of the single response for the certid */
2756 index
= OCSP_resp_find(bs
, id
, -1);
2758 /* cound not find this certificate in the response */
2759 ret
= KMF_ERR_OCSP_UNKNOWN_CERT
;
2764 printf("Successfully found the single response index for the cert.\n");
2767 /* Retrieve the single response and get the cert status */
2768 single
= OCSP_resp_get0(bs
, index
);
2769 status
= OCSP_single_get0_status(single
, &reason
, &rev
, &thisupd
,
2771 if (status
== V_OCSP_CERTSTATUS_GOOD
) {
2772 *cert_status
= OCSP_GOOD
;
2773 } else if (status
== V_OCSP_CERTSTATUS_UNKNOWN
) {
2774 *cert_status
= OCSP_UNKNOWN
;
2775 } else { /* revoked */
2776 *cert_status
= OCSP_REVOKED
;
2777 *response_reason
= reason
;
2781 /* resp. time is optional, so we don't care about the return code. */
2782 (void) kmf_get_attr(KMF_RESPONSE_LIFETIME_ATTR
, attrlist
, numattr
,
2783 (void *)&response_lifetime
, NULL
);
2785 if (!OCSP_check_validity(thisupd
, nextupd
, 300,
2786 response_lifetime
)) {
2787 ret
= KMF_ERR_OCSP_STATUS_TIME_INVALID
;
2792 printf("Successfully verify the time.\n");
2797 (void) BIO_free(derbio
);
2800 OCSP_RESPONSE_free(resp
);
2803 OCSP_BASICRESP_free(bs
);
2806 OCSP_CERTID_free(id
);
2812 fetch_key(KMF_HANDLE_T handle
, char *path
,
2813 KMF_KEY_CLASS keyclass
, KMF_KEY_HANDLE
*key
)
2815 KMF_RETURN rv
= KMF_OK
;
2816 EVP_PKEY
*pkey
= NULL
;
2817 KMF_RAW_SYM_KEY
*rkey
= NULL
;
2819 if (keyclass
== KMF_ASYM_PRI
||
2820 keyclass
== KMF_ASYM_PUB
) {
2821 pkey
= openssl_load_key(handle
, path
);
2823 return (KMF_ERR_KEY_NOT_FOUND
);
2826 if (pkey
->type
== EVP_PKEY_RSA
)
2827 key
->keyalg
= KMF_RSA
;
2828 else if (pkey
->type
== EVP_PKEY_DSA
)
2829 key
->keyalg
= KMF_DSA
;
2831 key
->kstype
= KMF_KEYSTORE_OPENSSL
;
2832 key
->keyclass
= keyclass
;
2833 key
->keyp
= (void *)pkey
;
2836 ((key
->keylabel
= strdup(path
)) == NULL
)) {
2837 EVP_PKEY_free(pkey
);
2838 return (KMF_ERR_MEMORY
);
2841 EVP_PKEY_free(pkey
);
2844 } else if (keyclass
== KMF_SYMMETRIC
) {
2845 KMF_ENCODE_FORMAT fmt
;
2847 * If the file is a recognized format,
2848 * then it is NOT a symmetric key.
2850 rv
= kmf_get_file_format(path
, &fmt
);
2851 if (rv
== KMF_OK
|| fmt
!= 0) {
2852 return (KMF_ERR_KEY_NOT_FOUND
);
2853 } else if (rv
== KMF_ERR_ENCODING
) {
2855 * If we don't know the encoding,
2856 * it is probably a symmetric key.
2859 } else if (rv
== KMF_ERR_OPEN_FILE
) {
2860 return (KMF_ERR_KEY_NOT_FOUND
);
2865 rkey
= malloc(sizeof (KMF_RAW_SYM_KEY
));
2867 rv
= KMF_ERR_MEMORY
;
2871 (void) memset(rkey
, 0, sizeof (KMF_RAW_SYM_KEY
));
2872 rv
= kmf_read_input_file(handle
, path
, &keyvalue
);
2876 rkey
->keydata
.len
= keyvalue
.Length
;
2877 rkey
->keydata
.val
= keyvalue
.Data
;
2879 key
->kstype
= KMF_KEYSTORE_OPENSSL
;
2880 key
->keyclass
= keyclass
;
2882 key
->keyp
= (void *)rkey
;
2884 ((key
->keylabel
= strdup(path
)) == NULL
)) {
2885 rv
= KMF_ERR_MEMORY
;
2892 kmf_free_raw_sym_key(rkey
);
2895 EVP_PKEY_free(pkey
);
2898 key
->keyalg
= KMF_KEYALG_NONE
;
2899 key
->keyclass
= KMF_KEYCLASS_NONE
;
2908 OpenSSL_FindKey(KMF_HANDLE_T handle
,
2909 int numattr
, KMF_ATTRIBUTE
*attrlist
)
2911 KMF_RETURN rv
= KMF_OK
;
2912 char *fullpath
= NULL
;
2914 KMF_KEY_HANDLE
*key
;
2916 KMF_KEY_CLASS keyclass
;
2917 KMF_RAW_KEY_DATA
*rawkey
;
2922 return (KMF_ERR_BAD_PARAMETER
);
2924 numkeys
= kmf_get_attr_ptr(KMF_COUNT_ATTR
, attrlist
, numattr
);
2925 if (numkeys
== NULL
)
2926 return (KMF_ERR_BAD_PARAMETER
);
2928 rv
= kmf_get_attr(KMF_KEYCLASS_ATTR
, attrlist
, numattr
,
2929 (void *)&keyclass
, NULL
);
2931 return (KMF_ERR_BAD_PARAMETER
);
2933 if (keyclass
!= KMF_ASYM_PUB
&&
2934 keyclass
!= KMF_ASYM_PRI
&&
2935 keyclass
!= KMF_SYMMETRIC
)
2936 return (KMF_ERR_BAD_KEY_CLASS
);
2938 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
2939 keyfile
= kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
, attrlist
, numattr
);
2941 fullpath
= get_fullpath(dirpath
, keyfile
);
2943 if (fullpath
== NULL
)
2944 return (KMF_ERR_BAD_PARAMETER
);
2948 maxkeys
= 0xFFFFFFFF;
2951 key
= kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR
, attrlist
, numattr
);
2952 /* it is okay to have "keys" contains NULL */
2955 * The caller may want a list of the raw key data as well.
2956 * Useful for importing keys from a file into other keystores.
2958 rawkey
= kmf_get_attr_ptr(KMF_RAW_KEY_ATTR
, attrlist
, numattr
);
2960 if (isdir(fullpath
)) {
2965 /* open all files in the directory and attempt to read them */
2966 if ((dirp
= opendir(fullpath
)) == NULL
) {
2967 return (KMF_ERR_BAD_PARAMETER
);
2970 while ((dp
= readdir(dirp
)) != NULL
&& n
< maxkeys
) {
2971 if (strcmp(dp
->d_name
, ".") &&
2972 strcmp(dp
->d_name
, "..")) {
2975 fname
= get_fullpath(fullpath
,
2976 (char *)&dp
->d_name
);
2978 rv
= fetch_key(handle
, fname
,
2979 keyclass
, key
? &key
[n
] : NULL
);
2982 if (key
!= NULL
&& rawkey
!= NULL
)
2983 rv
= convertToRawKey(
2984 key
[n
].keyp
, &rawkey
[n
]);
2988 if (rv
!= KMF_OK
|| key
== NULL
)
2992 (void) closedir(dirp
);
2996 rv
= fetch_key(handle
, fullpath
, keyclass
, key
);
3000 if (rv
!= KMF_OK
|| key
== NULL
)
3003 if (rv
== KMF_OK
&& key
!= NULL
&& rawkey
!= NULL
) {
3004 rv
= convertToRawKey(key
->keyp
, rawkey
);
3008 if (rv
== KMF_OK
&& (*numkeys
) == 0)
3009 rv
= KMF_ERR_KEY_NOT_FOUND
;
3010 else if (rv
== KMF_ERR_KEY_NOT_FOUND
&& (*numkeys
) > 0)
3016 #define HANDLE_PK12_ERROR { \
3017 SET_ERROR(kmfh, ERR_get_error()); \
3018 rv = KMF_ERR_ENCODING; \
3023 add_alias_to_bag(PKCS12_SAFEBAG
*bag
, X509
*xcert
)
3025 if (xcert
!= NULL
&& xcert
->aux
!= NULL
&&
3026 xcert
->aux
->alias
!= NULL
) {
3027 if (PKCS12_add_friendlyname_asc(bag
,
3028 (const char *)xcert
->aux
->alias
->data
,
3029 xcert
->aux
->alias
->length
) == 0)
3036 add_cert_to_safe(X509
*sslcert
, KMF_CREDENTIAL
*cred
,
3037 uchar_t
*keyid
, unsigned int keyidlen
)
3039 PKCS12_SAFEBAG
*bag
= NULL
;
3040 PKCS7
*cert_authsafe
= NULL
;
3041 STACK_OF(PKCS12_SAFEBAG
) *bag_stack
;
3043 bag_stack
= sk_PKCS12_SAFEBAG_new_null();
3044 if (bag_stack
== NULL
)
3047 /* Convert cert from X509 struct to PKCS#12 bag */
3048 bag
= PKCS12_x5092certbag(sslcert
);
3053 /* Add the key id to the certificate bag. */
3054 if (keyidlen
> 0 && !PKCS12_add_localkeyid(bag
, keyid
, keyidlen
)) {
3058 if (!add_alias_to_bag(bag
, sslcert
))
3061 /* Pile it on the bag_stack. */
3062 if (!sk_PKCS12_SAFEBAG_push(bag_stack
, bag
)) {
3065 /* Turn bag_stack of certs into encrypted authsafe. */
3066 cert_authsafe
= PKCS12_pack_p7encdata(
3067 NID_pbe_WithSHA1And40BitRC2_CBC
,
3068 cred
->cred
, cred
->credlen
, NULL
, 0,
3069 PKCS12_DEFAULT_ITER
, bag_stack
);
3072 if (bag_stack
!= NULL
)
3073 sk_PKCS12_SAFEBAG_pop_free(bag_stack
, PKCS12_SAFEBAG_free
);
3075 return (cert_authsafe
);
3079 add_key_to_safe(EVP_PKEY
*pkey
, KMF_CREDENTIAL
*cred
,
3080 uchar_t
*keyid
, unsigned int keyidlen
,
3081 char *label
, int label_len
)
3083 PKCS8_PRIV_KEY_INFO
*p8
= NULL
;
3084 STACK_OF(PKCS12_SAFEBAG
) *bag_stack
= NULL
;
3085 PKCS12_SAFEBAG
*bag
= NULL
;
3086 PKCS7
*key_authsafe
= NULL
;
3088 p8
= EVP_PKEY2PKCS8(pkey
);
3092 /* Put the shrouded key into a PKCS#12 bag. */
3093 bag
= PKCS12_MAKE_SHKEYBAG(
3094 NID_pbe_WithSHA1And3_Key_TripleDES_CBC
,
3095 cred
->cred
, cred
->credlen
,
3096 NULL
, 0, PKCS12_DEFAULT_ITER
, p8
);
3098 /* Clean up the PKCS#8 shrouded key, don't need it now. */
3099 PKCS8_PRIV_KEY_INFO_free(p8
);
3105 if (keyidlen
&& !PKCS12_add_localkeyid(bag
, keyid
, keyidlen
))
3107 if (label
!= NULL
&& !PKCS12_add_friendlyname(bag
, label
, label_len
))
3110 /* Start a PKCS#12 safebag container for the private key. */
3111 bag_stack
= sk_PKCS12_SAFEBAG_new_null();
3112 if (bag_stack
== NULL
)
3115 /* Pile on the private key on the bag_stack. */
3116 if (!sk_PKCS12_SAFEBAG_push(bag_stack
, bag
))
3119 key_authsafe
= PKCS12_pack_p7data(bag_stack
);
3122 if (bag_stack
!= NULL
)
3123 sk_PKCS12_SAFEBAG_pop_free(bag_stack
, PKCS12_SAFEBAG_free
);
3125 return (key_authsafe
);
3129 ImportRawRSAKey(KMF_RAW_RSA_KEY
*key
)
3132 EVP_PKEY
*newkey
= NULL
;
3134 if ((rsa
= RSA_new()) == NULL
)
3137 if ((rsa
->n
= BN_bin2bn(key
->mod
.val
, key
->mod
.len
, rsa
->n
)) == NULL
)
3140 if ((rsa
->e
= BN_bin2bn(key
->pubexp
.val
, key
->pubexp
.len
, rsa
->e
)) ==
3144 if (key
->priexp
.val
!= NULL
)
3145 if ((rsa
->d
= BN_bin2bn(key
->priexp
.val
, key
->priexp
.len
,
3149 if (key
->prime1
.val
!= NULL
)
3150 if ((rsa
->p
= BN_bin2bn(key
->prime1
.val
, key
->prime1
.len
,
3154 if (key
->prime2
.val
!= NULL
)
3155 if ((rsa
->q
= BN_bin2bn(key
->prime2
.val
, key
->prime2
.len
,
3159 if (key
->exp1
.val
!= NULL
)
3160 if ((rsa
->dmp1
= BN_bin2bn(key
->exp1
.val
, key
->exp1
.len
,
3161 rsa
->dmp1
)) == NULL
)
3164 if (key
->exp2
.val
!= NULL
)
3165 if ((rsa
->dmq1
= BN_bin2bn(key
->exp2
.val
, key
->exp2
.len
,
3166 rsa
->dmq1
)) == NULL
)
3169 if (key
->coef
.val
!= NULL
)
3170 if ((rsa
->iqmp
= BN_bin2bn(key
->coef
.val
, key
->coef
.len
,
3171 rsa
->iqmp
)) == NULL
)
3174 if ((newkey
= EVP_PKEY_new()) == NULL
)
3177 (void) EVP_PKEY_set1_RSA(newkey
, rsa
);
3179 /* The original key must be freed once here or it leaks memory */
3186 ImportRawDSAKey(KMF_RAW_DSA_KEY
*key
)
3189 EVP_PKEY
*newkey
= NULL
;
3191 if ((dsa
= DSA_new()) == NULL
)
3194 if ((dsa
->p
= BN_bin2bn(key
->prime
.val
, key
->prime
.len
,
3198 if ((dsa
->q
= BN_bin2bn(key
->subprime
.val
, key
->subprime
.len
,
3202 if ((dsa
->g
= BN_bin2bn(key
->base
.val
, key
->base
.len
,
3206 if ((dsa
->priv_key
= BN_bin2bn(key
->value
.val
, key
->value
.len
,
3207 dsa
->priv_key
)) == NULL
)
3210 if (key
->pubvalue
.val
!= NULL
) {
3211 if ((dsa
->pub_key
= BN_bin2bn(key
->pubvalue
.val
,
3212 key
->pubvalue
.len
, dsa
->pub_key
)) == NULL
)
3216 if ((newkey
= EVP_PKEY_new()) == NULL
)
3219 (void) EVP_PKEY_set1_DSA(newkey
, dsa
);
3221 /* The original key must be freed once here or it leaks memory */
3227 raw_key_to_pkey(KMF_KEY_HANDLE
*key
)
3229 EVP_PKEY
*pkey
= NULL
;
3230 KMF_RAW_KEY_DATA
*rawkey
;
3231 ASN1_TYPE
*attr
= NULL
;
3234 if (key
== NULL
|| !key
->israw
)
3237 rawkey
= (KMF_RAW_KEY_DATA
*)key
->keyp
;
3238 if (rawkey
->keytype
== KMF_RSA
) {
3239 pkey
= ImportRawRSAKey(&rawkey
->rawdata
.rsa
);
3240 } else if (rawkey
->keytype
== KMF_DSA
) {
3241 pkey
= ImportRawDSAKey(&rawkey
->rawdata
.dsa
);
3242 } else if (rawkey
->keytype
== KMF_ECDSA
) {
3244 * OpenSSL in Solaris does not support EC for
3249 /* wrong kind of key */
3253 if (rawkey
->label
!= NULL
) {
3254 if ((attr
= ASN1_TYPE_new()) == NULL
) {
3255 EVP_PKEY_free(pkey
);
3258 attr
->value
.bmpstring
= ASN1_STRING_type_new(V_ASN1_BMPSTRING
);
3259 (void) ASN1_STRING_set(attr
->value
.bmpstring
, rawkey
->label
,
3260 strlen(rawkey
->label
));
3261 attr
->type
= V_ASN1_BMPSTRING
;
3262 attr
->value
.ptr
= (char *)attr
->value
.bmpstring
;
3263 ret
= set_pkey_attrib(pkey
, attr
, NID_friendlyName
);
3264 if (ret
!= KMF_OK
) {
3265 EVP_PKEY_free(pkey
);
3266 ASN1_TYPE_free(attr
);
3270 if (rawkey
->id
.Data
!= NULL
) {
3271 if ((attr
= ASN1_TYPE_new()) == NULL
) {
3272 EVP_PKEY_free(pkey
);
3275 attr
->value
.octet_string
=
3276 ASN1_STRING_type_new(V_ASN1_OCTET_STRING
);
3277 attr
->type
= V_ASN1_OCTET_STRING
;
3278 (void) ASN1_STRING_set(attr
->value
.octet_string
,
3279 rawkey
->id
.Data
, rawkey
->id
.Length
);
3280 attr
->value
.ptr
= (char *)attr
->value
.octet_string
;
3281 ret
= set_pkey_attrib(pkey
, attr
, NID_localKeyID
);
3282 if (ret
!= KMF_OK
) {
3283 EVP_PKEY_free(pkey
);
3284 ASN1_TYPE_free(attr
);
3292 * Search a list of private keys to find one that goes with the certificate.
3295 find_matching_key(X509
*xcert
, int numkeys
, KMF_KEY_HANDLE
*keylist
)
3298 EVP_PKEY
*pkey
= NULL
;
3300 if (numkeys
== 0 || keylist
== NULL
|| xcert
== NULL
)
3302 for (i
= 0; i
< numkeys
; i
++) {
3303 if (keylist
[i
].israw
)
3304 pkey
= raw_key_to_pkey(&keylist
[i
]);
3306 pkey
= (EVP_PKEY
*)keylist
[i
].keyp
;
3308 if (X509_check_private_key(xcert
, pkey
)) {
3311 EVP_PKEY_free(pkey
);
3320 local_export_pk12(KMF_HANDLE_T handle
,
3321 KMF_CREDENTIAL
*cred
,
3322 int numcerts
, KMF_X509_DER_CERT
*certlist
,
3323 int numkeys
, KMF_KEY_HANDLE
*keylist
,
3326 KMF_RETURN rv
= KMF_OK
;
3327 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
3329 PKCS7
*cert_authsafe
= NULL
;
3330 PKCS7
*key_authsafe
= NULL
;
3331 STACK_OF(PKCS7
) *authsafe_stack
= NULL
;
3332 PKCS12
*p12_elem
= NULL
;
3335 if (numcerts
== 0 && numkeys
== 0)
3336 return (KMF_ERR_BAD_PARAMETER
);
3339 * Open the output file.
3341 if ((bio
= BIO_new_file(filename
, "wb")) == NULL
) {
3342 SET_ERROR(kmfh
, ERR_get_error());
3343 rv
= KMF_ERR_OPEN_FILE
;
3347 /* Start a PKCS#7 stack. */
3348 authsafe_stack
= sk_PKCS7_new_null();
3349 if (authsafe_stack
== NULL
) {
3350 rv
= KMF_ERR_MEMORY
;
3354 for (i
= 0; rv
== KMF_OK
&& i
< numcerts
; i
++) {
3355 const uchar_t
*p
= certlist
[i
].certificate
.Data
;
3356 long len
= certlist
[i
].certificate
.Length
;
3358 EVP_PKEY
*pkey
= NULL
;
3359 unsigned char keyid
[EVP_MAX_MD_SIZE
];
3360 unsigned int keyidlen
= 0;
3362 xcert
= d2i_X509(NULL
, &p
, len
);
3363 if (xcert
== NULL
) {
3364 SET_ERROR(kmfh
, ERR_get_error());
3365 rv
= KMF_ERR_ENCODING
;
3367 if (certlist
[i
].kmf_private
.label
!= NULL
) {
3368 /* Set alias attribute */
3369 (void) X509_alias_set1(xcert
,
3370 (uchar_t
*)certlist
[i
].kmf_private
.label
,
3371 strlen(certlist
[i
].kmf_private
.label
));
3373 /* Check if there is a key corresponding to this cert */
3374 pkey
= find_matching_key(xcert
, numkeys
, keylist
);
3377 * If key is found, get fingerprint and create a
3381 (void) X509_digest(xcert
, EVP_sha1(),
3383 key_authsafe
= add_key_to_safe(pkey
, cred
,
3385 certlist
[i
].kmf_private
.label
,
3386 (certlist
[i
].kmf_private
.label
?
3387 strlen(certlist
[i
].kmf_private
.label
) : 0));
3389 if (key_authsafe
== NULL
) {
3391 EVP_PKEY_free(pkey
);
3394 /* Put the key safe into the Auth Safe */
3395 if (!sk_PKCS7_push(authsafe_stack
,
3398 EVP_PKEY_free(pkey
);
3403 /* create a certificate safebag */
3404 cert_authsafe
= add_cert_to_safe(xcert
, cred
, keyid
,
3406 if (cert_authsafe
== NULL
) {
3408 EVP_PKEY_free(pkey
);
3411 if (!sk_PKCS7_push(authsafe_stack
, cert_authsafe
)) {
3413 EVP_PKEY_free(pkey
);
3419 EVP_PKEY_free(pkey
);
3421 } else if (numcerts
== 0 && numkeys
> 0) {
3423 * If only adding keys to the file.
3425 for (i
= 0; i
< numkeys
; i
++) {
3426 EVP_PKEY
*pkey
= NULL
;
3428 if (keylist
[i
].israw
)
3429 pkey
= raw_key_to_pkey(&keylist
[i
]);
3431 pkey
= (EVP_PKEY
*)keylist
[i
].keyp
;
3436 key_authsafe
= add_key_to_safe(pkey
, cred
,
3439 if (key_authsafe
== NULL
) {
3440 EVP_PKEY_free(pkey
);
3443 if (!sk_PKCS7_push(authsafe_stack
, key_authsafe
)) {
3444 EVP_PKEY_free(pkey
);
3449 p12_elem
= PKCS12_init(NID_pkcs7_data
);
3450 if (p12_elem
== NULL
) {
3454 /* Put the PKCS#7 stack into the PKCS#12 element. */
3455 if (!PKCS12_pack_authsafes(p12_elem
, authsafe_stack
)) {
3459 /* Set the integrity MAC on the PKCS#12 element. */
3460 if (!PKCS12_set_mac(p12_elem
, cred
->cred
, cred
->credlen
,
3461 NULL
, 0, PKCS12_DEFAULT_ITER
, NULL
)) {
3465 /* Write the PKCS#12 element to the export file. */
3466 if (!i2d_PKCS12_bio(bio
, p12_elem
)) {
3469 PKCS12_free(p12_elem
);
3472 /* Clear away the PKCS#7 stack, we're done with it. */
3474 sk_PKCS7_pop_free(authsafe_stack
, PKCS7_free
);
3477 (void) BIO_free_all(bio
);
3483 openssl_build_pk12(KMF_HANDLE_T handle
, int numcerts
,
3484 KMF_X509_DER_CERT
*certlist
, int numkeys
, KMF_KEY_HANDLE
*keylist
,
3485 KMF_CREDENTIAL
*p12cred
, char *filename
)
3489 if (certlist
== NULL
&& keylist
== NULL
)
3490 return (KMF_ERR_BAD_PARAMETER
);
3492 rv
= local_export_pk12(handle
, p12cred
, numcerts
, certlist
,
3493 numkeys
, keylist
, filename
);
3499 OpenSSL_ExportPK12(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
3502 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
3503 char *fullpath
= NULL
;
3504 char *dirpath
= NULL
;
3505 char *certfile
= NULL
;
3506 char *keyfile
= NULL
;
3507 char *filename
= NULL
;
3508 KMF_CREDENTIAL
*p12cred
= NULL
;
3509 KMF_X509_DER_CERT certdata
;
3515 return (KMF_ERR_BAD_PARAMETER
);
3518 * First, find the certificate.
3520 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
3521 certfile
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
, numattr
);
3522 if (certfile
!= NULL
) {
3523 fullpath
= get_fullpath(dirpath
, certfile
);
3524 if (fullpath
== NULL
)
3525 return (KMF_ERR_BAD_PARAMETER
);
3527 if (isdir(fullpath
)) {
3529 return (KMF_ERR_AMBIGUOUS_PATHNAME
);
3532 (void) memset(&certdata
, 0, sizeof (certdata
));
3533 rv
= kmf_load_cert(kmfh
, NULL
, NULL
, NULL
, NULL
,
3534 fullpath
, &certdata
.certificate
);
3539 certdata
.kmf_private
.keystore_type
= KMF_KEYSTORE_OPENSSL
;
3544 * Now find the private key.
3546 keyfile
= kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
, attrlist
, numattr
);
3547 if (keyfile
!= NULL
) {
3548 fullpath
= get_fullpath(dirpath
, keyfile
);
3549 if (fullpath
== NULL
)
3550 return (KMF_ERR_BAD_PARAMETER
);
3552 if (isdir(fullpath
)) {
3554 return (KMF_ERR_AMBIGUOUS_PATHNAME
);
3557 (void) memset(&key
, 0, sizeof (KMF_KEY_HANDLE
));
3558 rv
= fetch_key(handle
, fullpath
, KMF_ASYM_PRI
, &key
);
3565 * Open the output file.
3567 filename
= kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR
, attrlist
,
3569 if (filename
== NULL
) {
3570 rv
= KMF_ERR_BAD_PARAMETER
;
3574 /* Stick the key and the cert into a PKCS#12 file */
3575 p12cred
= kmf_get_attr_ptr(KMF_PK12CRED_ATTR
, attrlist
, numattr
);
3576 if (p12cred
== NULL
) {
3577 rv
= KMF_ERR_BAD_PARAMETER
;
3581 rv
= local_export_pk12(handle
, p12cred
, 1, &certdata
,
3589 kmf_free_kmf_cert(handle
, &certdata
);
3591 kmf_free_kmf_key(handle
, &key
);
3596 * Helper function to extract keys and certificates from
3597 * a single PEM file. Typically the file should contain a
3598 * private key and an associated public key wrapped in an x509 cert.
3599 * However, the file may be just a list of X509 certs with no keys.
3602 extract_pem(KMF_HANDLE
*kmfh
,
3603 char *issuer
, char *subject
, KMF_BIGINT
*serial
,
3604 char *filename
, CK_UTF8CHAR
*pin
,
3605 CK_ULONG pinlen
, EVP_PKEY
**priv_key
, KMF_DATA
**certs
,
3609 KMF_RETURN rv
= KMF_OK
;
3611 STACK_OF(X509_INFO
) *x509_info_stack
= NULL
;
3612 int i
, ncerts
= 0, matchcerts
= 0;
3613 EVP_PKEY
*pkey
= NULL
;
3616 X509_INFO
**cert_infos
= NULL
;
3617 KMF_DATA
*certlist
= NULL
;
3623 fp
= fopen(filename
, "r");
3625 return (KMF_ERR_OPEN_FILE
);
3627 x509_info_stack
= PEM_X509_INFO_read(fp
, NULL
, NULL
, pin
);
3628 if (x509_info_stack
== NULL
) {
3630 return (KMF_ERR_ENCODING
);
3632 cert_infos
= (X509_INFO
**)malloc(sk_X509_INFO_num(x509_info_stack
) *
3633 sizeof (X509_INFO
*));
3634 if (cert_infos
== NULL
) {
3636 rv
= KMF_ERR_MEMORY
;
3640 for (i
= 0; i
< sk_X509_INFO_num(x509_info_stack
); i
++) {
3641 cert_infos
[ncerts
] = sk_X509_INFO_value(x509_info_stack
, i
);
3647 rv
= KMF_ERR_CERT_NOT_FOUND
;
3651 if (priv_key
!= NULL
) {
3653 pkey
= PEM_read_PrivateKey(fp
, NULL
, NULL
, pin
);
3657 x
= cert_infos
[ncerts
- 1]->x509
;
3659 * Make sure the private key matchs the last cert in the file.
3661 if (pkey
!= NULL
&& !X509_check_private_key(x
, pkey
)) {
3662 EVP_PKEY_free(pkey
);
3663 rv
= KMF_ERR_KEY_MISMATCH
;
3667 certlist
= (KMF_DATA
*)calloc(ncerts
, sizeof (KMF_DATA
));
3668 if (certlist
== NULL
) {
3670 EVP_PKEY_free(pkey
);
3671 rv
= KMF_ERR_MEMORY
;
3676 * Convert all of the certs to DER format.
3679 for (i
= 0; rv
== KMF_OK
&& certs
!= NULL
&& i
< ncerts
; i
++) {
3680 boolean_t match
= FALSE
;
3681 info
= cert_infos
[ncerts
- 1 - i
];
3683 rv
= check_cert(info
->x509
, issuer
, subject
, serial
, &match
);
3684 if (rv
!= KMF_OK
|| match
!= TRUE
) {
3689 rv
= ssl_cert2KMFDATA(kmfh
, info
->x509
,
3690 &certlist
[matchcerts
++]);
3694 for (j
= 0; j
< matchcerts
; j
++)
3695 kmf_free_data(&certlist
[j
]);
3698 ncerts
= matchcerts
= 0;
3702 if (numcerts
!= NULL
)
3703 *numcerts
= matchcerts
;
3707 else if (certlist
!= NULL
) {
3708 for (i
= 0; i
< ncerts
; i
++)
3709 kmf_free_data(&certlist
[i
]);
3714 if (priv_key
== NULL
&& pkey
!= NULL
)
3715 EVP_PKEY_free(pkey
);
3716 else if (priv_key
!= NULL
&& pkey
!= NULL
)
3720 /* Cleanup the stack of X509 info records */
3721 for (i
= 0; i
< sk_X509_INFO_num(x509_info_stack
); i
++) {
3722 info
= (X509_INFO
*)sk_X509_INFO_value(x509_info_stack
, i
);
3723 X509_INFO_free(info
);
3725 if (x509_info_stack
)
3726 sk_X509_INFO_free(x509_info_stack
);
3728 if (cert_infos
!= NULL
)
3735 openssl_parse_bags(STACK_OF(PKCS12_SAFEBAG
) *bags
, char *pin
,
3736 STACK_OF(EVP_PKEY
) *keys
, STACK_OF(X509
) *certs
)
3741 for (i
= 0; i
< sk_PKCS12_SAFEBAG_num(bags
); i
++) {
3742 PKCS12_SAFEBAG
*bag
= sk_PKCS12_SAFEBAG_value(bags
, i
);
3743 ret
= openssl_parse_bag(bag
, pin
, (pin
? strlen(pin
) : 0),
3754 set_pkey_attrib(EVP_PKEY
*pkey
, ASN1_TYPE
*attrib
, int nid
)
3756 X509_ATTRIBUTE
*attr
= NULL
;
3758 if (pkey
== NULL
|| attrib
== NULL
)
3759 return (KMF_ERR_BAD_PARAMETER
);
3761 if (pkey
->attributes
== NULL
) {
3762 pkey
->attributes
= sk_X509_ATTRIBUTE_new_null();
3763 if (pkey
->attributes
== NULL
)
3764 return (KMF_ERR_MEMORY
);
3766 attr
= X509_ATTRIBUTE_create(nid
, attrib
->type
, attrib
->value
.ptr
);
3771 i
< sk_X509_ATTRIBUTE_num(pkey
->attributes
); i
++) {
3772 a
= sk_X509_ATTRIBUTE_value(pkey
->attributes
, i
);
3773 if (OBJ_obj2nid(a
->object
) == nid
) {
3774 X509_ATTRIBUTE_free(a
);
3775 (void) sk_X509_ATTRIBUTE_set(pkey
->attributes
,
3780 if (sk_X509_ATTRIBUTE_push(pkey
->attributes
, attr
) == NULL
) {
3781 X509_ATTRIBUTE_free(attr
);
3782 return (KMF_ERR_MEMORY
);
3785 return (KMF_ERR_MEMORY
);
3792 openssl_parse_bag(PKCS12_SAFEBAG
*bag
, char *pass
, int passlen
,
3793 STACK_OF(EVP_PKEY
) *keylist
, STACK_OF(X509
) *certlist
)
3795 KMF_RETURN ret
= KMF_OK
;
3796 PKCS8_PRIV_KEY_INFO
*p8
= NULL
;
3797 EVP_PKEY
*pkey
= NULL
;
3799 ASN1_TYPE
*keyid
= NULL
;
3800 ASN1_TYPE
*fname
= NULL
;
3801 uchar_t
*data
= NULL
;
3803 keyid
= PKCS12_get_attr(bag
, NID_localKeyID
);
3804 fname
= PKCS12_get_attr(bag
, NID_friendlyName
);
3806 switch (M_PKCS12_bag_type(bag
)) {
3808 if (keylist
== NULL
)
3810 pkey
= EVP_PKCS82PKEY(bag
->value
.keybag
);
3812 ret
= KMF_ERR_PKCS12_FORMAT
;
3815 case NID_pkcs8ShroudedKeyBag
:
3816 if (keylist
== NULL
)
3818 p8
= M_PKCS12_decrypt_skey(bag
, pass
, passlen
);
3820 return (KMF_ERR_AUTH_FAILED
);
3821 pkey
= EVP_PKCS82PKEY(p8
);
3822 PKCS8_PRIV_KEY_INFO_free(p8
);
3824 ret
= KMF_ERR_PKCS12_FORMAT
;
3827 if (certlist
== NULL
)
3829 if (M_PKCS12_cert_bag_type(bag
) != NID_x509Certificate
)
3830 return (KMF_ERR_PKCS12_FORMAT
);
3831 xcert
= M_PKCS12_certbag2x509(bag
);
3832 if (xcert
== NULL
) {
3833 ret
= KMF_ERR_PKCS12_FORMAT
;
3836 if (keyid
!= NULL
) {
3837 if (X509_keyid_set1(xcert
,
3838 keyid
->value
.octet_string
->data
,
3839 keyid
->value
.octet_string
->length
) == 0) {
3840 ret
= KMF_ERR_PKCS12_FORMAT
;
3844 if (fname
!= NULL
) {
3846 len
= ASN1_STRING_to_UTF8(&data
,
3847 fname
->value
.asn1_string
);
3848 if (len
> 0 && data
!= NULL
) {
3849 r
= X509_alias_set1(xcert
, data
, len
);
3851 ret
= KMF_ERR_PKCS12_FORMAT
;
3855 ret
= KMF_ERR_PKCS12_FORMAT
;
3859 if (sk_X509_push(certlist
, xcert
) == 0)
3860 ret
= KMF_ERR_MEMORY
;
3864 case NID_safeContentsBag
:
3865 return (openssl_parse_bags(bag
->value
.safes
, pass
,
3866 keylist
, certlist
));
3868 ret
= KMF_ERR_PKCS12_FORMAT
;
3873 * Set the ID and/or FriendlyName attributes on the key.
3874 * If converting to PKCS11 objects, these can translate to CKA_ID
3875 * and CKA_LABEL values.
3877 if (pkey
!= NULL
&& ret
== KMF_OK
) {
3878 ASN1_TYPE
*attr
= NULL
;
3879 if (keyid
!= NULL
&& keyid
->type
== V_ASN1_OCTET_STRING
) {
3880 if ((attr
= ASN1_TYPE_new()) == NULL
)
3881 return (KMF_ERR_MEMORY
);
3882 attr
->value
.octet_string
=
3883 ASN1_STRING_dup(keyid
->value
.octet_string
);
3884 attr
->type
= V_ASN1_OCTET_STRING
;
3885 attr
->value
.ptr
= (char *)attr
->value
.octet_string
;
3886 ret
= set_pkey_attrib(pkey
, attr
, NID_localKeyID
);
3890 if (ret
== KMF_OK
&& fname
!= NULL
&&
3891 fname
->type
== V_ASN1_BMPSTRING
) {
3892 if ((attr
= ASN1_TYPE_new()) == NULL
)
3893 return (KMF_ERR_MEMORY
);
3894 attr
->value
.bmpstring
=
3895 ASN1_STRING_dup(fname
->value
.bmpstring
);
3896 attr
->type
= V_ASN1_BMPSTRING
;
3897 attr
->value
.ptr
= (char *)attr
->value
.bmpstring
;
3898 ret
= set_pkey_attrib(pkey
, attr
, NID_friendlyName
);
3902 if (ret
== KMF_OK
&& keylist
!= NULL
&&
3903 sk_EVP_PKEY_push(keylist
, pkey
) == 0)
3904 ret
= KMF_ERR_MEMORY
;
3906 if (ret
== KMF_OK
&& keylist
!= NULL
)
3910 EVP_PKEY_free(pkey
);
3920 openssl_pkcs12_parse(PKCS12
*p12
, char *pin
,
3921 STACK_OF(EVP_PKEY
) *keys
,
3922 STACK_OF(X509
) *certs
,
3926 KMF_RETURN ret
= KMF_OK
;
3927 STACK_OF(PKCS7
) *asafes
= NULL
;
3928 STACK_OF(PKCS12_SAFEBAG
) *bags
= NULL
;
3932 if (p12
== NULL
|| (keys
== NULL
&& certs
== NULL
))
3933 return (KMF_ERR_BAD_PARAMETER
);
3935 if (pin
== NULL
|| *pin
== NULL
) {
3936 if (PKCS12_verify_mac(p12
, NULL
, 0)) {
3938 } else if (PKCS12_verify_mac(p12
, "", 0)) {
3941 return (KMF_ERR_AUTH_FAILED
);
3943 } else if (!PKCS12_verify_mac(p12
, pin
, -1)) {
3944 return (KMF_ERR_AUTH_FAILED
);
3947 if ((asafes
= PKCS12_unpack_authsafes(p12
)) == NULL
)
3948 return (KMF_ERR_PKCS12_FORMAT
);
3950 for (i
= 0; ret
== KMF_OK
&& i
< sk_PKCS7_num(asafes
); i
++) {
3952 p7
= sk_PKCS7_value(asafes
, i
);
3953 bagnid
= OBJ_obj2nid(p7
->type
);
3955 if (bagnid
== NID_pkcs7_data
) {
3956 bags
= PKCS12_unpack_p7data(p7
);
3957 } else if (bagnid
== NID_pkcs7_encrypted
) {
3958 bags
= PKCS12_unpack_p7encdata(p7
, pin
,
3959 (pin
? strlen(pin
) : 0));
3964 ret
= KMF_ERR_PKCS12_FORMAT
;
3968 if (openssl_parse_bags(bags
, pin
, keys
, certs
) != KMF_OK
)
3969 ret
= KMF_ERR_PKCS12_FORMAT
;
3971 sk_PKCS12_SAFEBAG_pop_free(bags
, PKCS12_SAFEBAG_free
);
3975 sk_PKCS7_pop_free(asafes
, PKCS7_free
);
3981 * Helper function to decrypt and parse PKCS#12 import file.
3984 extract_pkcs12(BIO
*fbio
, CK_UTF8CHAR
*pin
, CK_ULONG pinlen
,
3985 STACK_OF(EVP_PKEY
) **priv_key
, STACK_OF(X509
) **certs
,
3986 STACK_OF(X509
) **ca
)
3989 PKCS12
*pk12
, *pk12_tmp
;
3990 STACK_OF(EVP_PKEY
) *pkeylist
= NULL
;
3991 STACK_OF(X509
) *xcertlist
= NULL
;
3992 STACK_OF(X509
) *cacertlist
= NULL
;
3994 if ((pk12
= PKCS12_new()) == NULL
) {
3995 return (KMF_ERR_MEMORY
);
3998 if ((pk12_tmp
= d2i_PKCS12_bio(fbio
, &pk12
)) == NULL
) {
3999 /* This is ok; it seems to mean there is no more to read. */
4000 if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_ASN1
&&
4001 ERR_GET_REASON(ERR_peek_error()) == ASN1_R_HEADER_TOO_LONG
)
4002 goto end_extract_pkcs12
;
4005 return (KMF_ERR_PKCS12_FORMAT
);
4009 xcertlist
= sk_X509_new_null();
4010 if (xcertlist
== NULL
) {
4012 return (KMF_ERR_MEMORY
);
4014 pkeylist
= sk_EVP_PKEY_new_null();
4015 if (pkeylist
== NULL
) {
4016 sk_X509_pop_free(xcertlist
, X509_free
);
4018 return (KMF_ERR_MEMORY
);
4021 if (openssl_pkcs12_parse(pk12
, (char *)pin
, pkeylist
, xcertlist
,
4022 cacertlist
) != KMF_OK
) {
4023 sk_X509_pop_free(xcertlist
, X509_free
);
4024 sk_EVP_PKEY_pop_free(pkeylist
, EVP_PKEY_free
);
4026 return (KMF_ERR_PKCS12_FORMAT
);
4029 if (priv_key
&& pkeylist
)
4030 *priv_key
= pkeylist
;
4032 sk_EVP_PKEY_pop_free(pkeylist
, EVP_PKEY_free
);
4033 if (certs
&& xcertlist
)
4036 sk_X509_pop_free(xcertlist
, X509_free
);
4037 if (ca
&& cacertlist
)
4039 else if (cacertlist
)
4040 sk_X509_pop_free(cacertlist
, X509_free
);
4049 sslBN2KMFBN(BIGNUM
*from
, KMF_BIGINT
*to
)
4051 KMF_RETURN rv
= KMF_OK
;
4054 sz
= BN_num_bytes(from
);
4055 to
->val
= (uchar_t
*)malloc(sz
);
4056 if (to
->val
== NULL
)
4057 return (KMF_ERR_MEMORY
);
4059 if ((to
->len
= BN_bn2bin(from
, to
->val
)) != sz
) {
4063 rv
= KMF_ERR_MEMORY
;
4070 exportRawRSAKey(RSA
*rsa
, KMF_RAW_KEY_DATA
*key
)
4073 KMF_RAW_RSA_KEY
*kmfkey
= &key
->rawdata
.rsa
;
4075 (void) memset(kmfkey
, 0, sizeof (KMF_RAW_RSA_KEY
));
4076 if ((rv
= sslBN2KMFBN(rsa
->n
, &kmfkey
->mod
)) != KMF_OK
)
4079 if ((rv
= sslBN2KMFBN(rsa
->e
, &kmfkey
->pubexp
)) != KMF_OK
)
4083 if ((rv
= sslBN2KMFBN(rsa
->d
, &kmfkey
->priexp
)) != KMF_OK
)
4087 if ((rv
= sslBN2KMFBN(rsa
->p
, &kmfkey
->prime1
)) != KMF_OK
)
4091 if ((rv
= sslBN2KMFBN(rsa
->q
, &kmfkey
->prime2
)) != KMF_OK
)
4094 if (rsa
->dmp1
!= NULL
)
4095 if ((rv
= sslBN2KMFBN(rsa
->dmp1
, &kmfkey
->exp1
)) != KMF_OK
)
4098 if (rsa
->dmq1
!= NULL
)
4099 if ((rv
= sslBN2KMFBN(rsa
->dmq1
, &kmfkey
->exp2
)) != KMF_OK
)
4102 if (rsa
->iqmp
!= NULL
)
4103 if ((rv
= sslBN2KMFBN(rsa
->iqmp
, &kmfkey
->coef
)) != KMF_OK
)
4107 kmf_free_raw_key(key
);
4109 key
->keytype
= KMF_RSA
;
4112 * Free the reference to this key, SSL will not actually free
4113 * the memory until the refcount == 0, so this is safe.
4121 exportRawDSAKey(DSA
*dsa
, KMF_RAW_KEY_DATA
*key
)
4124 KMF_RAW_DSA_KEY
*kmfkey
= &key
->rawdata
.dsa
;
4126 (void) memset(kmfkey
, 0, sizeof (KMF_RAW_DSA_KEY
));
4127 if ((rv
= sslBN2KMFBN(dsa
->p
, &kmfkey
->prime
)) != KMF_OK
)
4130 if ((rv
= sslBN2KMFBN(dsa
->q
, &kmfkey
->subprime
)) != KMF_OK
)
4133 if ((rv
= sslBN2KMFBN(dsa
->g
, &kmfkey
->base
)) != KMF_OK
)
4136 if ((rv
= sslBN2KMFBN(dsa
->priv_key
, &kmfkey
->value
)) != KMF_OK
)
4141 kmf_free_raw_key(key
);
4143 key
->keytype
= KMF_DSA
;
4146 * Free the reference to this key, SSL will not actually free
4147 * the memory until the refcount == 0, so this is safe.
4155 add_cert_to_list(KMF_HANDLE
*kmfh
, X509
*sslcert
,
4156 KMF_X509_DER_CERT
**certlist
, int *ncerts
)
4158 KMF_RETURN rv
= KMF_OK
;
4159 KMF_X509_DER_CERT
*list
= (*certlist
);
4160 KMF_X509_DER_CERT cert
;
4164 list
= (KMF_X509_DER_CERT
*)malloc(sizeof (KMF_X509_DER_CERT
));
4166 list
= (KMF_X509_DER_CERT
*)realloc(list
,
4167 sizeof (KMF_X509_DER_CERT
) * (n
+ 1));
4171 return (KMF_ERR_MEMORY
);
4173 (void) memset(&cert
, 0, sizeof (cert
));
4174 rv
= ssl_cert2KMFDATA(kmfh
, sslcert
, &cert
.certificate
);
4177 /* Get the alias name for the cert if there is one */
4178 char *a
= (char *)X509_alias_get0(sslcert
, &len
);
4180 cert
.kmf_private
.label
= strdup(a
);
4181 cert
.kmf_private
.keystore_type
= KMF_KEYSTORE_OPENSSL
;
4195 add_key_to_list(KMF_RAW_KEY_DATA
**keylist
,
4196 KMF_RAW_KEY_DATA
*newkey
, int *nkeys
)
4198 KMF_RAW_KEY_DATA
*list
= (*keylist
);
4202 list
= (KMF_RAW_KEY_DATA
*)malloc(sizeof (KMF_RAW_KEY_DATA
));
4204 list
= (KMF_RAW_KEY_DATA
*)realloc(list
,
4205 sizeof (KMF_RAW_KEY_DATA
) * (n
+ 1));
4209 return (KMF_ERR_MEMORY
);
4219 static X509_ATTRIBUTE
*
4220 find_attr(STACK_OF(X509_ATTRIBUTE
) *attrs
, int nid
)
4228 for (i
= 0; i
< sk_X509_ATTRIBUTE_num(attrs
); i
++) {
4229 a
= sk_X509_ATTRIBUTE_value(attrs
, i
);
4230 if (OBJ_obj2nid(a
->object
) == nid
)
4237 convertToRawKey(EVP_PKEY
*pkey
, KMF_RAW_KEY_DATA
*key
)
4239 KMF_RETURN rv
= KMF_OK
;
4240 X509_ATTRIBUTE
*attr
;
4242 if (pkey
== NULL
|| key
== NULL
)
4243 return (KMF_ERR_BAD_PARAMETER
);
4244 /* Convert SSL key to raw key */
4245 switch (pkey
->type
) {
4247 rv
= exportRawRSAKey(EVP_PKEY_get1_RSA(pkey
),
4253 rv
= exportRawDSAKey(EVP_PKEY_get1_DSA(pkey
),
4259 return (KMF_ERR_BAD_PARAMETER
);
4262 * If friendlyName, add it to record.
4264 attr
= find_attr(pkey
->attributes
, NID_friendlyName
);
4266 ASN1_TYPE
*ty
= NULL
;
4267 int numattr
= sk_ASN1_TYPE_num(attr
->value
.set
);
4268 if (attr
->single
== 0 && numattr
> 0) {
4269 ty
= sk_ASN1_TYPE_value(attr
->value
.set
, 0);
4272 #if OPENSSL_VERSION_NUMBER < 0x10000000L
4273 key
->label
= uni2asc(ty
->value
.bmpstring
->data
,
4274 ty
->value
.bmpstring
->length
);
4276 key
->label
= OPENSSL_uni2asc(ty
->value
.bmpstring
->data
,
4277 ty
->value
.bmpstring
->length
);
4285 * If KeyID, add it to record as a KMF_DATA object.
4287 attr
= find_attr(pkey
->attributes
, NID_localKeyID
);
4289 ASN1_TYPE
*ty
= NULL
;
4290 int numattr
= sk_ASN1_TYPE_num(attr
->value
.set
);
4291 if (attr
->single
== 0 && numattr
> 0) {
4292 ty
= sk_ASN1_TYPE_value(attr
->value
.set
, 0);
4294 key
->id
.Data
= (uchar_t
*)malloc(
4295 ty
->value
.octet_string
->length
);
4296 if (key
->id
.Data
== NULL
)
4297 return (KMF_ERR_MEMORY
);
4298 (void) memcpy(key
->id
.Data
, ty
->value
.octet_string
->data
,
4299 ty
->value
.octet_string
->length
);
4300 key
->id
.Length
= ty
->value
.octet_string
->length
;
4302 (void) memset(&key
->id
, 0, sizeof (KMF_DATA
));
4311 STACK_OF(EVP_PKEY
) *sslkeys
,
4312 STACK_OF(X509
) *sslcert
,
4313 STACK_OF(X509
) *sslcacerts
,
4314 KMF_RAW_KEY_DATA
**keylist
, int *nkeys
,
4315 KMF_X509_DER_CERT
**certlist
, int *ncerts
)
4317 KMF_RETURN rv
= KMF_OK
;
4318 KMF_RAW_KEY_DATA key
;
4321 for (i
= 0; sslkeys
!= NULL
&& i
< sk_EVP_PKEY_num(sslkeys
); i
++) {
4322 EVP_PKEY
*pkey
= sk_EVP_PKEY_value(sslkeys
, i
);
4323 rv
= convertToRawKey(pkey
, &key
);
4325 rv
= add_key_to_list(keylist
, &key
, nkeys
);
4331 /* Now add the certificate to the certlist */
4332 for (i
= 0; sslcert
!= NULL
&& i
< sk_X509_num(sslcert
); i
++) {
4333 X509
*cert
= sk_X509_value(sslcert
, i
);
4334 rv
= add_cert_to_list(kmfh
, cert
, certlist
, ncerts
);
4339 /* Also add any included CA certs to the list */
4340 for (i
= 0; sslcacerts
!= NULL
&& i
< sk_X509_num(sslcacerts
); i
++) {
4343 * sk_X509_value() is macro that embeds a cast to (X509 *).
4344 * Here it translates into ((X509 *)sk_value((ca), (i))).
4345 * Lint is complaining about the embedded casting, and
4346 * to fix it, you need to fix openssl header files.
4348 c
= sk_X509_value(sslcacerts
, i
);
4350 /* Now add the ca cert to the certlist */
4351 rv
= add_cert_to_list(kmfh
, c
, certlist
, ncerts
);
4359 openssl_import_objects(KMF_HANDLE
*kmfh
,
4360 char *filename
, KMF_CREDENTIAL
*cred
,
4361 KMF_X509_DER_CERT
**certlist
, int *ncerts
,
4362 KMF_RAW_KEY_DATA
**keylist
, int *nkeys
)
4364 KMF_RETURN rv
= KMF_OK
;
4365 KMF_ENCODE_FORMAT format
;
4367 STACK_OF(EVP_PKEY
) *privkeys
= NULL
;
4368 STACK_OF(X509
) *certs
= NULL
;
4369 STACK_OF(X509
) *cacerts
= NULL
;
4372 * auto-detect the file format, regardless of what
4373 * the 'format' parameters in the params say.
4375 rv
= kmf_get_file_format(filename
, &format
);
4380 /* This function only works for PEM or PKCS#12 files */
4381 if (format
!= KMF_FORMAT_PEM
&&
4382 format
!= KMF_FORMAT_PEM_KEYPAIR
&&
4383 format
!= KMF_FORMAT_PKCS12
)
4384 return (KMF_ERR_ENCODING
);
4391 if (format
== KMF_FORMAT_PKCS12
) {
4392 bio
= BIO_new_file(filename
, "rb");
4394 SET_ERROR(kmfh
, ERR_get_error());
4395 rv
= KMF_ERR_OPEN_FILE
;
4399 rv
= extract_pkcs12(bio
, (uchar_t
*)cred
->cred
,
4400 (uint32_t)cred
->credlen
, &privkeys
, &certs
, &cacerts
);
4403 /* Convert keys and certs to exportable format */
4404 rv
= convertPK12Objects(kmfh
, privkeys
, certs
, cacerts
,
4405 keylist
, nkeys
, certlist
, ncerts
);
4408 KMF_DATA
*certdata
= NULL
;
4409 KMF_X509_DER_CERT
*kmfcerts
= NULL
;
4411 rv
= extract_pem(kmfh
, NULL
, NULL
, NULL
, filename
,
4412 (uchar_t
*)cred
->cred
, (uint32_t)cred
->credlen
,
4413 &pkey
, &certdata
, ncerts
);
4415 /* Reached end of import file? */
4416 if (rv
== KMF_OK
&& pkey
!= NULL
) {
4417 privkeys
= sk_EVP_PKEY_new_null();
4418 if (privkeys
== NULL
) {
4419 rv
= KMF_ERR_MEMORY
;
4422 (void) sk_EVP_PKEY_push(privkeys
, pkey
);
4423 /* convert the certificate list here */
4424 if (*ncerts
> 0 && certlist
!= NULL
) {
4425 kmfcerts
= (KMF_X509_DER_CERT
*)calloc(*ncerts
,
4426 sizeof (KMF_X509_DER_CERT
));
4427 if (kmfcerts
== NULL
) {
4428 rv
= KMF_ERR_MEMORY
;
4431 for (i
= 0; i
< *ncerts
; i
++) {
4432 kmfcerts
[i
].certificate
= certdata
[i
];
4433 kmfcerts
[i
].kmf_private
.keystore_type
=
4434 KMF_KEYSTORE_OPENSSL
;
4436 *certlist
= kmfcerts
;
4439 * Convert keys to exportable format, the certs
4442 rv
= convertPK12Objects(kmfh
, privkeys
, NULL
, NULL
,
4443 keylist
, nkeys
, NULL
, NULL
);
4448 (void) BIO_free(bio
);
4451 sk_EVP_PKEY_pop_free(privkeys
, EVP_PKEY_free
);
4453 sk_X509_pop_free(certs
, X509_free
);
4455 sk_X509_pop_free(cacerts
, X509_free
);
4461 create_deskey(DES_cblock
**deskey
)
4465 key
= (DES_cblock
*) malloc(sizeof (DES_cblock
));
4467 return (KMF_ERR_MEMORY
);
4470 if (DES_random_key(key
) == 0) {
4472 return (KMF_ERR_KEYGEN_FAILED
);
4479 #define KEYGEN_RETRY 3
4480 #define DES3_KEY_SIZE 24
4483 create_des3key(unsigned char **des3key
)
4485 KMF_RETURN ret
= KMF_OK
;
4486 DES_cblock
*deskey1
= NULL
;
4487 DES_cblock
*deskey2
= NULL
;
4488 DES_cblock
*deskey3
= NULL
;
4489 unsigned char *newkey
= NULL
;
4492 if ((newkey
= malloc(DES3_KEY_SIZE
)) == NULL
) {
4493 return (KMF_ERR_MEMORY
);
4496 /* create the 1st DES key */
4497 if ((ret
= create_deskey(&deskey1
)) != KMF_OK
) {
4502 * Create the 2nd DES key and make sure its value is different
4503 * from the 1st DES key.
4507 if (deskey2
!= NULL
) {
4512 if ((ret
= create_deskey(&deskey2
)) != KMF_OK
) {
4516 if (memcmp((const void *) deskey1
, (const void *) deskey2
, 8)
4518 ret
= KMF_ERR_KEYGEN_FAILED
;
4521 } while (ret
== KMF_ERR_KEYGEN_FAILED
&& retry
< KEYGEN_RETRY
);
4523 if (ret
!= KMF_OK
) {
4528 * Create the 3rd DES key and make sure its value is different
4529 * from the 2nd DES key.
4533 if (deskey3
!= NULL
) {
4538 if ((ret
= create_deskey(&deskey3
)) != KMF_OK
) {
4542 if (memcmp((const void *)deskey2
, (const void *)deskey3
, 8)
4544 ret
= KMF_ERR_KEYGEN_FAILED
;
4547 } while (ret
== KMF_ERR_KEYGEN_FAILED
&& retry
< KEYGEN_RETRY
);
4549 if (ret
!= KMF_OK
) {
4553 /* Concatenate 3 DES keys into a DES3 key */
4554 (void) memcpy((void *)newkey
, (const void *)deskey1
, 8);
4555 (void) memcpy((void *)(newkey
+ 8), (const void *)deskey2
, 8);
4556 (void) memcpy((void *)(newkey
+ 16), (const void *)deskey3
, 8);
4560 if (deskey1
!= NULL
)
4563 if (deskey2
!= NULL
)
4566 if (deskey3
!= NULL
)
4569 if (ret
!= KMF_OK
&& newkey
!= NULL
)
4576 OpenSSL_CreateSymKey(KMF_HANDLE_T handle
,
4577 int numattr
, KMF_ATTRIBUTE
*attrlist
)
4579 KMF_RETURN ret
= KMF_OK
;
4580 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
4581 char *fullpath
= NULL
;
4582 KMF_RAW_SYM_KEY
*rkey
= NULL
;
4583 DES_cblock
*deskey
= NULL
;
4584 unsigned char *des3key
= NULL
;
4585 unsigned char *random
= NULL
;
4587 KMF_KEY_HANDLE
*symkey
;
4588 KMF_KEY_ALG keytype
;
4590 uint32_t keylen_size
= sizeof (keylen
);
4595 return (KMF_ERR_UNINITIALIZED
);
4597 symkey
= kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR
, attrlist
, numattr
);
4599 return (KMF_ERR_BAD_PARAMETER
);
4601 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
4603 keyfile
= kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
, attrlist
, numattr
);
4604 if (keyfile
== NULL
)
4605 return (KMF_ERR_BAD_PARAMETER
);
4607 ret
= kmf_get_attr(KMF_KEYALG_ATTR
, attrlist
, numattr
,
4608 (void *)&keytype
, NULL
);
4610 return (KMF_ERR_BAD_PARAMETER
);
4612 ret
= kmf_get_attr(KMF_KEYLENGTH_ATTR
, attrlist
, numattr
,
4613 &keylen
, &keylen_size
);
4614 if (ret
== KMF_ERR_ATTR_NOT_FOUND
&&
4615 (keytype
== KMF_DES
|| keytype
== KMF_DES3
))
4616 /* keylength is not required for DES and 3DES */
4619 return (KMF_ERR_BAD_PARAMETER
);
4621 fullpath
= get_fullpath(dirpath
, keyfile
);
4622 if (fullpath
== NULL
)
4623 return (KMF_ERR_BAD_PARAMETER
);
4625 /* If the requested file exists, return an error */
4626 if (test_for_file(fullpath
, 0400) == 1) {
4628 return (KMF_ERR_DUPLICATE_KEYFILE
);
4631 fd
= open(fullpath
, O_CREAT
|O_TRUNC
|O_RDWR
, 0400);
4633 ret
= KMF_ERR_OPEN_FILE
;
4637 rkey
= malloc(sizeof (KMF_RAW_SYM_KEY
));
4639 ret
= KMF_ERR_MEMORY
;
4642 (void) memset(rkey
, 0, sizeof (KMF_RAW_SYM_KEY
));
4644 if (keytype
== KMF_DES
) {
4645 if ((ret
= create_deskey(&deskey
)) != KMF_OK
) {
4648 rkey
->keydata
.val
= (uchar_t
*)deskey
;
4649 rkey
->keydata
.len
= 8;
4651 symkey
->keyalg
= KMF_DES
;
4653 } else if (keytype
== KMF_DES3
) {
4654 if ((ret
= create_des3key(&des3key
)) != KMF_OK
) {
4657 rkey
->keydata
.val
= (uchar_t
*)des3key
;
4658 rkey
->keydata
.len
= DES3_KEY_SIZE
;
4659 symkey
->keyalg
= KMF_DES3
;
4661 } else if (keytype
== KMF_AES
|| keytype
== KMF_RC4
||
4662 keytype
== KMF_GENERIC_SECRET
) {
4665 if (keylen
% 8 != 0) {
4666 ret
= KMF_ERR_BAD_KEY_SIZE
;
4670 if (keytype
== KMF_AES
) {
4671 if (keylen
!= 128 &&
4674 ret
= KMF_ERR_BAD_KEY_SIZE
;
4680 random
= malloc(bytes
);
4681 if (random
== NULL
) {
4682 ret
= KMF_ERR_MEMORY
;
4685 if (RAND_bytes(random
, bytes
) != 1) {
4686 ret
= KMF_ERR_KEYGEN_FAILED
;
4690 rkey
->keydata
.val
= (uchar_t
*)random
;
4691 rkey
->keydata
.len
= bytes
;
4692 symkey
->keyalg
= keytype
;
4695 ret
= KMF_ERR_BAD_KEY_TYPE
;
4699 (void) write(fd
, (const void *) rkey
->keydata
.val
, rkey
->keydata
.len
);
4701 symkey
->kstype
= KMF_KEYSTORE_OPENSSL
;
4702 symkey
->keyclass
= KMF_SYMMETRIC
;
4703 symkey
->keylabel
= (char *)fullpath
;
4704 symkey
->israw
= TRUE
;
4705 symkey
->keyp
= rkey
;
4711 if (ret
!= KMF_OK
&& fullpath
!= NULL
) {
4714 if (ret
!= KMF_OK
) {
4715 kmf_free_raw_sym_key(rkey
);
4716 symkey
->keyp
= NULL
;
4717 symkey
->keyalg
= KMF_KEYALG_NONE
;
4724 * Check a file to see if it is a CRL file with PEM or DER format.
4725 * If success, return its format in the "pformat" argument.
4728 OpenSSL_IsCRLFile(KMF_HANDLE_T handle
, char *filename
, int *pformat
)
4730 KMF_RETURN ret
= KMF_OK
;
4731 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
4733 X509_CRL
*xcrl
= NULL
;
4735 if (filename
== NULL
) {
4736 return (KMF_ERR_BAD_PARAMETER
);
4739 bio
= BIO_new_file(filename
, "rb");
4741 SET_ERROR(kmfh
, ERR_get_error());
4742 ret
= KMF_ERR_OPEN_FILE
;
4746 if ((xcrl
= PEM_read_bio_X509_CRL(bio
, NULL
, NULL
, NULL
)) != NULL
) {
4747 *pformat
= KMF_FORMAT_PEM
;
4750 (void) BIO_free(bio
);
4753 * Now try to read it as raw DER data.
4755 bio
= BIO_new_file(filename
, "rb");
4757 SET_ERROR(kmfh
, ERR_get_error());
4758 ret
= KMF_ERR_OPEN_FILE
;
4762 if ((xcrl
= d2i_X509_CRL_bio(bio
, NULL
)) != NULL
) {
4763 *pformat
= KMF_FORMAT_ASN1
;
4765 ret
= KMF_ERR_BAD_CRLFILE
;
4770 (void) BIO_free(bio
);
4773 X509_CRL_free(xcrl
);
4779 OpenSSL_GetSymKeyValue(KMF_HANDLE_T handle
, KMF_KEY_HANDLE
*symkey
,
4780 KMF_RAW_SYM_KEY
*rkey
)
4782 KMF_RETURN rv
= KMF_OK
;
4783 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
4787 return (KMF_ERR_UNINITIALIZED
);
4789 if (symkey
== NULL
|| rkey
== NULL
)
4790 return (KMF_ERR_BAD_PARAMETER
);
4791 else if (symkey
->keyclass
!= KMF_SYMMETRIC
)
4792 return (KMF_ERR_BAD_KEY_CLASS
);
4794 if (symkey
->israw
) {
4795 KMF_RAW_SYM_KEY
*rawkey
= (KMF_RAW_SYM_KEY
*)symkey
->keyp
;
4797 if (rawkey
== NULL
||
4798 rawkey
->keydata
.val
== NULL
||
4799 rawkey
->keydata
.len
== 0)
4800 return (KMF_ERR_BAD_KEYHANDLE
);
4802 rkey
->keydata
.len
= rawkey
->keydata
.len
;
4803 if ((rkey
->keydata
.val
= malloc(rkey
->keydata
.len
)) == NULL
)
4804 return (KMF_ERR_MEMORY
);
4805 (void) memcpy(rkey
->keydata
.val
, rawkey
->keydata
.val
,
4808 rv
= kmf_read_input_file(handle
, symkey
->keylabel
, &keyvalue
);
4811 rkey
->keydata
.len
= keyvalue
.Length
;
4812 rkey
->keydata
.val
= keyvalue
.Data
;
4819 * substitute for the unsafe access(2) function.
4820 * If the file in question already exists, return 1.
4821 * else 0. If an error occurs during testing (other
4822 * than EEXIST), return -1.
4825 test_for_file(char *filename
, mode_t mode
)
4830 * Try to create the file with the EXCL flag.
4831 * The call should fail if the file exists.
4833 fd
= open(filename
, O_WRONLY
|O_CREAT
|O_EXCL
, mode
);
4834 if (fd
== -1 && errno
== EEXIST
)
4836 else if (fd
== -1) /* some other error */
4839 /* The file did NOT exist. Delete the testcase. */
4841 (void) unlink(filename
);
4846 OpenSSL_StoreKey(KMF_HANDLE_T handle
, int numattr
,
4847 KMF_ATTRIBUTE
*attrlist
)
4849 KMF_RETURN rv
= KMF_OK
;
4850 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
4851 KMF_KEY_HANDLE
*pubkey
= NULL
, *prikey
= NULL
;
4852 KMF_RAW_KEY_DATA
*rawkey
;
4853 EVP_PKEY
*pkey
= NULL
;
4854 KMF_ENCODE_FORMAT format
= KMF_FORMAT_PEM
;
4855 KMF_CREDENTIAL cred
= {NULL
, 0};
4858 char *fullpath
= NULL
;
4859 char *keyfile
= NULL
;
4860 char *dirpath
= NULL
;
4862 pubkey
= kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR
, attrlist
, numattr
);
4866 prikey
= kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR
, attrlist
, numattr
);
4870 rawkey
= kmf_get_attr_ptr(KMF_RAW_KEY_ATTR
, attrlist
, numattr
);
4875 * Exactly 1 type of key must be passed to this function.
4878 return (KMF_ERR_BAD_PARAMETER
);
4880 keyfile
= (char *)kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
, attrlist
,
4882 if (keyfile
== NULL
)
4883 return (KMF_ERR_BAD_PARAMETER
);
4885 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
4887 fullpath
= get_fullpath(dirpath
, keyfile
);
4889 /* Once we have the full path, we don't need the pieces */
4890 if (fullpath
== NULL
)
4891 return (KMF_ERR_BAD_PARAMETER
);
4893 /* If the requested file exists, return an error */
4894 if (test_for_file(fullpath
, 0400) == 1) {
4896 return (KMF_ERR_DUPLICATE_KEYFILE
);
4899 rv
= kmf_get_attr(KMF_ENCODE_FORMAT_ATTR
, attrlist
, numattr
,
4902 /* format is optional. */
4905 /* CRED is not required for OpenSSL files */
4906 (void) kmf_get_attr(KMF_CREDENTIAL_ATTR
, attrlist
, numattr
,
4909 /* Store the private key to the keyfile */
4910 out
= BIO_new_file(fullpath
, "wb");
4912 SET_ERROR(kmfh
, ERR_get_error());
4913 rv
= KMF_ERR_OPEN_FILE
;
4917 if (prikey
!= NULL
&& prikey
->keyp
!= NULL
) {
4918 if (prikey
->keyalg
== KMF_RSA
||
4919 prikey
->keyalg
== KMF_DSA
) {
4920 pkey
= (EVP_PKEY
*)prikey
->keyp
;
4922 rv
= ssl_write_key(kmfh
, format
,
4923 out
, &cred
, pkey
, TRUE
);
4925 if (rv
== KMF_OK
&& prikey
->keylabel
== NULL
) {
4926 prikey
->keylabel
= strdup(fullpath
);
4927 if (prikey
->keylabel
== NULL
)
4928 rv
= KMF_ERR_MEMORY
;
4931 } else if (pubkey
!= NULL
&& pubkey
->keyp
!= NULL
) {
4932 if (pubkey
->keyalg
== KMF_RSA
||
4933 pubkey
->keyalg
== KMF_DSA
) {
4934 pkey
= (EVP_PKEY
*)pubkey
->keyp
;
4936 rv
= ssl_write_key(kmfh
, format
,
4937 out
, &cred
, pkey
, FALSE
);
4939 if (rv
== KMF_OK
&& pubkey
->keylabel
== NULL
) {
4940 pubkey
->keylabel
= strdup(fullpath
);
4941 if (pubkey
->keylabel
== NULL
)
4942 rv
= KMF_ERR_MEMORY
;
4945 } else if (rawkey
!= NULL
) {
4946 if (rawkey
->keytype
== KMF_RSA
) {
4947 pkey
= ImportRawRSAKey(&rawkey
->rawdata
.rsa
);
4948 } else if (rawkey
->keytype
== KMF_DSA
) {
4949 pkey
= ImportRawDSAKey(&rawkey
->rawdata
.dsa
);
4951 rv
= KMF_ERR_BAD_PARAMETER
;
4954 KMF_KEY_CLASS kclass
= KMF_ASYM_PRI
;
4956 rv
= kmf_get_attr(KMF_KEYCLASS_ATTR
, attrlist
, numattr
,
4957 (void *)&kclass
, NULL
);
4960 rv
= ssl_write_key(kmfh
, format
, out
,
4961 &cred
, pkey
, (kclass
== KMF_ASYM_PRI
));
4962 EVP_PKEY_free(pkey
);
4969 (void) BIO_free(out
);
4973 (void) chmod(fullpath
, 0400);
4980 OpenSSL_ImportCRL(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
4982 KMF_RETURN ret
= KMF_OK
;
4983 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
4984 X509_CRL
*xcrl
= NULL
;
4987 KMF_ENCODE_FORMAT format
;
4988 BIO
*in
= NULL
, *out
= NULL
;
4989 int openssl_ret
= 0;
4990 KMF_ENCODE_FORMAT outformat
;
4991 boolean_t crlcheck
= FALSE
;
4992 char *certfile
, *dirpath
, *crlfile
, *incrl
, *outcrl
, *outcrlfile
;
4994 if (numattr
== 0 || attrlist
== NULL
) {
4995 return (KMF_ERR_BAD_PARAMETER
);
4998 /* CRL check is optional */
4999 (void) kmf_get_attr(KMF_CRL_CHECK_ATTR
, attrlist
, numattr
,
5002 certfile
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
, numattr
);
5003 if (crlcheck
== B_TRUE
&& certfile
== NULL
) {
5004 return (KMF_ERR_BAD_CERTFILE
);
5007 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
5008 incrl
= kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR
, attrlist
, numattr
);
5009 outcrl
= kmf_get_attr_ptr(KMF_CRL_OUTFILE_ATTR
, attrlist
, numattr
);
5011 crlfile
= get_fullpath(dirpath
, incrl
);
5013 if (crlfile
== NULL
)
5014 return (KMF_ERR_BAD_CRLFILE
);
5016 outcrlfile
= get_fullpath(dirpath
, outcrl
);
5017 if (outcrlfile
== NULL
)
5018 return (KMF_ERR_BAD_CRLFILE
);
5020 if (isdir(outcrlfile
)) {
5022 return (KMF_ERR_BAD_CRLFILE
);
5025 ret
= kmf_is_crl_file(handle
, crlfile
, &format
);
5026 if (ret
!= KMF_OK
) {
5031 in
= BIO_new_file(crlfile
, "rb");
5033 SET_ERROR(kmfh
, ERR_get_error());
5034 ret
= KMF_ERR_OPEN_FILE
;
5038 if (format
== KMF_FORMAT_ASN1
) {
5039 xcrl
= d2i_X509_CRL_bio(in
, NULL
);
5040 } else if (format
== KMF_FORMAT_PEM
) {
5041 xcrl
= PEM_read_bio_X509_CRL(in
, NULL
, NULL
, NULL
);
5045 SET_ERROR(kmfh
, ERR_get_error());
5046 ret
= KMF_ERR_BAD_CRLFILE
;
5050 /* If bypasscheck is specified, no need to verify. */
5051 if (crlcheck
== B_FALSE
)
5054 ret
= kmf_is_cert_file(handle
, certfile
, &format
);
5058 /* Read in the CA cert file and convert to X509 */
5059 if (BIO_read_filename(in
, certfile
) <= 0) {
5060 SET_ERROR(kmfh
, ERR_get_error());
5061 ret
= KMF_ERR_OPEN_FILE
;
5065 if (format
== KMF_FORMAT_ASN1
) {
5066 xcert
= d2i_X509_bio(in
, NULL
);
5067 } else if (format
== KMF_FORMAT_PEM
) {
5068 xcert
= PEM_read_bio_X509(in
, NULL
, NULL
, NULL
);
5070 ret
= KMF_ERR_BAD_CERT_FORMAT
;
5074 if (xcert
== NULL
) {
5075 SET_ERROR(kmfh
, ERR_get_error());
5076 ret
= KMF_ERR_BAD_CERT_FORMAT
;
5079 /* Now get the public key from the CA cert */
5080 pkey
= X509_get_pubkey(xcert
);
5082 SET_ERROR(kmfh
, ERR_get_error());
5083 ret
= KMF_ERR_BAD_CERTFILE
;
5087 /* Verify the CRL with the CA's public key */
5088 openssl_ret
= X509_CRL_verify(xcrl
, pkey
);
5089 EVP_PKEY_free(pkey
);
5090 if (openssl_ret
> 0) {
5091 ret
= KMF_OK
; /* verify succeed */
5093 SET_ERROR(kmfh
, openssl_ret
);
5094 ret
= KMF_ERR_BAD_CRLFILE
;
5098 ret
= kmf_get_attr(KMF_ENCODE_FORMAT_ATTR
, attrlist
, numattr
,
5100 if (ret
!= KMF_OK
) {
5102 outformat
= KMF_FORMAT_PEM
;
5105 out
= BIO_new_file(outcrlfile
, "wb");
5107 SET_ERROR(kmfh
, ERR_get_error());
5108 ret
= KMF_ERR_OPEN_FILE
;
5112 if (outformat
== KMF_FORMAT_ASN1
) {
5113 openssl_ret
= (int)i2d_X509_CRL_bio(out
, xcrl
);
5114 } else if (outformat
== KMF_FORMAT_PEM
) {
5115 openssl_ret
= PEM_write_bio_X509_CRL(out
, xcrl
);
5117 ret
= KMF_ERR_BAD_PARAMETER
;
5121 if (openssl_ret
<= 0) {
5122 SET_ERROR(kmfh
, ERR_get_error());
5123 ret
= KMF_ERR_WRITE_FILE
;
5130 X509_CRL_free(xcrl
);
5136 (void) BIO_free(in
);
5139 (void) BIO_free(out
);
5141 if (outcrlfile
!= NULL
)
5148 OpenSSL_ListCRL(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
5150 KMF_RETURN ret
= KMF_OK
;
5151 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
5153 KMF_ENCODE_FORMAT format
;
5154 char *crlfile
= NULL
;
5161 char *crlfilename
, *dirpath
;
5163 if (numattr
== 0 || attrlist
== NULL
) {
5164 return (KMF_ERR_BAD_PARAMETER
);
5166 crlfilename
= kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR
,
5168 if (crlfilename
== NULL
)
5169 return (KMF_ERR_BAD_CRLFILE
);
5171 crldata
= (char **)kmf_get_attr_ptr(KMF_CRL_DATA_ATTR
,
5174 if (crldata
== NULL
)
5175 return (KMF_ERR_BAD_PARAMETER
);
5177 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
5179 crlfile
= get_fullpath(dirpath
, crlfilename
);
5181 if (crlfile
== NULL
)
5182 return (KMF_ERR_BAD_CRLFILE
);
5184 if (isdir(crlfile
)) {
5186 return (KMF_ERR_BAD_CRLFILE
);
5189 ret
= kmf_is_crl_file(handle
, crlfile
, &format
);
5190 if (ret
!= KMF_OK
) {
5195 if (bio_err
== NULL
)
5196 bio_err
= BIO_new_fp(stderr
, BIO_NOCLOSE
);
5198 in
= BIO_new_file(crlfile
, "rb");
5200 SET_ERROR(kmfh
, ERR_get_error());
5201 ret
= KMF_ERR_OPEN_FILE
;
5205 if (format
== KMF_FORMAT_ASN1
) {
5206 x
= d2i_X509_CRL_bio(in
, NULL
);
5207 } else if (format
== KMF_FORMAT_PEM
) {
5208 x
= PEM_read_bio_X509_CRL(in
, NULL
, NULL
, NULL
);
5211 if (x
== NULL
) { /* should not happen */
5212 SET_ERROR(kmfh
, ERR_get_error());
5213 ret
= KMF_ERR_OPEN_FILE
;
5217 mem
= BIO_new(BIO_s_mem());
5219 SET_ERROR(kmfh
, ERR_get_error());
5220 ret
= KMF_ERR_MEMORY
;
5224 (void) X509_CRL_print(mem
, x
);
5225 len
= BIO_get_mem_data(mem
, &memptr
);
5227 SET_ERROR(kmfh
, ERR_get_error());
5228 ret
= KMF_ERR_MEMORY
;
5232 data
= malloc(len
+ 1);
5234 ret
= KMF_ERR_MEMORY
;
5238 (void) memcpy(data
, memptr
, len
);
5246 if (crlfile
!= NULL
)
5250 (void) BIO_free(in
);
5253 (void) BIO_free(mem
);
5259 OpenSSL_DeleteCRL(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
5261 KMF_RETURN ret
= KMF_OK
;
5262 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
5263 KMF_ENCODE_FORMAT format
;
5264 char *crlfile
= NULL
;
5266 char *crlfilename
, *dirpath
;
5268 if (numattr
== 0 || attrlist
== NULL
) {
5269 return (KMF_ERR_BAD_PARAMETER
);
5272 crlfilename
= kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR
,
5275 if (crlfilename
== NULL
)
5276 return (KMF_ERR_BAD_CRLFILE
);
5278 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
5280 crlfile
= get_fullpath(dirpath
, crlfilename
);
5282 if (crlfile
== NULL
)
5283 return (KMF_ERR_BAD_CRLFILE
);
5285 if (isdir(crlfile
)) {
5286 ret
= KMF_ERR_BAD_CRLFILE
;
5290 ret
= kmf_is_crl_file(handle
, crlfile
, &format
);
5294 if (unlink(crlfile
) != 0) {
5295 SET_SYS_ERROR(kmfh
, errno
);
5296 ret
= KMF_ERR_INTERNAL
;
5302 (void) BIO_free(in
);
5303 if (crlfile
!= NULL
)
5310 OpenSSL_FindCertInCRL(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
5312 KMF_RETURN ret
= KMF_OK
;
5313 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
5314 KMF_ENCODE_FORMAT format
;
5317 X509_CRL
*xcrl
= NULL
;
5318 STACK_OF(X509_REVOKED
) *revoke_stack
= NULL
;
5319 X509_REVOKED
*revoke
;
5321 char *crlfilename
, *crlfile
, *dirpath
, *certfile
;
5323 if (numattr
== 0 || attrlist
== NULL
) {
5324 return (KMF_ERR_BAD_PARAMETER
);
5327 crlfilename
= kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR
,
5330 if (crlfilename
== NULL
)
5331 return (KMF_ERR_BAD_CRLFILE
);
5333 certfile
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
, numattr
);
5334 if (certfile
== NULL
)
5335 return (KMF_ERR_BAD_CRLFILE
);
5337 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
5339 crlfile
= get_fullpath(dirpath
, crlfilename
);
5341 if (crlfile
== NULL
)
5342 return (KMF_ERR_BAD_CRLFILE
);
5344 if (isdir(crlfile
)) {
5345 ret
= KMF_ERR_BAD_CRLFILE
;
5349 ret
= kmf_is_crl_file(handle
, crlfile
, &format
);
5353 /* Read the CRL file and load it into a X509_CRL structure */
5354 in
= BIO_new_file(crlfilename
, "rb");
5356 SET_ERROR(kmfh
, ERR_get_error());
5357 ret
= KMF_ERR_OPEN_FILE
;
5361 if (format
== KMF_FORMAT_ASN1
) {
5362 xcrl
= d2i_X509_CRL_bio(in
, NULL
);
5363 } else if (format
== KMF_FORMAT_PEM
) {
5364 xcrl
= PEM_read_bio_X509_CRL(in
, NULL
, NULL
, NULL
);
5368 SET_ERROR(kmfh
, ERR_get_error());
5369 ret
= KMF_ERR_BAD_CRLFILE
;
5372 (void) BIO_free(in
);
5374 /* Read the Certificate file and load it into a X509 structure */
5375 ret
= kmf_is_cert_file(handle
, certfile
, &format
);
5379 in
= BIO_new_file(certfile
, "rb");
5381 SET_ERROR(kmfh
, ERR_get_error());
5382 ret
= KMF_ERR_OPEN_FILE
;
5386 if (format
== KMF_FORMAT_ASN1
) {
5387 xcert
= d2i_X509_bio(in
, NULL
);
5388 } else if (format
== KMF_FORMAT_PEM
) {
5389 xcert
= PEM_read_bio_X509(in
, NULL
, NULL
, NULL
);
5392 if (xcert
== NULL
) {
5393 SET_ERROR(kmfh
, ERR_get_error());
5394 ret
= KMF_ERR_BAD_CERTFILE
;
5398 /* Check if the certificate and the CRL have same issuer */
5399 if (X509_NAME_cmp(xcert
->cert_info
->issuer
, xcrl
->crl
->issuer
) != 0) {
5400 ret
= KMF_ERR_ISSUER
;
5404 /* Check to see if the certificate serial number is revoked */
5405 revoke_stack
= X509_CRL_get_REVOKED(xcrl
);
5406 if (sk_X509_REVOKED_num(revoke_stack
) <= 0) {
5407 /* No revoked certificates in the CRL file */
5408 SET_ERROR(kmfh
, ERR_get_error());
5409 ret
= KMF_ERR_EMPTY_CRL
;
5413 for (i
= 0; i
< sk_X509_REVOKED_num(revoke_stack
); i
++) {
5414 revoke
= sk_X509_REVOKED_value(revoke_stack
, i
);
5415 if (ASN1_INTEGER_cmp(xcert
->cert_info
->serialNumber
,
5416 revoke
->serialNumber
) == 0) {
5421 if (i
< sk_X509_REVOKED_num(revoke_stack
)) {
5424 ret
= KMF_ERR_NOT_REVOKED
;
5429 (void) BIO_free(in
);
5431 X509_CRL_free(xcrl
);
5439 OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle
, char *crlname
, KMF_DATA
*tacert
)
5441 KMF_RETURN ret
= KMF_OK
;
5442 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
5444 X509_CRL
*xcrl
= NULL
;
5448 KMF_ENCODE_FORMAT crl_format
;
5452 if (handle
== NULL
|| crlname
== NULL
|| tacert
== NULL
) {
5453 return (KMF_ERR_BAD_PARAMETER
);
5456 ret
= kmf_get_file_format(crlname
, &crl_format
);
5460 bcrl
= BIO_new_file(crlname
, "rb");
5462 SET_ERROR(kmfh
, ERR_get_error());
5463 ret
= KMF_ERR_OPEN_FILE
;
5467 if (crl_format
== KMF_FORMAT_ASN1
) {
5468 xcrl
= d2i_X509_CRL_bio(bcrl
, NULL
);
5469 } else if (crl_format
== KMF_FORMAT_PEM
) {
5470 xcrl
= PEM_read_bio_X509_CRL(bcrl
, NULL
, NULL
, NULL
);
5472 ret
= KMF_ERR_BAD_PARAMETER
;
5477 SET_ERROR(kmfh
, ERR_get_error());
5478 ret
= KMF_ERR_BAD_CRLFILE
;
5483 len
= tacert
->Length
;
5484 xcert
= d2i_X509(NULL
, (const uchar_t
**)&p
, len
);
5486 if (xcert
== NULL
) {
5487 SET_ERROR(kmfh
, ERR_get_error());
5488 ret
= KMF_ERR_BAD_CERTFILE
;
5492 /* Get issuer certificate public key */
5493 pkey
= X509_get_pubkey(xcert
);
5495 SET_ERROR(kmfh
, ERR_get_error());
5496 ret
= KMF_ERR_BAD_CERT_FORMAT
;
5500 /* Verify CRL signature */
5501 sslret
= X509_CRL_verify(xcrl
, pkey
);
5502 EVP_PKEY_free(pkey
);
5506 SET_ERROR(kmfh
, sslret
);
5507 ret
= KMF_ERR_BAD_CRLFILE
;
5512 (void) BIO_free(bcrl
);
5515 X509_CRL_free(xcrl
);
5525 OpenSSL_CheckCRLDate(KMF_HANDLE_T handle
, char *crlname
)
5527 KMF_RETURN ret
= KMF_OK
;
5528 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
5529 KMF_ENCODE_FORMAT crl_format
;
5531 X509_CRL
*xcrl
= NULL
;
5534 if (handle
== NULL
|| crlname
== NULL
) {
5535 return (KMF_ERR_BAD_PARAMETER
);
5538 ret
= kmf_is_crl_file(handle
, crlname
, &crl_format
);
5542 bcrl
= BIO_new_file(crlname
, "rb");
5544 SET_ERROR(kmfh
, ERR_get_error());
5545 ret
= KMF_ERR_OPEN_FILE
;
5549 if (crl_format
== KMF_FORMAT_ASN1
)
5550 xcrl
= d2i_X509_CRL_bio(bcrl
, NULL
);
5551 else if (crl_format
== KMF_FORMAT_PEM
)
5552 xcrl
= PEM_read_bio_X509_CRL(bcrl
, NULL
, NULL
, NULL
);
5555 SET_ERROR(kmfh
, ERR_get_error());
5556 ret
= KMF_ERR_BAD_CRLFILE
;
5559 i
= X509_cmp_time(X509_CRL_get_lastUpdate(xcrl
), NULL
);
5561 ret
= KMF_ERR_VALIDITY_PERIOD
;
5564 if (X509_CRL_get_nextUpdate(xcrl
)) {
5565 i
= X509_cmp_time(X509_CRL_get_nextUpdate(xcrl
), NULL
);
5568 ret
= KMF_ERR_VALIDITY_PERIOD
;
5577 (void) BIO_free(bcrl
);
5580 X509_CRL_free(xcrl
);