2 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
4 * Use is subject to license terms.
7 * Copyright (c) 2012, OmniTI Computer Consulting, Inc. All rights reserved.
10 * Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
14 * ====================================================================
15 * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved.
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
21 * 1. Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
24 * 2. Redistributions in binary form must reproduce the above copyright
25 * notice, this list of conditions and the following disclaimer in
26 * the documentation and/or other materials provided with the
29 * 3. All advertising materials mentioning features or use of this
30 * software must display the following acknowledgment:
31 * "This product includes software developed by the OpenSSL Project
32 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
34 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
35 * endorse or promote products derived from this software without
36 * prior written permission. For written permission, please contact
37 * licensing@OpenSSL.org.
39 * 5. Products derived from this software may not be called "OpenSSL"
40 * nor may "OpenSSL" appear in their names without prior written
41 * permission of the OpenSSL Project.
43 * 6. Redistributions of any form whatsoever must retain the following
45 * "This product includes software developed by the OpenSSL Project
46 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
48 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
49 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
51 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
52 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
53 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
54 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
55 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
57 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
58 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
59 * OF THE POSSIBILITY OF SUCH DAMAGE.
60 * ====================================================================
62 * This product includes cryptographic software written by Eric Young
63 * (eay@cryptsoft.com). This product includes software written by Tim
64 * Hudson (tjh@cryptsoft.com).
74 #include <cryptoutil.h>
78 /* OPENSSL related headers */
79 #include <openssl/bio.h>
80 #include <openssl/bn.h>
81 #include <openssl/asn1.h>
82 #include <openssl/err.h>
83 #include <openssl/bn.h>
84 #include <openssl/x509.h>
85 #include <openssl/rsa.h>
86 #include <openssl/dsa.h>
87 #include <openssl/x509v3.h>
88 #include <openssl/objects.h>
89 #include <openssl/pem.h>
90 #include <openssl/pkcs12.h>
91 #include <openssl/ocsp.h>
92 #include <openssl/des.h>
93 #include <openssl/rand.h>
95 #define PRINT_ANY_EXTENSION (\
96 KMF_X509_EXT_KEY_USAGE |\
97 KMF_X509_EXT_CERT_POLICIES |\
98 KMF_X509_EXT_SUBJALTNAME |\
99 KMF_X509_EXT_BASIC_CONSTRAINTS |\
100 KMF_X509_EXT_NAME_CONSTRAINTS |\
101 KMF_X509_EXT_POLICY_CONSTRAINTS |\
102 KMF_X509_EXT_EXT_KEY_USAGE |\
103 KMF_X509_EXT_INHIBIT_ANY_POLICY |\
104 KMF_X509_EXT_AUTH_KEY_ID |\
105 KMF_X509_EXT_SUBJ_KEY_ID |\
106 KMF_X509_EXT_POLICY_MAPPING)
108 static uchar_t P
[] = { 0x00, 0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76,
109 0xaa, 0x3d, 0x25, 0x75, 0x9b, 0xb0, 0x68, 0x69,
110 0xcb, 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d, 0x0c,
111 0xf7, 0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82,
112 0xe5, 0xd0, 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e,
113 0xaf, 0xc2, 0xe9, 0xad, 0xac, 0x32, 0xab, 0x7a,
114 0xac, 0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24,
115 0xc2, 0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02,
118 static uchar_t Q
[] = { 0x00, 0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8,
119 0xee, 0x99, 0x3b, 0x4f, 0x2d, 0xed, 0x30, 0xf4,
120 0x8e, 0xda, 0xce, 0x91, 0x5f };
122 static uchar_t G
[] = { 0x00, 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a,
123 0x13, 0x41, 0x31, 0x63, 0xa5, 0x5b, 0x4c, 0xb5,
124 0x00, 0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c, 0xef,
125 0xcb, 0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c,
126 0x2e, 0x71, 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba,
127 0xbf, 0x58, 0xe5, 0xb7, 0x95, 0x21, 0x92, 0x5c,
128 0x9c, 0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08,
129 0x8c, 0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88,
132 #define SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_OPENSSL; \
133 h->lasterr.errcode = c;
135 #define SET_SYS_ERROR(h, c) h->lasterr.kstype = -1; h->lasterr.errcode = c;
138 * Declare some new macros for managing stacks of EVP_PKEYS.
140 DECLARE_STACK_OF(EVP_PKEY
)
142 #define sk_EVP_PKEY_new_null() SKM_sk_new_null(EVP_PKEY)
143 #define sk_EVP_PKEY_free(st) SKM_sk_free(EVP_PKEY, (st))
144 #define sk_EVP_PKEY_num(st) SKM_sk_num(EVP_PKEY, (st))
145 #define sk_EVP_PKEY_value(st, i) SKM_sk_value(EVP_PKEY, (st), (i))
146 #define sk_EVP_PKEY_push(st, val) SKM_sk_push(EVP_PKEY, (st), (val))
147 #define sk_EVP_PKEY_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY, (st), \
150 mutex_t init_lock
= DEFAULTMUTEX
;
151 static int ssl_initialized
= 0;
152 static BIO
*bio_err
= NULL
;
155 test_for_file(char *, mode_t
);
157 openssl_parse_bag(PKCS12_SAFEBAG
*, char *, int,
158 STACK_OF(EVP_PKEY
) *, STACK_OF(X509
) *);
161 local_export_pk12(KMF_HANDLE_T
, KMF_CREDENTIAL
*, int, KMF_X509_DER_CERT
*,
162 int, KMF_KEY_HANDLE
*, char *);
164 static KMF_RETURN
set_pkey_attrib(EVP_PKEY
*, ASN1_TYPE
*, int);
167 extract_pem(KMF_HANDLE
*, char *, char *, KMF_BIGINT
*, char *,
168 CK_UTF8CHAR
*, CK_ULONG
, EVP_PKEY
**, KMF_DATA
**, int *);
171 kmf_load_cert(KMF_HANDLE
*, char *, char *, KMF_BIGINT
*, KMF_CERT_VALIDITY
,
175 load_certs(KMF_HANDLE
*, char *, char *, KMF_BIGINT
*, KMF_CERT_VALIDITY
,
176 char *, KMF_DATA
**, uint32_t *);
179 sslBN2KMFBN(BIGNUM
*, KMF_BIGINT
*);
182 ImportRawRSAKey(KMF_RAW_RSA_KEY
*);
185 convertToRawKey(EVP_PKEY
*, KMF_RAW_KEY_DATA
*);
188 OpenSSL_FindCert(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
191 OpenSSL_FreeKMFCert(KMF_HANDLE_T
, KMF_X509_DER_CERT
*);
194 OpenSSL_StoreCert(KMF_HANDLE_T handle
, int, KMF_ATTRIBUTE
*);
197 OpenSSL_DeleteCert(KMF_HANDLE_T handle
, int, KMF_ATTRIBUTE
*);
200 OpenSSL_CreateKeypair(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
203 OpenSSL_StoreKey(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
206 OpenSSL_EncodePubKeyData(KMF_HANDLE_T
, KMF_KEY_HANDLE
*, KMF_DATA
*);
209 OpenSSL_SignData(KMF_HANDLE_T
, KMF_KEY_HANDLE
*, KMF_OID
*,
210 KMF_DATA
*, KMF_DATA
*);
213 OpenSSL_DeleteKey(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
216 OpenSSL_ImportCRL(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
219 OpenSSL_DeleteCRL(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
222 OpenSSL_ListCRL(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
225 OpenSSL_FindCertInCRL(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
228 OpenSSL_CertGetPrintable(KMF_HANDLE_T
, const KMF_DATA
*,
229 KMF_PRINTABLE_ITEM
, char *);
232 OpenSSL_GetErrorString(KMF_HANDLE_T
, char **);
235 OpenSSL_FindPrikeyByCert(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
238 OpenSSL_DecryptData(KMF_HANDLE_T
, KMF_KEY_HANDLE
*, KMF_OID
*,
239 KMF_DATA
*, KMF_DATA
*);
242 OpenSSL_CreateOCSPRequest(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
245 OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
248 OpenSSL_FindKey(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
251 OpenSSL_ExportPK12(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
254 OpenSSL_CreateSymKey(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
257 OpenSSL_GetSymKeyValue(KMF_HANDLE_T
, KMF_KEY_HANDLE
*, KMF_RAW_SYM_KEY
*);
260 OpenSSL_VerifyCRLFile(KMF_HANDLE_T
, char *, KMF_DATA
*);
263 OpenSSL_CheckCRLDate(KMF_HANDLE_T
, char *);
266 KMF_PLUGIN_FUNCLIST openssl_plugin_table
=
269 NULL
, /* ConfigureKeystore */
273 NULL
, /* ImportCert */
277 OpenSSL_CreateKeypair
,
279 OpenSSL_EncodePubKeyData
,
284 OpenSSL_FindCertInCRL
,
285 OpenSSL_GetErrorString
,
286 OpenSSL_FindPrikeyByCert
,
289 OpenSSL_CreateSymKey
,
290 OpenSSL_GetSymKeyValue
,
291 NULL
, /* SetTokenPin */
296 static mutex_t
*lock_cs
;
297 static long *lock_count
;
301 locking_cb(int mode
, int type
, char *file
, int line
)
303 if (mode
& CRYPTO_LOCK
) {
304 (void) mutex_lock(&(lock_cs
[type
]));
307 (void) mutex_unlock(&(lock_cs
[type
]));
314 return ((unsigned long)thr_self());
317 KMF_PLUGIN_FUNCLIST
*
318 KMF_Plugin_Initialize()
322 (void) mutex_lock(&init_lock
);
323 if (!ssl_initialized
) {
325 * Add support for extension OIDs that are not yet in the
326 * openssl default set.
328 (void) OBJ_create("2.5.29.30", "nameConstraints",
329 "X509v3 Name Constraints");
330 (void) OBJ_create("2.5.29.33", "policyMappings",
331 "X509v3 Policy Mappings");
332 (void) OBJ_create("2.5.29.36", "policyConstraints",
333 "X509v3 Policy Constraints");
334 (void) OBJ_create("2.5.29.46", "freshestCRL",
335 "X509v3 Freshest CRL");
336 (void) OBJ_create("2.5.29.54", "inhibitAnyPolicy",
337 "X509v3 Inhibit Any-Policy");
339 * Set up for thread-safe operation.
341 lock_cs
= OPENSSL_malloc(CRYPTO_num_locks() * sizeof (mutex_t
));
342 if (lock_cs
== NULL
) {
343 (void) mutex_unlock(&init_lock
);
347 lock_count
= OPENSSL_malloc(CRYPTO_num_locks() * sizeof (long));
348 if (lock_count
== NULL
) {
349 OPENSSL_free(lock_cs
);
350 (void) mutex_unlock(&init_lock
);
354 for (i
= 0; i
< CRYPTO_num_locks(); i
++) {
356 (void) mutex_init(&lock_cs
[i
], USYNC_THREAD
, NULL
);
359 CRYPTO_set_id_callback((unsigned long (*)())thread_id
);
360 if (CRYPTO_get_locking_callback() == NULL
)
361 CRYPTO_set_locking_callback((void (*)())locking_cb
);
363 OpenSSL_add_all_algorithms();
365 /* Enable error strings for reporting */
366 ERR_load_crypto_strings();
370 (void) mutex_unlock(&init_lock
);
372 return (&openssl_plugin_table
);
375 * Convert an SSL DN to a KMF DN.
378 get_x509_dn(X509_NAME
*sslDN
, KMF_X509_NAME
*kmfDN
)
381 KMF_RETURN rv
= KMF_OK
;
384 /* Convert to raw DER format */
385 derdata
.Length
= i2d_X509_NAME(sslDN
, NULL
);
386 if ((tmp
= derdata
.Data
= (uchar_t
*)OPENSSL_malloc(derdata
.Length
))
388 return (KMF_ERR_MEMORY
);
390 (void) i2d_X509_NAME(sslDN
, &tmp
);
392 /* Decode to KMF format */
393 rv
= DerDecodeName(&derdata
, kmfDN
);
395 rv
= KMF_ERR_BAD_CERT_FORMAT
;
397 OPENSSL_free(derdata
.Data
);
407 if (stat(path
, &s
) == -1)
410 return ((s
.st_mode
& S_IFMT
) == S_IFDIR
);
414 ssl_cert2KMFDATA(KMF_HANDLE
*kmfh
, X509
*x509cert
, KMF_DATA
*cert
)
416 KMF_RETURN rv
= KMF_OK
;
417 unsigned char *buf
= NULL
, *p
;
421 * Convert the X509 internal struct to DER encoded data
423 if ((len
= i2d_X509(x509cert
, NULL
)) < 0) {
424 SET_ERROR(kmfh
, ERR_get_error());
425 rv
= KMF_ERR_BAD_CERT_FORMAT
;
428 if ((buf
= malloc(len
)) == NULL
) {
429 SET_SYS_ERROR(kmfh
, errno
);
435 * i2d_X509 will increment the buf pointer so that we need to
439 if ((len
= i2d_X509(x509cert
, &p
)) < 0) {
440 SET_ERROR(kmfh
, ERR_get_error());
442 rv
= KMF_ERR_BAD_CERT_FORMAT
;
446 /* caller's responsibility to free it */
463 check_cert(X509
*xcert
, char *issuer
, char *subject
, KMF_BIGINT
*serial
,
466 KMF_RETURN rv
= KMF_OK
;
467 boolean_t findIssuer
= FALSE
;
468 boolean_t findSubject
= FALSE
;
469 boolean_t findSerial
= FALSE
;
470 KMF_X509_NAME issuerDN
, subjectDN
;
471 KMF_X509_NAME certIssuerDN
, certSubjectDN
;
475 return (KMF_ERR_BAD_PARAMETER
);
478 (void) memset(&issuerDN
, 0, sizeof (KMF_X509_NAME
));
479 (void) memset(&subjectDN
, 0, sizeof (KMF_X509_NAME
));
480 (void) memset(&certIssuerDN
, 0, sizeof (KMF_X509_NAME
));
481 (void) memset(&certSubjectDN
, 0, sizeof (KMF_X509_NAME
));
483 if (issuer
!= NULL
&& strlen(issuer
)) {
484 rv
= kmf_dn_parser(issuer
, &issuerDN
);
486 return (KMF_ERR_BAD_PARAMETER
);
488 rv
= get_x509_dn(xcert
->cert_info
->issuer
, &certIssuerDN
);
490 kmf_free_dn(&issuerDN
);
491 return (KMF_ERR_BAD_PARAMETER
);
496 if (subject
!= NULL
&& strlen(subject
)) {
497 rv
= kmf_dn_parser(subject
, &subjectDN
);
499 rv
= KMF_ERR_BAD_PARAMETER
;
503 rv
= get_x509_dn(xcert
->cert_info
->subject
, &certSubjectDN
);
505 rv
= KMF_ERR_BAD_PARAMETER
;
510 if (serial
!= NULL
&& serial
->val
!= NULL
)
516 /* Comparing BIGNUMs is a pain! */
517 bn
= ASN1_INTEGER_to_BN(xcert
->cert_info
->serialNumber
, NULL
);
519 int bnlen
= BN_num_bytes(bn
);
521 if (bnlen
== serial
->len
) {
522 uchar_t
*a
= malloc(bnlen
);
528 bnlen
= BN_bn2bin(bn
, a
);
529 *match
= (memcmp(a
, serial
->val
, serial
->len
) ==
543 *match
= (kmf_compare_rdns(&issuerDN
, &certIssuerDN
) == 0);
544 if ((*match
) == B_FALSE
) {
545 /* stop checking and bail */
551 *match
= (kmf_compare_rdns(&subjectDN
, &certSubjectDN
) == 0);
552 if ((*match
) == B_FALSE
) {
553 /* stop checking and bail */
562 kmf_free_dn(&issuerDN
);
563 kmf_free_dn(&certIssuerDN
);
566 kmf_free_dn(&subjectDN
);
567 kmf_free_dn(&certSubjectDN
);
575 * This function loads a certificate file into an X509 data structure, and
576 * checks if its issuer, subject or the serial number matches with those
577 * values. If it matches, then return the X509 data structure.
580 load_X509cert(KMF_HANDLE
*kmfh
,
581 char *issuer
, char *subject
, KMF_BIGINT
*serial
,
582 char *pathname
, X509
**outcert
)
584 KMF_RETURN rv
= KMF_OK
;
587 boolean_t match
= FALSE
;
588 KMF_ENCODE_FORMAT format
;
591 * auto-detect the file format, regardless of what
592 * the 'format' parameters in the params say.
594 rv
= kmf_get_file_format(pathname
, &format
);
596 if (rv
== KMF_ERR_OPEN_FILE
)
597 rv
= KMF_ERR_CERT_NOT_FOUND
;
601 /* Not ASN1(DER) format */
602 if ((bcert
= BIO_new_file(pathname
, "rb")) == NULL
) {
603 SET_ERROR(kmfh
, ERR_get_error());
604 rv
= KMF_ERR_OPEN_FILE
;
608 if (format
== KMF_FORMAT_PEM
)
609 xcert
= PEM_read_bio_X509_AUX(bcert
, NULL
, NULL
, NULL
);
610 else if (format
== KMF_FORMAT_ASN1
)
611 xcert
= d2i_X509_bio(bcert
, NULL
);
612 else if (format
== KMF_FORMAT_PKCS12
) {
613 PKCS12
*p12
= d2i_PKCS12_bio(bcert
, NULL
);
615 (void) PKCS12_parse(p12
, NULL
, NULL
, &xcert
, NULL
);
619 SET_ERROR(kmfh
, ERR_get_error());
620 rv
= KMF_ERR_BAD_CERT_FORMAT
;
623 rv
= KMF_ERR_BAD_PARAMETER
;
628 SET_ERROR(kmfh
, ERR_get_error());
629 rv
= KMF_ERR_BAD_CERT_FORMAT
;
633 if (check_cert(xcert
, issuer
, subject
, serial
, &match
) != KMF_OK
||
635 rv
= KMF_ERR_CERT_NOT_FOUND
;
639 if (outcert
!= NULL
) {
644 if (bcert
!= NULL
) (void) BIO_free(bcert
);
645 if (rv
!= KMF_OK
&& xcert
!= NULL
)
652 datacmp(const void *a
, const void *b
)
654 KMF_DATA
*adata
= (KMF_DATA
*)a
;
655 KMF_DATA
*bdata
= (KMF_DATA
*)b
;
656 if (adata
->Length
> bdata
->Length
)
658 if (adata
->Length
< bdata
->Length
)
664 load_certs(KMF_HANDLE
*kmfh
, char *issuer
, char *subject
, KMF_BIGINT
*serial
,
665 KMF_CERT_VALIDITY validity
, char *pathname
,
666 KMF_DATA
**certlist
, uint32_t *numcerts
)
668 KMF_RETURN rv
= KMF_OK
;
670 KMF_DATA
*certs
= NULL
;
673 KMF_ENCODE_FORMAT format
;
675 rv
= kmf_get_file_format(pathname
, &format
);
677 if (rv
== KMF_ERR_OPEN_FILE
)
678 rv
= KMF_ERR_CERT_NOT_FOUND
;
681 if (format
== KMF_FORMAT_ASN1
) {
682 /* load a single certificate */
683 certs
= (KMF_DATA
*)malloc(sizeof (KMF_DATA
));
685 return (KMF_ERR_MEMORY
);
688 rv
= kmf_load_cert(kmfh
, issuer
, subject
, serial
, validity
,
694 kmf_free_data(certs
);
699 } else if (format
== KMF_FORMAT_PKCS12
) {
700 /* We need a credential to access a PKCS#12 file */
701 rv
= KMF_ERR_BAD_CERT_FORMAT
;
702 } else if (format
== KMF_FORMAT_PEM
||
703 format
!= KMF_FORMAT_PEM_KEYPAIR
) {
705 /* This function only works on PEM files */
706 rv
= extract_pem(kmfh
, issuer
, subject
, serial
, pathname
,
707 (uchar_t
*)NULL
, 0, NULL
, &certs
, &nc
);
709 return (KMF_ERR_ENCODING
);
715 for (i
= 0; i
< nc
; i
++) {
716 if (validity
== KMF_NONEXPIRED_CERTS
) {
717 rv
= kmf_check_cert_date(kmfh
, &certs
[i
]);
718 } else if (validity
== KMF_EXPIRED_CERTS
) {
719 rv
= kmf_check_cert_date(kmfh
, &certs
[i
]);
721 rv
= KMF_ERR_CERT_NOT_FOUND
;
722 if (rv
== KMF_ERR_VALIDITY_PERIOD
)
726 /* Remove this cert from the list by clearing it. */
727 kmf_free_data(&certs
[i
]);
729 hits
++; /* count valid certs found */
733 if (rv
== KMF_OK
&& hits
> 0) {
735 * Sort the list of certs by length to put the cleared ones
736 * at the end so they don't get accessed by the caller.
738 qsort((void *)certs
, nc
, sizeof (KMF_DATA
), datacmp
);
741 /* since we sorted the list, just return the number of hits */
744 if (rv
== KMF_OK
&& hits
== 0)
745 rv
= KMF_ERR_CERT_NOT_FOUND
;
755 kmf_load_cert(KMF_HANDLE
*kmfh
,
756 char *issuer
, char *subject
, KMF_BIGINT
*serial
,
757 KMF_CERT_VALIDITY validity
,
761 KMF_RETURN rv
= KMF_OK
;
762 X509
*x509cert
= NULL
;
764 rv
= load_X509cert(kmfh
, issuer
, subject
, serial
, pathname
, &x509cert
);
765 if (rv
== KMF_OK
&& x509cert
!= NULL
&& cert
!= NULL
) {
766 rv
= ssl_cert2KMFDATA(kmfh
, x509cert
, cert
);
770 if (validity
== KMF_NONEXPIRED_CERTS
) {
771 rv
= kmf_check_cert_date(kmfh
, cert
);
772 } else if (validity
== KMF_EXPIRED_CERTS
) {
773 rv
= kmf_check_cert_date(kmfh
, cert
);
776 * This is a valid cert so skip it.
778 rv
= KMF_ERR_CERT_NOT_FOUND
;
780 if (rv
== KMF_ERR_VALIDITY_PERIOD
) {
782 * We want to return success when we
783 * find an invalid cert.
791 if (x509cert
!= NULL
)
798 readAltFormatPrivateKey(KMF_DATA
*filedata
, EVP_PKEY
**pkey
)
800 KMF_RETURN ret
= KMF_OK
;
802 BerElement
*asn1
= NULL
;
804 BerValue OID
= { NULL
, 0 };
805 BerValue
*Mod
= NULL
, *PubExp
= NULL
;
806 BerValue
*PriExp
= NULL
, *Prime1
= NULL
, *Prime2
= NULL
;
807 BerValue
*Coef
= NULL
;
808 BIGNUM
*D
= NULL
, *P
= NULL
, *Q
= NULL
, *COEF
= NULL
;
809 BIGNUM
*Exp1
= NULL
, *Exp2
= NULL
, *pminus1
= NULL
;
810 BIGNUM
*qminus1
= NULL
;
815 filebuf
.bv_val
= (char *)filedata
->Data
;
816 filebuf
.bv_len
= filedata
->Length
;
818 asn1
= kmfder_init(&filebuf
);
820 ret
= KMF_ERR_MEMORY
;
824 if (kmfber_scanf(asn1
, "{{Dn{IIIIII}}}",
825 &OID
, &Mod
, &PubExp
, &PriExp
, &Prime1
,
826 &Prime2
, &Coef
) == -1) {
827 ret
= KMF_ERR_ENCODING
;
832 * We have to derive the 2 Exponents using Bignumber math.
833 * Exp1 = PriExp mod (Prime1 - 1)
834 * Exp2 = PriExp mod (Prime2 - 1)
837 /* D = PrivateExponent */
838 D
= BN_bin2bn((const uchar_t
*)PriExp
->bv_val
, PriExp
->bv_len
, D
);
840 ret
= KMF_ERR_MEMORY
;
844 /* P = Prime1 (first prime factor of Modulus) */
845 P
= BN_bin2bn((const uchar_t
*)Prime1
->bv_val
, Prime1
->bv_len
, P
);
847 ret
= KMF_ERR_MEMORY
;
851 /* Q = Prime2 (second prime factor of Modulus) */
852 Q
= BN_bin2bn((const uchar_t
*)Prime2
->bv_val
, Prime2
->bv_len
, Q
);
854 if ((ctx
= BN_CTX_new()) == NULL
) {
855 ret
= KMF_ERR_MEMORY
;
859 /* Compute (P - 1) */
861 (void) BN_sub(pminus1
, P
, BN_value_one());
863 /* Exponent1 = D mod (P - 1) */
865 (void) BN_mod(Exp1
, D
, pminus1
, ctx
);
867 /* Compute (Q - 1) */
869 (void) BN_sub(qminus1
, Q
, BN_value_one());
871 /* Exponent2 = D mod (Q - 1) */
873 (void) BN_mod(Exp2
, D
, qminus1
, ctx
);
875 /* Coef = (Inverse Q) mod P */
877 (void) BN_mod_inverse(COEF
, Q
, P
, ctx
);
879 /* Convert back to KMF format */
880 (void) memset(&rsa
, 0, sizeof (rsa
));
882 if ((ret
= sslBN2KMFBN(Exp1
, &rsa
.exp1
)) != KMF_OK
)
884 if ((ret
= sslBN2KMFBN(Exp2
, &rsa
.exp2
)) != KMF_OK
)
886 if ((ret
= sslBN2KMFBN(COEF
, &rsa
.coef
)) != KMF_OK
)
889 rsa
.mod
.val
= (uchar_t
*)Mod
->bv_val
;
890 rsa
.mod
.len
= Mod
->bv_len
;
892 rsa
.pubexp
.val
= (uchar_t
*)PubExp
->bv_val
;
893 rsa
.pubexp
.len
= PubExp
->bv_len
;
895 rsa
.priexp
.val
= (uchar_t
*)PriExp
->bv_val
;
896 rsa
.priexp
.len
= PriExp
->bv_len
;
898 rsa
.prime1
.val
= (uchar_t
*)Prime1
->bv_val
;
899 rsa
.prime1
.len
= Prime1
->bv_len
;
901 rsa
.prime2
.val
= (uchar_t
*)Prime2
->bv_val
;
902 rsa
.prime2
.len
= Prime2
->bv_len
;
904 *pkey
= ImportRawRSAKey(&rsa
);
907 kmfber_free(asn1
, 1);
922 (void) memset(Coef
->bv_val
, 0, Coef
->bv_len
);
941 BN_clear_free(pminus1
);
943 BN_clear_free(qminus1
);
954 openssl_load_key(KMF_HANDLE_T handle
, const char *file
)
957 EVP_PKEY
*pkey
= NULL
;
958 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
959 KMF_ENCODE_FORMAT format
;
967 if (kmf_get_file_format((char *)file
, &format
) != KMF_OK
)
970 keyfile
= BIO_new_file(file
, "rb");
971 if (keyfile
== NULL
) {
975 if (format
== KMF_FORMAT_ASN1
) {
976 pkey
= d2i_PrivateKey_bio(keyfile
, NULL
);
979 (void) BIO_free(keyfile
);
981 /* Try odd ASN.1 variations */
982 rv
= kmf_read_input_file(kmfh
, (char *)file
,
985 (void) readAltFormatPrivateKey(&filedata
,
987 kmf_free_data(&filedata
);
990 } else if (format
== KMF_FORMAT_PEM
||
991 format
== KMF_FORMAT_PEM_KEYPAIR
) {
992 pkey
= PEM_read_bio_PrivateKey(keyfile
, NULL
, NULL
, NULL
);
996 * Check if this is the alt. format
997 * RSA private key file.
999 rv
= kmf_read_input_file(kmfh
, (char *)file
,
1004 rv
= kmf_pem_to_der(filedata
.Data
,
1005 filedata
.Length
, &d
, &len
);
1006 if (rv
== KMF_OK
&& d
!= NULL
) {
1008 derdata
.Length
= (size_t)len
;
1009 (void) readAltFormatPrivateKey(
1013 kmf_free_data(&filedata
);
1020 SET_ERROR(kmfh
, ERR_get_error());
1022 if (keyfile
!= NULL
)
1023 (void) BIO_free(keyfile
);
1029 OpenSSL_FindCert(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
1031 KMF_RETURN rv
= KMF_OK
;
1032 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1034 uint32_t maxcerts
= 0;
1035 uint32_t *num_certs
;
1036 KMF_X509_DER_CERT
*kmf_cert
= NULL
;
1037 char *dirpath
= NULL
;
1038 char *filename
= NULL
;
1039 char *fullpath
= NULL
;
1040 char *issuer
= NULL
;
1041 char *subject
= NULL
;
1042 KMF_BIGINT
*serial
= NULL
;
1043 KMF_CERT_VALIDITY validity
;
1045 num_certs
= kmf_get_attr_ptr(KMF_COUNT_ATTR
, attrlist
, numattr
);
1046 if (num_certs
== NULL
)
1047 return (KMF_ERR_BAD_PARAMETER
);
1049 /* num_certs should reference the size of kmf_cert */
1050 maxcerts
= *num_certs
;
1052 maxcerts
= 0xFFFFFFFF;
1055 /* Get the optional returned certificate list */
1056 kmf_cert
= kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR
, attrlist
,
1060 * The dirpath attribute and the filename attribute can not be NULL
1063 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
1064 filename
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
,
1067 fullpath
= get_fullpath(dirpath
, filename
);
1068 if (fullpath
== NULL
)
1069 return (KMF_ERR_BAD_PARAMETER
);
1071 /* Get optional search criteria attributes */
1072 issuer
= kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR
, attrlist
, numattr
);
1073 subject
= kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR
, attrlist
, numattr
);
1074 serial
= kmf_get_attr_ptr(KMF_BIGINT_ATTR
, attrlist
, numattr
);
1075 rv
= kmf_get_attr(KMF_CERT_VALIDITY_ATTR
, attrlist
, numattr
,
1078 validity
= KMF_ALL_CERTS
;
1082 if (isdir(fullpath
)) {
1087 /* open all files in the directory and attempt to read them */
1088 if ((dirp
= opendir(fullpath
)) == NULL
) {
1089 return (KMF_ERR_BAD_PARAMETER
);
1091 while ((dp
= readdir(dirp
)) != NULL
) {
1093 KMF_DATA
*certlist
= NULL
;
1094 uint32_t loaded_certs
= 0;
1096 if (strcmp(dp
->d_name
, ".") == 0 ||
1097 strcmp(dp
->d_name
, "..") == 0)
1100 fname
= get_fullpath(fullpath
, (char *)&dp
->d_name
);
1102 rv
= load_certs(kmfh
, issuer
, subject
, serial
,
1103 validity
, fname
, &certlist
, &loaded_certs
);
1107 if (certlist
!= NULL
) {
1108 for (i
= 0; i
< loaded_certs
; i
++)
1109 kmf_free_data(&certlist
[i
]);
1115 /* If load succeeds, add certdata to the list */
1116 if (kmf_cert
!= NULL
) {
1117 for (i
= 0; i
< loaded_certs
&&
1118 n
< maxcerts
; i
++) {
1119 kmf_cert
[n
].certificate
.Data
=
1121 kmf_cert
[n
].certificate
.Length
=
1124 kmf_cert
[n
].kmf_private
.keystore_type
=
1125 KMF_KEYSTORE_OPENSSL
;
1126 kmf_cert
[n
].kmf_private
.flags
=
1127 KMF_FLAG_CERT_VALID
;
1128 kmf_cert
[n
].kmf_private
.label
=
1133 * If maxcerts < loaded_certs, clean up the
1134 * certs that were not used.
1136 for (; i
< loaded_certs
; i
++)
1137 kmf_free_data(&certlist
[i
]);
1139 for (i
= 0; i
< loaded_certs
; i
++)
1140 kmf_free_data(&certlist
[i
]);
1147 if (*num_certs
== 0)
1148 rv
= KMF_ERR_CERT_NOT_FOUND
;
1152 (void) closedir(dirp
);
1154 KMF_DATA
*certlist
= NULL
;
1155 uint32_t loaded_certs
= 0;
1157 rv
= load_certs(kmfh
, issuer
, subject
, serial
, validity
,
1158 fullpath
, &certlist
, &loaded_certs
);
1165 if (kmf_cert
!= NULL
&& certlist
!= NULL
) {
1166 for (i
= 0; i
< loaded_certs
&& i
< maxcerts
; i
++) {
1167 kmf_cert
[n
].certificate
.Data
=
1169 kmf_cert
[n
].certificate
.Length
=
1171 kmf_cert
[n
].kmf_private
.keystore_type
=
1172 KMF_KEYSTORE_OPENSSL
;
1173 kmf_cert
[n
].kmf_private
.flags
=
1174 KMF_FLAG_CERT_VALID
;
1175 kmf_cert
[n
].kmf_private
.label
=
1179 /* If maxcerts < loaded_certs, clean up */
1180 for (; i
< loaded_certs
; i
++)
1181 kmf_free_data(&certlist
[i
]);
1182 } else if (certlist
!= NULL
) {
1183 for (i
= 0; i
< loaded_certs
; i
++)
1184 kmf_free_data(&certlist
[i
]);
1187 if (certlist
!= NULL
)
1199 OpenSSL_FreeKMFCert(KMF_HANDLE_T handle
,
1200 KMF_X509_DER_CERT
*kmf_cert
)
1202 if (kmf_cert
!= NULL
) {
1203 if (kmf_cert
->certificate
.Data
!= NULL
) {
1204 kmf_free_data(&kmf_cert
->certificate
);
1206 if (kmf_cert
->kmf_private
.label
)
1207 free(kmf_cert
->kmf_private
.label
);
1213 OpenSSL_StoreCert(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
1215 KMF_RETURN ret
= KMF_OK
;
1216 KMF_DATA
*cert
= NULL
;
1217 char *outfilename
= NULL
;
1218 char *dirpath
= NULL
;
1219 char *fullpath
= NULL
;
1220 KMF_ENCODE_FORMAT format
;
1222 /* Get the cert data */
1223 cert
= kmf_get_attr_ptr(KMF_CERT_DATA_ATTR
, attrlist
, numattr
);
1224 if (cert
== NULL
|| cert
->Data
== NULL
)
1225 return (KMF_ERR_BAD_PARAMETER
);
1227 /* Check the output filename and directory attributes. */
1228 outfilename
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
,
1230 if (outfilename
== NULL
)
1231 return (KMF_ERR_BAD_PARAMETER
);
1233 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
1234 fullpath
= get_fullpath(dirpath
, outfilename
);
1235 if (fullpath
== NULL
)
1236 return (KMF_ERR_BAD_CERTFILE
);
1238 /* Check the optional format attribute */
1239 ret
= kmf_get_attr(KMF_ENCODE_FORMAT_ATTR
, attrlist
, numattr
,
1241 if (ret
!= KMF_OK
) {
1242 /* If there is no format attribute, then default to PEM */
1243 format
= KMF_FORMAT_PEM
;
1245 } else if (format
!= KMF_FORMAT_ASN1
&& format
!= KMF_FORMAT_PEM
) {
1246 ret
= KMF_ERR_BAD_CERT_FORMAT
;
1250 /* Store the certificate in the file with the specified format */
1251 ret
= kmf_create_cert_file(cert
, format
, fullpath
);
1254 if (fullpath
!= NULL
)
1262 OpenSSL_DeleteCert(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
1265 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1266 KMF_DATA certdata
= { 0, NULL
};
1267 char *dirpath
= NULL
;
1268 char *filename
= NULL
;
1269 char *fullpath
= NULL
;
1270 char *issuer
= NULL
;
1271 char *subject
= NULL
;
1272 KMF_BIGINT
*serial
= NULL
;
1273 KMF_CERT_VALIDITY validity
;
1276 * Get the DIRPATH and CERT_FILENAME attributes. They can not be
1277 * NULL at the same time.
1279 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
1280 filename
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
,
1282 fullpath
= get_fullpath(dirpath
, filename
);
1283 if (fullpath
== NULL
)
1284 return (KMF_ERR_BAD_PARAMETER
);
1286 /* Get optional search criteria attributes */
1287 issuer
= kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR
, attrlist
, numattr
);
1288 subject
= kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR
, attrlist
, numattr
);
1289 serial
= kmf_get_attr_ptr(KMF_BIGINT_ATTR
, attrlist
, numattr
);
1290 rv
= kmf_get_attr(KMF_CERT_VALIDITY_ATTR
, attrlist
, numattr
,
1293 validity
= KMF_ALL_CERTS
;
1297 if (isdir(fullpath
)) {
1301 /* open all files in the directory and attempt to read them */
1302 if ((dirp
= opendir(fullpath
)) == NULL
) {
1303 return (KMF_ERR_BAD_PARAMETER
);
1306 while ((dp
= readdir(dirp
)) != NULL
) {
1307 if (strcmp(dp
->d_name
, ".") != 0 &&
1308 strcmp(dp
->d_name
, "..") != 0) {
1311 fname
= get_fullpath(fullpath
,
1312 (char *)&dp
->d_name
);
1314 if (fname
== NULL
) {
1315 rv
= KMF_ERR_MEMORY
;
1319 rv
= kmf_load_cert(kmfh
, issuer
, subject
,
1320 serial
, validity
, fname
, &certdata
);
1322 if (rv
== KMF_ERR_CERT_NOT_FOUND
) {
1324 kmf_free_data(&certdata
);
1327 } else if (rv
!= KMF_OK
) {
1332 if (unlink(fname
) != 0) {
1333 SET_SYS_ERROR(kmfh
, errno
);
1334 rv
= KMF_ERR_INTERNAL
;
1339 kmf_free_data(&certdata
);
1342 (void) closedir(dirp
);
1344 /* Just try to load a single certificate */
1345 rv
= kmf_load_cert(kmfh
, issuer
, subject
, serial
, validity
,
1346 fullpath
, &certdata
);
1348 if (unlink(fullpath
) != 0) {
1349 SET_SYS_ERROR(kmfh
, errno
);
1350 rv
= KMF_ERR_INTERNAL
;
1356 if (fullpath
!= NULL
)
1359 kmf_free_data(&certdata
);
1365 OpenSSL_EncodePubKeyData(KMF_HANDLE_T handle
, KMF_KEY_HANDLE
*key
,
1368 KMF_RETURN rv
= KMF_OK
;
1369 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1372 if (key
== NULL
|| keydata
== NULL
||
1374 return (KMF_ERR_BAD_PARAMETER
);
1376 if (key
->keyalg
== KMF_RSA
) {
1377 RSA
*pubkey
= EVP_PKEY_get1_RSA(key
->keyp
);
1379 if (!(n
= i2d_RSA_PUBKEY(pubkey
, &keydata
->Data
))) {
1380 SET_ERROR(kmfh
, ERR_get_error());
1381 return (KMF_ERR_ENCODING
);
1384 } else if (key
->keyalg
== KMF_DSA
) {
1385 DSA
*pubkey
= EVP_PKEY_get1_DSA(key
->keyp
);
1387 if (!(n
= i2d_DSA_PUBKEY(pubkey
, &keydata
->Data
))) {
1388 SET_ERROR(kmfh
, ERR_get_error());
1389 return (KMF_ERR_ENCODING
);
1393 return (KMF_ERR_BAD_PARAMETER
);
1395 keydata
->Length
= n
;
1400 free(keydata
->Data
);
1401 keydata
->Data
= NULL
;
1402 keydata
->Length
= 0;
1409 ssl_write_key(KMF_HANDLE
*kmfh
, KMF_ENCODE_FORMAT format
, BIO
*out
,
1410 KMF_CREDENTIAL
*cred
, EVP_PKEY
*pkey
, boolean_t
private)
1416 if (pkey
== NULL
|| out
== NULL
)
1417 return (KMF_ERR_BAD_PARAMETER
);
1420 case KMF_FORMAT_RAWKEY
:
1422 case KMF_FORMAT_ASN1
:
1423 if (pkey
->type
== EVP_PKEY_RSA
) {
1424 rsa
= EVP_PKEY_get1_RSA(pkey
);
1426 rv
= i2d_RSAPrivateKey_bio(out
, rsa
);
1428 rv
= i2d_RSAPublicKey_bio(out
, rsa
);
1430 } else if (pkey
->type
== EVP_PKEY_DSA
) {
1431 dsa
= EVP_PKEY_get1_DSA(pkey
);
1432 rv
= i2d_DSAPrivateKey_bio(out
, dsa
);
1438 SET_ERROR(kmfh
, rv
);
1441 case KMF_FORMAT_PEM
:
1442 if (pkey
->type
== EVP_PKEY_RSA
) {
1443 rsa
= EVP_PKEY_get1_RSA(pkey
);
1445 rv
= PEM_write_bio_RSAPrivateKey(out
,
1446 rsa
, NULL
, NULL
, 0, NULL
,
1447 (cred
!= NULL
? cred
->cred
: NULL
));
1449 rv
= PEM_write_bio_RSAPublicKey(out
,
1452 } else if (pkey
->type
== EVP_PKEY_DSA
) {
1453 dsa
= EVP_PKEY_get1_DSA(pkey
);
1454 rv
= PEM_write_bio_DSAPrivateKey(out
,
1455 dsa
, NULL
, NULL
, 0, NULL
,
1456 (cred
!= NULL
? cred
->cred
: NULL
));
1463 SET_ERROR(kmfh
, rv
);
1468 rv
= KMF_ERR_BAD_PARAMETER
;
1475 OpenSSL_CreateKeypair(KMF_HANDLE_T handle
, int numattr
,
1476 KMF_ATTRIBUTE
*attrlist
)
1478 KMF_RETURN rv
= KMF_OK
;
1479 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1480 uint32_t eValue
= 0x010001;
1481 RSA
*sslPrivKey
= NULL
;
1482 DSA
*sslDSAKey
= NULL
;
1483 EVP_PKEY
*eprikey
= NULL
;
1484 EVP_PKEY
*epubkey
= NULL
;
1486 KMF_KEY_HANDLE
*pubkey
= NULL
, *privkey
= NULL
;
1487 uint32_t keylen
= 1024;
1488 uint32_t keylen_size
= sizeof (uint32_t);
1489 boolean_t storekey
= TRUE
;
1490 KMF_KEY_ALG keytype
= KMF_RSA
;
1492 rv
= kmf_get_attr(KMF_STOREKEY_BOOL_ATTR
, attrlist
, numattr
,
1495 /* "storekey" is optional. Default is TRUE */
1499 rv
= kmf_get_attr(KMF_KEYALG_ATTR
, attrlist
, numattr
,
1500 (void *)&keytype
, NULL
);
1502 /* keytype is optional. KMF_RSA is default */
1505 pubkey
= kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR
, attrlist
, numattr
);
1507 return (KMF_ERR_BAD_PARAMETER
);
1509 privkey
= kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR
, attrlist
, numattr
);
1510 if (privkey
== NULL
)
1511 return (KMF_ERR_BAD_PARAMETER
);
1513 (void) memset(pubkey
, 0, sizeof (KMF_KEY_HANDLE
));
1514 (void) memset(privkey
, 0, sizeof (KMF_KEY_HANDLE
));
1516 eprikey
= EVP_PKEY_new();
1517 if (eprikey
== NULL
) {
1518 SET_ERROR(kmfh
, ERR_get_error());
1519 rv
= KMF_ERR_KEYGEN_FAILED
;
1522 epubkey
= EVP_PKEY_new();
1523 if (epubkey
== NULL
) {
1524 SET_ERROR(kmfh
, ERR_get_error());
1525 rv
= KMF_ERR_KEYGEN_FAILED
;
1528 if (keytype
== KMF_RSA
) {
1529 KMF_BIGINT
*rsaexp
= NULL
;
1531 rsaexp
= kmf_get_attr_ptr(KMF_RSAEXP_ATTR
, attrlist
, numattr
);
1532 if (rsaexp
!= NULL
) {
1533 if (rsaexp
->len
> 0 &&
1534 rsaexp
->len
<= sizeof (eValue
) &&
1535 rsaexp
->val
!= NULL
) {
1536 /* LINTED E_BAD_PTR_CAST_ALIGN */
1537 eValue
= *(uint32_t *)rsaexp
->val
;
1539 rv
= KMF_ERR_BAD_PARAMETER
;
1543 /* RSA Exponent is optional. Default is 0x10001 */
1547 rv
= kmf_get_attr(KMF_KEYLENGTH_ATTR
, attrlist
, numattr
,
1548 &keylen
, &keylen_size
);
1549 if (rv
== KMF_ERR_ATTR_NOT_FOUND
)
1550 /* keylen is optional, default is 1024 */
1553 rv
= KMF_ERR_BAD_PARAMETER
;
1557 sslPrivKey
= RSA_generate_key(keylen
, eValue
, NULL
, NULL
);
1558 if (sslPrivKey
== NULL
) {
1559 SET_ERROR(kmfh
, ERR_get_error());
1560 rv
= KMF_ERR_KEYGEN_FAILED
;
1562 (void) EVP_PKEY_set1_RSA(eprikey
, sslPrivKey
);
1563 privkey
->kstype
= KMF_KEYSTORE_OPENSSL
;
1564 privkey
->keyalg
= KMF_RSA
;
1565 privkey
->keyclass
= KMF_ASYM_PRI
;
1566 privkey
->israw
= FALSE
;
1567 privkey
->keyp
= (void *)eprikey
;
1569 /* OpenSSL derives the public key from the private */
1570 (void) EVP_PKEY_set1_RSA(epubkey
, sslPrivKey
);
1571 pubkey
->kstype
= KMF_KEYSTORE_OPENSSL
;
1572 pubkey
->keyalg
= KMF_RSA
;
1573 pubkey
->israw
= FALSE
;
1574 pubkey
->keyclass
= KMF_ASYM_PUB
;
1575 pubkey
->keyp
= (void *)epubkey
;
1577 } else if (keytype
== KMF_DSA
) {
1579 sslDSAKey
= DSA_new();
1580 if (sslDSAKey
== NULL
) {
1581 SET_ERROR(kmfh
, ERR_get_error());
1582 return (KMF_ERR_MEMORY
);
1585 if ((sslDSAKey
->p
= BN_bin2bn(P
, sizeof (P
), sslDSAKey
->p
)) ==
1587 SET_ERROR(kmfh
, ERR_get_error());
1588 rv
= KMF_ERR_KEYGEN_FAILED
;
1591 if ((sslDSAKey
->q
= BN_bin2bn(Q
, sizeof (Q
), sslDSAKey
->q
)) ==
1593 SET_ERROR(kmfh
, ERR_get_error());
1594 rv
= KMF_ERR_KEYGEN_FAILED
;
1597 if ((sslDSAKey
->g
= BN_bin2bn(G
, sizeof (G
), sslDSAKey
->g
)) ==
1599 SET_ERROR(kmfh
, ERR_get_error());
1600 rv
= KMF_ERR_KEYGEN_FAILED
;
1604 if (!DSA_generate_key(sslDSAKey
)) {
1605 SET_ERROR(kmfh
, ERR_get_error());
1606 rv
= KMF_ERR_KEYGEN_FAILED
;
1610 privkey
->kstype
= KMF_KEYSTORE_OPENSSL
;
1611 privkey
->keyalg
= KMF_DSA
;
1612 privkey
->keyclass
= KMF_ASYM_PRI
;
1613 privkey
->israw
= FALSE
;
1614 if (EVP_PKEY_set1_DSA(eprikey
, sslDSAKey
)) {
1615 privkey
->keyp
= (void *)eprikey
;
1617 SET_ERROR(kmfh
, ERR_get_error());
1618 rv
= KMF_ERR_KEYGEN_FAILED
;
1622 /* Make a copy for the public key */
1624 if ((dp
->p
= BN_new()) == NULL
) {
1625 SET_ERROR(kmfh
, ERR_get_error());
1626 rv
= KMF_ERR_MEMORY
;
1630 if ((dp
->q
= BN_new()) == NULL
) {
1631 SET_ERROR(kmfh
, ERR_get_error());
1632 rv
= KMF_ERR_MEMORY
;
1637 if ((dp
->g
= BN_new()) == NULL
) {
1638 SET_ERROR(kmfh
, ERR_get_error());
1639 rv
= KMF_ERR_MEMORY
;
1645 if ((dp
->pub_key
= BN_new()) == NULL
) {
1646 SET_ERROR(kmfh
, ERR_get_error());
1647 rv
= KMF_ERR_MEMORY
;
1654 (void) BN_copy(dp
->p
, sslDSAKey
->p
);
1655 (void) BN_copy(dp
->q
, sslDSAKey
->q
);
1656 (void) BN_copy(dp
->g
, sslDSAKey
->g
);
1657 (void) BN_copy(dp
->pub_key
, sslDSAKey
->pub_key
);
1659 pubkey
->kstype
= KMF_KEYSTORE_OPENSSL
;
1660 pubkey
->keyalg
= KMF_DSA
;
1661 pubkey
->keyclass
= KMF_ASYM_PUB
;
1662 pubkey
->israw
= FALSE
;
1664 if (EVP_PKEY_set1_DSA(epubkey
, sslDSAKey
)) {
1665 pubkey
->keyp
= (void *)epubkey
;
1667 SET_ERROR(kmfh
, ERR_get_error());
1668 rv
= KMF_ERR_KEYGEN_FAILED
;
1679 KMF_ATTRIBUTE storeattrs
[4]; /* max. 4 attributes needed */
1681 char *keyfile
= NULL
, *dirpath
= NULL
;
1682 KMF_ENCODE_FORMAT format
;
1684 * Construct a new attribute arrray and call openssl_store_key
1686 kmf_set_attr_at_index(storeattrs
, i
, KMF_PRIVKEY_HANDLE_ATTR
,
1687 privkey
, sizeof (privkey
));
1690 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
1691 if (dirpath
!= NULL
) {
1692 storeattrs
[i
].type
= KMF_DIRPATH_ATTR
;
1693 storeattrs
[i
].pValue
= dirpath
;
1694 storeattrs
[i
].valueLen
= strlen(dirpath
);
1697 rv
= KMF_OK
; /* DIRPATH is optional */
1699 keyfile
= kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
,
1701 if (keyfile
!= NULL
) {
1702 storeattrs
[i
].type
= KMF_KEY_FILENAME_ATTR
;
1703 storeattrs
[i
].pValue
= keyfile
;
1704 storeattrs
[i
].valueLen
= strlen(keyfile
);
1707 goto cleanup
; /* KEYFILE is required */
1709 rv
= kmf_get_attr(KMF_ENCODE_FORMAT_ATTR
, attrlist
, numattr
,
1710 (void *)&format
, NULL
);
1712 storeattrs
[i
].type
= KMF_ENCODE_FORMAT_ATTR
;
1713 storeattrs
[i
].pValue
= &format
;
1714 storeattrs
[i
].valueLen
= sizeof (format
);
1718 rv
= OpenSSL_StoreKey(handle
, i
, storeattrs
);
1723 if (eprikey
!= NULL
)
1724 EVP_PKEY_free(eprikey
);
1726 if (epubkey
!= NULL
)
1727 EVP_PKEY_free(epubkey
);
1729 if (pubkey
->keylabel
) {
1730 free(pubkey
->keylabel
);
1731 pubkey
->keylabel
= NULL
;
1734 if (privkey
->keylabel
) {
1735 free(privkey
->keylabel
);
1736 privkey
->keylabel
= NULL
;
1739 pubkey
->keyp
= NULL
;
1740 privkey
->keyp
= NULL
;
1744 RSA_free(sslPrivKey
);
1747 DSA_free(sslDSAKey
);
1750 (void) BIO_free(out
);
1756 * Make sure the BN conversion is properly padded with 0x00
1757 * bytes. If not, signature verification for DSA signatures
1758 * may fail in the case where the bignum value does not use
1762 fixbnlen(BIGNUM
*bn
, unsigned char *buf
, int len
) {
1763 int bytes
= len
- BN_num_bytes(bn
);
1765 /* prepend with leading 0x00 if necessary */
1769 (void) BN_bn2bin(bn
, buf
);
1771 * Return the desired length since we prepended it
1772 * with the necessary 0x00 padding.
1778 OpenSSL_SignData(KMF_HANDLE_T handle
, KMF_KEY_HANDLE
*key
,
1779 KMF_OID
*AlgOID
, KMF_DATA
*tobesigned
, KMF_DATA
*output
)
1781 KMF_RETURN ret
= KMF_OK
;
1782 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1783 KMF_ALGORITHM_INDEX AlgId
;
1787 if (key
== NULL
|| AlgOID
== NULL
||
1788 tobesigned
== NULL
|| output
== NULL
||
1789 tobesigned
->Data
== NULL
||
1790 output
->Data
== NULL
)
1791 return (KMF_ERR_BAD_PARAMETER
);
1793 /* Map the OID to an OpenSSL algorithm */
1794 AlgId
= x509_algoid_to_algid(AlgOID
);
1795 if (AlgId
== KMF_ALGID_NONE
)
1796 return (KMF_ERR_BAD_ALGORITHM
);
1798 if (key
->keyalg
== KMF_RSA
) {
1799 EVP_PKEY
*pkey
= (EVP_PKEY
*)key
->keyp
;
1802 if (AlgId
== KMF_ALGID_MD5WithRSA
)
1804 else if (AlgId
== KMF_ALGID_SHA1WithRSA
)
1806 else if (AlgId
== KMF_ALGID_SHA256WithRSA
)
1808 else if (AlgId
== KMF_ALGID_SHA384WithRSA
)
1810 else if (AlgId
== KMF_ALGID_SHA512WithRSA
)
1812 else if (AlgId
== KMF_ALGID_RSA
)
1815 return (KMF_ERR_BAD_ALGORITHM
);
1817 if ((md
== NULL
) && (AlgId
== KMF_ALGID_RSA
)) {
1818 RSA
*rsa
= EVP_PKEY_get1_RSA((EVP_PKEY
*)pkey
);
1821 if ((len
= RSA_private_encrypt(tobesigned
->Length
,
1822 tobesigned
->Data
, p
, rsa
,
1823 RSA_PKCS1_PADDING
)) <= 0) {
1824 SET_ERROR(kmfh
, ERR_get_error());
1825 ret
= KMF_ERR_INTERNAL
;
1827 output
->Length
= len
;
1829 (void) EVP_MD_CTX_init(&ctx
);
1830 (void) EVP_SignInit_ex(&ctx
, md
, NULL
);
1831 (void) EVP_SignUpdate(&ctx
, tobesigned
->Data
,
1832 (uint32_t)tobesigned
->Length
);
1833 len
= (uint32_t)output
->Length
;
1835 if (!EVP_SignFinal(&ctx
, p
, (uint32_t *)&len
, pkey
)) {
1836 SET_ERROR(kmfh
, ERR_get_error());
1838 ret
= KMF_ERR_INTERNAL
;
1840 output
->Length
= len
;
1841 (void) EVP_MD_CTX_cleanup(&ctx
);
1843 } else if (key
->keyalg
== KMF_DSA
) {
1844 DSA
*dsa
= EVP_PKEY_get1_DSA(key
->keyp
);
1846 uchar_t hash
[EVP_MAX_MD_SIZE
];
1850 if (AlgId
== KMF_ALGID_DSA
||
1851 AlgId
== KMF_ALGID_SHA1WithDSA
)
1853 else if (AlgId
== KMF_ALGID_SHA256WithDSA
)
1855 else /* Bad algorithm */
1856 return (KMF_ERR_BAD_ALGORITHM
);
1859 * OpenSSL EVP_Sign operation automatically converts to
1860 * ASN.1 output so we do the operations separately so we
1861 * are assured of NOT getting ASN.1 output returned.
1862 * KMF does not want ASN.1 encoded results because
1863 * not all mechanisms return ASN.1 encodings (PKCS#11
1864 * and NSS return raw signature data).
1866 EVP_MD_CTX_init(&ctx
);
1867 (void) EVP_DigestInit_ex(&ctx
, md
, NULL
);
1868 (void) EVP_DigestUpdate(&ctx
, tobesigned
->Data
,
1869 tobesigned
->Length
);
1870 (void) EVP_DigestFinal_ex(&ctx
, hash
, &hashlen
);
1872 /* Only sign first 20 bytes for SHA2 */
1873 if (AlgId
== KMF_ALGID_SHA256WithDSA
)
1875 dsasig
= DSA_do_sign(hash
, hashlen
, dsa
);
1876 if (dsasig
!= NULL
) {
1878 output
->Length
= i
= fixbnlen(dsasig
->r
, output
->Data
,
1881 output
->Length
+= fixbnlen(dsasig
->s
, &output
->Data
[i
],
1884 DSA_SIG_free(dsasig
);
1886 SET_ERROR(kmfh
, ERR_get_error());
1888 (void) EVP_MD_CTX_cleanup(&ctx
);
1890 return (KMF_ERR_BAD_PARAMETER
);
1898 OpenSSL_DeleteKey(KMF_HANDLE_T handle
,
1899 int numattr
, KMF_ATTRIBUTE
*attrlist
)
1901 KMF_RETURN rv
= KMF_OK
;
1902 KMF_KEY_HANDLE
*key
;
1903 boolean_t destroy
= B_TRUE
;
1905 key
= kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR
, attrlist
, numattr
);
1906 if (key
== NULL
|| key
->keyp
== NULL
)
1907 return (KMF_ERR_BAD_PARAMETER
);
1909 rv
= kmf_get_attr(KMF_DESTROY_BOOL_ATTR
, attrlist
, numattr
,
1910 (void *)&destroy
, NULL
);
1912 /* "destroy" is optional. Default is TRUE */
1916 if (key
->keyclass
!= KMF_ASYM_PUB
&&
1917 key
->keyclass
!= KMF_ASYM_PRI
&&
1918 key
->keyclass
!= KMF_SYMMETRIC
)
1919 return (KMF_ERR_BAD_KEY_CLASS
);
1921 if (key
->keyclass
== KMF_SYMMETRIC
) {
1922 kmf_free_raw_sym_key((KMF_RAW_SYM_KEY
*)key
->keyp
);
1925 if (key
->keyp
!= NULL
) {
1926 EVP_PKEY_free(key
->keyp
);
1931 if (key
->keylabel
!= NULL
) {
1932 EVP_PKEY
*pkey
= NULL
;
1933 /* If the file exists, make sure it is a proper key. */
1934 pkey
= openssl_load_key(handle
, key
->keylabel
);
1936 if (key
->keylabel
!= NULL
) {
1937 free(key
->keylabel
);
1938 key
->keylabel
= NULL
;
1940 return (KMF_ERR_KEY_NOT_FOUND
);
1942 EVP_PKEY_free(pkey
);
1945 if (unlink(key
->keylabel
) != 0) {
1946 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1947 SET_SYS_ERROR(kmfh
, errno
);
1948 rv
= KMF_ERR_INTERNAL
;
1951 if (key
->keylabel
!= NULL
) {
1952 free(key
->keylabel
);
1953 key
->keylabel
= NULL
;
1960 OpenSSL_GetErrorString(KMF_HANDLE_T handle
, char **msgstr
)
1962 KMF_RETURN ret
= KMF_OK
;
1963 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1964 char str
[256]; /* OpenSSL needs at least 120 byte buffer */
1966 ERR_error_string_n(kmfh
->lasterr
.errcode
, str
, sizeof (str
));
1968 *msgstr
= (char *)strdup(str
);
1969 if ((*msgstr
) == NULL
)
1970 ret
= KMF_ERR_MEMORY
;
1982 case KMF_X509_EXT_KEY_USAGE
:
1983 return (NID_key_usage
);
1984 case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD
:
1985 return (NID_private_key_usage_period
);
1986 case KMF_X509_EXT_CERT_POLICIES
:
1987 return (NID_certificate_policies
);
1988 case KMF_X509_EXT_SUBJ_ALTNAME
:
1989 return (NID_subject_alt_name
);
1990 case KMF_X509_EXT_ISSUER_ALTNAME
:
1991 return (NID_issuer_alt_name
);
1992 case KMF_X509_EXT_BASIC_CONSTRAINTS
:
1993 return (NID_basic_constraints
);
1994 case KMF_X509_EXT_EXT_KEY_USAGE
:
1995 return (NID_ext_key_usage
);
1996 case KMF_X509_EXT_AUTH_KEY_ID
:
1997 return (NID_authority_key_identifier
);
1998 case KMF_X509_EXT_CRL_DIST_POINTS
:
1999 return (NID_crl_distribution_points
);
2000 case KMF_X509_EXT_SUBJ_KEY_ID
:
2001 return (NID_subject_key_identifier
);
2002 case KMF_X509_EXT_POLICY_MAPPINGS
:
2003 return (OBJ_sn2nid("policyMappings"));
2004 case KMF_X509_EXT_NAME_CONSTRAINTS
:
2005 return (OBJ_sn2nid("nameConstraints"));
2006 case KMF_X509_EXT_POLICY_CONSTRAINTS
:
2007 return (OBJ_sn2nid("policyConstraints"));
2008 case KMF_X509_EXT_INHIBIT_ANY_POLICY
:
2009 return (OBJ_sn2nid("inhibitAnyPolicy"));
2010 case KMF_X509_EXT_FRESHEST_CRL
:
2011 return (OBJ_sn2nid("freshestCRL"));
2018 OpenSSL_CertGetPrintable(KMF_HANDLE_T handle
, const KMF_DATA
*pcert
,
2019 KMF_PRINTABLE_ITEM flag
, char *resultStr
)
2021 KMF_RETURN ret
= KMF_OK
;
2022 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2024 unsigned char *outbuf
= NULL
;
2025 unsigned char *outbuf_p
;
2026 char *tmpstr
= NULL
;
2028 int ext_index
, nid
, len
;
2030 #if OPENSSL_VERSION_NUMBER < 0x10000000L
2031 STACK
*emlst
= NULL
;
2033 STACK_OF(OPENSSL_STRING
) *emlst
= NULL
;
2038 if (pcert
== NULL
|| pcert
->Data
== NULL
|| pcert
->Length
== 0) {
2039 return (KMF_ERR_BAD_PARAMETER
);
2042 /* copy cert data to outbuf */
2043 outbuf
= malloc(pcert
->Length
);
2044 if (outbuf
== NULL
) {
2045 return (KMF_ERR_MEMORY
);
2047 (void) memcpy(outbuf
, pcert
->Data
, pcert
->Length
);
2049 outbuf_p
= outbuf
; /* use a temp pointer; required by openssl */
2050 xcert
= d2i_X509(NULL
, (const uchar_t
**)&outbuf_p
, pcert
->Length
);
2051 if (xcert
== NULL
) {
2052 SET_ERROR(kmfh
, ERR_get_error());
2053 ret
= KMF_ERR_ENCODING
;
2057 mem
= BIO_new(BIO_s_mem());
2059 SET_ERROR(kmfh
, ERR_get_error());
2060 ret
= KMF_ERR_MEMORY
;
2065 case KMF_CERT_ISSUER
:
2066 (void) X509_NAME_print_ex(mem
, X509_get_issuer_name(xcert
), 0,
2067 XN_FLAG_SEP_CPLUS_SPC
);
2068 len
= BIO_gets(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2071 case KMF_CERT_SUBJECT
:
2072 (void) X509_NAME_print_ex(mem
, X509_get_subject_name(xcert
), 0,
2073 XN_FLAG_SEP_CPLUS_SPC
);
2074 len
= BIO_gets(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2077 case KMF_CERT_VERSION
:
2078 tmpstr
= i2s_ASN1_INTEGER(NULL
, xcert
->cert_info
->version
);
2079 (void) strncpy(resultStr
, tmpstr
, KMF_CERT_PRINTABLE_LEN
);
2080 OPENSSL_free(tmpstr
);
2081 len
= strlen(resultStr
);
2084 case KMF_CERT_SERIALNUM
:
2085 if (i2a_ASN1_INTEGER(mem
, X509_get_serialNumber(xcert
)) > 0) {
2086 (void) strcpy(resultStr
, "0x");
2087 len
= BIO_gets(mem
, &resultStr
[2],
2088 KMF_CERT_PRINTABLE_LEN
- 2);
2092 case KMF_CERT_NOTBEFORE
:
2093 (void) ASN1_TIME_print(mem
, X509_get_notBefore(xcert
));
2094 len
= BIO_gets(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2097 case KMF_CERT_NOTAFTER
:
2098 (void) ASN1_TIME_print(mem
, X509_get_notAfter(xcert
));
2099 len
= BIO_gets(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2102 case KMF_CERT_PUBKEY_DATA
:
2104 EVP_PKEY
*pkey
= X509_get_pubkey(xcert
);
2106 SET_ERROR(kmfh
, ERR_get_error());
2107 ret
= KMF_ERR_ENCODING
;
2111 if (pkey
->type
== EVP_PKEY_RSA
) {
2112 (void) BIO_printf(mem
,
2113 "RSA Public Key: (%d bit)\n",
2114 BN_num_bits(pkey
->pkey
.rsa
->n
));
2115 (void) RSA_print(mem
, pkey
->pkey
.rsa
, 0);
2116 } else if (pkey
->type
== EVP_PKEY_DSA
) {
2117 (void) BIO_printf(mem
,
2118 "%12sDSA Public Key:\n", "");
2119 (void) DSA_print(mem
, pkey
->pkey
.dsa
, 0);
2121 (void) BIO_printf(mem
,
2122 "%12sUnknown Public Key:\n", "");
2124 (void) BIO_printf(mem
, "\n");
2125 EVP_PKEY_free(pkey
);
2127 len
= BIO_read(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2129 case KMF_CERT_SIGNATURE_ALG
:
2130 case KMF_CERT_PUBKEY_ALG
:
2131 if (flag
== KMF_CERT_SIGNATURE_ALG
) {
2132 len
= i2a_ASN1_OBJECT(mem
,
2133 xcert
->sig_alg
->algorithm
);
2135 len
= i2a_ASN1_OBJECT(mem
,
2136 xcert
->cert_info
->key
->algor
->algorithm
);
2140 len
= BIO_read(mem
, resultStr
,
2141 KMF_CERT_PRINTABLE_LEN
);
2145 case KMF_CERT_EMAIL
:
2146 emlst
= X509_get1_email(xcert
);
2147 #if OPENSSL_VERSION_NUMBER < 0x10000000L
2148 for (j
= 0; j
< sk_num(emlst
); j
++)
2149 (void) BIO_printf(mem
, "%s\n", sk_value(emlst
, j
));
2151 for (j
= 0; j
< sk_OPENSSL_STRING_num(emlst
); j
++)
2152 (void) BIO_printf(mem
, "%s\n",
2153 sk_OPENSSL_STRING_value(emlst
, j
));
2156 len
= BIO_gets(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2157 X509_email_free(emlst
);
2159 case KMF_X509_EXT_ISSUER_ALTNAME
:
2160 case KMF_X509_EXT_SUBJ_ALTNAME
:
2161 case KMF_X509_EXT_KEY_USAGE
:
2162 case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD
:
2163 case KMF_X509_EXT_CERT_POLICIES
:
2164 case KMF_X509_EXT_BASIC_CONSTRAINTS
:
2165 case KMF_X509_EXT_NAME_CONSTRAINTS
:
2166 case KMF_X509_EXT_POLICY_CONSTRAINTS
:
2167 case KMF_X509_EXT_EXT_KEY_USAGE
:
2168 case KMF_X509_EXT_INHIBIT_ANY_POLICY
:
2169 case KMF_X509_EXT_AUTH_KEY_ID
:
2170 case KMF_X509_EXT_SUBJ_KEY_ID
:
2171 case KMF_X509_EXT_POLICY_MAPPINGS
:
2172 case KMF_X509_EXT_CRL_DIST_POINTS
:
2173 case KMF_X509_EXT_FRESHEST_CRL
:
2174 nid
= ext2NID(flag
);
2175 if (nid
== NID_undef
) {
2176 ret
= KMF_ERR_EXTENSION_NOT_FOUND
;
2179 ci
= xcert
->cert_info
;
2181 ext_index
= X509v3_get_ext_by_NID(ci
->extensions
, nid
, -1);
2182 if (ext_index
== -1) {
2183 SET_ERROR(kmfh
, ERR_get_error());
2185 ret
= KMF_ERR_EXTENSION_NOT_FOUND
;
2188 ex
= X509v3_get_ext(ci
->extensions
, ext_index
);
2190 (void) i2a_ASN1_OBJECT(mem
, X509_EXTENSION_get_object(ex
));
2192 if (BIO_printf(mem
, ": %s\n",
2193 X509_EXTENSION_get_critical(ex
) ? "critical" : "") <= 0) {
2194 SET_ERROR(kmfh
, ERR_get_error());
2195 ret
= KMF_ERR_ENCODING
;
2198 if (!X509V3_EXT_print(mem
, ex
, X509V3_EXT_DUMP_UNKNOWN
, 4)) {
2199 (void) BIO_printf(mem
, "%*s", 4, "");
2200 (void) M_ASN1_OCTET_STRING_print(mem
, ex
->value
);
2202 if (BIO_write(mem
, "\n", 1) <= 0) {
2203 SET_ERROR(kmfh
, ERR_get_error());
2204 ret
= KMF_ERR_ENCODING
;
2207 len
= BIO_read(mem
, resultStr
, KMF_CERT_PRINTABLE_LEN
);
2210 SET_ERROR(kmfh
, ERR_get_error());
2211 ret
= KMF_ERR_ENCODING
;
2215 if (outbuf
!= NULL
) {
2219 if (xcert
!= NULL
) {
2224 (void) BIO_free(mem
);
2232 OpenSSL_FindPrikeyByCert(KMF_HANDLE_T handle
, int numattr
,
2233 KMF_ATTRIBUTE
*attrlist
)
2235 KMF_RETURN rv
= KMF_OK
;
2236 KMF_KEYSTORE_TYPE kstype
= KMF_KEYSTORE_OPENSSL
;
2237 KMF_KEY_CLASS keyclass
= KMF_ASYM_PRI
;
2238 KMF_KEY_HANDLE
*key
= NULL
;
2239 uint32_t numkeys
= 1; /* 1 key only */
2240 char *dirpath
= NULL
;
2241 char *keyfile
= NULL
;
2242 KMF_ATTRIBUTE new_attrlist
[16];
2246 * This is really just a FindKey operation, reuse the
2249 kmf_set_attr_at_index(new_attrlist
, i
,
2250 KMF_KEYSTORE_TYPE_ATTR
, &kstype
, sizeof (kstype
));
2253 kmf_set_attr_at_index(new_attrlist
, i
,
2254 KMF_COUNT_ATTR
, &numkeys
, sizeof (uint32_t));
2257 kmf_set_attr_at_index(new_attrlist
, i
,
2258 KMF_KEYCLASS_ATTR
, &keyclass
, sizeof (keyclass
));
2261 key
= kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR
, attrlist
, numattr
);
2263 return (KMF_ERR_BAD_PARAMETER
);
2265 kmf_set_attr_at_index(new_attrlist
, i
,
2266 KMF_KEY_HANDLE_ATTR
, key
, sizeof (KMF_KEY_HANDLE
));
2270 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
2271 if (dirpath
!= NULL
) {
2272 kmf_set_attr_at_index(new_attrlist
, i
,
2273 KMF_DIRPATH_ATTR
, dirpath
, strlen(dirpath
));
2277 keyfile
= kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
, attrlist
, numattr
);
2278 if (keyfile
== NULL
)
2279 return (KMF_ERR_BAD_PARAMETER
);
2281 kmf_set_attr_at_index(new_attrlist
, i
,
2282 KMF_KEY_FILENAME_ATTR
, keyfile
, strlen(keyfile
));
2286 rv
= OpenSSL_FindKey(handle
, i
, new_attrlist
);
2292 OpenSSL_DecryptData(KMF_HANDLE_T handle
, KMF_KEY_HANDLE
*key
,
2293 KMF_OID
*AlgOID
, KMF_DATA
*ciphertext
,
2296 KMF_RETURN ret
= KMF_OK
;
2298 unsigned int in_len
= 0, out_len
= 0;
2299 unsigned int total_decrypted
= 0, modulus_len
= 0;
2300 uint8_t *in_data
, *out_data
;
2303 if (key
== NULL
|| AlgOID
== NULL
||
2304 ciphertext
== NULL
|| output
== NULL
||
2305 ciphertext
->Data
== NULL
||
2306 output
->Data
== NULL
)
2307 return (KMF_ERR_BAD_PARAMETER
);
2309 if (key
->keyalg
== KMF_RSA
) {
2310 rsa
= EVP_PKEY_get1_RSA((EVP_PKEY
*)key
->keyp
);
2311 modulus_len
= RSA_size(rsa
);
2313 return (KMF_ERR_BAD_PARAMETER
);
2316 blocks
= ciphertext
->Length
/modulus_len
;
2317 out_data
= output
->Data
;
2318 in_data
= ciphertext
->Data
;
2319 out_len
= modulus_len
- 11;
2320 in_len
= modulus_len
;
2322 for (i
= 0; i
< blocks
; i
++) {
2323 out_len
= RSA_private_decrypt(in_len
,
2324 in_data
, out_data
, rsa
, RSA_PKCS1_PADDING
);
2327 ret
= KMF_ERR_INTERNAL
;
2331 out_data
+= out_len
;
2332 total_decrypted
+= out_len
;
2336 output
->Length
= total_decrypted
;
2348 * This function will create a certid from issuer_cert and user_cert.
2349 * The caller should use OCSP_CERTID_free(OCSP_CERTID *) to deallocate
2350 * certid memory after use.
2353 create_certid(KMF_HANDLE_T handle
, const KMF_DATA
*issuer_cert
,
2354 const KMF_DATA
*user_cert
, OCSP_CERTID
**certid
)
2356 KMF_RETURN ret
= KMF_OK
;
2357 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2358 X509
*issuer
= NULL
;
2360 unsigned char *ptmp
;
2362 if (issuer_cert
== NULL
|| user_cert
== NULL
) {
2363 return (KMF_ERR_BAD_PARAMETER
);
2366 /* convert the DER-encoded issuer cert to an internal X509 */
2367 ptmp
= issuer_cert
->Data
;
2368 issuer
= d2i_X509(NULL
, (const uchar_t
**)&ptmp
,
2369 issuer_cert
->Length
);
2370 if (issuer
== NULL
) {
2371 SET_ERROR(kmfh
, ERR_get_error());
2372 ret
= KMF_ERR_OCSP_BAD_ISSUER
;
2376 /* convert the DER-encoded user cert to an internal X509 */
2377 ptmp
= user_cert
->Data
;
2378 cert
= d2i_X509(NULL
, (const uchar_t
**)&ptmp
,
2381 SET_ERROR(kmfh
, ERR_get_error());
2383 ret
= KMF_ERR_OCSP_BAD_CERT
;
2387 /* create a CERTID */
2388 *certid
= OCSP_cert_to_id(NULL
, cert
, issuer
);
2389 if (*certid
== NULL
) {
2390 SET_ERROR(kmfh
, ERR_get_error());
2391 ret
= KMF_ERR_OCSP_CERTID
;
2396 if (issuer
!= NULL
) {
2408 OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle
,
2409 int numattr
, KMF_ATTRIBUTE
*attrlist
)
2411 KMF_RETURN ret
= KMF_OK
;
2412 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2413 OCSP_CERTID
*id
= NULL
;
2414 OCSP_REQUEST
*req
= NULL
;
2417 KMF_DATA
*issuer_cert
;
2418 KMF_DATA
*user_cert
;
2420 user_cert
= kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR
,
2422 if (user_cert
== NULL
)
2423 return (KMF_ERR_BAD_PARAMETER
);
2425 issuer_cert
= kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR
,
2427 if (issuer_cert
== NULL
)
2428 return (KMF_ERR_BAD_PARAMETER
);
2430 reqfile
= kmf_get_attr_ptr(KMF_OCSP_REQUEST_FILENAME_ATTR
,
2432 if (reqfile
== NULL
)
2433 return (KMF_ERR_BAD_PARAMETER
);
2435 ret
= create_certid(handle
, issuer_cert
, user_cert
, &id
);
2436 if (ret
!= KMF_OK
) {
2440 /* Create an OCSP request */
2441 req
= OCSP_REQUEST_new();
2443 SET_ERROR(kmfh
, ERR_get_error());
2444 ret
= KMF_ERR_OCSP_CREATE_REQUEST
;
2448 if (!OCSP_request_add0_id(req
, id
)) {
2449 ret
= KMF_ERR_OCSP_CREATE_REQUEST
;
2453 /* Write the request to the output file with DER encoding */
2454 derbio
= BIO_new_file(reqfile
, "wb");
2456 SET_ERROR(kmfh
, ERR_get_error());
2457 ret
= KMF_ERR_OPEN_FILE
;
2460 if (i2d_OCSP_REQUEST_bio(derbio
, req
) <= 0) {
2461 ret
= KMF_ERR_ENCODING
;
2466 * We don't need to free "id" explicitely, because OCSP_REQUEST_free()
2467 * will also deallocate certid's space.
2470 OCSP_REQUEST_free(req
);
2473 if (derbio
!= NULL
) {
2474 (void) BIO_free(derbio
);
2480 /* ocsp_find_signer_sk() is copied from openssl source */
2481 static X509
*ocsp_find_signer_sk(STACK_OF(X509
) *certs
, OCSP_RESPID
*id
)
2484 unsigned char tmphash
[SHA_DIGEST_LENGTH
], *keyhash
;
2486 /* Easy if lookup by name */
2487 if (id
->type
== V_OCSP_RESPID_NAME
)
2488 return (X509_find_by_subject(certs
, id
->value
.byName
));
2490 /* Lookup by key hash */
2492 /* If key hash isn't SHA1 length then forget it */
2493 if (id
->value
.byKey
->length
!= SHA_DIGEST_LENGTH
)
2496 keyhash
= id
->value
.byKey
->data
;
2497 /* Calculate hash of each key and compare */
2498 for (i
= 0; i
< sk_X509_num(certs
); i
++) {
2499 /* LINTED E_BAD_PTR_CAST_ALIGN */
2500 X509
*x
= sk_X509_value(certs
, i
);
2501 /* Use pubkey_digest to get the key ID value */
2502 (void) X509_pubkey_digest(x
, EVP_sha1(), tmphash
, NULL
);
2503 if (!memcmp(keyhash
, tmphash
, SHA_DIGEST_LENGTH
))
2509 /* ocsp_find_signer() is copied from openssl source */
2512 ocsp_find_signer(X509
**psigner
, OCSP_BASICRESP
*bs
, STACK_OF(X509
) *certs
,
2513 X509_STORE
*st
, unsigned long flags
)
2516 OCSP_RESPID
*rid
= bs
->tbsResponseData
->responderId
;
2517 if ((signer
= ocsp_find_signer_sk(certs
, rid
))) {
2521 if (!(flags
& OCSP_NOINTERN
) &&
2522 (signer
= ocsp_find_signer_sk(bs
->certs
, rid
))) {
2526 /* Maybe lookup from store if by subject name */
2533 * This function will verify the signature of a basic response, using
2534 * the public key from the OCSP responder certificate.
2537 check_response_signature(KMF_HANDLE_T handle
, OCSP_BASICRESP
*bs
,
2538 KMF_DATA
*signer_cert
, KMF_DATA
*issuer_cert
)
2540 KMF_RETURN ret
= KMF_OK
;
2541 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2542 STACK_OF(X509
) *cert_stack
= NULL
;
2543 X509
*signer
= NULL
;
2544 X509
*issuer
= NULL
;
2545 EVP_PKEY
*skey
= NULL
;
2546 unsigned char *ptmp
;
2549 if (bs
== NULL
|| issuer_cert
== NULL
)
2550 return (KMF_ERR_BAD_PARAMETER
);
2553 * Find the certificate that signed the basic response.
2555 * If signer_cert is not NULL, we will use that as the signer cert.
2556 * Otherwise, we will check if the issuer cert is actually the signer.
2557 * If we still do not find a signer, we will look for it from the
2558 * certificate list came with the response file.
2560 if (signer_cert
!= NULL
) {
2561 ptmp
= signer_cert
->Data
;
2562 signer
= d2i_X509(NULL
, (const uchar_t
**)&ptmp
,
2563 signer_cert
->Length
);
2564 if (signer
== NULL
) {
2565 SET_ERROR(kmfh
, ERR_get_error());
2566 ret
= KMF_ERR_OCSP_BAD_SIGNER
;
2571 * Convert the issuer cert into X509 and push it into a
2572 * stack to be used by ocsp_find_signer().
2574 ptmp
= issuer_cert
->Data
;
2575 issuer
= d2i_X509(NULL
, (const uchar_t
**)&ptmp
,
2576 issuer_cert
->Length
);
2577 if (issuer
== NULL
) {
2578 SET_ERROR(kmfh
, ERR_get_error());
2579 ret
= KMF_ERR_OCSP_BAD_ISSUER
;
2583 if ((cert_stack
= sk_X509_new_null()) == NULL
) {
2584 ret
= KMF_ERR_INTERNAL
;
2588 if (sk_X509_push(cert_stack
, issuer
) == NULL
) {
2589 ret
= KMF_ERR_INTERNAL
;
2593 ret
= ocsp_find_signer(&signer
, bs
, cert_stack
, NULL
, 0);
2595 /* can not find the signer */
2596 ret
= KMF_ERR_OCSP_BAD_SIGNER
;
2601 /* Verify the signature of the response */
2602 skey
= X509_get_pubkey(signer
);
2604 ret
= KMF_ERR_OCSP_BAD_SIGNER
;
2608 ret
= OCSP_BASICRESP_verify(bs
, skey
, 0);
2610 ret
= KMF_ERR_OCSP_RESPONSE_SIGNATURE
;
2615 if (issuer
!= NULL
) {
2619 if (signer
!= NULL
) {
2624 EVP_PKEY_free(skey
);
2627 if (cert_stack
!= NULL
) {
2628 sk_X509_free(cert_stack
);
2637 OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle
,
2638 int numattr
, KMF_ATTRIBUTE
*attrlist
)
2640 KMF_RETURN ret
= KMF_OK
;
2642 OCSP_RESPONSE
*resp
= NULL
;
2643 OCSP_BASICRESP
*bs
= NULL
;
2644 OCSP_CERTID
*id
= NULL
;
2645 OCSP_SINGLERESP
*single
= NULL
;
2646 ASN1_GENERALIZEDTIME
*rev
, *thisupd
, *nextupd
;
2647 int index
, status
, reason
;
2648 KMF_DATA
*issuer_cert
;
2649 KMF_DATA
*user_cert
;
2650 KMF_DATA
*signer_cert
;
2652 int *response_reason
, *response_status
, *cert_status
;
2653 boolean_t ignore_response_sign
= B_FALSE
; /* default is FALSE */
2654 uint32_t response_lifetime
;
2656 issuer_cert
= kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR
,
2658 if (issuer_cert
== NULL
)
2659 return (KMF_ERR_BAD_PARAMETER
);
2661 user_cert
= kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR
,
2663 if (user_cert
== NULL
)
2664 return (KMF_ERR_BAD_PARAMETER
);
2666 response
= kmf_get_attr_ptr(KMF_OCSP_RESPONSE_DATA_ATTR
,
2668 if (response
== NULL
)
2669 return (KMF_ERR_BAD_PARAMETER
);
2671 response_status
= kmf_get_attr_ptr(KMF_OCSP_RESPONSE_STATUS_ATTR
,
2673 if (response_status
== NULL
)
2674 return (KMF_ERR_BAD_PARAMETER
);
2676 response_reason
= kmf_get_attr_ptr(KMF_OCSP_RESPONSE_REASON_ATTR
,
2678 if (response_reason
== NULL
)
2679 return (KMF_ERR_BAD_PARAMETER
);
2681 cert_status
= kmf_get_attr_ptr(KMF_OCSP_RESPONSE_CERT_STATUS_ATTR
,
2683 if (cert_status
== NULL
)
2684 return (KMF_ERR_BAD_PARAMETER
);
2686 /* Read in the response */
2687 derbio
= BIO_new_mem_buf(response
->Data
, response
->Length
);
2689 ret
= KMF_ERR_MEMORY
;
2693 resp
= d2i_OCSP_RESPONSE_bio(derbio
, NULL
);
2695 ret
= KMF_ERR_OCSP_MALFORMED_RESPONSE
;
2699 /* Check the response status */
2700 status
= OCSP_response_status(resp
);
2701 *response_status
= status
;
2702 if (status
!= OCSP_RESPONSE_STATUS_SUCCESSFUL
) {
2703 ret
= KMF_ERR_OCSP_RESPONSE_STATUS
;
2708 printf("Successfully checked the response file status.\n");
2711 /* Extract basic response */
2712 bs
= OCSP_response_get1_basic(resp
);
2714 ret
= KMF_ERR_OCSP_NO_BASIC_RESPONSE
;
2719 printf("Successfully retrieved the basic response.\n");
2722 /* Check the basic response signature if required */
2723 ret
= kmf_get_attr(KMF_IGNORE_RESPONSE_SIGN_ATTR
, attrlist
, numattr
,
2724 (void *)&ignore_response_sign
, NULL
);
2728 signer_cert
= kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR
,
2731 if (ignore_response_sign
== B_FALSE
) {
2732 ret
= check_response_signature(handle
, bs
,
2733 signer_cert
, issuer_cert
);
2739 printf("Successfully verified the response signature.\n");
2742 /* Create a certid for the certificate in question */
2743 ret
= create_certid(handle
, issuer_cert
, user_cert
, &id
);
2744 if (ret
!= KMF_OK
) {
2745 ret
= KMF_ERR_OCSP_CERTID
;
2750 printf("successfully created a certid for the cert.\n");
2753 /* Find the index of the single response for the certid */
2754 index
= OCSP_resp_find(bs
, id
, -1);
2756 /* cound not find this certificate in the response */
2757 ret
= KMF_ERR_OCSP_UNKNOWN_CERT
;
2762 printf("Successfully found the single response index for the cert.\n");
2765 /* Retrieve the single response and get the cert status */
2766 single
= OCSP_resp_get0(bs
, index
);
2767 status
= OCSP_single_get0_status(single
, &reason
, &rev
, &thisupd
,
2769 if (status
== V_OCSP_CERTSTATUS_GOOD
) {
2770 *cert_status
= OCSP_GOOD
;
2771 } else if (status
== V_OCSP_CERTSTATUS_UNKNOWN
) {
2772 *cert_status
= OCSP_UNKNOWN
;
2773 } else { /* revoked */
2774 *cert_status
= OCSP_REVOKED
;
2775 *response_reason
= reason
;
2779 /* resp. time is optional, so we don't care about the return code. */
2780 (void) kmf_get_attr(KMF_RESPONSE_LIFETIME_ATTR
, attrlist
, numattr
,
2781 (void *)&response_lifetime
, NULL
);
2783 if (!OCSP_check_validity(thisupd
, nextupd
, 300,
2784 response_lifetime
)) {
2785 ret
= KMF_ERR_OCSP_STATUS_TIME_INVALID
;
2790 printf("Successfully verify the time.\n");
2795 (void) BIO_free(derbio
);
2798 OCSP_RESPONSE_free(resp
);
2801 OCSP_BASICRESP_free(bs
);
2804 OCSP_CERTID_free(id
);
2810 fetch_key(KMF_HANDLE_T handle
, char *path
,
2811 KMF_KEY_CLASS keyclass
, KMF_KEY_HANDLE
*key
)
2813 KMF_RETURN rv
= KMF_OK
;
2814 EVP_PKEY
*pkey
= NULL
;
2815 KMF_RAW_SYM_KEY
*rkey
= NULL
;
2817 if (keyclass
== KMF_ASYM_PRI
||
2818 keyclass
== KMF_ASYM_PUB
) {
2819 pkey
= openssl_load_key(handle
, path
);
2821 return (KMF_ERR_KEY_NOT_FOUND
);
2824 if (pkey
->type
== EVP_PKEY_RSA
)
2825 key
->keyalg
= KMF_RSA
;
2826 else if (pkey
->type
== EVP_PKEY_DSA
)
2827 key
->keyalg
= KMF_DSA
;
2829 key
->kstype
= KMF_KEYSTORE_OPENSSL
;
2830 key
->keyclass
= keyclass
;
2831 key
->keyp
= (void *)pkey
;
2834 ((key
->keylabel
= strdup(path
)) == NULL
)) {
2835 EVP_PKEY_free(pkey
);
2836 return (KMF_ERR_MEMORY
);
2839 EVP_PKEY_free(pkey
);
2842 } else if (keyclass
== KMF_SYMMETRIC
) {
2843 KMF_ENCODE_FORMAT fmt
;
2845 * If the file is a recognized format,
2846 * then it is NOT a symmetric key.
2848 rv
= kmf_get_file_format(path
, &fmt
);
2849 if (rv
== KMF_OK
|| fmt
!= 0) {
2850 return (KMF_ERR_KEY_NOT_FOUND
);
2851 } else if (rv
== KMF_ERR_ENCODING
) {
2853 * If we don't know the encoding,
2854 * it is probably a symmetric key.
2857 } else if (rv
== KMF_ERR_OPEN_FILE
) {
2858 return (KMF_ERR_KEY_NOT_FOUND
);
2863 rkey
= malloc(sizeof (KMF_RAW_SYM_KEY
));
2865 rv
= KMF_ERR_MEMORY
;
2869 (void) memset(rkey
, 0, sizeof (KMF_RAW_SYM_KEY
));
2870 rv
= kmf_read_input_file(handle
, path
, &keyvalue
);
2874 rkey
->keydata
.len
= keyvalue
.Length
;
2875 rkey
->keydata
.val
= keyvalue
.Data
;
2877 key
->kstype
= KMF_KEYSTORE_OPENSSL
;
2878 key
->keyclass
= keyclass
;
2880 key
->keyp
= (void *)rkey
;
2882 ((key
->keylabel
= strdup(path
)) == NULL
)) {
2883 rv
= KMF_ERR_MEMORY
;
2890 kmf_free_raw_sym_key(rkey
);
2893 EVP_PKEY_free(pkey
);
2896 key
->keyalg
= KMF_KEYALG_NONE
;
2897 key
->keyclass
= KMF_KEYCLASS_NONE
;
2906 OpenSSL_FindKey(KMF_HANDLE_T handle
,
2907 int numattr
, KMF_ATTRIBUTE
*attrlist
)
2909 KMF_RETURN rv
= KMF_OK
;
2910 char *fullpath
= NULL
;
2912 KMF_KEY_HANDLE
*key
;
2914 KMF_KEY_CLASS keyclass
;
2915 KMF_RAW_KEY_DATA
*rawkey
;
2920 return (KMF_ERR_BAD_PARAMETER
);
2922 numkeys
= kmf_get_attr_ptr(KMF_COUNT_ATTR
, attrlist
, numattr
);
2923 if (numkeys
== NULL
)
2924 return (KMF_ERR_BAD_PARAMETER
);
2926 rv
= kmf_get_attr(KMF_KEYCLASS_ATTR
, attrlist
, numattr
,
2927 (void *)&keyclass
, NULL
);
2929 return (KMF_ERR_BAD_PARAMETER
);
2931 if (keyclass
!= KMF_ASYM_PUB
&&
2932 keyclass
!= KMF_ASYM_PRI
&&
2933 keyclass
!= KMF_SYMMETRIC
)
2934 return (KMF_ERR_BAD_KEY_CLASS
);
2936 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
2937 keyfile
= kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
, attrlist
, numattr
);
2939 fullpath
= get_fullpath(dirpath
, keyfile
);
2941 if (fullpath
== NULL
)
2942 return (KMF_ERR_BAD_PARAMETER
);
2946 maxkeys
= 0xFFFFFFFF;
2949 key
= kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR
, attrlist
, numattr
);
2950 /* it is okay to have "keys" contains NULL */
2953 * The caller may want a list of the raw key data as well.
2954 * Useful for importing keys from a file into other keystores.
2956 rawkey
= kmf_get_attr_ptr(KMF_RAW_KEY_ATTR
, attrlist
, numattr
);
2958 if (isdir(fullpath
)) {
2963 /* open all files in the directory and attempt to read them */
2964 if ((dirp
= opendir(fullpath
)) == NULL
) {
2965 return (KMF_ERR_BAD_PARAMETER
);
2968 while ((dp
= readdir(dirp
)) != NULL
&& n
< maxkeys
) {
2969 if (strcmp(dp
->d_name
, ".") &&
2970 strcmp(dp
->d_name
, "..")) {
2973 fname
= get_fullpath(fullpath
,
2974 (char *)&dp
->d_name
);
2976 rv
= fetch_key(handle
, fname
,
2977 keyclass
, key
? &key
[n
] : NULL
);
2980 if (key
!= NULL
&& rawkey
!= NULL
)
2981 rv
= convertToRawKey(
2982 key
[n
].keyp
, &rawkey
[n
]);
2986 if (rv
!= KMF_OK
|| key
== NULL
)
2990 (void) closedir(dirp
);
2994 rv
= fetch_key(handle
, fullpath
, keyclass
, key
);
2998 if (rv
!= KMF_OK
|| key
== NULL
)
3001 if (rv
== KMF_OK
&& key
!= NULL
&& rawkey
!= NULL
) {
3002 rv
= convertToRawKey(key
->keyp
, rawkey
);
3006 if (rv
== KMF_OK
&& (*numkeys
) == 0)
3007 rv
= KMF_ERR_KEY_NOT_FOUND
;
3008 else if (rv
== KMF_ERR_KEY_NOT_FOUND
&& (*numkeys
) > 0)
3014 #define HANDLE_PK12_ERROR { \
3015 SET_ERROR(kmfh, ERR_get_error()); \
3016 rv = KMF_ERR_ENCODING; \
3021 add_alias_to_bag(PKCS12_SAFEBAG
*bag
, X509
*xcert
)
3023 if (xcert
!= NULL
&& xcert
->aux
!= NULL
&&
3024 xcert
->aux
->alias
!= NULL
) {
3025 if (PKCS12_add_friendlyname_asc(bag
,
3026 (const char *)xcert
->aux
->alias
->data
,
3027 xcert
->aux
->alias
->length
) == 0)
3034 add_cert_to_safe(X509
*sslcert
, KMF_CREDENTIAL
*cred
,
3035 uchar_t
*keyid
, unsigned int keyidlen
)
3037 PKCS12_SAFEBAG
*bag
= NULL
;
3038 PKCS7
*cert_authsafe
= NULL
;
3039 STACK_OF(PKCS12_SAFEBAG
) *bag_stack
;
3041 bag_stack
= sk_PKCS12_SAFEBAG_new_null();
3042 if (bag_stack
== NULL
)
3045 /* Convert cert from X509 struct to PKCS#12 bag */
3046 bag
= PKCS12_x5092certbag(sslcert
);
3051 /* Add the key id to the certificate bag. */
3052 if (keyidlen
> 0 && !PKCS12_add_localkeyid(bag
, keyid
, keyidlen
)) {
3056 if (!add_alias_to_bag(bag
, sslcert
))
3059 /* Pile it on the bag_stack. */
3060 if (!sk_PKCS12_SAFEBAG_push(bag_stack
, bag
)) {
3063 /* Turn bag_stack of certs into encrypted authsafe. */
3064 cert_authsafe
= PKCS12_pack_p7encdata(
3065 NID_pbe_WithSHA1And40BitRC2_CBC
,
3066 cred
->cred
, cred
->credlen
, NULL
, 0,
3067 PKCS12_DEFAULT_ITER
, bag_stack
);
3070 if (bag_stack
!= NULL
)
3071 sk_PKCS12_SAFEBAG_pop_free(bag_stack
, PKCS12_SAFEBAG_free
);
3073 return (cert_authsafe
);
3077 add_key_to_safe(EVP_PKEY
*pkey
, KMF_CREDENTIAL
*cred
,
3078 uchar_t
*keyid
, unsigned int keyidlen
,
3079 char *label
, int label_len
)
3081 PKCS8_PRIV_KEY_INFO
*p8
= NULL
;
3082 STACK_OF(PKCS12_SAFEBAG
) *bag_stack
= NULL
;
3083 PKCS12_SAFEBAG
*bag
= NULL
;
3084 PKCS7
*key_authsafe
= NULL
;
3086 p8
= EVP_PKEY2PKCS8(pkey
);
3090 /* Put the shrouded key into a PKCS#12 bag. */
3091 bag
= PKCS12_MAKE_SHKEYBAG(
3092 NID_pbe_WithSHA1And3_Key_TripleDES_CBC
,
3093 cred
->cred
, cred
->credlen
,
3094 NULL
, 0, PKCS12_DEFAULT_ITER
, p8
);
3096 /* Clean up the PKCS#8 shrouded key, don't need it now. */
3097 PKCS8_PRIV_KEY_INFO_free(p8
);
3103 if (keyidlen
&& !PKCS12_add_localkeyid(bag
, keyid
, keyidlen
))
3105 if (label
!= NULL
&& !PKCS12_add_friendlyname(bag
, label
, label_len
))
3108 /* Start a PKCS#12 safebag container for the private key. */
3109 bag_stack
= sk_PKCS12_SAFEBAG_new_null();
3110 if (bag_stack
== NULL
)
3113 /* Pile on the private key on the bag_stack. */
3114 if (!sk_PKCS12_SAFEBAG_push(bag_stack
, bag
))
3117 key_authsafe
= PKCS12_pack_p7data(bag_stack
);
3120 if (bag_stack
!= NULL
)
3121 sk_PKCS12_SAFEBAG_pop_free(bag_stack
, PKCS12_SAFEBAG_free
);
3123 return (key_authsafe
);
3127 ImportRawRSAKey(KMF_RAW_RSA_KEY
*key
)
3130 EVP_PKEY
*newkey
= NULL
;
3132 if ((rsa
= RSA_new()) == NULL
)
3135 if ((rsa
->n
= BN_bin2bn(key
->mod
.val
, key
->mod
.len
, rsa
->n
)) == NULL
)
3138 if ((rsa
->e
= BN_bin2bn(key
->pubexp
.val
, key
->pubexp
.len
, rsa
->e
)) ==
3142 if (key
->priexp
.val
!= NULL
)
3143 if ((rsa
->d
= BN_bin2bn(key
->priexp
.val
, key
->priexp
.len
,
3147 if (key
->prime1
.val
!= NULL
)
3148 if ((rsa
->p
= BN_bin2bn(key
->prime1
.val
, key
->prime1
.len
,
3152 if (key
->prime2
.val
!= NULL
)
3153 if ((rsa
->q
= BN_bin2bn(key
->prime2
.val
, key
->prime2
.len
,
3157 if (key
->exp1
.val
!= NULL
)
3158 if ((rsa
->dmp1
= BN_bin2bn(key
->exp1
.val
, key
->exp1
.len
,
3159 rsa
->dmp1
)) == NULL
)
3162 if (key
->exp2
.val
!= NULL
)
3163 if ((rsa
->dmq1
= BN_bin2bn(key
->exp2
.val
, key
->exp2
.len
,
3164 rsa
->dmq1
)) == NULL
)
3167 if (key
->coef
.val
!= NULL
)
3168 if ((rsa
->iqmp
= BN_bin2bn(key
->coef
.val
, key
->coef
.len
,
3169 rsa
->iqmp
)) == NULL
)
3172 if ((newkey
= EVP_PKEY_new()) == NULL
)
3175 (void) EVP_PKEY_set1_RSA(newkey
, rsa
);
3177 /* The original key must be freed once here or it leaks memory */
3184 ImportRawDSAKey(KMF_RAW_DSA_KEY
*key
)
3187 EVP_PKEY
*newkey
= NULL
;
3189 if ((dsa
= DSA_new()) == NULL
)
3192 if ((dsa
->p
= BN_bin2bn(key
->prime
.val
, key
->prime
.len
,
3196 if ((dsa
->q
= BN_bin2bn(key
->subprime
.val
, key
->subprime
.len
,
3200 if ((dsa
->g
= BN_bin2bn(key
->base
.val
, key
->base
.len
,
3204 if ((dsa
->priv_key
= BN_bin2bn(key
->value
.val
, key
->value
.len
,
3205 dsa
->priv_key
)) == NULL
)
3208 if (key
->pubvalue
.val
!= NULL
) {
3209 if ((dsa
->pub_key
= BN_bin2bn(key
->pubvalue
.val
,
3210 key
->pubvalue
.len
, dsa
->pub_key
)) == NULL
)
3214 if ((newkey
= EVP_PKEY_new()) == NULL
)
3217 (void) EVP_PKEY_set1_DSA(newkey
, dsa
);
3219 /* The original key must be freed once here or it leaks memory */
3225 raw_key_to_pkey(KMF_KEY_HANDLE
*key
)
3227 EVP_PKEY
*pkey
= NULL
;
3228 KMF_RAW_KEY_DATA
*rawkey
;
3229 ASN1_TYPE
*attr
= NULL
;
3232 if (key
== NULL
|| !key
->israw
)
3235 rawkey
= (KMF_RAW_KEY_DATA
*)key
->keyp
;
3236 if (rawkey
->keytype
== KMF_RSA
) {
3237 pkey
= ImportRawRSAKey(&rawkey
->rawdata
.rsa
);
3238 } else if (rawkey
->keytype
== KMF_DSA
) {
3239 pkey
= ImportRawDSAKey(&rawkey
->rawdata
.dsa
);
3240 } else if (rawkey
->keytype
== KMF_ECDSA
) {
3242 * OpenSSL in Solaris does not support EC for
3247 /* wrong kind of key */
3251 if (rawkey
->label
!= NULL
) {
3252 if ((attr
= ASN1_TYPE_new()) == NULL
) {
3253 EVP_PKEY_free(pkey
);
3256 attr
->value
.bmpstring
= ASN1_STRING_type_new(V_ASN1_BMPSTRING
);
3257 (void) ASN1_STRING_set(attr
->value
.bmpstring
, rawkey
->label
,
3258 strlen(rawkey
->label
));
3259 attr
->type
= V_ASN1_BMPSTRING
;
3260 attr
->value
.ptr
= (char *)attr
->value
.bmpstring
;
3261 ret
= set_pkey_attrib(pkey
, attr
, NID_friendlyName
);
3262 if (ret
!= KMF_OK
) {
3263 EVP_PKEY_free(pkey
);
3264 ASN1_TYPE_free(attr
);
3268 if (rawkey
->id
.Data
!= NULL
) {
3269 if ((attr
= ASN1_TYPE_new()) == NULL
) {
3270 EVP_PKEY_free(pkey
);
3273 attr
->value
.octet_string
=
3274 ASN1_STRING_type_new(V_ASN1_OCTET_STRING
);
3275 attr
->type
= V_ASN1_OCTET_STRING
;
3276 (void) ASN1_STRING_set(attr
->value
.octet_string
,
3277 rawkey
->id
.Data
, rawkey
->id
.Length
);
3278 attr
->value
.ptr
= (char *)attr
->value
.octet_string
;
3279 ret
= set_pkey_attrib(pkey
, attr
, NID_localKeyID
);
3280 if (ret
!= KMF_OK
) {
3281 EVP_PKEY_free(pkey
);
3282 ASN1_TYPE_free(attr
);
3290 * Search a list of private keys to find one that goes with the certificate.
3293 find_matching_key(X509
*xcert
, int numkeys
, KMF_KEY_HANDLE
*keylist
)
3296 EVP_PKEY
*pkey
= NULL
;
3298 if (numkeys
== 0 || keylist
== NULL
|| xcert
== NULL
)
3300 for (i
= 0; i
< numkeys
; i
++) {
3301 if (keylist
[i
].israw
)
3302 pkey
= raw_key_to_pkey(&keylist
[i
]);
3304 pkey
= (EVP_PKEY
*)keylist
[i
].keyp
;
3306 if (X509_check_private_key(xcert
, pkey
)) {
3309 EVP_PKEY_free(pkey
);
3318 local_export_pk12(KMF_HANDLE_T handle
,
3319 KMF_CREDENTIAL
*cred
,
3320 int numcerts
, KMF_X509_DER_CERT
*certlist
,
3321 int numkeys
, KMF_KEY_HANDLE
*keylist
,
3324 KMF_RETURN rv
= KMF_OK
;
3325 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
3327 PKCS7
*cert_authsafe
= NULL
;
3328 PKCS7
*key_authsafe
= NULL
;
3329 STACK_OF(PKCS7
) *authsafe_stack
= NULL
;
3330 PKCS12
*p12_elem
= NULL
;
3333 if (numcerts
== 0 && numkeys
== 0)
3334 return (KMF_ERR_BAD_PARAMETER
);
3337 * Open the output file.
3339 if ((bio
= BIO_new_file(filename
, "wb")) == NULL
) {
3340 SET_ERROR(kmfh
, ERR_get_error());
3341 rv
= KMF_ERR_OPEN_FILE
;
3345 /* Start a PKCS#7 stack. */
3346 authsafe_stack
= sk_PKCS7_new_null();
3347 if (authsafe_stack
== NULL
) {
3348 rv
= KMF_ERR_MEMORY
;
3352 for (i
= 0; rv
== KMF_OK
&& i
< numcerts
; i
++) {
3353 const uchar_t
*p
= certlist
[i
].certificate
.Data
;
3354 long len
= certlist
[i
].certificate
.Length
;
3356 EVP_PKEY
*pkey
= NULL
;
3357 unsigned char keyid
[EVP_MAX_MD_SIZE
];
3358 unsigned int keyidlen
= 0;
3360 xcert
= d2i_X509(NULL
, &p
, len
);
3361 if (xcert
== NULL
) {
3362 SET_ERROR(kmfh
, ERR_get_error());
3363 rv
= KMF_ERR_ENCODING
;
3365 if (certlist
[i
].kmf_private
.label
!= NULL
) {
3366 /* Set alias attribute */
3367 (void) X509_alias_set1(xcert
,
3368 (uchar_t
*)certlist
[i
].kmf_private
.label
,
3369 strlen(certlist
[i
].kmf_private
.label
));
3371 /* Check if there is a key corresponding to this cert */
3372 pkey
= find_matching_key(xcert
, numkeys
, keylist
);
3375 * If key is found, get fingerprint and create a
3379 (void) X509_digest(xcert
, EVP_sha1(),
3381 key_authsafe
= add_key_to_safe(pkey
, cred
,
3383 certlist
[i
].kmf_private
.label
,
3384 (certlist
[i
].kmf_private
.label
?
3385 strlen(certlist
[i
].kmf_private
.label
) : 0));
3387 if (key_authsafe
== NULL
) {
3389 EVP_PKEY_free(pkey
);
3392 /* Put the key safe into the Auth Safe */
3393 if (!sk_PKCS7_push(authsafe_stack
,
3396 EVP_PKEY_free(pkey
);
3401 /* create a certificate safebag */
3402 cert_authsafe
= add_cert_to_safe(xcert
, cred
, keyid
,
3404 if (cert_authsafe
== NULL
) {
3406 EVP_PKEY_free(pkey
);
3409 if (!sk_PKCS7_push(authsafe_stack
, cert_authsafe
)) {
3411 EVP_PKEY_free(pkey
);
3417 EVP_PKEY_free(pkey
);
3419 } else if (numcerts
== 0 && numkeys
> 0) {
3421 * If only adding keys to the file.
3423 for (i
= 0; i
< numkeys
; i
++) {
3424 EVP_PKEY
*pkey
= NULL
;
3426 if (keylist
[i
].israw
)
3427 pkey
= raw_key_to_pkey(&keylist
[i
]);
3429 pkey
= (EVP_PKEY
*)keylist
[i
].keyp
;
3434 key_authsafe
= add_key_to_safe(pkey
, cred
,
3437 if (key_authsafe
== NULL
) {
3438 EVP_PKEY_free(pkey
);
3441 if (!sk_PKCS7_push(authsafe_stack
, key_authsafe
)) {
3442 EVP_PKEY_free(pkey
);
3447 p12_elem
= PKCS12_init(NID_pkcs7_data
);
3448 if (p12_elem
== NULL
) {
3452 /* Put the PKCS#7 stack into the PKCS#12 element. */
3453 if (!PKCS12_pack_authsafes(p12_elem
, authsafe_stack
)) {
3457 /* Set the integrity MAC on the PKCS#12 element. */
3458 if (!PKCS12_set_mac(p12_elem
, cred
->cred
, cred
->credlen
,
3459 NULL
, 0, PKCS12_DEFAULT_ITER
, NULL
)) {
3463 /* Write the PKCS#12 element to the export file. */
3464 if (!i2d_PKCS12_bio(bio
, p12_elem
)) {
3467 PKCS12_free(p12_elem
);
3470 /* Clear away the PKCS#7 stack, we're done with it. */
3472 sk_PKCS7_pop_free(authsafe_stack
, PKCS7_free
);
3475 (void) BIO_free_all(bio
);
3481 openssl_build_pk12(KMF_HANDLE_T handle
, int numcerts
,
3482 KMF_X509_DER_CERT
*certlist
, int numkeys
, KMF_KEY_HANDLE
*keylist
,
3483 KMF_CREDENTIAL
*p12cred
, char *filename
)
3487 if (certlist
== NULL
&& keylist
== NULL
)
3488 return (KMF_ERR_BAD_PARAMETER
);
3490 rv
= local_export_pk12(handle
, p12cred
, numcerts
, certlist
,
3491 numkeys
, keylist
, filename
);
3497 OpenSSL_ExportPK12(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
3500 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
3501 char *fullpath
= NULL
;
3502 char *dirpath
= NULL
;
3503 char *certfile
= NULL
;
3504 char *keyfile
= NULL
;
3505 char *filename
= NULL
;
3506 KMF_CREDENTIAL
*p12cred
= NULL
;
3507 KMF_X509_DER_CERT certdata
;
3513 return (KMF_ERR_BAD_PARAMETER
);
3516 * First, find the certificate.
3518 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
3519 certfile
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
, numattr
);
3520 if (certfile
!= NULL
) {
3521 fullpath
= get_fullpath(dirpath
, certfile
);
3522 if (fullpath
== NULL
)
3523 return (KMF_ERR_BAD_PARAMETER
);
3525 if (isdir(fullpath
)) {
3527 return (KMF_ERR_AMBIGUOUS_PATHNAME
);
3530 (void) memset(&certdata
, 0, sizeof (certdata
));
3531 rv
= kmf_load_cert(kmfh
, NULL
, NULL
, NULL
, NULL
,
3532 fullpath
, &certdata
.certificate
);
3537 certdata
.kmf_private
.keystore_type
= KMF_KEYSTORE_OPENSSL
;
3542 * Now find the private key.
3544 keyfile
= kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
, attrlist
, numattr
);
3545 if (keyfile
!= NULL
) {
3546 fullpath
= get_fullpath(dirpath
, keyfile
);
3547 if (fullpath
== NULL
)
3548 return (KMF_ERR_BAD_PARAMETER
);
3550 if (isdir(fullpath
)) {
3552 return (KMF_ERR_AMBIGUOUS_PATHNAME
);
3555 (void) memset(&key
, 0, sizeof (KMF_KEY_HANDLE
));
3556 rv
= fetch_key(handle
, fullpath
, KMF_ASYM_PRI
, &key
);
3563 * Open the output file.
3565 filename
= kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR
, attrlist
,
3567 if (filename
== NULL
) {
3568 rv
= KMF_ERR_BAD_PARAMETER
;
3572 /* Stick the key and the cert into a PKCS#12 file */
3573 p12cred
= kmf_get_attr_ptr(KMF_PK12CRED_ATTR
, attrlist
, numattr
);
3574 if (p12cred
== NULL
) {
3575 rv
= KMF_ERR_BAD_PARAMETER
;
3579 rv
= local_export_pk12(handle
, p12cred
, 1, &certdata
,
3587 kmf_free_kmf_cert(handle
, &certdata
);
3589 kmf_free_kmf_key(handle
, &key
);
3594 * Helper function to extract keys and certificates from
3595 * a single PEM file. Typically the file should contain a
3596 * private key and an associated public key wrapped in an x509 cert.
3597 * However, the file may be just a list of X509 certs with no keys.
3600 extract_pem(KMF_HANDLE
*kmfh
,
3601 char *issuer
, char *subject
, KMF_BIGINT
*serial
,
3602 char *filename
, CK_UTF8CHAR
*pin
,
3603 CK_ULONG pinlen
, EVP_PKEY
**priv_key
, KMF_DATA
**certs
,
3607 KMF_RETURN rv
= KMF_OK
;
3609 STACK_OF(X509_INFO
) *x509_info_stack
= NULL
;
3610 int i
, ncerts
= 0, matchcerts
= 0;
3611 EVP_PKEY
*pkey
= NULL
;
3614 X509_INFO
**cert_infos
= NULL
;
3615 KMF_DATA
*certlist
= NULL
;
3621 fp
= fopen(filename
, "r");
3623 return (KMF_ERR_OPEN_FILE
);
3625 x509_info_stack
= PEM_X509_INFO_read(fp
, NULL
, NULL
, pin
);
3626 if (x509_info_stack
== NULL
) {
3628 return (KMF_ERR_ENCODING
);
3630 cert_infos
= (X509_INFO
**)malloc(sk_X509_INFO_num(x509_info_stack
) *
3631 sizeof (X509_INFO
*));
3632 if (cert_infos
== NULL
) {
3634 rv
= KMF_ERR_MEMORY
;
3638 for (i
= 0; i
< sk_X509_INFO_num(x509_info_stack
); i
++) {
3639 /* LINTED E_BAD_PTR_CAST_ALIGN */
3640 cert_infos
[ncerts
] = sk_X509_INFO_value(x509_info_stack
, i
);
3646 rv
= KMF_ERR_CERT_NOT_FOUND
;
3650 if (priv_key
!= NULL
) {
3652 pkey
= PEM_read_PrivateKey(fp
, NULL
, NULL
, pin
);
3656 x
= cert_infos
[ncerts
- 1]->x509
;
3658 * Make sure the private key matchs the last cert in the file.
3660 if (pkey
!= NULL
&& !X509_check_private_key(x
, pkey
)) {
3661 EVP_PKEY_free(pkey
);
3662 rv
= KMF_ERR_KEY_MISMATCH
;
3666 certlist
= (KMF_DATA
*)calloc(ncerts
, sizeof (KMF_DATA
));
3667 if (certlist
== NULL
) {
3669 EVP_PKEY_free(pkey
);
3670 rv
= KMF_ERR_MEMORY
;
3675 * Convert all of the certs to DER format.
3678 for (i
= 0; rv
== KMF_OK
&& certs
!= NULL
&& i
< ncerts
; i
++) {
3679 boolean_t match
= FALSE
;
3680 info
= cert_infos
[ncerts
- 1 - i
];
3682 rv
= check_cert(info
->x509
, issuer
, subject
, serial
, &match
);
3683 if (rv
!= KMF_OK
|| match
!= TRUE
) {
3688 rv
= ssl_cert2KMFDATA(kmfh
, info
->x509
,
3689 &certlist
[matchcerts
++]);
3693 for (j
= 0; j
< matchcerts
; j
++)
3694 kmf_free_data(&certlist
[j
]);
3697 ncerts
= matchcerts
= 0;
3701 if (numcerts
!= NULL
)
3702 *numcerts
= matchcerts
;
3706 else if (certlist
!= NULL
) {
3707 for (i
= 0; i
< ncerts
; i
++)
3708 kmf_free_data(&certlist
[i
]);
3713 if (priv_key
== NULL
&& pkey
!= NULL
)
3714 EVP_PKEY_free(pkey
);
3715 else if (priv_key
!= NULL
&& pkey
!= NULL
)
3719 /* Cleanup the stack of X509 info records */
3720 for (i
= 0; i
< sk_X509_INFO_num(x509_info_stack
); i
++) {
3721 /* LINTED E_BAD_PTR_CAST_ALIGN */
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 /* LINTED E_BAD_PTR_CAST_ALIGN */
3743 PKCS12_SAFEBAG
*bag
= sk_PKCS12_SAFEBAG_value(bags
, i
);
3744 ret
= openssl_parse_bag(bag
, pin
, (pin
? strlen(pin
) : 0),
3755 set_pkey_attrib(EVP_PKEY
*pkey
, ASN1_TYPE
*attrib
, int nid
)
3757 X509_ATTRIBUTE
*attr
= NULL
;
3759 if (pkey
== NULL
|| attrib
== NULL
)
3760 return (KMF_ERR_BAD_PARAMETER
);
3762 if (pkey
->attributes
== NULL
) {
3763 pkey
->attributes
= sk_X509_ATTRIBUTE_new_null();
3764 if (pkey
->attributes
== NULL
)
3765 return (KMF_ERR_MEMORY
);
3767 attr
= X509_ATTRIBUTE_create(nid
, attrib
->type
, attrib
->value
.ptr
);
3772 i
< sk_X509_ATTRIBUTE_num(pkey
->attributes
); i
++) {
3773 /* LINTED E_BAD_PTR_CASE_ALIGN */
3774 a
= sk_X509_ATTRIBUTE_value(pkey
->attributes
, i
);
3775 if (OBJ_obj2nid(a
->object
) == nid
) {
3776 X509_ATTRIBUTE_free(a
);
3777 /* LINTED E_BAD_PTR_CAST_ALIGN */
3778 (void) sk_X509_ATTRIBUTE_set(pkey
->attributes
,
3783 if (sk_X509_ATTRIBUTE_push(pkey
->attributes
, attr
) == NULL
) {
3784 X509_ATTRIBUTE_free(attr
);
3785 return (KMF_ERR_MEMORY
);
3788 return (KMF_ERR_MEMORY
);
3795 openssl_parse_bag(PKCS12_SAFEBAG
*bag
, char *pass
, int passlen
,
3796 STACK_OF(EVP_PKEY
) *keylist
, STACK_OF(X509
) *certlist
)
3798 KMF_RETURN ret
= KMF_OK
;
3799 PKCS8_PRIV_KEY_INFO
*p8
= NULL
;
3800 EVP_PKEY
*pkey
= NULL
;
3802 ASN1_TYPE
*keyid
= NULL
;
3803 ASN1_TYPE
*fname
= NULL
;
3804 uchar_t
*data
= NULL
;
3806 keyid
= PKCS12_get_attr(bag
, NID_localKeyID
);
3807 fname
= PKCS12_get_attr(bag
, NID_friendlyName
);
3809 switch (M_PKCS12_bag_type(bag
)) {
3811 if (keylist
== NULL
)
3813 pkey
= EVP_PKCS82PKEY(bag
->value
.keybag
);
3815 ret
= KMF_ERR_PKCS12_FORMAT
;
3818 case NID_pkcs8ShroudedKeyBag
:
3819 if (keylist
== NULL
)
3821 p8
= M_PKCS12_decrypt_skey(bag
, pass
, passlen
);
3823 return (KMF_ERR_AUTH_FAILED
);
3824 pkey
= EVP_PKCS82PKEY(p8
);
3825 PKCS8_PRIV_KEY_INFO_free(p8
);
3827 ret
= KMF_ERR_PKCS12_FORMAT
;
3830 if (certlist
== NULL
)
3832 if (M_PKCS12_cert_bag_type(bag
) != NID_x509Certificate
)
3833 return (KMF_ERR_PKCS12_FORMAT
);
3834 xcert
= M_PKCS12_certbag2x509(bag
);
3835 if (xcert
== NULL
) {
3836 ret
= KMF_ERR_PKCS12_FORMAT
;
3839 if (keyid
!= NULL
) {
3840 if (X509_keyid_set1(xcert
,
3841 keyid
->value
.octet_string
->data
,
3842 keyid
->value
.octet_string
->length
) == 0) {
3843 ret
= KMF_ERR_PKCS12_FORMAT
;
3847 if (fname
!= NULL
) {
3849 len
= ASN1_STRING_to_UTF8(&data
,
3850 fname
->value
.asn1_string
);
3851 if (len
> 0 && data
!= NULL
) {
3852 r
= X509_alias_set1(xcert
, data
, len
);
3854 ret
= KMF_ERR_PKCS12_FORMAT
;
3858 ret
= KMF_ERR_PKCS12_FORMAT
;
3862 if (sk_X509_push(certlist
, xcert
) == 0)
3863 ret
= KMF_ERR_MEMORY
;
3867 case NID_safeContentsBag
:
3868 return (openssl_parse_bags(bag
->value
.safes
, pass
,
3869 keylist
, certlist
));
3871 ret
= KMF_ERR_PKCS12_FORMAT
;
3876 * Set the ID and/or FriendlyName attributes on the key.
3877 * If converting to PKCS11 objects, these can translate to CKA_ID
3878 * and CKA_LABEL values.
3880 if (pkey
!= NULL
&& ret
== KMF_OK
) {
3881 ASN1_TYPE
*attr
= NULL
;
3882 if (keyid
!= NULL
&& keyid
->type
== V_ASN1_OCTET_STRING
) {
3883 if ((attr
= ASN1_TYPE_new()) == NULL
)
3884 return (KMF_ERR_MEMORY
);
3885 attr
->value
.octet_string
=
3886 ASN1_STRING_dup(keyid
->value
.octet_string
);
3887 attr
->type
= V_ASN1_OCTET_STRING
;
3888 attr
->value
.ptr
= (char *)attr
->value
.octet_string
;
3889 ret
= set_pkey_attrib(pkey
, attr
, NID_localKeyID
);
3893 if (ret
== KMF_OK
&& fname
!= NULL
&&
3894 fname
->type
== V_ASN1_BMPSTRING
) {
3895 if ((attr
= ASN1_TYPE_new()) == NULL
)
3896 return (KMF_ERR_MEMORY
);
3897 attr
->value
.bmpstring
=
3898 ASN1_STRING_dup(fname
->value
.bmpstring
);
3899 attr
->type
= V_ASN1_BMPSTRING
;
3900 attr
->value
.ptr
= (char *)attr
->value
.bmpstring
;
3901 ret
= set_pkey_attrib(pkey
, attr
, NID_friendlyName
);
3905 if (ret
== KMF_OK
&& keylist
!= NULL
&&
3906 sk_EVP_PKEY_push(keylist
, pkey
) == 0)
3907 ret
= KMF_ERR_MEMORY
;
3909 if (ret
== KMF_OK
&& keylist
!= NULL
)
3913 EVP_PKEY_free(pkey
);
3923 openssl_pkcs12_parse(PKCS12
*p12
, char *pin
,
3924 STACK_OF(EVP_PKEY
) *keys
,
3925 STACK_OF(X509
) *certs
,
3929 KMF_RETURN ret
= KMF_OK
;
3930 STACK_OF(PKCS7
) *asafes
= NULL
;
3931 STACK_OF(PKCS12_SAFEBAG
) *bags
= NULL
;
3935 if (p12
== NULL
|| (keys
== NULL
&& certs
== NULL
))
3936 return (KMF_ERR_BAD_PARAMETER
);
3938 if (pin
== NULL
|| *pin
== NULL
) {
3939 if (PKCS12_verify_mac(p12
, NULL
, 0)) {
3941 } else if (PKCS12_verify_mac(p12
, "", 0)) {
3944 return (KMF_ERR_AUTH_FAILED
);
3946 } else if (!PKCS12_verify_mac(p12
, pin
, -1)) {
3947 return (KMF_ERR_AUTH_FAILED
);
3950 if ((asafes
= PKCS12_unpack_authsafes(p12
)) == NULL
)
3951 return (KMF_ERR_PKCS12_FORMAT
);
3953 for (i
= 0; ret
== KMF_OK
&& i
< sk_PKCS7_num(asafes
); i
++) {
3955 /* LINTED E_BAD_PTR_CAST_ALIGN */
3956 p7
= sk_PKCS7_value(asafes
, i
);
3957 bagnid
= OBJ_obj2nid(p7
->type
);
3959 if (bagnid
== NID_pkcs7_data
) {
3960 bags
= PKCS12_unpack_p7data(p7
);
3961 } else if (bagnid
== NID_pkcs7_encrypted
) {
3962 bags
= PKCS12_unpack_p7encdata(p7
, pin
,
3963 (pin
? strlen(pin
) : 0));
3968 ret
= KMF_ERR_PKCS12_FORMAT
;
3972 if (openssl_parse_bags(bags
, pin
, keys
, certs
) != KMF_OK
)
3973 ret
= KMF_ERR_PKCS12_FORMAT
;
3975 sk_PKCS12_SAFEBAG_pop_free(bags
, PKCS12_SAFEBAG_free
);
3979 sk_PKCS7_pop_free(asafes
, PKCS7_free
);
3985 * Helper function to decrypt and parse PKCS#12 import file.
3988 extract_pkcs12(BIO
*fbio
, CK_UTF8CHAR
*pin
, CK_ULONG pinlen
,
3989 STACK_OF(EVP_PKEY
) **priv_key
, STACK_OF(X509
) **certs
,
3990 STACK_OF(X509
) **ca
)
3993 PKCS12
*pk12
, *pk12_tmp
;
3994 STACK_OF(EVP_PKEY
) *pkeylist
= NULL
;
3995 STACK_OF(X509
) *xcertlist
= NULL
;
3996 STACK_OF(X509
) *cacertlist
= NULL
;
3998 if ((pk12
= PKCS12_new()) == NULL
) {
3999 return (KMF_ERR_MEMORY
);
4002 if ((pk12_tmp
= d2i_PKCS12_bio(fbio
, &pk12
)) == NULL
) {
4003 /* This is ok; it seems to mean there is no more to read. */
4004 if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_ASN1
&&
4005 ERR_GET_REASON(ERR_peek_error()) == ASN1_R_HEADER_TOO_LONG
)
4006 goto end_extract_pkcs12
;
4009 return (KMF_ERR_PKCS12_FORMAT
);
4013 xcertlist
= sk_X509_new_null();
4014 if (xcertlist
== NULL
) {
4016 return (KMF_ERR_MEMORY
);
4018 pkeylist
= sk_EVP_PKEY_new_null();
4019 if (pkeylist
== NULL
) {
4020 sk_X509_pop_free(xcertlist
, X509_free
);
4022 return (KMF_ERR_MEMORY
);
4025 if (openssl_pkcs12_parse(pk12
, (char *)pin
, pkeylist
, xcertlist
,
4026 cacertlist
) != KMF_OK
) {
4027 sk_X509_pop_free(xcertlist
, X509_free
);
4028 sk_EVP_PKEY_pop_free(pkeylist
, EVP_PKEY_free
);
4030 return (KMF_ERR_PKCS12_FORMAT
);
4033 if (priv_key
&& pkeylist
)
4034 *priv_key
= pkeylist
;
4036 sk_EVP_PKEY_pop_free(pkeylist
, EVP_PKEY_free
);
4037 if (certs
&& xcertlist
)
4040 sk_X509_pop_free(xcertlist
, X509_free
);
4041 if (ca
&& cacertlist
)
4043 else if (cacertlist
)
4044 sk_X509_pop_free(cacertlist
, X509_free
);
4053 sslBN2KMFBN(BIGNUM
*from
, KMF_BIGINT
*to
)
4055 KMF_RETURN rv
= KMF_OK
;
4058 sz
= BN_num_bytes(from
);
4059 to
->val
= (uchar_t
*)malloc(sz
);
4060 if (to
->val
== NULL
)
4061 return (KMF_ERR_MEMORY
);
4063 if ((to
->len
= BN_bn2bin(from
, to
->val
)) != sz
) {
4067 rv
= KMF_ERR_MEMORY
;
4074 exportRawRSAKey(RSA
*rsa
, KMF_RAW_KEY_DATA
*key
)
4077 KMF_RAW_RSA_KEY
*kmfkey
= &key
->rawdata
.rsa
;
4079 (void) memset(kmfkey
, 0, sizeof (KMF_RAW_RSA_KEY
));
4080 if ((rv
= sslBN2KMFBN(rsa
->n
, &kmfkey
->mod
)) != KMF_OK
)
4083 if ((rv
= sslBN2KMFBN(rsa
->e
, &kmfkey
->pubexp
)) != KMF_OK
)
4087 if ((rv
= sslBN2KMFBN(rsa
->d
, &kmfkey
->priexp
)) != KMF_OK
)
4091 if ((rv
= sslBN2KMFBN(rsa
->p
, &kmfkey
->prime1
)) != KMF_OK
)
4095 if ((rv
= sslBN2KMFBN(rsa
->q
, &kmfkey
->prime2
)) != KMF_OK
)
4098 if (rsa
->dmp1
!= NULL
)
4099 if ((rv
= sslBN2KMFBN(rsa
->dmp1
, &kmfkey
->exp1
)) != KMF_OK
)
4102 if (rsa
->dmq1
!= NULL
)
4103 if ((rv
= sslBN2KMFBN(rsa
->dmq1
, &kmfkey
->exp2
)) != KMF_OK
)
4106 if (rsa
->iqmp
!= NULL
)
4107 if ((rv
= sslBN2KMFBN(rsa
->iqmp
, &kmfkey
->coef
)) != KMF_OK
)
4111 kmf_free_raw_key(key
);
4113 key
->keytype
= KMF_RSA
;
4116 * Free the reference to this key, SSL will not actually free
4117 * the memory until the refcount == 0, so this is safe.
4125 exportRawDSAKey(DSA
*dsa
, KMF_RAW_KEY_DATA
*key
)
4128 KMF_RAW_DSA_KEY
*kmfkey
= &key
->rawdata
.dsa
;
4130 (void) memset(kmfkey
, 0, sizeof (KMF_RAW_DSA_KEY
));
4131 if ((rv
= sslBN2KMFBN(dsa
->p
, &kmfkey
->prime
)) != KMF_OK
)
4134 if ((rv
= sslBN2KMFBN(dsa
->q
, &kmfkey
->subprime
)) != KMF_OK
)
4137 if ((rv
= sslBN2KMFBN(dsa
->g
, &kmfkey
->base
)) != KMF_OK
)
4140 if ((rv
= sslBN2KMFBN(dsa
->priv_key
, &kmfkey
->value
)) != KMF_OK
)
4145 kmf_free_raw_key(key
);
4147 key
->keytype
= KMF_DSA
;
4150 * Free the reference to this key, SSL will not actually free
4151 * the memory until the refcount == 0, so this is safe.
4159 add_cert_to_list(KMF_HANDLE
*kmfh
, X509
*sslcert
,
4160 KMF_X509_DER_CERT
**certlist
, int *ncerts
)
4162 KMF_RETURN rv
= KMF_OK
;
4163 KMF_X509_DER_CERT
*list
= (*certlist
);
4164 KMF_X509_DER_CERT cert
;
4168 list
= (KMF_X509_DER_CERT
*)malloc(sizeof (KMF_X509_DER_CERT
));
4170 list
= (KMF_X509_DER_CERT
*)realloc(list
,
4171 sizeof (KMF_X509_DER_CERT
) * (n
+ 1));
4175 return (KMF_ERR_MEMORY
);
4177 (void) memset(&cert
, 0, sizeof (cert
));
4178 rv
= ssl_cert2KMFDATA(kmfh
, sslcert
, &cert
.certificate
);
4181 /* Get the alias name for the cert if there is one */
4182 char *a
= (char *)X509_alias_get0(sslcert
, &len
);
4184 cert
.kmf_private
.label
= strdup(a
);
4185 cert
.kmf_private
.keystore_type
= KMF_KEYSTORE_OPENSSL
;
4199 add_key_to_list(KMF_RAW_KEY_DATA
**keylist
,
4200 KMF_RAW_KEY_DATA
*newkey
, int *nkeys
)
4202 KMF_RAW_KEY_DATA
*list
= (*keylist
);
4206 list
= (KMF_RAW_KEY_DATA
*)malloc(sizeof (KMF_RAW_KEY_DATA
));
4208 list
= (KMF_RAW_KEY_DATA
*)realloc(list
,
4209 sizeof (KMF_RAW_KEY_DATA
) * (n
+ 1));
4213 return (KMF_ERR_MEMORY
);
4223 static X509_ATTRIBUTE
*
4224 find_attr(STACK_OF(X509_ATTRIBUTE
) *attrs
, int nid
)
4232 for (i
= 0; i
< sk_X509_ATTRIBUTE_num(attrs
); i
++) {
4233 /* LINTED E_BAD_PTR_CAST_ALIGN */
4234 a
= sk_X509_ATTRIBUTE_value(attrs
, i
);
4235 if (OBJ_obj2nid(a
->object
) == nid
)
4242 convertToRawKey(EVP_PKEY
*pkey
, KMF_RAW_KEY_DATA
*key
)
4244 KMF_RETURN rv
= KMF_OK
;
4245 X509_ATTRIBUTE
*attr
;
4247 if (pkey
== NULL
|| key
== NULL
)
4248 return (KMF_ERR_BAD_PARAMETER
);
4249 /* Convert SSL key to raw key */
4250 switch (pkey
->type
) {
4252 rv
= exportRawRSAKey(EVP_PKEY_get1_RSA(pkey
),
4258 rv
= exportRawDSAKey(EVP_PKEY_get1_DSA(pkey
),
4264 return (KMF_ERR_BAD_PARAMETER
);
4267 * If friendlyName, add it to record.
4269 attr
= find_attr(pkey
->attributes
, NID_friendlyName
);
4271 ASN1_TYPE
*ty
= NULL
;
4272 int numattr
= sk_ASN1_TYPE_num(attr
->value
.set
);
4273 if (attr
->single
== 0 && numattr
> 0) {
4274 /* LINTED E_BAD_PTR_CAST_ALIGN */
4275 ty
= sk_ASN1_TYPE_value(attr
->value
.set
, 0);
4278 #if OPENSSL_VERSION_NUMBER < 0x10000000L
4279 key
->label
= uni2asc(ty
->value
.bmpstring
->data
,
4280 ty
->value
.bmpstring
->length
);
4282 key
->label
= OPENSSL_uni2asc(ty
->value
.bmpstring
->data
,
4283 ty
->value
.bmpstring
->length
);
4291 * If KeyID, add it to record as a KMF_DATA object.
4293 attr
= find_attr(pkey
->attributes
, NID_localKeyID
);
4295 ASN1_TYPE
*ty
= NULL
;
4296 int numattr
= sk_ASN1_TYPE_num(attr
->value
.set
);
4297 if (attr
->single
== 0 && numattr
> 0) {
4298 /* LINTED E_BAD_PTR_CAST_ALIGN */
4299 ty
= sk_ASN1_TYPE_value(attr
->value
.set
, 0);
4301 key
->id
.Data
= (uchar_t
*)malloc(
4302 ty
->value
.octet_string
->length
);
4303 if (key
->id
.Data
== NULL
)
4304 return (KMF_ERR_MEMORY
);
4305 (void) memcpy(key
->id
.Data
, ty
->value
.octet_string
->data
,
4306 ty
->value
.octet_string
->length
);
4307 key
->id
.Length
= ty
->value
.octet_string
->length
;
4309 (void) memset(&key
->id
, 0, sizeof (KMF_DATA
));
4318 STACK_OF(EVP_PKEY
) *sslkeys
,
4319 STACK_OF(X509
) *sslcert
,
4320 STACK_OF(X509
) *sslcacerts
,
4321 KMF_RAW_KEY_DATA
**keylist
, int *nkeys
,
4322 KMF_X509_DER_CERT
**certlist
, int *ncerts
)
4324 KMF_RETURN rv
= KMF_OK
;
4325 KMF_RAW_KEY_DATA key
;
4328 for (i
= 0; sslkeys
!= NULL
&& i
< sk_EVP_PKEY_num(sslkeys
); i
++) {
4329 /* LINTED E_BAD_PTR_CAST_ALIGN */
4330 EVP_PKEY
*pkey
= sk_EVP_PKEY_value(sslkeys
, i
);
4331 rv
= convertToRawKey(pkey
, &key
);
4333 rv
= add_key_to_list(keylist
, &key
, nkeys
);
4339 /* Now add the certificate to the certlist */
4340 for (i
= 0; sslcert
!= NULL
&& i
< sk_X509_num(sslcert
); i
++) {
4341 /* LINTED E_BAD_PTR_CAST_ALIGN */
4342 X509
*cert
= sk_X509_value(sslcert
, i
);
4343 rv
= add_cert_to_list(kmfh
, cert
, certlist
, ncerts
);
4348 /* Also add any included CA certs to the list */
4349 for (i
= 0; sslcacerts
!= NULL
&& i
< sk_X509_num(sslcacerts
); i
++) {
4352 * sk_X509_value() is macro that embeds a cast to (X509 *).
4353 * Here it translates into ((X509 *)sk_value((ca), (i))).
4354 * Lint is complaining about the embedded casting, and
4355 * to fix it, you need to fix openssl header files.
4357 /* LINTED E_BAD_PTR_CAST_ALIGN */
4358 c
= sk_X509_value(sslcacerts
, i
);
4360 /* Now add the ca cert to the certlist */
4361 rv
= add_cert_to_list(kmfh
, c
, certlist
, ncerts
);
4369 openssl_import_objects(KMF_HANDLE
*kmfh
,
4370 char *filename
, KMF_CREDENTIAL
*cred
,
4371 KMF_X509_DER_CERT
**certlist
, int *ncerts
,
4372 KMF_RAW_KEY_DATA
**keylist
, int *nkeys
)
4374 KMF_RETURN rv
= KMF_OK
;
4375 KMF_ENCODE_FORMAT format
;
4377 STACK_OF(EVP_PKEY
) *privkeys
= NULL
;
4378 STACK_OF(X509
) *certs
= NULL
;
4379 STACK_OF(X509
) *cacerts
= NULL
;
4382 * auto-detect the file format, regardless of what
4383 * the 'format' parameters in the params say.
4385 rv
= kmf_get_file_format(filename
, &format
);
4390 /* This function only works for PEM or PKCS#12 files */
4391 if (format
!= KMF_FORMAT_PEM
&&
4392 format
!= KMF_FORMAT_PEM_KEYPAIR
&&
4393 format
!= KMF_FORMAT_PKCS12
)
4394 return (KMF_ERR_ENCODING
);
4401 if (format
== KMF_FORMAT_PKCS12
) {
4402 bio
= BIO_new_file(filename
, "rb");
4404 SET_ERROR(kmfh
, ERR_get_error());
4405 rv
= KMF_ERR_OPEN_FILE
;
4409 rv
= extract_pkcs12(bio
, (uchar_t
*)cred
->cred
,
4410 (uint32_t)cred
->credlen
, &privkeys
, &certs
, &cacerts
);
4413 /* Convert keys and certs to exportable format */
4414 rv
= convertPK12Objects(kmfh
, privkeys
, certs
, cacerts
,
4415 keylist
, nkeys
, certlist
, ncerts
);
4418 KMF_DATA
*certdata
= NULL
;
4419 KMF_X509_DER_CERT
*kmfcerts
= NULL
;
4421 rv
= extract_pem(kmfh
, NULL
, NULL
, NULL
, filename
,
4422 (uchar_t
*)cred
->cred
, (uint32_t)cred
->credlen
,
4423 &pkey
, &certdata
, ncerts
);
4425 /* Reached end of import file? */
4426 if (rv
== KMF_OK
&& pkey
!= NULL
) {
4427 privkeys
= sk_EVP_PKEY_new_null();
4428 if (privkeys
== NULL
) {
4429 rv
= KMF_ERR_MEMORY
;
4432 (void) sk_EVP_PKEY_push(privkeys
, pkey
);
4433 /* convert the certificate list here */
4434 if (*ncerts
> 0 && certlist
!= NULL
) {
4435 kmfcerts
= (KMF_X509_DER_CERT
*)calloc(*ncerts
,
4436 sizeof (KMF_X509_DER_CERT
));
4437 if (kmfcerts
== NULL
) {
4438 rv
= KMF_ERR_MEMORY
;
4441 for (i
= 0; i
< *ncerts
; i
++) {
4442 kmfcerts
[i
].certificate
= certdata
[i
];
4443 kmfcerts
[i
].kmf_private
.keystore_type
=
4444 KMF_KEYSTORE_OPENSSL
;
4446 *certlist
= kmfcerts
;
4449 * Convert keys to exportable format, the certs
4452 rv
= convertPK12Objects(kmfh
, privkeys
, NULL
, NULL
,
4453 keylist
, nkeys
, NULL
, NULL
);
4458 (void) BIO_free(bio
);
4461 sk_EVP_PKEY_pop_free(privkeys
, EVP_PKEY_free
);
4463 sk_X509_pop_free(certs
, X509_free
);
4465 sk_X509_pop_free(cacerts
, X509_free
);
4471 create_deskey(DES_cblock
**deskey
)
4475 key
= (DES_cblock
*) malloc(sizeof (DES_cblock
));
4477 return (KMF_ERR_MEMORY
);
4480 if (DES_random_key(key
) == 0) {
4482 return (KMF_ERR_KEYGEN_FAILED
);
4489 #define KEYGEN_RETRY 3
4490 #define DES3_KEY_SIZE 24
4493 create_des3key(unsigned char **des3key
)
4495 KMF_RETURN ret
= KMF_OK
;
4496 DES_cblock
*deskey1
= NULL
;
4497 DES_cblock
*deskey2
= NULL
;
4498 DES_cblock
*deskey3
= NULL
;
4499 unsigned char *newkey
= NULL
;
4502 if ((newkey
= malloc(DES3_KEY_SIZE
)) == NULL
) {
4503 return (KMF_ERR_MEMORY
);
4506 /* create the 1st DES key */
4507 if ((ret
= create_deskey(&deskey1
)) != KMF_OK
) {
4512 * Create the 2nd DES key and make sure its value is different
4513 * from the 1st DES key.
4517 if (deskey2
!= NULL
) {
4522 if ((ret
= create_deskey(&deskey2
)) != KMF_OK
) {
4526 if (memcmp((const void *) deskey1
, (const void *) deskey2
, 8)
4528 ret
= KMF_ERR_KEYGEN_FAILED
;
4531 } while (ret
== KMF_ERR_KEYGEN_FAILED
&& retry
< KEYGEN_RETRY
);
4533 if (ret
!= KMF_OK
) {
4538 * Create the 3rd DES key and make sure its value is different
4539 * from the 2nd DES key.
4543 if (deskey3
!= NULL
) {
4548 if ((ret
= create_deskey(&deskey3
)) != KMF_OK
) {
4552 if (memcmp((const void *)deskey2
, (const void *)deskey3
, 8)
4554 ret
= KMF_ERR_KEYGEN_FAILED
;
4557 } while (ret
== KMF_ERR_KEYGEN_FAILED
&& retry
< KEYGEN_RETRY
);
4559 if (ret
!= KMF_OK
) {
4563 /* Concatenate 3 DES keys into a DES3 key */
4564 (void) memcpy((void *)newkey
, (const void *)deskey1
, 8);
4565 (void) memcpy((void *)(newkey
+ 8), (const void *)deskey2
, 8);
4566 (void) memcpy((void *)(newkey
+ 16), (const void *)deskey3
, 8);
4570 if (deskey1
!= NULL
)
4573 if (deskey2
!= NULL
)
4576 if (deskey3
!= NULL
)
4579 if (ret
!= KMF_OK
&& newkey
!= NULL
)
4586 OpenSSL_CreateSymKey(KMF_HANDLE_T handle
,
4587 int numattr
, KMF_ATTRIBUTE
*attrlist
)
4589 KMF_RETURN ret
= KMF_OK
;
4590 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
4591 char *fullpath
= NULL
;
4592 KMF_RAW_SYM_KEY
*rkey
= NULL
;
4593 DES_cblock
*deskey
= NULL
;
4594 unsigned char *des3key
= NULL
;
4595 unsigned char *random
= NULL
;
4597 KMF_KEY_HANDLE
*symkey
;
4598 KMF_KEY_ALG keytype
;
4600 uint32_t keylen_size
= sizeof (keylen
);
4605 return (KMF_ERR_UNINITIALIZED
);
4607 symkey
= kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR
, attrlist
, numattr
);
4609 return (KMF_ERR_BAD_PARAMETER
);
4611 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
4613 keyfile
= kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
, attrlist
, numattr
);
4614 if (keyfile
== NULL
)
4615 return (KMF_ERR_BAD_PARAMETER
);
4617 ret
= kmf_get_attr(KMF_KEYALG_ATTR
, attrlist
, numattr
,
4618 (void *)&keytype
, NULL
);
4620 return (KMF_ERR_BAD_PARAMETER
);
4622 ret
= kmf_get_attr(KMF_KEYLENGTH_ATTR
, attrlist
, numattr
,
4623 &keylen
, &keylen_size
);
4624 if (ret
== KMF_ERR_ATTR_NOT_FOUND
&&
4625 (keytype
== KMF_DES
|| keytype
== KMF_DES3
))
4626 /* keylength is not required for DES and 3DES */
4629 return (KMF_ERR_BAD_PARAMETER
);
4631 fullpath
= get_fullpath(dirpath
, keyfile
);
4632 if (fullpath
== NULL
)
4633 return (KMF_ERR_BAD_PARAMETER
);
4635 /* If the requested file exists, return an error */
4636 if (test_for_file(fullpath
, 0400) == 1) {
4638 return (KMF_ERR_DUPLICATE_KEYFILE
);
4641 fd
= open(fullpath
, O_CREAT
|O_TRUNC
|O_RDWR
, 0400);
4643 ret
= KMF_ERR_OPEN_FILE
;
4647 rkey
= malloc(sizeof (KMF_RAW_SYM_KEY
));
4649 ret
= KMF_ERR_MEMORY
;
4652 (void) memset(rkey
, 0, sizeof (KMF_RAW_SYM_KEY
));
4654 if (keytype
== KMF_DES
) {
4655 if ((ret
= create_deskey(&deskey
)) != KMF_OK
) {
4658 rkey
->keydata
.val
= (uchar_t
*)deskey
;
4659 rkey
->keydata
.len
= 8;
4661 symkey
->keyalg
= KMF_DES
;
4663 } else if (keytype
== KMF_DES3
) {
4664 if ((ret
= create_des3key(&des3key
)) != KMF_OK
) {
4667 rkey
->keydata
.val
= (uchar_t
*)des3key
;
4668 rkey
->keydata
.len
= DES3_KEY_SIZE
;
4669 symkey
->keyalg
= KMF_DES3
;
4671 } else if (keytype
== KMF_AES
|| keytype
== KMF_RC4
||
4672 keytype
== KMF_GENERIC_SECRET
) {
4675 if (keylen
% 8 != 0) {
4676 ret
= KMF_ERR_BAD_KEY_SIZE
;
4680 if (keytype
== KMF_AES
) {
4681 if (keylen
!= 128 &&
4684 ret
= KMF_ERR_BAD_KEY_SIZE
;
4690 random
= malloc(bytes
);
4691 if (random
== NULL
) {
4692 ret
= KMF_ERR_MEMORY
;
4695 if (RAND_bytes(random
, bytes
) != 1) {
4696 ret
= KMF_ERR_KEYGEN_FAILED
;
4700 rkey
->keydata
.val
= (uchar_t
*)random
;
4701 rkey
->keydata
.len
= bytes
;
4702 symkey
->keyalg
= keytype
;
4705 ret
= KMF_ERR_BAD_KEY_TYPE
;
4709 (void) write(fd
, (const void *) rkey
->keydata
.val
, rkey
->keydata
.len
);
4711 symkey
->kstype
= KMF_KEYSTORE_OPENSSL
;
4712 symkey
->keyclass
= KMF_SYMMETRIC
;
4713 symkey
->keylabel
= (char *)fullpath
;
4714 symkey
->israw
= TRUE
;
4715 symkey
->keyp
= rkey
;
4721 if (ret
!= KMF_OK
&& fullpath
!= NULL
) {
4724 if (ret
!= KMF_OK
) {
4725 kmf_free_raw_sym_key(rkey
);
4726 symkey
->keyp
= NULL
;
4727 symkey
->keyalg
= KMF_KEYALG_NONE
;
4734 * Check a file to see if it is a CRL file with PEM or DER format.
4735 * If success, return its format in the "pformat" argument.
4738 OpenSSL_IsCRLFile(KMF_HANDLE_T handle
, char *filename
, int *pformat
)
4740 KMF_RETURN ret
= KMF_OK
;
4741 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
4743 X509_CRL
*xcrl
= NULL
;
4745 if (filename
== NULL
) {
4746 return (KMF_ERR_BAD_PARAMETER
);
4749 bio
= BIO_new_file(filename
, "rb");
4751 SET_ERROR(kmfh
, ERR_get_error());
4752 ret
= KMF_ERR_OPEN_FILE
;
4756 if ((xcrl
= PEM_read_bio_X509_CRL(bio
, NULL
, NULL
, NULL
)) != NULL
) {
4757 *pformat
= KMF_FORMAT_PEM
;
4760 (void) BIO_free(bio
);
4763 * Now try to read it as raw DER data.
4765 bio
= BIO_new_file(filename
, "rb");
4767 SET_ERROR(kmfh
, ERR_get_error());
4768 ret
= KMF_ERR_OPEN_FILE
;
4772 if ((xcrl
= d2i_X509_CRL_bio(bio
, NULL
)) != NULL
) {
4773 *pformat
= KMF_FORMAT_ASN1
;
4775 ret
= KMF_ERR_BAD_CRLFILE
;
4780 (void) BIO_free(bio
);
4783 X509_CRL_free(xcrl
);
4789 OpenSSL_GetSymKeyValue(KMF_HANDLE_T handle
, KMF_KEY_HANDLE
*symkey
,
4790 KMF_RAW_SYM_KEY
*rkey
)
4792 KMF_RETURN rv
= KMF_OK
;
4793 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
4797 return (KMF_ERR_UNINITIALIZED
);
4799 if (symkey
== NULL
|| rkey
== NULL
)
4800 return (KMF_ERR_BAD_PARAMETER
);
4801 else if (symkey
->keyclass
!= KMF_SYMMETRIC
)
4802 return (KMF_ERR_BAD_KEY_CLASS
);
4804 if (symkey
->israw
) {
4805 KMF_RAW_SYM_KEY
*rawkey
= (KMF_RAW_SYM_KEY
*)symkey
->keyp
;
4807 if (rawkey
== NULL
||
4808 rawkey
->keydata
.val
== NULL
||
4809 rawkey
->keydata
.len
== 0)
4810 return (KMF_ERR_BAD_KEYHANDLE
);
4812 rkey
->keydata
.len
= rawkey
->keydata
.len
;
4813 if ((rkey
->keydata
.val
= malloc(rkey
->keydata
.len
)) == NULL
)
4814 return (KMF_ERR_MEMORY
);
4815 (void) memcpy(rkey
->keydata
.val
, rawkey
->keydata
.val
,
4818 rv
= kmf_read_input_file(handle
, symkey
->keylabel
, &keyvalue
);
4821 rkey
->keydata
.len
= keyvalue
.Length
;
4822 rkey
->keydata
.val
= keyvalue
.Data
;
4829 * substitute for the unsafe access(2) function.
4830 * If the file in question already exists, return 1.
4831 * else 0. If an error occurs during testing (other
4832 * than EEXIST), return -1.
4835 test_for_file(char *filename
, mode_t mode
)
4840 * Try to create the file with the EXCL flag.
4841 * The call should fail if the file exists.
4843 fd
= open(filename
, O_WRONLY
|O_CREAT
|O_EXCL
, mode
);
4844 if (fd
== -1 && errno
== EEXIST
)
4846 else if (fd
== -1) /* some other error */
4849 /* The file did NOT exist. Delete the testcase. */
4851 (void) unlink(filename
);
4856 OpenSSL_StoreKey(KMF_HANDLE_T handle
, int numattr
,
4857 KMF_ATTRIBUTE
*attrlist
)
4859 KMF_RETURN rv
= KMF_OK
;
4860 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
4861 KMF_KEY_HANDLE
*pubkey
= NULL
, *prikey
= NULL
;
4862 KMF_RAW_KEY_DATA
*rawkey
;
4863 EVP_PKEY
*pkey
= NULL
;
4864 KMF_ENCODE_FORMAT format
= KMF_FORMAT_PEM
;
4865 KMF_CREDENTIAL cred
= { NULL
, 0 };
4868 char *fullpath
= NULL
;
4869 char *keyfile
= NULL
;
4870 char *dirpath
= NULL
;
4872 pubkey
= kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR
, attrlist
, numattr
);
4876 prikey
= kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR
, attrlist
, numattr
);
4880 rawkey
= kmf_get_attr_ptr(KMF_RAW_KEY_ATTR
, attrlist
, numattr
);
4885 * Exactly 1 type of key must be passed to this function.
4888 return (KMF_ERR_BAD_PARAMETER
);
4890 keyfile
= (char *)kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR
, attrlist
,
4892 if (keyfile
== NULL
)
4893 return (KMF_ERR_BAD_PARAMETER
);
4895 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
4897 fullpath
= get_fullpath(dirpath
, keyfile
);
4899 /* Once we have the full path, we don't need the pieces */
4900 if (fullpath
== NULL
)
4901 return (KMF_ERR_BAD_PARAMETER
);
4903 /* If the requested file exists, return an error */
4904 if (test_for_file(fullpath
, 0400) == 1) {
4906 return (KMF_ERR_DUPLICATE_KEYFILE
);
4909 rv
= kmf_get_attr(KMF_ENCODE_FORMAT_ATTR
, attrlist
, numattr
,
4912 /* format is optional. */
4915 /* CRED is not required for OpenSSL files */
4916 (void) kmf_get_attr(KMF_CREDENTIAL_ATTR
, attrlist
, numattr
,
4919 /* Store the private key to the keyfile */
4920 out
= BIO_new_file(fullpath
, "wb");
4922 SET_ERROR(kmfh
, ERR_get_error());
4923 rv
= KMF_ERR_OPEN_FILE
;
4927 if (prikey
!= NULL
&& prikey
->keyp
!= NULL
) {
4928 if (prikey
->keyalg
== KMF_RSA
||
4929 prikey
->keyalg
== KMF_DSA
) {
4930 pkey
= (EVP_PKEY
*)prikey
->keyp
;
4932 rv
= ssl_write_key(kmfh
, format
,
4933 out
, &cred
, pkey
, TRUE
);
4935 if (rv
== KMF_OK
&& prikey
->keylabel
== NULL
) {
4936 prikey
->keylabel
= strdup(fullpath
);
4937 if (prikey
->keylabel
== NULL
)
4938 rv
= KMF_ERR_MEMORY
;
4941 } else if (pubkey
!= NULL
&& pubkey
->keyp
!= NULL
) {
4942 if (pubkey
->keyalg
== KMF_RSA
||
4943 pubkey
->keyalg
== KMF_DSA
) {
4944 pkey
= (EVP_PKEY
*)pubkey
->keyp
;
4946 rv
= ssl_write_key(kmfh
, format
,
4947 out
, &cred
, pkey
, FALSE
);
4949 if (rv
== KMF_OK
&& pubkey
->keylabel
== NULL
) {
4950 pubkey
->keylabel
= strdup(fullpath
);
4951 if (pubkey
->keylabel
== NULL
)
4952 rv
= KMF_ERR_MEMORY
;
4955 } else if (rawkey
!= NULL
) {
4956 if (rawkey
->keytype
== KMF_RSA
) {
4957 pkey
= ImportRawRSAKey(&rawkey
->rawdata
.rsa
);
4958 } else if (rawkey
->keytype
== KMF_DSA
) {
4959 pkey
= ImportRawDSAKey(&rawkey
->rawdata
.dsa
);
4961 rv
= KMF_ERR_BAD_PARAMETER
;
4964 KMF_KEY_CLASS kclass
= KMF_ASYM_PRI
;
4966 rv
= kmf_get_attr(KMF_KEYCLASS_ATTR
, attrlist
, numattr
,
4967 (void *)&kclass
, NULL
);
4970 rv
= ssl_write_key(kmfh
, format
, out
,
4971 &cred
, pkey
, (kclass
== KMF_ASYM_PRI
));
4972 EVP_PKEY_free(pkey
);
4979 (void) BIO_free(out
);
4983 (void) chmod(fullpath
, 0400);
4990 OpenSSL_ImportCRL(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
4992 KMF_RETURN ret
= KMF_OK
;
4993 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
4994 X509_CRL
*xcrl
= NULL
;
4997 KMF_ENCODE_FORMAT format
;
4998 BIO
*in
= NULL
, *out
= NULL
;
4999 int openssl_ret
= 0;
5000 KMF_ENCODE_FORMAT outformat
;
5001 boolean_t crlcheck
= FALSE
;
5002 char *certfile
, *dirpath
, *crlfile
, *incrl
, *outcrl
, *outcrlfile
;
5004 if (numattr
== 0 || attrlist
== NULL
) {
5005 return (KMF_ERR_BAD_PARAMETER
);
5008 /* CRL check is optional */
5009 (void) kmf_get_attr(KMF_CRL_CHECK_ATTR
, attrlist
, numattr
,
5012 certfile
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
, numattr
);
5013 if (crlcheck
== B_TRUE
&& certfile
== NULL
) {
5014 return (KMF_ERR_BAD_CERTFILE
);
5017 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
5018 incrl
= kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR
, attrlist
, numattr
);
5019 outcrl
= kmf_get_attr_ptr(KMF_CRL_OUTFILE_ATTR
, attrlist
, numattr
);
5021 crlfile
= get_fullpath(dirpath
, incrl
);
5023 if (crlfile
== NULL
)
5024 return (KMF_ERR_BAD_CRLFILE
);
5026 outcrlfile
= get_fullpath(dirpath
, outcrl
);
5027 if (outcrlfile
== NULL
)
5028 return (KMF_ERR_BAD_CRLFILE
);
5030 if (isdir(outcrlfile
)) {
5032 return (KMF_ERR_BAD_CRLFILE
);
5035 ret
= kmf_is_crl_file(handle
, crlfile
, &format
);
5036 if (ret
!= KMF_OK
) {
5041 in
= BIO_new_file(crlfile
, "rb");
5043 SET_ERROR(kmfh
, ERR_get_error());
5044 ret
= KMF_ERR_OPEN_FILE
;
5048 if (format
== KMF_FORMAT_ASN1
) {
5049 xcrl
= d2i_X509_CRL_bio(in
, NULL
);
5050 } else if (format
== KMF_FORMAT_PEM
) {
5051 xcrl
= PEM_read_bio_X509_CRL(in
, NULL
, NULL
, NULL
);
5055 SET_ERROR(kmfh
, ERR_get_error());
5056 ret
= KMF_ERR_BAD_CRLFILE
;
5060 /* If bypasscheck is specified, no need to verify. */
5061 if (crlcheck
== B_FALSE
)
5064 ret
= kmf_is_cert_file(handle
, certfile
, &format
);
5068 /* Read in the CA cert file and convert to X509 */
5069 if (BIO_read_filename(in
, certfile
) <= 0) {
5070 SET_ERROR(kmfh
, ERR_get_error());
5071 ret
= KMF_ERR_OPEN_FILE
;
5075 if (format
== KMF_FORMAT_ASN1
) {
5076 xcert
= d2i_X509_bio(in
, NULL
);
5077 } else if (format
== KMF_FORMAT_PEM
) {
5078 xcert
= PEM_read_bio_X509(in
, NULL
, NULL
, NULL
);
5080 ret
= KMF_ERR_BAD_CERT_FORMAT
;
5084 if (xcert
== NULL
) {
5085 SET_ERROR(kmfh
, ERR_get_error());
5086 ret
= KMF_ERR_BAD_CERT_FORMAT
;
5089 /* Now get the public key from the CA cert */
5090 pkey
= X509_get_pubkey(xcert
);
5092 SET_ERROR(kmfh
, ERR_get_error());
5093 ret
= KMF_ERR_BAD_CERTFILE
;
5097 /* Verify the CRL with the CA's public key */
5098 openssl_ret
= X509_CRL_verify(xcrl
, pkey
);
5099 EVP_PKEY_free(pkey
);
5100 if (openssl_ret
> 0) {
5101 ret
= KMF_OK
; /* verify succeed */
5103 SET_ERROR(kmfh
, openssl_ret
);
5104 ret
= KMF_ERR_BAD_CRLFILE
;
5108 ret
= kmf_get_attr(KMF_ENCODE_FORMAT_ATTR
, attrlist
, numattr
,
5110 if (ret
!= KMF_OK
) {
5112 outformat
= KMF_FORMAT_PEM
;
5115 out
= BIO_new_file(outcrlfile
, "wb");
5117 SET_ERROR(kmfh
, ERR_get_error());
5118 ret
= KMF_ERR_OPEN_FILE
;
5122 if (outformat
== KMF_FORMAT_ASN1
) {
5123 openssl_ret
= (int)i2d_X509_CRL_bio(out
, xcrl
);
5124 } else if (outformat
== KMF_FORMAT_PEM
) {
5125 openssl_ret
= PEM_write_bio_X509_CRL(out
, xcrl
);
5127 ret
= KMF_ERR_BAD_PARAMETER
;
5131 if (openssl_ret
<= 0) {
5132 SET_ERROR(kmfh
, ERR_get_error());
5133 ret
= KMF_ERR_WRITE_FILE
;
5140 X509_CRL_free(xcrl
);
5146 (void) BIO_free(in
);
5149 (void) BIO_free(out
);
5151 if (outcrlfile
!= NULL
)
5158 OpenSSL_ListCRL(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
5160 KMF_RETURN ret
= KMF_OK
;
5161 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
5163 KMF_ENCODE_FORMAT format
;
5164 char *crlfile
= NULL
;
5171 char *crlfilename
, *dirpath
;
5173 if (numattr
== 0 || attrlist
== NULL
) {
5174 return (KMF_ERR_BAD_PARAMETER
);
5176 crlfilename
= kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR
,
5178 if (crlfilename
== NULL
)
5179 return (KMF_ERR_BAD_CRLFILE
);
5181 crldata
= (char **)kmf_get_attr_ptr(KMF_CRL_DATA_ATTR
,
5184 if (crldata
== NULL
)
5185 return (KMF_ERR_BAD_PARAMETER
);
5187 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
5189 crlfile
= get_fullpath(dirpath
, crlfilename
);
5191 if (crlfile
== NULL
)
5192 return (KMF_ERR_BAD_CRLFILE
);
5194 if (isdir(crlfile
)) {
5196 return (KMF_ERR_BAD_CRLFILE
);
5199 ret
= kmf_is_crl_file(handle
, crlfile
, &format
);
5200 if (ret
!= KMF_OK
) {
5205 if (bio_err
== NULL
)
5206 bio_err
= BIO_new_fp(stderr
, BIO_NOCLOSE
);
5208 in
= BIO_new_file(crlfile
, "rb");
5210 SET_ERROR(kmfh
, ERR_get_error());
5211 ret
= KMF_ERR_OPEN_FILE
;
5215 if (format
== KMF_FORMAT_ASN1
) {
5216 x
= d2i_X509_CRL_bio(in
, NULL
);
5217 } else if (format
== KMF_FORMAT_PEM
) {
5218 x
= PEM_read_bio_X509_CRL(in
, NULL
, NULL
, NULL
);
5221 if (x
== NULL
) { /* should not happen */
5222 SET_ERROR(kmfh
, ERR_get_error());
5223 ret
= KMF_ERR_OPEN_FILE
;
5227 mem
= BIO_new(BIO_s_mem());
5229 SET_ERROR(kmfh
, ERR_get_error());
5230 ret
= KMF_ERR_MEMORY
;
5234 (void) X509_CRL_print(mem
, x
);
5235 len
= BIO_get_mem_data(mem
, &memptr
);
5237 SET_ERROR(kmfh
, ERR_get_error());
5238 ret
= KMF_ERR_MEMORY
;
5242 data
= malloc(len
+ 1);
5244 ret
= KMF_ERR_MEMORY
;
5248 (void) memcpy(data
, memptr
, len
);
5256 if (crlfile
!= NULL
)
5260 (void) BIO_free(in
);
5263 (void) BIO_free(mem
);
5269 OpenSSL_DeleteCRL(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
5271 KMF_RETURN ret
= KMF_OK
;
5272 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
5273 KMF_ENCODE_FORMAT format
;
5274 char *crlfile
= NULL
;
5276 char *crlfilename
, *dirpath
;
5278 if (numattr
== 0 || attrlist
== NULL
) {
5279 return (KMF_ERR_BAD_PARAMETER
);
5282 crlfilename
= kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR
,
5285 if (crlfilename
== NULL
)
5286 return (KMF_ERR_BAD_CRLFILE
);
5288 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
5290 crlfile
= get_fullpath(dirpath
, crlfilename
);
5292 if (crlfile
== NULL
)
5293 return (KMF_ERR_BAD_CRLFILE
);
5295 if (isdir(crlfile
)) {
5296 ret
= KMF_ERR_BAD_CRLFILE
;
5300 ret
= kmf_is_crl_file(handle
, crlfile
, &format
);
5304 if (unlink(crlfile
) != 0) {
5305 SET_SYS_ERROR(kmfh
, errno
);
5306 ret
= KMF_ERR_INTERNAL
;
5312 (void) BIO_free(in
);
5313 if (crlfile
!= NULL
)
5320 OpenSSL_FindCertInCRL(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
5322 KMF_RETURN ret
= KMF_OK
;
5323 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
5324 KMF_ENCODE_FORMAT format
;
5327 X509_CRL
*xcrl
= NULL
;
5328 STACK_OF(X509_REVOKED
) *revoke_stack
= NULL
;
5329 X509_REVOKED
*revoke
;
5331 char *crlfilename
, *crlfile
, *dirpath
, *certfile
;
5333 if (numattr
== 0 || attrlist
== NULL
) {
5334 return (KMF_ERR_BAD_PARAMETER
);
5337 crlfilename
= kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR
,
5340 if (crlfilename
== NULL
)
5341 return (KMF_ERR_BAD_CRLFILE
);
5343 certfile
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
, numattr
);
5344 if (certfile
== NULL
)
5345 return (KMF_ERR_BAD_CRLFILE
);
5347 dirpath
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
5349 crlfile
= get_fullpath(dirpath
, crlfilename
);
5351 if (crlfile
== NULL
)
5352 return (KMF_ERR_BAD_CRLFILE
);
5354 if (isdir(crlfile
)) {
5355 ret
= KMF_ERR_BAD_CRLFILE
;
5359 ret
= kmf_is_crl_file(handle
, crlfile
, &format
);
5363 /* Read the CRL file and load it into a X509_CRL structure */
5364 in
= BIO_new_file(crlfilename
, "rb");
5366 SET_ERROR(kmfh
, ERR_get_error());
5367 ret
= KMF_ERR_OPEN_FILE
;
5371 if (format
== KMF_FORMAT_ASN1
) {
5372 xcrl
= d2i_X509_CRL_bio(in
, NULL
);
5373 } else if (format
== KMF_FORMAT_PEM
) {
5374 xcrl
= PEM_read_bio_X509_CRL(in
, NULL
, NULL
, NULL
);
5378 SET_ERROR(kmfh
, ERR_get_error());
5379 ret
= KMF_ERR_BAD_CRLFILE
;
5382 (void) BIO_free(in
);
5384 /* Read the Certificate file and load it into a X509 structure */
5385 ret
= kmf_is_cert_file(handle
, certfile
, &format
);
5389 in
= BIO_new_file(certfile
, "rb");
5391 SET_ERROR(kmfh
, ERR_get_error());
5392 ret
= KMF_ERR_OPEN_FILE
;
5396 if (format
== KMF_FORMAT_ASN1
) {
5397 xcert
= d2i_X509_bio(in
, NULL
);
5398 } else if (format
== KMF_FORMAT_PEM
) {
5399 xcert
= PEM_read_bio_X509(in
, NULL
, NULL
, NULL
);
5402 if (xcert
== NULL
) {
5403 SET_ERROR(kmfh
, ERR_get_error());
5404 ret
= KMF_ERR_BAD_CERTFILE
;
5408 /* Check if the certificate and the CRL have same issuer */
5409 if (X509_NAME_cmp(xcert
->cert_info
->issuer
, xcrl
->crl
->issuer
) != 0) {
5410 ret
= KMF_ERR_ISSUER
;
5414 /* Check to see if the certificate serial number is revoked */
5415 revoke_stack
= X509_CRL_get_REVOKED(xcrl
);
5416 if (sk_X509_REVOKED_num(revoke_stack
) <= 0) {
5417 /* No revoked certificates in the CRL file */
5418 SET_ERROR(kmfh
, ERR_get_error());
5419 ret
= KMF_ERR_EMPTY_CRL
;
5423 for (i
= 0; i
< sk_X509_REVOKED_num(revoke_stack
); i
++) {
5424 /* LINTED E_BAD_PTR_CAST_ALIGN */
5425 revoke
= sk_X509_REVOKED_value(revoke_stack
, i
);
5426 if (ASN1_INTEGER_cmp(xcert
->cert_info
->serialNumber
,
5427 revoke
->serialNumber
) == 0) {
5432 if (i
< sk_X509_REVOKED_num(revoke_stack
)) {
5435 ret
= KMF_ERR_NOT_REVOKED
;
5440 (void) BIO_free(in
);
5442 X509_CRL_free(xcrl
);
5450 OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle
, char *crlname
, KMF_DATA
*tacert
)
5452 KMF_RETURN ret
= KMF_OK
;
5453 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
5455 X509_CRL
*xcrl
= NULL
;
5459 KMF_ENCODE_FORMAT crl_format
;
5463 if (handle
== NULL
|| crlname
== NULL
|| tacert
== NULL
) {
5464 return (KMF_ERR_BAD_PARAMETER
);
5467 ret
= kmf_get_file_format(crlname
, &crl_format
);
5471 bcrl
= BIO_new_file(crlname
, "rb");
5473 SET_ERROR(kmfh
, ERR_get_error());
5474 ret
= KMF_ERR_OPEN_FILE
;
5478 if (crl_format
== KMF_FORMAT_ASN1
) {
5479 xcrl
= d2i_X509_CRL_bio(bcrl
, NULL
);
5480 } else if (crl_format
== KMF_FORMAT_PEM
) {
5481 xcrl
= PEM_read_bio_X509_CRL(bcrl
, NULL
, NULL
, NULL
);
5483 ret
= KMF_ERR_BAD_PARAMETER
;
5488 SET_ERROR(kmfh
, ERR_get_error());
5489 ret
= KMF_ERR_BAD_CRLFILE
;
5494 len
= tacert
->Length
;
5495 xcert
= d2i_X509(NULL
, (const uchar_t
**)&p
, len
);
5497 if (xcert
== NULL
) {
5498 SET_ERROR(kmfh
, ERR_get_error());
5499 ret
= KMF_ERR_BAD_CERTFILE
;
5503 /* Get issuer certificate public key */
5504 pkey
= X509_get_pubkey(xcert
);
5506 SET_ERROR(kmfh
, ERR_get_error());
5507 ret
= KMF_ERR_BAD_CERT_FORMAT
;
5511 /* Verify CRL signature */
5512 sslret
= X509_CRL_verify(xcrl
, pkey
);
5513 EVP_PKEY_free(pkey
);
5517 SET_ERROR(kmfh
, sslret
);
5518 ret
= KMF_ERR_BAD_CRLFILE
;
5523 (void) BIO_free(bcrl
);
5526 X509_CRL_free(xcrl
);
5536 OpenSSL_CheckCRLDate(KMF_HANDLE_T handle
, char *crlname
)
5538 KMF_RETURN ret
= KMF_OK
;
5539 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
5540 KMF_ENCODE_FORMAT crl_format
;
5542 X509_CRL
*xcrl
= NULL
;
5545 if (handle
== NULL
|| crlname
== NULL
) {
5546 return (KMF_ERR_BAD_PARAMETER
);
5549 ret
= kmf_is_crl_file(handle
, crlname
, &crl_format
);
5553 bcrl
= BIO_new_file(crlname
, "rb");
5555 SET_ERROR(kmfh
, ERR_get_error());
5556 ret
= KMF_ERR_OPEN_FILE
;
5560 if (crl_format
== KMF_FORMAT_ASN1
)
5561 xcrl
= d2i_X509_CRL_bio(bcrl
, NULL
);
5562 else if (crl_format
== KMF_FORMAT_PEM
)
5563 xcrl
= PEM_read_bio_X509_CRL(bcrl
, NULL
, NULL
, NULL
);
5566 SET_ERROR(kmfh
, ERR_get_error());
5567 ret
= KMF_ERR_BAD_CRLFILE
;
5570 i
= X509_cmp_time(X509_CRL_get_lastUpdate(xcrl
), NULL
);
5572 ret
= KMF_ERR_VALIDITY_PERIOD
;
5575 if (X509_CRL_get_nextUpdate(xcrl
)) {
5576 i
= X509_cmp_time(X509_CRL_get_nextUpdate(xcrl
), NULL
);
5579 ret
= KMF_ERR_VALIDITY_PERIOD
;
5588 (void) BIO_free(bcrl
);
5591 X509_CRL_free(xcrl
);