13089Swyllys /*
2*12234Swyllys.ingersoll@sun.com * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
3*12234Swyllys.ingersoll@sun.com *
43089Swyllys * Use is subject to license terms.
53089Swyllys */
63433Shaimay /*
73433Shaimay * Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
83433Shaimay * project 2000.
93433Shaimay */
103433Shaimay /*
113433Shaimay * ====================================================================
123433Shaimay * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved.
133433Shaimay *
143433Shaimay * Redistribution and use in source and binary forms, with or without
153433Shaimay * modification, are permitted provided that the following conditions
163433Shaimay * are met:
173433Shaimay *
183433Shaimay * 1. Redistributions of source code must retain the above copyright
193433Shaimay * notice, this list of conditions and the following disclaimer.
203433Shaimay *
213433Shaimay * 2. Redistributions in binary form must reproduce the above copyright
223433Shaimay * notice, this list of conditions and the following disclaimer in
233433Shaimay * the documentation and/or other materials provided with the
243433Shaimay * distribution.
253433Shaimay *
263433Shaimay * 3. All advertising materials mentioning features or use of this
273433Shaimay * software must display the following acknowledgment:
283433Shaimay * "This product includes software developed by the OpenSSL Project
293433Shaimay * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
303433Shaimay *
313433Shaimay * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
323433Shaimay * endorse or promote products derived from this software without
333433Shaimay * prior written permission. For written permission, please contact
343433Shaimay * licensing@OpenSSL.org.
353433Shaimay *
363433Shaimay * 5. Products derived from this software may not be called "OpenSSL"
373433Shaimay * nor may "OpenSSL" appear in their names without prior written
383433Shaimay * permission of the OpenSSL Project.
393433Shaimay *
403433Shaimay * 6. Redistributions of any form whatsoever must retain the following
413433Shaimay * acknowledgment:
423433Shaimay * "This product includes software developed by the OpenSSL Project
433433Shaimay * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
443433Shaimay *
453433Shaimay * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
463433Shaimay * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
473433Shaimay * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
483433Shaimay * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
493433Shaimay * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
503433Shaimay * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
513433Shaimay * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
523433Shaimay * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
533433Shaimay * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
543433Shaimay * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
553433Shaimay * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
563433Shaimay * OF THE POSSIBILITY OF SUCH DAMAGE.
573433Shaimay * ====================================================================
583433Shaimay *
593433Shaimay * This product includes cryptographic software written by Eric Young
603433Shaimay * (eay@cryptsoft.com). This product includes software written by Tim
613433Shaimay * Hudson (tjh@cryptsoft.com).
623433Shaimay *
633433Shaimay */
643089Swyllys
653408Swyllys #include <stdlib.h>
663089Swyllys #include <kmfapiP.h>
673089Swyllys #include <ber_der.h>
683089Swyllys #include <fcntl.h>
693089Swyllys #include <sys/stat.h>
703089Swyllys #include <dirent.h>
713089Swyllys #include <cryptoutil.h>
723089Swyllys #include <synch.h>
733089Swyllys #include <thread.h>
743089Swyllys
753089Swyllys /* OPENSSL related headers */
763089Swyllys #include <openssl/bio.h>
773089Swyllys #include <openssl/bn.h>
783089Swyllys #include <openssl/asn1.h>
793089Swyllys #include <openssl/err.h>
803089Swyllys #include <openssl/bn.h>
813089Swyllys #include <openssl/x509.h>
823089Swyllys #include <openssl/rsa.h>
833089Swyllys #include <openssl/dsa.h>
843089Swyllys #include <openssl/x509v3.h>
853089Swyllys #include <openssl/objects.h>
863089Swyllys #include <openssl/pem.h>
873089Swyllys #include <openssl/pkcs12.h>
883089Swyllys #include <openssl/ocsp.h>
893089Swyllys #include <openssl/des.h>
903089Swyllys #include <openssl/rand.h>
913089Swyllys
923089Swyllys #define PRINT_ANY_EXTENSION (\
933089Swyllys KMF_X509_EXT_KEY_USAGE |\
943089Swyllys KMF_X509_EXT_CERT_POLICIES |\
953089Swyllys KMF_X509_EXT_SUBJALTNAME |\
963089Swyllys KMF_X509_EXT_BASIC_CONSTRAINTS |\
973089Swyllys KMF_X509_EXT_NAME_CONSTRAINTS |\
983089Swyllys KMF_X509_EXT_POLICY_CONSTRAINTS |\
993089Swyllys KMF_X509_EXT_EXT_KEY_USAGE |\
1003089Swyllys KMF_X509_EXT_INHIBIT_ANY_POLICY |\
1013089Swyllys KMF_X509_EXT_AUTH_KEY_ID |\
1023089Swyllys KMF_X509_EXT_SUBJ_KEY_ID |\
1033089Swyllys KMF_X509_EXT_POLICY_MAPPING)
1043089Swyllys
1053089Swyllys static uchar_t P[] = { 0x00, 0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76,
1063089Swyllys 0xaa, 0x3d, 0x25, 0x75, 0x9b, 0xb0, 0x68, 0x69,
1073089Swyllys 0xcb, 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d, 0x0c,
1083089Swyllys 0xf7, 0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82,
1093089Swyllys 0xe5, 0xd0, 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e,
1103089Swyllys 0xaf, 0xc2, 0xe9, 0xad, 0xac, 0x32, 0xab, 0x7a,
1113089Swyllys 0xac, 0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24,
1123089Swyllys 0xc2, 0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02,
1133089Swyllys 0x91 };
1143089Swyllys
1153089Swyllys static uchar_t Q[] = { 0x00, 0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8,
1163089Swyllys 0xee, 0x99, 0x3b, 0x4f, 0x2d, 0xed, 0x30, 0xf4,
1173089Swyllys 0x8e, 0xda, 0xce, 0x91, 0x5f };
1183089Swyllys
1193089Swyllys static uchar_t G[] = { 0x00, 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a,
1203089Swyllys 0x13, 0x41, 0x31, 0x63, 0xa5, 0x5b, 0x4c, 0xb5,
1213089Swyllys 0x00, 0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c, 0xef,
1223089Swyllys 0xcb, 0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c,
1233089Swyllys 0x2e, 0x71, 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba,
1243089Swyllys 0xbf, 0x58, 0xe5, 0xb7, 0x95, 0x21, 0x92, 0x5c,
1253089Swyllys 0x9c, 0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08,
1263089Swyllys 0x8c, 0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88,
1273089Swyllys 0x02 };
1283089Swyllys
1293089Swyllys #define SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_OPENSSL; \
1303089Swyllys h->lasterr.errcode = c;
1313089Swyllys
1323089Swyllys #define SET_SYS_ERROR(h, c) h->lasterr.kstype = -1; h->lasterr.errcode = c;
1333089Swyllys
1345536Swyllys /*
1355536Swyllys * Declare some new macros for managing stacks of EVP_PKEYS, similar to
1365536Swyllys * what wanboot did.
1375536Swyllys */
1385536Swyllys DECLARE_STACK_OF(EVP_PKEY)
1395536Swyllys
1405536Swyllys #define sk_EVP_PKEY_new_null() SKM_sk_new_null(EVP_PKEY)
1415536Swyllys #define sk_EVP_PKEY_free(st) SKM_sk_free(EVP_PKEY, (st))
1425536Swyllys #define sk_EVP_PKEY_num(st) SKM_sk_num(EVP_PKEY, (st))
1435536Swyllys #define sk_EVP_PKEY_value(st, i) SKM_sk_value(EVP_PKEY, (st), (i))
1445536Swyllys #define sk_EVP_PKEY_push(st, val) SKM_sk_push(EVP_PKEY, (st), (val))
1455536Swyllys #define sk_EVP_PKEY_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY, (st), \
1465536Swyllys (free_func))
1475536Swyllys
1483089Swyllys mutex_t init_lock = DEFAULTMUTEX;
1493089Swyllys static int ssl_initialized = 0;
1505051Swyllys static BIO *bio_err = NULL;
1515051Swyllys
1525051Swyllys static int
1535051Swyllys test_for_file(char *, mode_t);
1545536Swyllys static KMF_RETURN
1555536Swyllys openssl_parse_bag(PKCS12_SAFEBAG *, char *, int,
1565536Swyllys STACK_OF(EVP_PKEY) *, STACK_OF(X509) *);
1575536Swyllys
1585536Swyllys static KMF_RETURN
1595536Swyllys local_export_pk12(KMF_HANDLE_T, KMF_CREDENTIAL *, int, KMF_X509_DER_CERT *,
1605536Swyllys int, KMF_KEY_HANDLE *, char *);
1615536Swyllys
1625536Swyllys static KMF_RETURN set_pkey_attrib(EVP_PKEY *, ASN1_TYPE *, int);
1633089Swyllys
1643408Swyllys static KMF_RETURN
1655051Swyllys extract_pem(KMF_HANDLE *, char *, char *, KMF_BIGINT *, char *,
1665051Swyllys CK_UTF8CHAR *, CK_ULONG, EVP_PKEY **, KMF_DATA **, int *);
1673408Swyllys
1683408Swyllys static KMF_RETURN
1695051Swyllys kmf_load_cert(KMF_HANDLE *, char *, char *, KMF_BIGINT *, KMF_CERT_VALIDITY,
1705051Swyllys char *, KMF_DATA *);
1715051Swyllys
1725051Swyllys static KMF_RETURN
1735051Swyllys load_certs(KMF_HANDLE *, char *, char *, KMF_BIGINT *, KMF_CERT_VALIDITY,
1745051Swyllys char *, KMF_DATA **, uint32_t *);
1753408Swyllys
1763754Swyllys static KMF_RETURN
1773754Swyllys sslBN2KMFBN(BIGNUM *, KMF_BIGINT *);
1783754Swyllys
1793754Swyllys static EVP_PKEY *
1803754Swyllys ImportRawRSAKey(KMF_RAW_RSA_KEY *);
1813754Swyllys
1825051Swyllys static KMF_RETURN
1835051Swyllys convertToRawKey(EVP_PKEY *, KMF_RAW_KEY_DATA *);
1845051Swyllys
1853089Swyllys KMF_RETURN
1865051Swyllys OpenSSL_FindCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
1873089Swyllys
1883089Swyllys void
1893089Swyllys OpenSSL_FreeKMFCert(KMF_HANDLE_T, KMF_X509_DER_CERT *);
1903089Swyllys
1913089Swyllys KMF_RETURN
1925051Swyllys OpenSSL_StoreCert(KMF_HANDLE_T handle, int, KMF_ATTRIBUTE *);
1933089Swyllys
1943089Swyllys KMF_RETURN
1955051Swyllys OpenSSL_DeleteCert(KMF_HANDLE_T handle, int, KMF_ATTRIBUTE *);
1963089Swyllys
1973089Swyllys KMF_RETURN
1985051Swyllys OpenSSL_CreateKeypair(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
1995051Swyllys
2005051Swyllys KMF_RETURN
2015051Swyllys OpenSSL_StoreKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
2023089Swyllys
2033089Swyllys KMF_RETURN
2043089Swyllys OpenSSL_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *);
2053089Swyllys
2063089Swyllys KMF_RETURN
2073089Swyllys OpenSSL_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
2083089Swyllys KMF_DATA *, KMF_DATA *);
2093089Swyllys
2103089Swyllys KMF_RETURN
2115051Swyllys OpenSSL_DeleteKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
2123089Swyllys
2133089Swyllys KMF_RETURN
2145051Swyllys OpenSSL_ImportCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
2153089Swyllys
2163089Swyllys KMF_RETURN
2175051Swyllys OpenSSL_DeleteCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
2183089Swyllys
2193089Swyllys KMF_RETURN
2205051Swyllys OpenSSL_ListCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
2213089Swyllys
2223089Swyllys KMF_RETURN
2235051Swyllys OpenSSL_FindCertInCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
2243089Swyllys
2253089Swyllys KMF_RETURN
2263089Swyllys OpenSSL_CertGetPrintable(KMF_HANDLE_T, const KMF_DATA *,
2273089Swyllys KMF_PRINTABLE_ITEM, char *);
2283089Swyllys
2293089Swyllys KMF_RETURN
2303089Swyllys OpenSSL_GetErrorString(KMF_HANDLE_T, char **);
2313089Swyllys
2323089Swyllys KMF_RETURN
2335051Swyllys OpenSSL_FindPrikeyByCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
2343089Swyllys
2353089Swyllys KMF_RETURN
2363089Swyllys OpenSSL_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
2373089Swyllys KMF_DATA *, KMF_DATA *);
2383089Swyllys
2393089Swyllys KMF_RETURN
2405051Swyllys OpenSSL_CreateOCSPRequest(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
2413089Swyllys
2423089Swyllys KMF_RETURN
2435051Swyllys OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
2443089Swyllys
2453089Swyllys KMF_RETURN
2465051Swyllys OpenSSL_FindKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
2473089Swyllys
2483089Swyllys KMF_RETURN
2495051Swyllys OpenSSL_ExportPK12(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
2503089Swyllys
2513089Swyllys KMF_RETURN
2525051Swyllys OpenSSL_CreateSymKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
2533089Swyllys
2543089Swyllys KMF_RETURN
2553089Swyllys OpenSSL_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *);
2563089Swyllys
2573089Swyllys KMF_RETURN
2585051Swyllys OpenSSL_VerifyCRLFile(KMF_HANDLE_T, char *, KMF_DATA *);
2593089Swyllys
2603089Swyllys KMF_RETURN
2615051Swyllys OpenSSL_CheckCRLDate(KMF_HANDLE_T, char *);
2623089Swyllys
2633089Swyllys static
2643089Swyllys KMF_PLUGIN_FUNCLIST openssl_plugin_table =
2653089Swyllys {
2663089Swyllys 1, /* Version */
2673089Swyllys NULL, /* ConfigureKeystore */
2683089Swyllys OpenSSL_FindCert,
2693089Swyllys OpenSSL_FreeKMFCert,
2703089Swyllys OpenSSL_StoreCert,
2713089Swyllys NULL, /* ImportCert */
2723089Swyllys OpenSSL_ImportCRL,
2733089Swyllys OpenSSL_DeleteCert,
2743089Swyllys OpenSSL_DeleteCRL,
2753089Swyllys OpenSSL_CreateKeypair,
2763089Swyllys OpenSSL_FindKey,
2773089Swyllys OpenSSL_EncodePubKeyData,
2783089Swyllys OpenSSL_SignData,
2793089Swyllys OpenSSL_DeleteKey,
2803089Swyllys OpenSSL_ListCRL,
2813089Swyllys NULL, /* FindCRL */
2823089Swyllys OpenSSL_FindCertInCRL,
2833089Swyllys OpenSSL_GetErrorString,
2845051Swyllys OpenSSL_FindPrikeyByCert,
2853089Swyllys OpenSSL_DecryptData,
2865051Swyllys OpenSSL_ExportPK12,
2873089Swyllys OpenSSL_CreateSymKey,
2883089Swyllys OpenSSL_GetSymKeyValue,
2893089Swyllys NULL, /* SetTokenPin */
2905051Swyllys OpenSSL_StoreKey,
2913089Swyllys NULL /* Finalize */
2923089Swyllys };
2933089Swyllys
2943089Swyllys static mutex_t *lock_cs;
2953089Swyllys static long *lock_count;
2963089Swyllys
2973089Swyllys static void
29811673Sopensolaris@drydog.com /* ARGSUSED1 */
locking_cb(int mode,int type,char * file,int line)2993089Swyllys locking_cb(int mode, int type, char *file, int line)
3003089Swyllys {
3013089Swyllys if (mode & CRYPTO_LOCK) {
3023089Swyllys (void) mutex_lock(&(lock_cs[type]));
3033089Swyllys lock_count[type]++;
3043089Swyllys } else {
3053089Swyllys (void) mutex_unlock(&(lock_cs[type]));
3063089Swyllys }
3073089Swyllys }
3083089Swyllys
3093089Swyllys static unsigned long
thread_id()3103089Swyllys thread_id()
3113089Swyllys {
3123089Swyllys return ((unsigned long)thr_self());
3133089Swyllys }
3143089Swyllys
3153089Swyllys KMF_PLUGIN_FUNCLIST *
KMF_Plugin_Initialize()3163089Swyllys KMF_Plugin_Initialize()
3173089Swyllys {
3183089Swyllys int i;
3193089Swyllys
3203089Swyllys (void) mutex_lock(&init_lock);
3213089Swyllys if (!ssl_initialized) {
3223089Swyllys /*
3233089Swyllys * Add support for extension OIDs that are not yet in the
3243089Swyllys * openssl default set.
3253089Swyllys */
3263089Swyllys (void) OBJ_create("2.5.29.30", "nameConstraints",
3274315Swyllys "X509v3 Name Constraints");
3283089Swyllys (void) OBJ_create("2.5.29.33", "policyMappings",
3294315Swyllys "X509v3 Policy Mappings");
3303089Swyllys (void) OBJ_create("2.5.29.36", "policyConstraints",
3314315Swyllys "X509v3 Policy Constraints");
3323089Swyllys (void) OBJ_create("2.5.29.46", "freshestCRL",
3334315Swyllys "X509v3 Freshest CRL");
3343089Swyllys (void) OBJ_create("2.5.29.54", "inhibitAnyPolicy",
3354315Swyllys "X509v3 Inhibit Any-Policy");
3363089Swyllys /*
3373089Swyllys * Set up for thread-safe operation.
3383089Swyllys */
3393089Swyllys lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (mutex_t));
3403089Swyllys if (lock_cs == NULL) {
3413089Swyllys (void) mutex_unlock(&init_lock);
3423089Swyllys return (NULL);
3433089Swyllys }
3443089Swyllys
3453089Swyllys lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (long));
3463089Swyllys if (lock_count == NULL) {
3473089Swyllys OPENSSL_free(lock_cs);
3483089Swyllys (void) mutex_unlock(&init_lock);
3493089Swyllys return (NULL);
3503089Swyllys }
3513089Swyllys
3523089Swyllys for (i = 0; i < CRYPTO_num_locks(); i++) {
3533089Swyllys lock_count[i] = 0;
3543089Swyllys (void) mutex_init(&lock_cs[i], USYNC_THREAD, NULL);
3553089Swyllys }
3563089Swyllys
3573089Swyllys CRYPTO_set_id_callback((unsigned long (*)())thread_id);
358*12234Swyllys.ingersoll@sun.com if (CRYPTO_get_locking_callback() == NULL)
359*12234Swyllys.ingersoll@sun.com CRYPTO_set_locking_callback((void (*)())locking_cb);
360*12234Swyllys.ingersoll@sun.com
361*12234Swyllys.ingersoll@sun.com OpenSSL_add_all_algorithms();
362*12234Swyllys.ingersoll@sun.com
363*12234Swyllys.ingersoll@sun.com /* Enable error strings for reporting */
364*12234Swyllys.ingersoll@sun.com ERR_load_crypto_strings();
365*12234Swyllys.ingersoll@sun.com
3663089Swyllys ssl_initialized = 1;
3673089Swyllys }
3683089Swyllys (void) mutex_unlock(&init_lock);
3693089Swyllys
3703089Swyllys return (&openssl_plugin_table);
3713089Swyllys }
3723089Swyllys /*
3733089Swyllys * Convert an SSL DN to a KMF DN.
3743089Swyllys */
3753089Swyllys static KMF_RETURN
get_x509_dn(X509_NAME * sslDN,KMF_X509_NAME * kmfDN)3763089Swyllys get_x509_dn(X509_NAME *sslDN, KMF_X509_NAME *kmfDN)
3773089Swyllys {
3783089Swyllys KMF_DATA derdata;
3793089Swyllys KMF_RETURN rv = KMF_OK;
3803089Swyllys uchar_t *tmp;
3813089Swyllys
3823089Swyllys /* Convert to raw DER format */
3833089Swyllys derdata.Length = i2d_X509_NAME(sslDN, NULL);
3843089Swyllys if ((tmp = derdata.Data = (uchar_t *)OPENSSL_malloc(derdata.Length))
3854315Swyllys == NULL) {
3863089Swyllys return (KMF_ERR_MEMORY);
3873089Swyllys }
3883089Swyllys (void) i2d_X509_NAME(sslDN, &tmp);
3893089Swyllys
3903089Swyllys /* Decode to KMF format */
3913089Swyllys rv = DerDecodeName(&derdata, kmfDN);
3923089Swyllys if (rv != KMF_OK) {
3933089Swyllys rv = KMF_ERR_BAD_CERT_FORMAT;
3943089Swyllys }
3953089Swyllys OPENSSL_free(derdata.Data);
3963089Swyllys
3973089Swyllys return (rv);
3983089Swyllys }
3993089Swyllys
4005051Swyllys int
isdir(char * path)4013089Swyllys isdir(char *path)
4023089Swyllys {
4033089Swyllys struct stat s;
4043089Swyllys
4053089Swyllys if (stat(path, &s) == -1)
4063089Swyllys return (0);
4073089Swyllys
4085051Swyllys return ((s.st_mode & S_IFMT) == S_IFDIR);
4093089Swyllys }
4103089Swyllys
4113089Swyllys static KMF_RETURN
ssl_cert2KMFDATA(KMF_HANDLE * kmfh,X509 * x509cert,KMF_DATA * cert)4123089Swyllys ssl_cert2KMFDATA(KMF_HANDLE *kmfh, X509 *x509cert, KMF_DATA *cert)
4133089Swyllys {
4143089Swyllys KMF_RETURN rv = KMF_OK;
4153089Swyllys unsigned char *buf = NULL, *p;
4163089Swyllys int len;
4173089Swyllys
4183089Swyllys /*
4193089Swyllys * Convert the X509 internal struct to DER encoded data
4203089Swyllys */
4213089Swyllys if ((len = i2d_X509(x509cert, NULL)) < 0) {
4223089Swyllys SET_ERROR(kmfh, ERR_get_error());
4233089Swyllys rv = KMF_ERR_BAD_CERT_FORMAT;
4243089Swyllys goto cleanup;
4253089Swyllys }
4263089Swyllys if ((buf = malloc(len)) == NULL) {
4273089Swyllys SET_SYS_ERROR(kmfh, errno);
4283089Swyllys rv = KMF_ERR_MEMORY;
4293089Swyllys goto cleanup;
4303089Swyllys }
4313089Swyllys
4323089Swyllys /*
4333089Swyllys * i2d_X509 will increment the buf pointer so that we need to
4343089Swyllys * save it.
4353089Swyllys */
4363089Swyllys p = buf;
4373089Swyllys if ((len = i2d_X509(x509cert, &p)) < 0) {
4383089Swyllys SET_ERROR(kmfh, ERR_get_error());
4393089Swyllys free(buf);
4403089Swyllys rv = KMF_ERR_BAD_CERT_FORMAT;
4413089Swyllys goto cleanup;
4423089Swyllys }
4433089Swyllys
4443089Swyllys /* caller's responsibility to free it */
4453089Swyllys cert->Data = buf;
4463089Swyllys cert->Length = len;
4473089Swyllys
4483089Swyllys cleanup:
4493089Swyllys if (rv != KMF_OK) {
4503089Swyllys if (buf)
4513089Swyllys free(buf);
4523089Swyllys cert->Data = NULL;
4533089Swyllys cert->Length = 0;
4543089Swyllys }
4553089Swyllys
4563089Swyllys return (rv);
4573089Swyllys }
4583089Swyllys
4595051Swyllys
4603089Swyllys static KMF_RETURN
check_cert(X509 * xcert,char * issuer,char * subject,KMF_BIGINT * serial,boolean_t * match)4615051Swyllys check_cert(X509 *xcert, char *issuer, char *subject, KMF_BIGINT *serial,
4625051Swyllys boolean_t *match)
4633089Swyllys {
4643089Swyllys KMF_RETURN rv = KMF_OK;
4653089Swyllys boolean_t findIssuer = FALSE;
4663089Swyllys boolean_t findSubject = FALSE;
4673089Swyllys boolean_t findSerial = FALSE;
4683089Swyllys KMF_X509_NAME issuerDN, subjectDN;
4693089Swyllys KMF_X509_NAME certIssuerDN, certSubjectDN;
4703089Swyllys
4713089Swyllys *match = FALSE;
4723089Swyllys if (xcert == NULL) {
4733089Swyllys return (KMF_ERR_BAD_PARAMETER);
4743089Swyllys }
4753089Swyllys
4763089Swyllys (void) memset(&issuerDN, 0, sizeof (KMF_X509_NAME));
4773089Swyllys (void) memset(&subjectDN, 0, sizeof (KMF_X509_NAME));
4783089Swyllys (void) memset(&certIssuerDN, 0, sizeof (KMF_X509_NAME));
4793089Swyllys (void) memset(&certSubjectDN, 0, sizeof (KMF_X509_NAME));
4803089Swyllys
4815051Swyllys if (issuer != NULL && strlen(issuer)) {
4825051Swyllys rv = kmf_dn_parser(issuer, &issuerDN);
4833089Swyllys if (rv != KMF_OK)
4843089Swyllys return (KMF_ERR_BAD_PARAMETER);
4853089Swyllys
4863089Swyllys rv = get_x509_dn(xcert->cert_info->issuer, &certIssuerDN);
4873089Swyllys if (rv != KMF_OK) {
4885051Swyllys kmf_free_dn(&issuerDN);
4893089Swyllys return (KMF_ERR_BAD_PARAMETER);
4903089Swyllys }
4913089Swyllys
4923089Swyllys findIssuer = TRUE;
4933089Swyllys }
4945051Swyllys if (subject != NULL && strlen(subject)) {
4955051Swyllys rv = kmf_dn_parser(subject, &subjectDN);
4963089Swyllys if (rv != KMF_OK) {
4973089Swyllys rv = KMF_ERR_BAD_PARAMETER;
4983089Swyllys goto cleanup;
4993089Swyllys }
5003089Swyllys
5013089Swyllys rv = get_x509_dn(xcert->cert_info->subject, &certSubjectDN);
5023089Swyllys if (rv != KMF_OK) {
5033089Swyllys rv = KMF_ERR_BAD_PARAMETER;
5043089Swyllys goto cleanup;
5053089Swyllys }
5063089Swyllys findSubject = TRUE;
5073089Swyllys }
5085051Swyllys if (serial != NULL && serial->val != NULL)
5093089Swyllys findSerial = TRUE;
5103089Swyllys
5113089Swyllys if (findSerial) {
5123089Swyllys BIGNUM *bn;
5133089Swyllys
5143089Swyllys /* Comparing BIGNUMs is a pain! */
5153089Swyllys bn = ASN1_INTEGER_to_BN(xcert->cert_info->serialNumber, NULL);
5163089Swyllys if (bn != NULL) {
5173089Swyllys int bnlen = BN_num_bytes(bn);
5183089Swyllys
5195051Swyllys if (bnlen == serial->len) {
5203089Swyllys uchar_t *a = malloc(bnlen);
5213089Swyllys if (a == NULL) {
5223089Swyllys rv = KMF_ERR_MEMORY;
5233089Swyllys BN_free(bn);
5243089Swyllys goto cleanup;
5253089Swyllys }
5263089Swyllys bnlen = BN_bn2bin(bn, a);
5275051Swyllys *match = (memcmp(a, serial->val, serial->len) ==
5285051Swyllys 0);
5293089Swyllys rv = KMF_OK;
5303089Swyllys free(a);
5313089Swyllys }
5323089Swyllys BN_free(bn);
5333089Swyllys if (!(*match))
5343089Swyllys goto cleanup;
5353089Swyllys } else {
5363089Swyllys rv = KMF_OK;
5373089Swyllys goto cleanup;
5383089Swyllys }
5393089Swyllys }
5403089Swyllys if (findIssuer) {
5415051Swyllys *match = (kmf_compare_rdns(&issuerDN, &certIssuerDN) == 0);
5425051Swyllys if ((*match) == B_FALSE) {
5435051Swyllys /* stop checking and bail */
5443089Swyllys rv = KMF_OK;
5453089Swyllys goto cleanup;
5463089Swyllys }
5473089Swyllys }
5483089Swyllys if (findSubject) {
5495051Swyllys *match = (kmf_compare_rdns(&subjectDN, &certSubjectDN) == 0);
5505051Swyllys if ((*match) == B_FALSE) {
5515051Swyllys /* stop checking and bail */
5523089Swyllys rv = KMF_OK;
5533089Swyllys goto cleanup;
5543089Swyllys }
5553089Swyllys }
5563089Swyllys
5573089Swyllys *match = TRUE;
5583089Swyllys cleanup:
5593089Swyllys if (findIssuer) {
5605051Swyllys kmf_free_dn(&issuerDN);
5615051Swyllys kmf_free_dn(&certIssuerDN);
5623089Swyllys }
5633089Swyllys if (findSubject) {
5645051Swyllys kmf_free_dn(&subjectDN);
5655051Swyllys kmf_free_dn(&certSubjectDN);
5663089Swyllys }
5673089Swyllys
5683089Swyllys return (rv);
5693089Swyllys }
5703089Swyllys
5715051Swyllys
5725051Swyllys /*
5735051Swyllys * This function loads a certificate file into an X509 data structure, and
5745051Swyllys * checks if its issuer, subject or the serial number matches with those
5755051Swyllys * values. If it matches, then return the X509 data structure.
5765051Swyllys */
5773089Swyllys static KMF_RETURN
load_X509cert(KMF_HANDLE * kmfh,char * issuer,char * subject,KMF_BIGINT * serial,char * pathname,X509 ** outcert)5783089Swyllys load_X509cert(KMF_HANDLE *kmfh,
5795051Swyllys char *issuer, char *subject, KMF_BIGINT *serial,
5805051Swyllys char *pathname, X509 **outcert)
5813089Swyllys {
5823089Swyllys KMF_RETURN rv = KMF_OK;
5833089Swyllys X509 *xcert = NULL;
5843089Swyllys BIO *bcert = NULL;
5853089Swyllys boolean_t match = FALSE;
5863089Swyllys KMF_ENCODE_FORMAT format;
5873089Swyllys
5883089Swyllys /*
5893089Swyllys * auto-detect the file format, regardless of what
5903089Swyllys * the 'format' parameters in the params say.
5913089Swyllys */
5925051Swyllys rv = kmf_get_file_format(pathname, &format);
5933089Swyllys if (rv != KMF_OK) {
5943089Swyllys if (rv == KMF_ERR_OPEN_FILE)
5953089Swyllys rv = KMF_ERR_CERT_NOT_FOUND;
5963089Swyllys return (rv);
5973089Swyllys }
5983089Swyllys
5993089Swyllys /* Not ASN1(DER) format */
6003089Swyllys if ((bcert = BIO_new_file(pathname, "rb")) == NULL) {
6013089Swyllys SET_ERROR(kmfh, ERR_get_error());
6023089Swyllys rv = KMF_ERR_OPEN_FILE;
6033089Swyllys goto cleanup;
6043089Swyllys }
6053089Swyllys
6063089Swyllys if (format == KMF_FORMAT_PEM)
6073089Swyllys xcert = PEM_read_bio_X509_AUX(bcert, NULL, NULL, NULL);
6083089Swyllys else if (format == KMF_FORMAT_ASN1)
6093089Swyllys xcert = d2i_X509_bio(bcert, NULL);
6103089Swyllys else if (format == KMF_FORMAT_PKCS12) {
6113089Swyllys PKCS12 *p12 = d2i_PKCS12_bio(bcert, NULL);
6123089Swyllys if (p12 != NULL) {
6133089Swyllys (void) PKCS12_parse(p12, NULL, NULL, &xcert, NULL);
6143089Swyllys PKCS12_free(p12);
6153089Swyllys p12 = NULL;
6163089Swyllys } else {
6173089Swyllys SET_ERROR(kmfh, ERR_get_error());
6183089Swyllys rv = KMF_ERR_BAD_CERT_FORMAT;
6193089Swyllys }
6203089Swyllys } else {
6213089Swyllys rv = KMF_ERR_BAD_PARAMETER;
6223089Swyllys goto cleanup;
6233089Swyllys }
6243089Swyllys
6253089Swyllys if (xcert == NULL) {
6263089Swyllys SET_ERROR(kmfh, ERR_get_error());
6273089Swyllys rv = KMF_ERR_BAD_CERT_FORMAT;
6283089Swyllys goto cleanup;
6293089Swyllys }
6303089Swyllys
6315051Swyllys if (check_cert(xcert, issuer, subject, serial, &match) != KMF_OK ||
6325051Swyllys match == FALSE) {
6333089Swyllys rv = KMF_ERR_CERT_NOT_FOUND;
6343089Swyllys goto cleanup;
6353089Swyllys }
6363089Swyllys
6373089Swyllys if (outcert != NULL) {
6383089Swyllys *outcert = xcert;
6393089Swyllys }
6403089Swyllys
6413089Swyllys cleanup:
6423089Swyllys if (bcert != NULL) (void) BIO_free(bcert);
6433089Swyllys if (rv != KMF_OK && xcert != NULL)
6443089Swyllys X509_free(xcert);
6453089Swyllys
6463089Swyllys return (rv);
6473089Swyllys }
6483089Swyllys
6493408Swyllys static int
datacmp(const void * a,const void * b)6503408Swyllys datacmp(const void *a, const void *b)
6513408Swyllys {
6523408Swyllys KMF_DATA *adata = (KMF_DATA *)a;
6533408Swyllys KMF_DATA *bdata = (KMF_DATA *)b;
6543408Swyllys if (adata->Length > bdata->Length)
6553408Swyllys return (-1);
6563408Swyllys if (adata->Length < bdata->Length)
6573408Swyllys return (1);
6583408Swyllys return (0);
6593408Swyllys }
6603408Swyllys
6613408Swyllys static KMF_RETURN
load_certs(KMF_HANDLE * kmfh,char * issuer,char * subject,KMF_BIGINT * serial,KMF_CERT_VALIDITY validity,char * pathname,KMF_DATA ** certlist,uint32_t * numcerts)6625051Swyllys load_certs(KMF_HANDLE *kmfh, char *issuer, char *subject, KMF_BIGINT *serial,
6635051Swyllys KMF_CERT_VALIDITY validity, char *pathname,
6645051Swyllys KMF_DATA **certlist, uint32_t *numcerts)
6653408Swyllys {
6663408Swyllys KMF_RETURN rv = KMF_OK;
6673408Swyllys int i;
6683408Swyllys KMF_DATA *certs = NULL;
6693408Swyllys int nc = 0;
6703408Swyllys int hits = 0;
6713408Swyllys KMF_ENCODE_FORMAT format;
6723408Swyllys
6735051Swyllys rv = kmf_get_file_format(pathname, &format);
6743408Swyllys if (rv != KMF_OK) {
6753408Swyllys if (rv == KMF_ERR_OPEN_FILE)
6763408Swyllys rv = KMF_ERR_CERT_NOT_FOUND;
6773408Swyllys return (rv);
6783408Swyllys }
6793408Swyllys if (format == KMF_FORMAT_ASN1) {
6803408Swyllys /* load a single certificate */
6813408Swyllys certs = (KMF_DATA *)malloc(sizeof (KMF_DATA));
6823408Swyllys if (certs == NULL)
6833408Swyllys return (KMF_ERR_MEMORY);
6843408Swyllys certs->Data = NULL;
6853408Swyllys certs->Length = 0;
6865051Swyllys rv = kmf_load_cert(kmfh, issuer, subject, serial, validity,
6875051Swyllys pathname, certs);
6883408Swyllys if (rv == KMF_OK) {
6893408Swyllys *certlist = certs;
6903408Swyllys *numcerts = 1;
69111673Sopensolaris@drydog.com } else {
69211673Sopensolaris@drydog.com kmf_free_data(certs);
69311673Sopensolaris@drydog.com free(certs);
69411673Sopensolaris@drydog.com certs = NULL;
6953408Swyllys }
6963408Swyllys return (rv);
6973408Swyllys } else if (format == KMF_FORMAT_PKCS12) {
6983408Swyllys /* We need a credential to access a PKCS#12 file */
6993408Swyllys rv = KMF_ERR_BAD_CERT_FORMAT;
7003408Swyllys } else if (format == KMF_FORMAT_PEM ||
7014315Swyllys format != KMF_FORMAT_PEM_KEYPAIR) {
70211973Swyllys.ingersoll@sun.com
7033408Swyllys /* This function only works on PEM files */
7045051Swyllys rv = extract_pem(kmfh, issuer, subject, serial, pathname,
7054315Swyllys (uchar_t *)NULL, 0, NULL, &certs, &nc);
7063408Swyllys } else {
7073408Swyllys return (KMF_ERR_ENCODING);
7083408Swyllys }
7093408Swyllys
7103408Swyllys if (rv != KMF_OK)
7113408Swyllys return (rv);
7123408Swyllys
7133408Swyllys for (i = 0; i < nc; i++) {
7145051Swyllys if (validity == KMF_NONEXPIRED_CERTS) {
7155051Swyllys rv = kmf_check_cert_date(kmfh, &certs[i]);
7165051Swyllys } else if (validity == KMF_EXPIRED_CERTS) {
7175051Swyllys rv = kmf_check_cert_date(kmfh, &certs[i]);
7183408Swyllys if (rv == KMF_OK)
7193408Swyllys rv = KMF_ERR_CERT_NOT_FOUND;
7203408Swyllys if (rv == KMF_ERR_VALIDITY_PERIOD)
7213408Swyllys rv = KMF_OK;
7223408Swyllys }
7233408Swyllys if (rv != KMF_OK) {
7243408Swyllys /* Remove this cert from the list by clearing it. */
7255051Swyllys kmf_free_data(&certs[i]);
7263408Swyllys } else {
7273408Swyllys hits++; /* count valid certs found */
7283408Swyllys }
7293408Swyllys rv = KMF_OK;
7303408Swyllys }
73111673Sopensolaris@drydog.com if (rv == KMF_OK && hits > 0) {
7323408Swyllys /*
7333408Swyllys * Sort the list of certs by length to put the cleared ones
7343408Swyllys * at the end so they don't get accessed by the caller.
7353408Swyllys */
7363408Swyllys qsort((void *)certs, nc, sizeof (KMF_DATA), datacmp);
7373408Swyllys *certlist = certs;
7383408Swyllys
7393408Swyllys /* since we sorted the list, just return the number of hits */
7403408Swyllys *numcerts = hits;
74111673Sopensolaris@drydog.com } else {
74211973Swyllys.ingersoll@sun.com if (rv == KMF_OK && hits == 0)
74311673Sopensolaris@drydog.com rv = KMF_ERR_CERT_NOT_FOUND;
74411673Sopensolaris@drydog.com if (certs != NULL) {
74511673Sopensolaris@drydog.com free(certs);
74611673Sopensolaris@drydog.com certs = NULL;
74711673Sopensolaris@drydog.com }
74811673Sopensolaris@drydog.com }
7493408Swyllys return (rv);
7503408Swyllys }
7513408Swyllys
7523089Swyllys static KMF_RETURN
kmf_load_cert(KMF_HANDLE * kmfh,char * issuer,char * subject,KMF_BIGINT * serial,KMF_CERT_VALIDITY validity,char * pathname,KMF_DATA * cert)7533089Swyllys kmf_load_cert(KMF_HANDLE *kmfh,
7545051Swyllys char *issuer, char *subject, KMF_BIGINT *serial,
7555051Swyllys KMF_CERT_VALIDITY validity,
7565051Swyllys char *pathname,
7575051Swyllys KMF_DATA *cert)
7583089Swyllys {
7593089Swyllys KMF_RETURN rv = KMF_OK;
7603089Swyllys X509 *x509cert = NULL;
7613089Swyllys
7625051Swyllys rv = load_X509cert(kmfh, issuer, subject, serial, pathname, &x509cert);
7633089Swyllys if (rv == KMF_OK && x509cert != NULL && cert != NULL) {
7643089Swyllys rv = ssl_cert2KMFDATA(kmfh, x509cert, cert);
7653089Swyllys if (rv != KMF_OK) {
7663089Swyllys goto cleanup;
7673089Swyllys }
7685051Swyllys if (validity == KMF_NONEXPIRED_CERTS) {
7695051Swyllys rv = kmf_check_cert_date(kmfh, cert);
7705051Swyllys } else if (validity == KMF_EXPIRED_CERTS) {
7715051Swyllys rv = kmf_check_cert_date(kmfh, cert);
7723089Swyllys if (rv == KMF_OK) {
7733089Swyllys /*
7743089Swyllys * This is a valid cert so skip it.
7753089Swyllys */
7763089Swyllys rv = KMF_ERR_CERT_NOT_FOUND;
7773089Swyllys }
7783089Swyllys if (rv == KMF_ERR_VALIDITY_PERIOD) {
7793089Swyllys /*
7803089Swyllys * We want to return success when we
7813089Swyllys * find an invalid cert.
7823089Swyllys */
7833089Swyllys rv = KMF_OK;
7843089Swyllys goto cleanup;
7853089Swyllys }
7863089Swyllys }
7873089Swyllys }
7883089Swyllys cleanup:
7893089Swyllys if (x509cert != NULL)
7903089Swyllys X509_free(x509cert);
7913089Swyllys
7923089Swyllys return (rv);
7933089Swyllys }
7943089Swyllys
7953754Swyllys static KMF_RETURN
readAltFormatPrivateKey(KMF_DATA * filedata,EVP_PKEY ** pkey)7963754Swyllys readAltFormatPrivateKey(KMF_DATA *filedata, EVP_PKEY **pkey)
7973754Swyllys {
7983754Swyllys KMF_RETURN ret = KMF_OK;
7993754Swyllys KMF_RAW_RSA_KEY rsa;
8003754Swyllys BerElement *asn1 = NULL;
8013754Swyllys BerValue filebuf;
8023754Swyllys BerValue OID = { NULL, 0 };
8033754Swyllys BerValue *Mod = NULL, *PubExp = NULL;
8043754Swyllys BerValue *PriExp = NULL, *Prime1 = NULL, *Prime2 = NULL;
8053754Swyllys BerValue *Coef = NULL;
8063754Swyllys BIGNUM *D = NULL, *P = NULL, *Q = NULL, *COEF = NULL;
8073754Swyllys BIGNUM *Exp1 = NULL, *Exp2 = NULL, *pminus1 = NULL;
8083754Swyllys BIGNUM *qminus1 = NULL;
8093754Swyllys BN_CTX *ctx = NULL;
8103754Swyllys
8113754Swyllys *pkey = NULL;
8123754Swyllys
8133754Swyllys filebuf.bv_val = (char *)filedata->Data;
8143754Swyllys filebuf.bv_len = filedata->Length;
8153754Swyllys
8163754Swyllys asn1 = kmfder_init(&filebuf);
8173754Swyllys if (asn1 == NULL) {
8183754Swyllys ret = KMF_ERR_MEMORY;
8193754Swyllys goto out;
8203754Swyllys }
8213754Swyllys
8223754Swyllys if (kmfber_scanf(asn1, "{{Dn{IIIIII}}}",
8234315Swyllys &OID, &Mod, &PubExp, &PriExp, &Prime1,
8244315Swyllys &Prime2, &Coef) == -1) {
8253754Swyllys ret = KMF_ERR_ENCODING;
8263754Swyllys goto out;
8273754Swyllys }
8283754Swyllys
8293754Swyllys /*
8303754Swyllys * We have to derive the 2 Exponents using Bignumber math.
8313754Swyllys * Exp1 = PriExp mod (Prime1 - 1)
8323754Swyllys * Exp2 = PriExp mod (Prime2 - 1)
8333754Swyllys */
8343754Swyllys
8353754Swyllys /* D = PrivateExponent */
8363754Swyllys D = BN_bin2bn((const uchar_t *)PriExp->bv_val, PriExp->bv_len, D);
8373754Swyllys if (D == NULL) {
8383754Swyllys ret = KMF_ERR_MEMORY;
8393754Swyllys goto out;
8403754Swyllys }
8413754Swyllys
8423754Swyllys /* P = Prime1 (first prime factor of Modulus) */
8433754Swyllys P = BN_bin2bn((const uchar_t *)Prime1->bv_val, Prime1->bv_len, P);
8443754Swyllys if (D == NULL) {
8453754Swyllys ret = KMF_ERR_MEMORY;
8463754Swyllys goto out;
8473754Swyllys }
8483754Swyllys
8493754Swyllys /* Q = Prime2 (second prime factor of Modulus) */
8503754Swyllys Q = BN_bin2bn((const uchar_t *)Prime2->bv_val, Prime2->bv_len, Q);
8513754Swyllys
8523754Swyllys if ((ctx = BN_CTX_new()) == NULL) {
8533754Swyllys ret = KMF_ERR_MEMORY;
8543754Swyllys goto out;
8553754Swyllys }
8563754Swyllys
8573754Swyllys /* Compute (P - 1) */
8583754Swyllys pminus1 = BN_new();
8593754Swyllys (void) BN_sub(pminus1, P, BN_value_one());
8603754Swyllys
8613754Swyllys /* Exponent1 = D mod (P - 1) */
8623754Swyllys Exp1 = BN_new();
8633754Swyllys (void) BN_mod(Exp1, D, pminus1, ctx);
8643754Swyllys
8653754Swyllys /* Compute (Q - 1) */
8663754Swyllys qminus1 = BN_new();
8673754Swyllys (void) BN_sub(qminus1, Q, BN_value_one());
8683754Swyllys
8693754Swyllys /* Exponent2 = D mod (Q - 1) */
8703754Swyllys Exp2 = BN_new();
8713754Swyllys (void) BN_mod(Exp2, D, qminus1, ctx);
8723754Swyllys
8733754Swyllys /* Coef = (Inverse Q) mod P */
8743754Swyllys COEF = BN_new();
8753754Swyllys (void) BN_mod_inverse(COEF, Q, P, ctx);
8763754Swyllys
8773754Swyllys /* Convert back to KMF format */
8783754Swyllys (void) memset(&rsa, 0, sizeof (rsa));
8793754Swyllys
8803754Swyllys if ((ret = sslBN2KMFBN(Exp1, &rsa.exp1)) != KMF_OK)
8813754Swyllys goto out;
8823754Swyllys if ((ret = sslBN2KMFBN(Exp2, &rsa.exp2)) != KMF_OK)
8833754Swyllys goto out;
8843754Swyllys if ((ret = sslBN2KMFBN(COEF, &rsa.coef)) != KMF_OK)
8853754Swyllys goto out;
8863754Swyllys
8873754Swyllys rsa.mod.val = (uchar_t *)Mod->bv_val;
8883754Swyllys rsa.mod.len = Mod->bv_len;
8893754Swyllys
8903754Swyllys rsa.pubexp.val = (uchar_t *)PubExp->bv_val;
8913754Swyllys rsa.pubexp.len = PubExp->bv_len;
8923754Swyllys
8933754Swyllys rsa.priexp.val = (uchar_t *)PriExp->bv_val;
8943754Swyllys rsa.priexp.len = PriExp->bv_len;
8953754Swyllys
8963754Swyllys rsa.prime1.val = (uchar_t *)Prime1->bv_val;
8973754Swyllys rsa.prime1.len = Prime1->bv_len;
8983754Swyllys
8993754Swyllys rsa.prime2.val = (uchar_t *)Prime2->bv_val;
9003754Swyllys rsa.prime2.len = Prime2->bv_len;
9013754Swyllys
9023754Swyllys *pkey = ImportRawRSAKey(&rsa);
9033754Swyllys out:
9043754Swyllys if (asn1 != NULL)
9053754Swyllys kmfber_free(asn1, 1);
9063754Swyllys
9073754Swyllys if (OID.bv_val) {
9083754Swyllys free(OID.bv_val);
9093754Swyllys }
9103754Swyllys if (PriExp)
9113754Swyllys free(PriExp);
9123754Swyllys
9133754Swyllys if (Mod)
9143754Swyllys free(Mod);
9153754Swyllys
9163754Swyllys if (PubExp)
9173754Swyllys free(PubExp);
9183754Swyllys
9193754Swyllys if (Coef) {
9203754Swyllys (void) memset(Coef->bv_val, 0, Coef->bv_len);
9213754Swyllys free(Coef->bv_val);
9223754Swyllys free(Coef);
9233754Swyllys }
9243754Swyllys if (Prime1)
9253754Swyllys free(Prime1);
9263754Swyllys if (Prime2)
9273754Swyllys free(Prime2);
9283754Swyllys
9293754Swyllys if (ctx != NULL)
9303754Swyllys BN_CTX_free(ctx);
9313754Swyllys
9323754Swyllys if (D)
9333754Swyllys BN_clear_free(D);
9343754Swyllys if (P)
9353754Swyllys BN_clear_free(P);
9363754Swyllys if (Q)
9373754Swyllys BN_clear_free(Q);
9383754Swyllys if (pminus1)
9393754Swyllys BN_clear_free(pminus1);
9403754Swyllys if (qminus1)
9413754Swyllys BN_clear_free(qminus1);
9423754Swyllys if (Exp1)
9433754Swyllys BN_clear_free(Exp1);
9443754Swyllys if (Exp2)
9453754Swyllys BN_clear_free(Exp2);
9463754Swyllys
9473754Swyllys return (ret);
9483754Swyllys
9493754Swyllys }
9503754Swyllys
9513089Swyllys static EVP_PKEY *
openssl_load_key(KMF_HANDLE_T handle,const char * file)9523089Swyllys openssl_load_key(KMF_HANDLE_T handle, const char *file)
9533089Swyllys {
9543089Swyllys BIO *keyfile = NULL;
9553089Swyllys EVP_PKEY *pkey = NULL;
9563089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
9573089Swyllys KMF_ENCODE_FORMAT format;
9583754Swyllys KMF_RETURN rv;
9593754Swyllys KMF_DATA filedata;
9603089Swyllys
9613089Swyllys if (file == NULL) {
9623089Swyllys return (NULL);
9633089Swyllys }
9643089Swyllys
9655051Swyllys if (kmf_get_file_format((char *)file, &format) != KMF_OK)
9663089Swyllys return (NULL);
9673089Swyllys
9683089Swyllys keyfile = BIO_new_file(file, "rb");
9693089Swyllys if (keyfile == NULL) {
9703089Swyllys goto end;
9713089Swyllys }
9723089Swyllys
9733754Swyllys if (format == KMF_FORMAT_ASN1) {
9743089Swyllys pkey = d2i_PrivateKey_bio(keyfile, NULL);
9753754Swyllys if (pkey == NULL) {
9763754Swyllys
9773754Swyllys (void) BIO_free(keyfile);
9783754Swyllys keyfile = NULL;
9793754Swyllys /* Try odd ASN.1 variations */
9805051Swyllys rv = kmf_read_input_file(kmfh, (char *)file,
9814315Swyllys &filedata);
9823754Swyllys if (rv == KMF_OK) {
9833754Swyllys (void) readAltFormatPrivateKey(&filedata,
9844315Swyllys &pkey);
9855051Swyllys kmf_free_data(&filedata);
9863754Swyllys }
9873754Swyllys }
9883754Swyllys } else if (format == KMF_FORMAT_PEM ||
9894315Swyllys format == KMF_FORMAT_PEM_KEYPAIR) {
9903089Swyllys pkey = PEM_read_bio_PrivateKey(keyfile, NULL, NULL, NULL);
9913754Swyllys if (pkey == NULL) {
9923754Swyllys KMF_DATA derdata;
9933754Swyllys /*
9943754Swyllys * Check if this is the alt. format
9953754Swyllys * RSA private key file.
9963754Swyllys */
9975051Swyllys rv = kmf_read_input_file(kmfh, (char *)file,
9984315Swyllys &filedata);
9993754Swyllys if (rv == KMF_OK) {
10003754Swyllys uchar_t *d = NULL;
10013754Swyllys int len;
10025051Swyllys rv = kmf_pem_to_der(filedata.Data,
10034315Swyllys filedata.Length, &d, &len);
10043754Swyllys if (rv == KMF_OK && d != NULL) {
10053754Swyllys derdata.Data = d;
10063754Swyllys derdata.Length = (size_t)len;
10073754Swyllys (void) readAltFormatPrivateKey(
10084315Swyllys &derdata, &pkey);
10093754Swyllys free(d);
10103754Swyllys }
10115051Swyllys kmf_free_data(&filedata);
10123754Swyllys }
10133754Swyllys }
10143754Swyllys }
10153089Swyllys
10163089Swyllys end:
10173089Swyllys if (pkey == NULL)
10183089Swyllys SET_ERROR(kmfh, ERR_get_error());
10193089Swyllys
10203089Swyllys if (keyfile != NULL)
10213089Swyllys (void) BIO_free(keyfile);
10223089Swyllys
10233089Swyllys return (pkey);
10243089Swyllys }
10253089Swyllys
10263089Swyllys KMF_RETURN
OpenSSL_FindCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)10275051Swyllys OpenSSL_FindCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
10283089Swyllys {
10293089Swyllys KMF_RETURN rv = KMF_OK;
10303089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
10314025Swyllys int i, n;
10324025Swyllys uint32_t maxcerts = 0;
10335051Swyllys uint32_t *num_certs;
10345051Swyllys KMF_X509_DER_CERT *kmf_cert = NULL;
10355051Swyllys char *dirpath = NULL;
10365051Swyllys char *filename = NULL;
10375051Swyllys char *fullpath = NULL;
10385051Swyllys char *issuer = NULL;
10395051Swyllys char *subject = NULL;
10405051Swyllys KMF_BIGINT *serial = NULL;
10415051Swyllys KMF_CERT_VALIDITY validity;
10425051Swyllys
10435051Swyllys num_certs = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
10445051Swyllys if (num_certs == NULL)
10453089Swyllys return (KMF_ERR_BAD_PARAMETER);
10463089Swyllys
10475051Swyllys /* num_certs should reference the size of kmf_cert */
10484025Swyllys maxcerts = *num_certs;
10494025Swyllys if (maxcerts == 0)
10504025Swyllys maxcerts = 0xFFFFFFFF;
10513089Swyllys *num_certs = 0;
10523089Swyllys
10535051Swyllys /* Get the optional returned certificate list */
10545051Swyllys kmf_cert = kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR, attrlist,
10555051Swyllys numattr);
10565051Swyllys
10575051Swyllys /*
10585051Swyllys * The dirpath attribute and the filename attribute can not be NULL
10595051Swyllys * at the same time.
10605051Swyllys */
10615051Swyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
10625051Swyllys filename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist,
10635051Swyllys numattr);
10645051Swyllys
10655051Swyllys fullpath = get_fullpath(dirpath, filename);
10663089Swyllys if (fullpath == NULL)
10673089Swyllys return (KMF_ERR_BAD_PARAMETER);
10683089Swyllys
10695051Swyllys /* Get optional search criteria attributes */
10705051Swyllys issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
10715051Swyllys subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
10725051Swyllys serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
10735051Swyllys rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
10745051Swyllys &validity, NULL);
10755051Swyllys if (rv != KMF_OK) {
10765051Swyllys validity = KMF_ALL_CERTS;
10775051Swyllys rv = KMF_OK;
10785051Swyllys }
10795051Swyllys
10803089Swyllys if (isdir(fullpath)) {
10813089Swyllys DIR *dirp;
10823089Swyllys struct dirent *dp;
10834025Swyllys
10844025Swyllys n = 0;
10853089Swyllys /* open all files in the directory and attempt to read them */
10863089Swyllys if ((dirp = opendir(fullpath)) == NULL) {
10873089Swyllys return (KMF_ERR_BAD_PARAMETER);
10883089Swyllys }
10893089Swyllys while ((dp = readdir(dirp)) != NULL) {
10903089Swyllys char *fname;
10913408Swyllys KMF_DATA *certlist = NULL;
10924025Swyllys uint32_t loaded_certs = 0;
10933408Swyllys
10943089Swyllys if (strcmp(dp->d_name, ".") == 0 ||
10953089Swyllys strcmp(dp->d_name, "..") == 0)
10963089Swyllys continue;
10973089Swyllys
10984315Swyllys fname = get_fullpath(fullpath, (char *)&dp->d_name);
10993089Swyllys
11005051Swyllys rv = load_certs(kmfh, issuer, subject, serial,
11015051Swyllys validity, fname, &certlist, &loaded_certs);
11023089Swyllys
11033089Swyllys if (rv != KMF_OK) {
11043089Swyllys free(fname);
11053408Swyllys if (certlist != NULL) {
11064025Swyllys for (i = 0; i < loaded_certs; i++)
11075051Swyllys kmf_free_data(&certlist[i]);
11083408Swyllys free(certlist);
11093408Swyllys }
11103089Swyllys continue;
11113089Swyllys }
11123089Swyllys
11133089Swyllys /* If load succeeds, add certdata to the list */
11143089Swyllys if (kmf_cert != NULL) {
11154025Swyllys for (i = 0; i < loaded_certs &&
11164090Swyllys n < maxcerts; i++) {
11173408Swyllys kmf_cert[n].certificate.Data =
11184315Swyllys certlist[i].Data;
11193408Swyllys kmf_cert[n].certificate.Length =
11204315Swyllys certlist[i].Length;
11213408Swyllys
11223408Swyllys kmf_cert[n].kmf_private.keystore_type =
11234315Swyllys KMF_KEYSTORE_OPENSSL;
11243408Swyllys kmf_cert[n].kmf_private.flags =
11254315Swyllys KMF_FLAG_CERT_VALID;
11263408Swyllys kmf_cert[n].kmf_private.label =
11274315Swyllys strdup(fname);
11283408Swyllys n++;
11293408Swyllys }
11304090Swyllys /*
11314090Swyllys * If maxcerts < loaded_certs, clean up the
11324090Swyllys * certs that were not used.
11334090Swyllys */
11344025Swyllys for (; i < loaded_certs; i++)
11355051Swyllys kmf_free_data(&certlist[i]);
11364025Swyllys } else {
11374025Swyllys for (i = 0; i < loaded_certs; i++)
11385051Swyllys kmf_free_data(&certlist[i]);
11394025Swyllys n += loaded_certs;
11403089Swyllys }
11414025Swyllys free(certlist);
11423408Swyllys free(fname);
11433089Swyllys }
11443089Swyllys (*num_certs) = n;
11453089Swyllys if (*num_certs == 0)
11463089Swyllys rv = KMF_ERR_CERT_NOT_FOUND;
11475051Swyllys if (*num_certs > 0)
11483089Swyllys rv = KMF_OK;
11493089Swyllys exit:
11503089Swyllys (void) closedir(dirp);
11513089Swyllys } else {
11523408Swyllys KMF_DATA *certlist = NULL;
11534025Swyllys uint32_t loaded_certs = 0;
11544025Swyllys
11555051Swyllys rv = load_certs(kmfh, issuer, subject, serial, validity,
11565051Swyllys fullpath, &certlist, &loaded_certs);
11573089Swyllys if (rv != KMF_OK) {
11583089Swyllys free(fullpath);
11593089Swyllys return (rv);
11603089Swyllys }
11613089Swyllys
11624025Swyllys n = 0;
11633408Swyllys if (kmf_cert != NULL && certlist != NULL) {
11644025Swyllys for (i = 0; i < loaded_certs && i < maxcerts; i++) {
11654025Swyllys kmf_cert[n].certificate.Data =
11664315Swyllys certlist[i].Data;
11674025Swyllys kmf_cert[n].certificate.Length =
11684315Swyllys certlist[i].Length;
11694025Swyllys kmf_cert[n].kmf_private.keystore_type =
11704315Swyllys KMF_KEYSTORE_OPENSSL;
11714025Swyllys kmf_cert[n].kmf_private.flags =
11724315Swyllys KMF_FLAG_CERT_VALID;
11734025Swyllys kmf_cert[n].kmf_private.label =
11744315Swyllys strdup(fullpath);
11754025Swyllys n++;
11763408Swyllys }
11774025Swyllys /* If maxcerts < loaded_certs, clean up */
11784025Swyllys for (; i < loaded_certs; i++)
11795051Swyllys kmf_free_data(&certlist[i]);
11804025Swyllys } else if (certlist != NULL) {
11814025Swyllys for (i = 0; i < loaded_certs; i++)
11825051Swyllys kmf_free_data(&certlist[i]);
11834025Swyllys n = loaded_certs;
11844025Swyllys }
11855051Swyllys if (certlist != NULL)
11863408Swyllys free(certlist);
11874025Swyllys *num_certs = n;
11883408Swyllys }
11893408Swyllys
11903408Swyllys free(fullpath);
11913089Swyllys
11923089Swyllys return (rv);
11933089Swyllys }
11943089Swyllys
11953089Swyllys void
11963089Swyllys /*ARGSUSED*/
OpenSSL_FreeKMFCert(KMF_HANDLE_T handle,KMF_X509_DER_CERT * kmf_cert)11973089Swyllys OpenSSL_FreeKMFCert(KMF_HANDLE_T handle,
11983089Swyllys KMF_X509_DER_CERT *kmf_cert)
11993089Swyllys {
12003089Swyllys if (kmf_cert != NULL) {
12013089Swyllys if (kmf_cert->certificate.Data != NULL) {
120211973Swyllys.ingersoll@sun.com kmf_free_data(&kmf_cert->certificate);
12033089Swyllys }
12043089Swyllys if (kmf_cert->kmf_private.label)
12053089Swyllys free(kmf_cert->kmf_private.label);
12063089Swyllys }
12073089Swyllys }
12083089Swyllys
12095051Swyllys /*ARGSUSED*/
12103089Swyllys KMF_RETURN
OpenSSL_StoreCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)12115051Swyllys OpenSSL_StoreCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
12123089Swyllys {
12133089Swyllys KMF_RETURN ret = KMF_OK;
12145051Swyllys KMF_DATA *cert = NULL;
12155051Swyllys char *outfilename = NULL;
12165051Swyllys char *dirpath = NULL;
12175051Swyllys char *fullpath = NULL;
12183089Swyllys KMF_ENCODE_FORMAT format;
12193089Swyllys
12205051Swyllys /* Get the cert data */
12215051Swyllys cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
12225051Swyllys if (cert == NULL || cert->Data == NULL)
12233089Swyllys return (KMF_ERR_BAD_PARAMETER);
12245051Swyllys
12255051Swyllys /* Check the output filename and directory attributes. */
12265051Swyllys outfilename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist,
12275051Swyllys numattr);
12285051Swyllys if (outfilename == NULL)
12293089Swyllys return (KMF_ERR_BAD_PARAMETER);
12305051Swyllys
12315051Swyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
12325051Swyllys fullpath = get_fullpath(dirpath, outfilename);
12335051Swyllys if (fullpath == NULL)
12345051Swyllys return (KMF_ERR_BAD_CERTFILE);
12355051Swyllys
12365051Swyllys /* Check the optional format attribute */
12375051Swyllys ret = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
12385051Swyllys &format, NULL);
12395051Swyllys if (ret != KMF_OK) {
12405051Swyllys /* If there is no format attribute, then default to PEM */
12415051Swyllys format = KMF_FORMAT_PEM;
12425051Swyllys ret = KMF_OK;
12435051Swyllys } else if (format != KMF_FORMAT_ASN1 && format != KMF_FORMAT_PEM) {
12445051Swyllys ret = KMF_ERR_BAD_CERT_FORMAT;
12453089Swyllys goto out;
12463089Swyllys }
12473089Swyllys
12485051Swyllys /* Store the certificate in the file with the specified format */
12495051Swyllys ret = kmf_create_cert_file(cert, format, fullpath);
12503089Swyllys
12513089Swyllys out:
12523089Swyllys if (fullpath != NULL)
12533089Swyllys free(fullpath);
12543089Swyllys
12553089Swyllys return (ret);
12563089Swyllys }
12573089Swyllys
12585051Swyllys
12593089Swyllys KMF_RETURN
OpenSSL_DeleteCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)12605051Swyllys OpenSSL_DeleteCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
12613089Swyllys {
12623089Swyllys KMF_RETURN rv;
12633089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
12645051Swyllys KMF_DATA certdata = {NULL, 0};
12655051Swyllys char *dirpath = NULL;
12665051Swyllys char *filename = NULL;
12673089Swyllys char *fullpath = NULL;
12685051Swyllys char *issuer = NULL;
12695051Swyllys char *subject = NULL;
12705051Swyllys KMF_BIGINT *serial = NULL;
12715051Swyllys KMF_CERT_VALIDITY validity;
12725051Swyllys
12735051Swyllys /*
12745051Swyllys * Get the DIRPATH and CERT_FILENAME attributes. They can not be
12755051Swyllys * NULL at the same time.
12765051Swyllys */
12775051Swyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
12785051Swyllys filename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist,
12795051Swyllys numattr);
12805051Swyllys fullpath = get_fullpath(dirpath, filename);
12813089Swyllys if (fullpath == NULL)
12823089Swyllys return (KMF_ERR_BAD_PARAMETER);
12833089Swyllys
12845051Swyllys /* Get optional search criteria attributes */
12855051Swyllys issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
12865051Swyllys subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
12875051Swyllys serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
12885051Swyllys rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
12895051Swyllys &validity, NULL);
12905051Swyllys if (rv != KMF_OK) {
12915051Swyllys validity = KMF_ALL_CERTS;
12925051Swyllys rv = KMF_OK;
12935051Swyllys }
12945051Swyllys
12953089Swyllys if (isdir(fullpath)) {
12963089Swyllys DIR *dirp;
12973089Swyllys struct dirent *dp;
12983089Swyllys
12993089Swyllys /* open all files in the directory and attempt to read them */
13003089Swyllys if ((dirp = opendir(fullpath)) == NULL) {
13013089Swyllys return (KMF_ERR_BAD_PARAMETER);
13023089Swyllys }
13033089Swyllys
13043089Swyllys while ((dp = readdir(dirp)) != NULL) {
13053089Swyllys if (strcmp(dp->d_name, ".") != 0 &&
13063089Swyllys strcmp(dp->d_name, "..") != 0) {
13073089Swyllys char *fname;
13083089Swyllys
13093089Swyllys fname = get_fullpath(fullpath,
13104315Swyllys (char *)&dp->d_name);
13113089Swyllys
13123089Swyllys if (fname == NULL) {
13133089Swyllys rv = KMF_ERR_MEMORY;
13143089Swyllys break;
13153089Swyllys }
13163089Swyllys
13175051Swyllys rv = kmf_load_cert(kmfh, issuer, subject,
13185051Swyllys serial, validity, fname, &certdata);
13193089Swyllys
13203089Swyllys if (rv == KMF_ERR_CERT_NOT_FOUND) {
13213089Swyllys free(fname);
132211973Swyllys.ingersoll@sun.com kmf_free_data(&certdata);
13233089Swyllys rv = KMF_OK;
13243089Swyllys continue;
13253089Swyllys } else if (rv != KMF_OK) {
13263089Swyllys free(fname);
13273089Swyllys break;
13283089Swyllys }
13293089Swyllys
13303089Swyllys if (unlink(fname) != 0) {
13313089Swyllys SET_SYS_ERROR(kmfh, errno);
13323089Swyllys rv = KMF_ERR_INTERNAL;
13333089Swyllys free(fname);
13343089Swyllys break;
13353089Swyllys }
13363089Swyllys free(fname);
133711973Swyllys.ingersoll@sun.com kmf_free_data(&certdata);
13383089Swyllys }
13393089Swyllys }
13403089Swyllys (void) closedir(dirp);
13413089Swyllys } else {
13423089Swyllys /* Just try to load a single certificate */
13435051Swyllys rv = kmf_load_cert(kmfh, issuer, subject, serial, validity,
13445051Swyllys fullpath, &certdata);
13453089Swyllys if (rv == KMF_OK) {
13463089Swyllys if (unlink(fullpath) != 0) {
13473089Swyllys SET_SYS_ERROR(kmfh, errno);
13483089Swyllys rv = KMF_ERR_INTERNAL;
13493089Swyllys }
13503089Swyllys }
13513089Swyllys }
13523089Swyllys
13533089Swyllys out:
13543089Swyllys if (fullpath != NULL)
13553089Swyllys free(fullpath);
13563089Swyllys
135711973Swyllys.ingersoll@sun.com kmf_free_data(&certdata);
13583089Swyllys
13593089Swyllys return (rv);
13603089Swyllys }
13613089Swyllys
13623089Swyllys KMF_RETURN
OpenSSL_EncodePubKeyData(KMF_HANDLE_T handle,KMF_KEY_HANDLE * key,KMF_DATA * keydata)13633089Swyllys OpenSSL_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
13643089Swyllys KMF_DATA *keydata)
13653089Swyllys {
13663089Swyllys KMF_RETURN rv = KMF_OK;
13673089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
13683089Swyllys int n;
13693089Swyllys
13703089Swyllys if (key == NULL || keydata == NULL ||
13713089Swyllys key->keyp == NULL)
13723089Swyllys return (KMF_ERR_BAD_PARAMETER);
13733089Swyllys
13743089Swyllys if (key->keyalg == KMF_RSA) {
13753089Swyllys RSA *pubkey = EVP_PKEY_get1_RSA(key->keyp);
13763089Swyllys
13773089Swyllys if (!(n = i2d_RSA_PUBKEY(pubkey, &keydata->Data))) {
13783089Swyllys SET_ERROR(kmfh, ERR_get_error());
13793089Swyllys return (KMF_ERR_ENCODING);
13803089Swyllys }
13813089Swyllys RSA_free(pubkey);
13823089Swyllys } else if (key->keyalg == KMF_DSA) {
13833089Swyllys DSA *pubkey = EVP_PKEY_get1_DSA(key->keyp);
13843089Swyllys
13853089Swyllys if (!(n = i2d_DSA_PUBKEY(pubkey, &keydata->Data))) {
13863089Swyllys SET_ERROR(kmfh, ERR_get_error());
13873089Swyllys return (KMF_ERR_ENCODING);
13883089Swyllys }
13893089Swyllys DSA_free(pubkey);
13903089Swyllys } else {
13914315Swyllys return (KMF_ERR_BAD_PARAMETER);
13923089Swyllys }
13933089Swyllys keydata->Length = n;
13943089Swyllys
13953089Swyllys cleanup:
13963089Swyllys if (rv != KMF_OK) {
13973089Swyllys if (keydata->Data)
13983089Swyllys free(keydata->Data);
13993089Swyllys keydata->Data = NULL;
14003089Swyllys keydata->Length = 0;
14013089Swyllys }
14023089Swyllys
14033089Swyllys return (rv);
14043089Swyllys }
14053089Swyllys
14063089Swyllys static KMF_RETURN
ssl_write_key(KMF_HANDLE * kmfh,KMF_ENCODE_FORMAT format,BIO * out,KMF_CREDENTIAL * cred,EVP_PKEY * pkey,boolean_t private)14075051Swyllys ssl_write_key(KMF_HANDLE *kmfh, KMF_ENCODE_FORMAT format, BIO *out,
14085051Swyllys KMF_CREDENTIAL *cred, EVP_PKEY *pkey, boolean_t private)
14093089Swyllys {
14103089Swyllys int rv = 0;
14113089Swyllys RSA *rsa;
14123089Swyllys DSA *dsa;
14133089Swyllys
14145536Swyllys if (pkey == NULL || out == NULL)
14155536Swyllys return (KMF_ERR_BAD_PARAMETER);
14165536Swyllys
14173089Swyllys switch (format) {
14185637Swyllys case KMF_FORMAT_RAWKEY:
14195637Swyllys /* same as ASN.1 */
14203089Swyllys case KMF_FORMAT_ASN1:
14213089Swyllys if (pkey->type == EVP_PKEY_RSA) {
14223089Swyllys rsa = EVP_PKEY_get1_RSA(pkey);
14235051Swyllys if (private)
14245051Swyllys rv = i2d_RSAPrivateKey_bio(out, rsa);
14255051Swyllys else
14265051Swyllys rv = i2d_RSAPublicKey_bio(out, rsa);
14273089Swyllys RSA_free(rsa);
14283089Swyllys } else if (pkey->type == EVP_PKEY_DSA) {
14293089Swyllys dsa = EVP_PKEY_get1_DSA(pkey);
14303089Swyllys rv = i2d_DSAPrivateKey_bio(out, dsa);
14313089Swyllys DSA_free(dsa);
14323089Swyllys }
14333089Swyllys if (rv == 1) {
14343089Swyllys rv = KMF_OK;
14353089Swyllys } else {
14363089Swyllys SET_ERROR(kmfh, rv);
14373089Swyllys }
14383089Swyllys break;
14393089Swyllys case KMF_FORMAT_PEM:
14403089Swyllys if (pkey->type == EVP_PKEY_RSA) {
14413089Swyllys rsa = EVP_PKEY_get1_RSA(pkey);
14425051Swyllys if (private)
14435051Swyllys rv = PEM_write_bio_RSAPrivateKey(out,
14445051Swyllys rsa, NULL, NULL, 0, NULL,
14455051Swyllys (cred != NULL ? cred->cred : NULL));
14465051Swyllys else
14475051Swyllys rv = PEM_write_bio_RSAPublicKey(out,
14485051Swyllys rsa);
14493089Swyllys RSA_free(rsa);
14503089Swyllys } else if (pkey->type == EVP_PKEY_DSA) {
14513089Swyllys dsa = EVP_PKEY_get1_DSA(pkey);
14523089Swyllys rv = PEM_write_bio_DSAPrivateKey(out,
14535051Swyllys dsa, NULL, NULL, 0, NULL,
14545051Swyllys (cred != NULL ? cred->cred : NULL));
14553089Swyllys DSA_free(dsa);
14563089Swyllys }
14573089Swyllys
14583089Swyllys if (rv == 1) {
14593089Swyllys rv = KMF_OK;
14603089Swyllys } else {
14613089Swyllys SET_ERROR(kmfh, rv);
14623089Swyllys }
14633089Swyllys break;
14643089Swyllys
14653089Swyllys default:
14663089Swyllys rv = KMF_ERR_BAD_PARAMETER;
14673089Swyllys }
14683089Swyllys
14693089Swyllys return (rv);
14703089Swyllys }
14713089Swyllys
14723089Swyllys KMF_RETURN
OpenSSL_CreateKeypair(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)14735051Swyllys OpenSSL_CreateKeypair(KMF_HANDLE_T handle, int numattr,
14745051Swyllys KMF_ATTRIBUTE *attrlist)
14753089Swyllys {
14763089Swyllys KMF_RETURN rv = KMF_OK;
14773089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
14783089Swyllys uint32_t eValue = 0x010001;
14793089Swyllys RSA *sslPrivKey = NULL;
14803089Swyllys DSA *sslDSAKey = NULL;
14813089Swyllys EVP_PKEY *eprikey = NULL;
14823089Swyllys EVP_PKEY *epubkey = NULL;
14833089Swyllys BIO *out = NULL;
14845051Swyllys KMF_KEY_HANDLE *pubkey = NULL, *privkey = NULL;
14855051Swyllys uint32_t keylen = 1024;
14865051Swyllys uint32_t keylen_size = sizeof (uint32_t);
14875051Swyllys boolean_t storekey = TRUE;
14885051Swyllys KMF_KEY_ALG keytype = KMF_RSA;
14895051Swyllys
14905051Swyllys rv = kmf_get_attr(KMF_STOREKEY_BOOL_ATTR, attrlist, numattr,
14915051Swyllys &storekey, NULL);
14925051Swyllys if (rv != KMF_OK) {
14935051Swyllys /* "storekey" is optional. Default is TRUE */
14945051Swyllys rv = KMF_OK;
14955051Swyllys }
14965051Swyllys
14975051Swyllys rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
14985051Swyllys (void *)&keytype, NULL);
14995051Swyllys if (rv != KMF_OK)
15005051Swyllys /* keytype is optional. KMF_RSA is default */
15015051Swyllys rv = KMF_OK;
15025051Swyllys
15035051Swyllys pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr);
15045051Swyllys if (pubkey == NULL)
15053089Swyllys return (KMF_ERR_BAD_PARAMETER);
15065051Swyllys
15075051Swyllys privkey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr);
15085051Swyllys if (privkey == NULL)
15093089Swyllys return (KMF_ERR_BAD_PARAMETER);
15103089Swyllys
15115051Swyllys (void) memset(pubkey, 0, sizeof (KMF_KEY_HANDLE));
15125051Swyllys (void) memset(privkey, 0, sizeof (KMF_KEY_HANDLE));
15133089Swyllys
15143089Swyllys eprikey = EVP_PKEY_new();
15153089Swyllys if (eprikey == NULL) {
15163089Swyllys SET_ERROR(kmfh, ERR_get_error());
15173089Swyllys rv = KMF_ERR_KEYGEN_FAILED;
15183089Swyllys goto cleanup;
15193089Swyllys }
15203089Swyllys epubkey = EVP_PKEY_new();
15213089Swyllys if (epubkey == NULL) {
15223089Swyllys SET_ERROR(kmfh, ERR_get_error());
15233089Swyllys rv = KMF_ERR_KEYGEN_FAILED;
15243089Swyllys goto cleanup;
15253089Swyllys }
15265051Swyllys if (keytype == KMF_RSA) {
15275051Swyllys KMF_BIGINT *rsaexp = NULL;
15285051Swyllys
15295051Swyllys rsaexp = kmf_get_attr_ptr(KMF_RSAEXP_ATTR, attrlist, numattr);
15305051Swyllys if (rsaexp != NULL) {
15315051Swyllys if (rsaexp->len > 0 &&
15325051Swyllys rsaexp->len <= sizeof (eValue) &&
15335051Swyllys rsaexp->val != NULL) {
153411673Sopensolaris@drydog.com /* LINTED E_BAD_PTR_CAST_ALIGN */
15355051Swyllys eValue = *(uint32_t *)rsaexp->val;
15365051Swyllys } else {
15375051Swyllys rv = KMF_ERR_BAD_PARAMETER;
15385051Swyllys goto cleanup;
15395051Swyllys }
15405051Swyllys } else {
15415051Swyllys /* RSA Exponent is optional. Default is 0x10001 */
15425051Swyllys rv = KMF_OK;
15435051Swyllys }
15445051Swyllys
15455051Swyllys rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
15465051Swyllys &keylen, &keylen_size);
15475051Swyllys if (rv == KMF_ERR_ATTR_NOT_FOUND)
15485051Swyllys /* keylen is optional, default is 1024 */
15495051Swyllys rv = KMF_OK;
15505051Swyllys if (rv != KMF_OK) {
15515051Swyllys rv = KMF_ERR_BAD_PARAMETER;
15525051Swyllys goto cleanup;
15535051Swyllys }
15545051Swyllys
15555051Swyllys sslPrivKey = RSA_generate_key(keylen, eValue, NULL, NULL);
15563089Swyllys if (sslPrivKey == NULL) {
15573089Swyllys SET_ERROR(kmfh, ERR_get_error());
15583089Swyllys rv = KMF_ERR_KEYGEN_FAILED;
15593089Swyllys } else {
15605051Swyllys (void) EVP_PKEY_set1_RSA(eprikey, sslPrivKey);
15615051Swyllys privkey->kstype = KMF_KEYSTORE_OPENSSL;
15625051Swyllys privkey->keyalg = KMF_RSA;
15635051Swyllys privkey->keyclass = KMF_ASYM_PRI;
15645051Swyllys privkey->israw = FALSE;
15655051Swyllys privkey->keyp = (void *)eprikey;
15665051Swyllys
15673089Swyllys /* OpenSSL derives the public key from the private */
15685051Swyllys (void) EVP_PKEY_set1_RSA(epubkey, sslPrivKey);
15695051Swyllys pubkey->kstype = KMF_KEYSTORE_OPENSSL;
15705051Swyllys pubkey->keyalg = KMF_RSA;
15715051Swyllys pubkey->israw = FALSE;
15725051Swyllys pubkey->keyclass = KMF_ASYM_PUB;
15735051Swyllys pubkey->keyp = (void *)epubkey;
15743089Swyllys }
15755051Swyllys } else if (keytype == KMF_DSA) {
15765051Swyllys DSA *dp;
15773089Swyllys sslDSAKey = DSA_new();
15783089Swyllys if (sslDSAKey == NULL) {
15793089Swyllys SET_ERROR(kmfh, ERR_get_error());
15803089Swyllys return (KMF_ERR_MEMORY);
15813089Swyllys }
15823089Swyllys
15833089Swyllys if ((sslDSAKey->p = BN_bin2bn(P, sizeof (P), sslDSAKey->p)) ==
15844315Swyllys NULL) {
15853089Swyllys SET_ERROR(kmfh, ERR_get_error());
15863089Swyllys rv = KMF_ERR_KEYGEN_FAILED;
15873089Swyllys goto cleanup;
15883089Swyllys }
15893089Swyllys if ((sslDSAKey->q = BN_bin2bn(Q, sizeof (Q), sslDSAKey->q)) ==
15904315Swyllys NULL) {
15913089Swyllys SET_ERROR(kmfh, ERR_get_error());
15923089Swyllys rv = KMF_ERR_KEYGEN_FAILED;
15933089Swyllys goto cleanup;
15943089Swyllys }
15953089Swyllys if ((sslDSAKey->g = BN_bin2bn(G, sizeof (G), sslDSAKey->g)) ==
15964315Swyllys NULL) {
15973089Swyllys SET_ERROR(kmfh, ERR_get_error());
15983089Swyllys rv = KMF_ERR_KEYGEN_FAILED;
15993089Swyllys goto cleanup;
16003089Swyllys }
16013089Swyllys
16023089Swyllys if (!DSA_generate_key(sslDSAKey)) {
16033089Swyllys SET_ERROR(kmfh, ERR_get_error());
16043089Swyllys rv = KMF_ERR_KEYGEN_FAILED;
16053089Swyllys goto cleanup;
16063089Swyllys }
16073089Swyllys
16085051Swyllys privkey->kstype = KMF_KEYSTORE_OPENSSL;
16095051Swyllys privkey->keyalg = KMF_DSA;
16105051Swyllys privkey->keyclass = KMF_ASYM_PRI;
16115051Swyllys privkey->israw = FALSE;
16125051Swyllys if (EVP_PKEY_set1_DSA(eprikey, sslDSAKey)) {
16135051Swyllys privkey->keyp = (void *)eprikey;
16145051Swyllys } else {
16155051Swyllys SET_ERROR(kmfh, ERR_get_error());
16165051Swyllys rv = KMF_ERR_KEYGEN_FAILED;
16175051Swyllys goto cleanup;
16185051Swyllys }
16195051Swyllys dp = DSA_new();
16205051Swyllys /* Make a copy for the public key */
16215051Swyllys if (dp != NULL) {
16225051Swyllys if ((dp->p = BN_new()) == NULL) {
16235051Swyllys SET_ERROR(kmfh, ERR_get_error());
16245051Swyllys rv = KMF_ERR_MEMORY;
16255051Swyllys DSA_free(dp);
16265051Swyllys goto cleanup;
16275051Swyllys }
16285051Swyllys if ((dp->q = BN_new()) == NULL) {
16295051Swyllys SET_ERROR(kmfh, ERR_get_error());
16305051Swyllys rv = KMF_ERR_MEMORY;
16315051Swyllys BN_free(dp->p);
16325051Swyllys DSA_free(dp);
16335051Swyllys goto cleanup;
16345051Swyllys }
16355051Swyllys if ((dp->g = BN_new()) == NULL) {
16365051Swyllys SET_ERROR(kmfh, ERR_get_error());
16375051Swyllys rv = KMF_ERR_MEMORY;
16385051Swyllys BN_free(dp->q);
16395051Swyllys BN_free(dp->p);
16405051Swyllys DSA_free(dp);
16415051Swyllys goto cleanup;
16425051Swyllys }
16435051Swyllys if ((dp->pub_key = BN_new()) == NULL) {
16445051Swyllys SET_ERROR(kmfh, ERR_get_error());
16455051Swyllys rv = KMF_ERR_MEMORY;
16465051Swyllys BN_free(dp->q);
16475051Swyllys BN_free(dp->p);
16485051Swyllys BN_free(dp->g);
16495051Swyllys DSA_free(dp);
16505051Swyllys goto cleanup;
16515051Swyllys }
16525051Swyllys (void) BN_copy(dp->p, sslDSAKey->p);
16535051Swyllys (void) BN_copy(dp->q, sslDSAKey->q);
16545051Swyllys (void) BN_copy(dp->g, sslDSAKey->g);
16555051Swyllys (void) BN_copy(dp->pub_key, sslDSAKey->pub_key);
16565051Swyllys
16575051Swyllys pubkey->kstype = KMF_KEYSTORE_OPENSSL;
16585051Swyllys pubkey->keyalg = KMF_DSA;
16595051Swyllys pubkey->keyclass = KMF_ASYM_PUB;
16605051Swyllys pubkey->israw = FALSE;
16615051Swyllys
16625051Swyllys if (EVP_PKEY_set1_DSA(epubkey, sslDSAKey)) {
16635051Swyllys pubkey->keyp = (void *)epubkey;
16643089Swyllys } else {
16653089Swyllys SET_ERROR(kmfh, ERR_get_error());
16663089Swyllys rv = KMF_ERR_KEYGEN_FAILED;
16673089Swyllys goto cleanup;
16683089Swyllys }
16693089Swyllys }
16703089Swyllys }
16713089Swyllys
16723089Swyllys if (rv != KMF_OK) {
16733089Swyllys goto cleanup;
16743089Swyllys }
16753089Swyllys
16765051Swyllys if (storekey) {
16775051Swyllys KMF_ATTRIBUTE storeattrs[4]; /* max. 4 attributes needed */
16785051Swyllys int i = 0;
16795051Swyllys char *keyfile = NULL, *dirpath = NULL;
16805051Swyllys KMF_ENCODE_FORMAT format;
16815051Swyllys /*
16825051Swyllys * Construct a new attribute arrray and call openssl_store_key
16835051Swyllys */
16845051Swyllys kmf_set_attr_at_index(storeattrs, i, KMF_PRIVKEY_HANDLE_ATTR,
16855051Swyllys privkey, sizeof (privkey));
16865051Swyllys i++;
16875051Swyllys
16885051Swyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
16895051Swyllys if (dirpath != NULL) {
16905051Swyllys storeattrs[i].type = KMF_DIRPATH_ATTR;
16915051Swyllys storeattrs[i].pValue = dirpath;
16925051Swyllys storeattrs[i].valueLen = strlen(dirpath);
16935051Swyllys i++;
16945051Swyllys } else {
16955051Swyllys rv = KMF_OK; /* DIRPATH is optional */
16965051Swyllys }
16975051Swyllys keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR,
16985051Swyllys attrlist, numattr);
16995051Swyllys if (keyfile != NULL) {
17005051Swyllys storeattrs[i].type = KMF_KEY_FILENAME_ATTR;
17015051Swyllys storeattrs[i].pValue = keyfile;
17025051Swyllys storeattrs[i].valueLen = strlen(keyfile);
17035051Swyllys i++;
17045051Swyllys } else {
17055051Swyllys goto cleanup; /* KEYFILE is required */
17065051Swyllys }
17075051Swyllys rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
17085051Swyllys (void *)&format, NULL);
17095051Swyllys if (rv == KMF_OK) {
17105051Swyllys storeattrs[i].type = KMF_ENCODE_FORMAT_ATTR;
17115051Swyllys storeattrs[i].pValue = &format;
17125051Swyllys storeattrs[i].valueLen = sizeof (format);
17135051Swyllys i++;
17145051Swyllys }
17155051Swyllys
17165051Swyllys rv = OpenSSL_StoreKey(handle, i, storeattrs);
17175051Swyllys }
17183089Swyllys
17193089Swyllys cleanup:
17203089Swyllys if (rv != KMF_OK) {
17213089Swyllys if (eprikey != NULL)
17223089Swyllys EVP_PKEY_free(eprikey);
17233089Swyllys
17243089Swyllys if (epubkey != NULL)
17253089Swyllys EVP_PKEY_free(epubkey);
17263089Swyllys
17273089Swyllys if (pubkey->keylabel) {
17283089Swyllys free(pubkey->keylabel);
17293089Swyllys pubkey->keylabel = NULL;
17303089Swyllys }
17313089Swyllys
17323089Swyllys if (privkey->keylabel) {
17333089Swyllys free(privkey->keylabel);
17343089Swyllys privkey->keylabel = NULL;
17353089Swyllys }
17363089Swyllys
17373089Swyllys pubkey->keyp = NULL;
17383089Swyllys privkey->keyp = NULL;
17393089Swyllys }
17403089Swyllys
17413089Swyllys if (sslPrivKey)
17423089Swyllys RSA_free(sslPrivKey);
17433089Swyllys
17443089Swyllys if (sslDSAKey)
17453089Swyllys DSA_free(sslDSAKey);
17463089Swyllys
17473089Swyllys if (out != NULL)
17483089Swyllys (void) BIO_free(out);
17493089Swyllys
17503089Swyllys return (rv);
17513089Swyllys }
17523089Swyllys
175311973Swyllys.ingersoll@sun.com /*
175411973Swyllys.ingersoll@sun.com * Make sure the BN conversion is properly padded with 0x00
175511973Swyllys.ingersoll@sun.com * bytes. If not, signature verification for DSA signatures
175611973Swyllys.ingersoll@sun.com * may fail in the case where the bignum value does not use
175711973Swyllys.ingersoll@sun.com * all of the bits.
175811973Swyllys.ingersoll@sun.com */
175911973Swyllys.ingersoll@sun.com static int
fixbnlen(BIGNUM * bn,unsigned char * buf,int len)176011973Swyllys.ingersoll@sun.com fixbnlen(BIGNUM *bn, unsigned char *buf, int len) {
176111973Swyllys.ingersoll@sun.com int bytes = len - BN_num_bytes(bn);
1762*12234Swyllys.ingersoll@sun.com
1763*12234Swyllys.ingersoll@sun.com /* prepend with leading 0x00 if necessary */
176411973Swyllys.ingersoll@sun.com while (bytes-- > 0)
176511973Swyllys.ingersoll@sun.com *buf++ = 0;
176611973Swyllys.ingersoll@sun.com
1767*12234Swyllys.ingersoll@sun.com (void) BN_bn2bin(bn, buf);
1768*12234Swyllys.ingersoll@sun.com /*
1769*12234Swyllys.ingersoll@sun.com * Return the desired length since we prepended it
1770*12234Swyllys.ingersoll@sun.com * with the necessary 0x00 padding.
1771*12234Swyllys.ingersoll@sun.com */
1772*12234Swyllys.ingersoll@sun.com return (len);
177311973Swyllys.ingersoll@sun.com }
177411973Swyllys.ingersoll@sun.com
17753089Swyllys KMF_RETURN
OpenSSL_SignData(KMF_HANDLE_T handle,KMF_KEY_HANDLE * key,KMF_OID * AlgOID,KMF_DATA * tobesigned,KMF_DATA * output)17763089Swyllys OpenSSL_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
17773089Swyllys KMF_OID *AlgOID, KMF_DATA *tobesigned, KMF_DATA *output)
17783089Swyllys {
17793089Swyllys KMF_RETURN ret = KMF_OK;
17803089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
17813089Swyllys KMF_ALGORITHM_INDEX AlgId;
17823089Swyllys EVP_MD_CTX ctx;
17833089Swyllys const EVP_MD *md;
17843754Swyllys
17853089Swyllys if (key == NULL || AlgOID == NULL ||
17864315Swyllys tobesigned == NULL || output == NULL ||
17874315Swyllys tobesigned->Data == NULL ||
17884315Swyllys output->Data == NULL)
17893089Swyllys return (KMF_ERR_BAD_PARAMETER);
17903089Swyllys
17913089Swyllys /* Map the OID to an OpenSSL algorithm */
17925051Swyllys AlgId = x509_algoid_to_algid(AlgOID);
17933089Swyllys if (AlgId == KMF_ALGID_NONE)
179411973Swyllys.ingersoll@sun.com return (KMF_ERR_BAD_ALGORITHM);
17953089Swyllys
17963089Swyllys if (key->keyalg == KMF_RSA) {
17973089Swyllys EVP_PKEY *pkey = (EVP_PKEY *)key->keyp;
17983089Swyllys uchar_t *p;
17993754Swyllys int len;
18003089Swyllys if (AlgId == KMF_ALGID_MD5WithRSA)
18013089Swyllys md = EVP_md5();
18023089Swyllys else if (AlgId == KMF_ALGID_MD2WithRSA)
18033089Swyllys md = EVP_md2();
18043089Swyllys else if (AlgId == KMF_ALGID_SHA1WithRSA)
18053089Swyllys md = EVP_sha1();
180611973Swyllys.ingersoll@sun.com else if (AlgId == KMF_ALGID_SHA256WithRSA)
180711973Swyllys.ingersoll@sun.com md = EVP_sha256();
180811973Swyllys.ingersoll@sun.com else if (AlgId == KMF_ALGID_SHA384WithRSA)
180911973Swyllys.ingersoll@sun.com md = EVP_sha384();
181011973Swyllys.ingersoll@sun.com else if (AlgId == KMF_ALGID_SHA512WithRSA)
181111973Swyllys.ingersoll@sun.com md = EVP_sha512();
18123754Swyllys else if (AlgId == KMF_ALGID_RSA)
18133754Swyllys md = NULL;
18143089Swyllys else
181511973Swyllys.ingersoll@sun.com return (KMF_ERR_BAD_ALGORITHM);
18163089Swyllys
18173754Swyllys if ((md == NULL) && (AlgId == KMF_ALGID_RSA)) {
18183754Swyllys RSA *rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)pkey);
18193754Swyllys
18203754Swyllys p = output->Data;
18213754Swyllys if ((len = RSA_private_encrypt(tobesigned->Length,
18224315Swyllys tobesigned->Data, p, rsa,
18234315Swyllys RSA_PKCS1_PADDING)) <= 0) {
18243754Swyllys SET_ERROR(kmfh, ERR_get_error());
18253754Swyllys ret = KMF_ERR_INTERNAL;
18263754Swyllys }
18273754Swyllys output->Length = len;
18283754Swyllys } else {
18293754Swyllys (void) EVP_MD_CTX_init(&ctx);
18303754Swyllys (void) EVP_SignInit_ex(&ctx, md, NULL);
18313754Swyllys (void) EVP_SignUpdate(&ctx, tobesigned->Data,
18324315Swyllys (uint32_t)tobesigned->Length);
18333754Swyllys len = (uint32_t)output->Length;
18343754Swyllys p = output->Data;
18353754Swyllys if (!EVP_SignFinal(&ctx, p, (uint32_t *)&len, pkey)) {
18363754Swyllys SET_ERROR(kmfh, ERR_get_error());
18373754Swyllys len = 0;
18383754Swyllys ret = KMF_ERR_INTERNAL;
18393754Swyllys }
18403754Swyllys output->Length = len;
18413754Swyllys (void) EVP_MD_CTX_cleanup(&ctx);
18423089Swyllys }
18433089Swyllys } else if (key->keyalg == KMF_DSA) {
18443089Swyllys DSA *dsa = EVP_PKEY_get1_DSA(key->keyp);
18453089Swyllys
18463089Swyllys uchar_t hash[EVP_MAX_MD_SIZE];
18473089Swyllys uint32_t hashlen;
18483089Swyllys DSA_SIG *dsasig;
18493089Swyllys
185011973Swyllys.ingersoll@sun.com if (AlgId == KMF_ALGID_DSA ||
185111973Swyllys.ingersoll@sun.com AlgId == KMF_ALGID_SHA1WithDSA)
185211973Swyllys.ingersoll@sun.com md = EVP_sha1();
185311973Swyllys.ingersoll@sun.com else if (AlgId == KMF_ALGID_SHA256WithDSA)
185411973Swyllys.ingersoll@sun.com md = EVP_sha256();
185511973Swyllys.ingersoll@sun.com else /* Bad algorithm */
185611973Swyllys.ingersoll@sun.com return (KMF_ERR_BAD_ALGORITHM);
185711973Swyllys.ingersoll@sun.com
18583089Swyllys /*
18593089Swyllys * OpenSSL EVP_Sign operation automatically converts to
18603089Swyllys * ASN.1 output so we do the operations separately so we
18613089Swyllys * are assured of NOT getting ASN.1 output returned.
18623089Swyllys * KMF does not want ASN.1 encoded results because
18633089Swyllys * not all mechanisms return ASN.1 encodings (PKCS#11
18643089Swyllys * and NSS return raw signature data).
18653089Swyllys */
18663089Swyllys EVP_MD_CTX_init(&ctx);
18673089Swyllys (void) EVP_DigestInit_ex(&ctx, md, NULL);
18683089Swyllys (void) EVP_DigestUpdate(&ctx, tobesigned->Data,
18694315Swyllys tobesigned->Length);
18703089Swyllys (void) EVP_DigestFinal_ex(&ctx, hash, &hashlen);
187111973Swyllys.ingersoll@sun.com
187211973Swyllys.ingersoll@sun.com /* Only sign first 20 bytes for SHA2 */
187311973Swyllys.ingersoll@sun.com if (AlgId == KMF_ALGID_SHA256WithDSA)
187411973Swyllys.ingersoll@sun.com hashlen = 20;
18753089Swyllys dsasig = DSA_do_sign(hash, hashlen, dsa);
18763089Swyllys if (dsasig != NULL) {
18773089Swyllys int i;
187811973Swyllys.ingersoll@sun.com output->Length = i = fixbnlen(dsasig->r, output->Data,
187911973Swyllys.ingersoll@sun.com hashlen);
1880*12234Swyllys.ingersoll@sun.com
188111973Swyllys.ingersoll@sun.com output->Length += fixbnlen(dsasig->s, &output->Data[i],
188211973Swyllys.ingersoll@sun.com hashlen);
1883*12234Swyllys.ingersoll@sun.com
18843089Swyllys DSA_SIG_free(dsasig);
18853089Swyllys } else {
18863089Swyllys SET_ERROR(kmfh, ERR_get_error());
18873089Swyllys }
188811973Swyllys.ingersoll@sun.com (void) EVP_MD_CTX_cleanup(&ctx);
18893089Swyllys } else {
18903089Swyllys return (KMF_ERR_BAD_PARAMETER);
18913089Swyllys }
18923089Swyllys cleanup:
18933089Swyllys return (ret);
18943089Swyllys }
18953089Swyllys
18963089Swyllys KMF_RETURN
18973089Swyllys /*ARGSUSED*/
OpenSSL_DeleteKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)18985051Swyllys OpenSSL_DeleteKey(KMF_HANDLE_T handle,
18995051Swyllys int numattr, KMF_ATTRIBUTE *attrlist)
19003089Swyllys {
19013089Swyllys KMF_RETURN rv = KMF_OK;
19025051Swyllys KMF_KEY_HANDLE *key;
19035051Swyllys boolean_t destroy = B_TRUE;
19045051Swyllys
19055051Swyllys key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
19063089Swyllys if (key == NULL || key->keyp == NULL)
19073089Swyllys return (KMF_ERR_BAD_PARAMETER);
19083089Swyllys
19095051Swyllys rv = kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr,
19105051Swyllys (void *)&destroy, NULL);
19115051Swyllys if (rv != KMF_OK) {
19125051Swyllys /* "destroy" is optional. Default is TRUE */
19135051Swyllys rv = KMF_OK;
19145051Swyllys }
19155051Swyllys
19163089Swyllys if (key->keyclass != KMF_ASYM_PUB &&
19174315Swyllys key->keyclass != KMF_ASYM_PRI &&
19184315Swyllys key->keyclass != KMF_SYMMETRIC)
19193089Swyllys return (KMF_ERR_BAD_KEY_CLASS);
19203089Swyllys
19213089Swyllys if (key->keyclass == KMF_SYMMETRIC) {
19225051Swyllys kmf_free_raw_sym_key((KMF_RAW_SYM_KEY *)key->keyp);
19233089Swyllys key->keyp = NULL;
19243089Swyllys } else {
19253089Swyllys if (key->keyp != NULL) {
19263089Swyllys EVP_PKEY_free(key->keyp);
19273089Swyllys key->keyp = NULL;
19283089Swyllys }
19293089Swyllys }
19303089Swyllys
19313089Swyllys if (key->keylabel != NULL) {
19323089Swyllys EVP_PKEY *pkey = NULL;
19333089Swyllys /* If the file exists, make sure it is a proper key. */
19343089Swyllys pkey = openssl_load_key(handle, key->keylabel);
19353089Swyllys if (pkey == NULL) {
19365536Swyllys if (key->keylabel != NULL) {
19375536Swyllys free(key->keylabel);
19385536Swyllys key->keylabel = NULL;
19395536Swyllys }
19403089Swyllys return (KMF_ERR_KEY_NOT_FOUND);
19413089Swyllys }
19423089Swyllys EVP_PKEY_free(pkey);
19433089Swyllys
19443089Swyllys if (destroy) {
19453089Swyllys if (unlink(key->keylabel) != 0) {
19463089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
19473089Swyllys SET_SYS_ERROR(kmfh, errno);
19483089Swyllys rv = KMF_ERR_INTERNAL;
19493089Swyllys }
19503089Swyllys }
19513089Swyllys if (key->keylabel != NULL) {
19523089Swyllys free(key->keylabel);
19533089Swyllys key->keylabel = NULL;
19543089Swyllys }
19553089Swyllys }
19563089Swyllys return (rv);
19573089Swyllys }
19583089Swyllys
19593089Swyllys KMF_RETURN
OpenSSL_GetErrorString(KMF_HANDLE_T handle,char ** msgstr)19603089Swyllys OpenSSL_GetErrorString(KMF_HANDLE_T handle, char **msgstr)
19613089Swyllys {
19623089Swyllys KMF_RETURN ret = KMF_OK;
19633089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
19643089Swyllys char str[256]; /* OpenSSL needs at least 120 byte buffer */
19653089Swyllys
19663089Swyllys ERR_error_string_n(kmfh->lasterr.errcode, str, sizeof (str));
19673089Swyllys if (strlen(str)) {
19683089Swyllys *msgstr = (char *)strdup(str);
19693089Swyllys if ((*msgstr) == NULL)
19703089Swyllys ret = KMF_ERR_MEMORY;
19713089Swyllys } else {
19723089Swyllys *msgstr = NULL;
19733089Swyllys }
19743089Swyllys
19753089Swyllys return (ret);
19763089Swyllys }
19773089Swyllys
19783089Swyllys static int
ext2NID(int kmfext)19793089Swyllys ext2NID(int kmfext)
19803089Swyllys {
19813089Swyllys switch (kmfext) {
19823089Swyllys case KMF_X509_EXT_KEY_USAGE:
19833089Swyllys return (NID_key_usage);
19843089Swyllys case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD:
19853089Swyllys return (NID_private_key_usage_period);
19863089Swyllys case KMF_X509_EXT_CERT_POLICIES:
19873089Swyllys return (NID_certificate_policies);
19883089Swyllys case KMF_X509_EXT_SUBJ_ALTNAME:
19893089Swyllys return (NID_subject_alt_name);
19903089Swyllys case KMF_X509_EXT_ISSUER_ALTNAME:
19913089Swyllys return (NID_issuer_alt_name);
19923089Swyllys case KMF_X509_EXT_BASIC_CONSTRAINTS:
19933089Swyllys return (NID_basic_constraints);
19943089Swyllys case KMF_X509_EXT_EXT_KEY_USAGE:
19953089Swyllys return (NID_ext_key_usage);
19963089Swyllys case KMF_X509_EXT_AUTH_KEY_ID:
19973089Swyllys return (NID_authority_key_identifier);
19983089Swyllys case KMF_X509_EXT_CRL_DIST_POINTS:
19993089Swyllys return (NID_crl_distribution_points);
20003089Swyllys case KMF_X509_EXT_SUBJ_KEY_ID:
20013089Swyllys return (NID_subject_key_identifier);
20023089Swyllys case KMF_X509_EXT_POLICY_MAPPINGS:
20033089Swyllys return (OBJ_sn2nid("policyMappings"));
20043089Swyllys case KMF_X509_EXT_NAME_CONSTRAINTS:
20053089Swyllys return (OBJ_sn2nid("nameConstraints"));
20063089Swyllys case KMF_X509_EXT_POLICY_CONSTRAINTS:
20073089Swyllys return (OBJ_sn2nid("policyConstraints"));
20083089Swyllys case KMF_X509_EXT_INHIBIT_ANY_POLICY:
20093089Swyllys return (OBJ_sn2nid("inhibitAnyPolicy"));
20103089Swyllys case KMF_X509_EXT_FRESHEST_CRL:
20113089Swyllys return (OBJ_sn2nid("freshestCRL"));
20123089Swyllys default:
20133089Swyllys return (NID_undef);
20143089Swyllys }
20153089Swyllys }
20163089Swyllys
20173089Swyllys KMF_RETURN
OpenSSL_CertGetPrintable(KMF_HANDLE_T handle,const KMF_DATA * pcert,KMF_PRINTABLE_ITEM flag,char * resultStr)20183089Swyllys OpenSSL_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *pcert,
20193089Swyllys KMF_PRINTABLE_ITEM flag, char *resultStr)
20203089Swyllys {
20213089Swyllys KMF_RETURN ret = KMF_OK;
20223089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
20233089Swyllys X509 *xcert = NULL;
20243089Swyllys unsigned char *outbuf = NULL;
20253089Swyllys unsigned char *outbuf_p;
20263089Swyllys char *tmpstr = NULL;
20273089Swyllys int j;
20283089Swyllys int ext_index, nid, len;
20293089Swyllys BIO *mem = NULL;
20303089Swyllys STACK *emlst = NULL;
20313089Swyllys X509_EXTENSION *ex;
20323089Swyllys X509_CINF *ci;
20333089Swyllys
20343089Swyllys if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0) {
20353089Swyllys return (KMF_ERR_BAD_PARAMETER);
20363089Swyllys }
20373089Swyllys
20383089Swyllys /* copy cert data to outbuf */
20393089Swyllys outbuf = malloc(pcert->Length);
20403089Swyllys if (outbuf == NULL) {
20413089Swyllys return (KMF_ERR_MEMORY);
20423089Swyllys }
20433089Swyllys (void) memcpy(outbuf, pcert->Data, pcert->Length);
20443089Swyllys
20453089Swyllys outbuf_p = outbuf; /* use a temp pointer; required by openssl */
20463089Swyllys xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, pcert->Length);
20473089Swyllys if (xcert == NULL) {
20483089Swyllys SET_ERROR(kmfh, ERR_get_error());
20493089Swyllys ret = KMF_ERR_ENCODING;
20503089Swyllys goto out;
20513089Swyllys }
20523089Swyllys
20533089Swyllys mem = BIO_new(BIO_s_mem());
20543089Swyllys if (mem == NULL) {
20553089Swyllys SET_ERROR(kmfh, ERR_get_error());
20563089Swyllys ret = KMF_ERR_MEMORY;
20573089Swyllys goto out;
20583089Swyllys }
20593089Swyllys
20603089Swyllys switch (flag) {
20613089Swyllys case KMF_CERT_ISSUER:
20623089Swyllys (void) X509_NAME_print_ex(mem, X509_get_issuer_name(xcert), 0,
20633089Swyllys XN_FLAG_SEP_CPLUS_SPC);
20643089Swyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
20653089Swyllys break;
20663089Swyllys
20673089Swyllys case KMF_CERT_SUBJECT:
20683089Swyllys (void) X509_NAME_print_ex(mem, X509_get_subject_name(xcert), 0,
20693089Swyllys XN_FLAG_SEP_CPLUS_SPC);
20703089Swyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
20713089Swyllys break;
20723089Swyllys
20733089Swyllys case KMF_CERT_VERSION:
20743089Swyllys tmpstr = i2s_ASN1_INTEGER(NULL, xcert->cert_info->version);
20753089Swyllys (void) strncpy(resultStr, tmpstr, KMF_CERT_PRINTABLE_LEN);
20763089Swyllys OPENSSL_free(tmpstr);
20773089Swyllys len = strlen(resultStr);
20783089Swyllys break;
20793089Swyllys
20803089Swyllys case KMF_CERT_SERIALNUM:
20813089Swyllys if (i2a_ASN1_INTEGER(mem, X509_get_serialNumber(xcert)) > 0) {
20823089Swyllys (void) strcpy(resultStr, "0x");
20833089Swyllys len = BIO_gets(mem, &resultStr[2],
20844315Swyllys KMF_CERT_PRINTABLE_LEN - 2);
20853089Swyllys }
20863089Swyllys break;
20873089Swyllys
20883089Swyllys case KMF_CERT_NOTBEFORE:
20893089Swyllys (void) ASN1_TIME_print(mem, X509_get_notBefore(xcert));
20903089Swyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
20913089Swyllys break;
20923089Swyllys
20933089Swyllys case KMF_CERT_NOTAFTER:
20943089Swyllys (void) ASN1_TIME_print(mem, X509_get_notAfter(xcert));
20953089Swyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
20963089Swyllys break;
20973089Swyllys
20983089Swyllys case KMF_CERT_PUBKEY_DATA:
20993089Swyllys {
21003089Swyllys EVP_PKEY *pkey = X509_get_pubkey(xcert);
21013089Swyllys if (pkey == NULL) {
21023089Swyllys SET_ERROR(kmfh, ERR_get_error());
21033089Swyllys ret = KMF_ERR_ENCODING;
21043089Swyllys goto out;
21053089Swyllys }
21063089Swyllys
21073089Swyllys if (pkey->type == EVP_PKEY_RSA) {
21083089Swyllys (void) BIO_printf(mem,
21094315Swyllys "RSA Public Key: (%d bit)\n",
21104315Swyllys BN_num_bits(pkey->pkey.rsa->n));
21113089Swyllys (void) RSA_print(mem, pkey->pkey.rsa, 0);
21123089Swyllys } else if (pkey->type == EVP_PKEY_DSA) {
21133089Swyllys (void) BIO_printf(mem,
21144315Swyllys "%12sDSA Public Key:\n", "");
21153089Swyllys (void) DSA_print(mem, pkey->pkey.dsa, 0);
21163089Swyllys } else {
21173089Swyllys (void) BIO_printf(mem,
21184315Swyllys "%12sUnknown Public Key:\n", "");
21193089Swyllys }
21203089Swyllys (void) BIO_printf(mem, "\n");
21213089Swyllys EVP_PKEY_free(pkey);
21223089Swyllys }
21233089Swyllys len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
21243089Swyllys break;
21253089Swyllys case KMF_CERT_SIGNATURE_ALG:
21263089Swyllys case KMF_CERT_PUBKEY_ALG:
21273089Swyllys if (flag == KMF_CERT_SIGNATURE_ALG) {
21283089Swyllys len = i2a_ASN1_OBJECT(mem,
21294315Swyllys xcert->sig_alg->algorithm);
21303089Swyllys } else {
21313089Swyllys len = i2a_ASN1_OBJECT(mem,
21324315Swyllys xcert->cert_info->key->algor->algorithm);
21333089Swyllys }
21343089Swyllys
21353089Swyllys if (len > 0) {
21363089Swyllys len = BIO_read(mem, resultStr,
21374315Swyllys KMF_CERT_PRINTABLE_LEN);
21383089Swyllys }
21393089Swyllys break;
21403089Swyllys
21413089Swyllys case KMF_CERT_EMAIL:
21423089Swyllys emlst = X509_get1_email(xcert);
21433089Swyllys for (j = 0; j < sk_num(emlst); j++)
21443089Swyllys (void) BIO_printf(mem, "%s\n", sk_value(emlst, j));
21453089Swyllys
21463089Swyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
21473089Swyllys X509_email_free(emlst);
21483089Swyllys break;
21493089Swyllys case KMF_X509_EXT_ISSUER_ALTNAME:
21503089Swyllys case KMF_X509_EXT_SUBJ_ALTNAME:
21513089Swyllys case KMF_X509_EXT_KEY_USAGE:
21523089Swyllys case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD:
21533089Swyllys case KMF_X509_EXT_CERT_POLICIES:
21543089Swyllys case KMF_X509_EXT_BASIC_CONSTRAINTS:
21553089Swyllys case KMF_X509_EXT_NAME_CONSTRAINTS:
21563089Swyllys case KMF_X509_EXT_POLICY_CONSTRAINTS:
21573089Swyllys case KMF_X509_EXT_EXT_KEY_USAGE:
21583089Swyllys case KMF_X509_EXT_INHIBIT_ANY_POLICY:
21593089Swyllys case KMF_X509_EXT_AUTH_KEY_ID:
21603089Swyllys case KMF_X509_EXT_SUBJ_KEY_ID:
21613089Swyllys case KMF_X509_EXT_POLICY_MAPPINGS:
21623089Swyllys case KMF_X509_EXT_CRL_DIST_POINTS:
21633089Swyllys case KMF_X509_EXT_FRESHEST_CRL:
21643089Swyllys nid = ext2NID(flag);
21653089Swyllys if (nid == NID_undef) {
21663089Swyllys ret = KMF_ERR_EXTENSION_NOT_FOUND;
21673089Swyllys goto out;
21683089Swyllys }
21693089Swyllys ci = xcert->cert_info;
21703089Swyllys
21713089Swyllys ext_index = X509v3_get_ext_by_NID(ci->extensions, nid, -1);
21723089Swyllys if (ext_index == -1) {
21733089Swyllys SET_ERROR(kmfh, ERR_get_error());
21743089Swyllys
21753089Swyllys ret = KMF_ERR_EXTENSION_NOT_FOUND;
21763089Swyllys goto out;
21773089Swyllys }
21783089Swyllys ex = X509v3_get_ext(ci->extensions, ext_index);
21793089Swyllys
21803089Swyllys (void) i2a_ASN1_OBJECT(mem, X509_EXTENSION_get_object(ex));
21813089Swyllys
21823089Swyllys if (BIO_printf(mem, ": %s\n",
21835051Swyllys X509_EXTENSION_get_critical(ex) ? "critical" : "") <= 0) {
21843089Swyllys SET_ERROR(kmfh, ERR_get_error());
21853089Swyllys ret = KMF_ERR_ENCODING;
21863089Swyllys goto out;
21873089Swyllys }
21883089Swyllys if (!X509V3_EXT_print(mem, ex, X509V3_EXT_DUMP_UNKNOWN, 4)) {
21893089Swyllys (void) BIO_printf(mem, "%*s", 4, "");
21903089Swyllys (void) M_ASN1_OCTET_STRING_print(mem, ex->value);
21913089Swyllys }
21923089Swyllys if (BIO_write(mem, "\n", 1) <= 0) {
21933089Swyllys SET_ERROR(kmfh, ERR_get_error());
21943089Swyllys ret = KMF_ERR_ENCODING;
21953089Swyllys goto out;
21963089Swyllys }
21973089Swyllys len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
21983089Swyllys }
21993089Swyllys if (len <= 0) {
22003089Swyllys SET_ERROR(kmfh, ERR_get_error());
22013089Swyllys ret = KMF_ERR_ENCODING;
22023089Swyllys }
22033089Swyllys
22043089Swyllys out:
22053089Swyllys if (outbuf != NULL) {
22063089Swyllys free(outbuf);
22073089Swyllys }
22083089Swyllys
22093089Swyllys if (xcert != NULL) {
22103089Swyllys X509_free(xcert);
22113089Swyllys }
22123089Swyllys
22133089Swyllys if (mem != NULL) {
22143089Swyllys (void) BIO_free(mem);
22153089Swyllys }
22163089Swyllys
22173089Swyllys return (ret);
22183089Swyllys }
22195051Swyllys
22203089Swyllys KMF_RETURN
22213089Swyllys /*ARGSUSED*/
OpenSSL_FindPrikeyByCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)22225051Swyllys OpenSSL_FindPrikeyByCert(KMF_HANDLE_T handle, int numattr,
22235051Swyllys KMF_ATTRIBUTE *attrlist)
22243089Swyllys {
22253089Swyllys KMF_RETURN rv = KMF_OK;
22265051Swyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
22275051Swyllys KMF_KEY_CLASS keyclass = KMF_ASYM_PRI;
22285051Swyllys KMF_KEY_HANDLE *key = NULL;
22295051Swyllys uint32_t numkeys = 1; /* 1 key only */
22305051Swyllys char *dirpath = NULL;
22315051Swyllys char *keyfile = NULL;
22325051Swyllys KMF_ATTRIBUTE new_attrlist[16];
22335051Swyllys int i = 0;
22343089Swyllys
22353089Swyllys /*
22363089Swyllys * This is really just a FindKey operation, reuse the
22373089Swyllys * FindKey function.
22383089Swyllys */
22395051Swyllys kmf_set_attr_at_index(new_attrlist, i,
22405051Swyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
22415051Swyllys i++;
22425051Swyllys
22435051Swyllys kmf_set_attr_at_index(new_attrlist, i,
22445051Swyllys KMF_COUNT_ATTR, &numkeys, sizeof (uint32_t));
22455051Swyllys i++;
22465051Swyllys
22475051Swyllys kmf_set_attr_at_index(new_attrlist, i,
22485051Swyllys KMF_KEYCLASS_ATTR, &keyclass, sizeof (keyclass));
22495051Swyllys i++;
22505051Swyllys
22515051Swyllys key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
22525051Swyllys if (key == NULL) {
22535051Swyllys return (KMF_ERR_BAD_PARAMETER);
22545051Swyllys } else {
22555051Swyllys kmf_set_attr_at_index(new_attrlist, i,
22565051Swyllys KMF_KEY_HANDLE_ATTR, key, sizeof (KMF_KEY_HANDLE));
22575051Swyllys i++;
22585051Swyllys }
22595051Swyllys
22605051Swyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
22615051Swyllys if (dirpath != NULL) {
22625051Swyllys kmf_set_attr_at_index(new_attrlist, i,
22635051Swyllys KMF_DIRPATH_ATTR, dirpath, strlen(dirpath));
22645051Swyllys i++;
22655051Swyllys }
22665051Swyllys
22675051Swyllys keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
22685051Swyllys if (keyfile == NULL)
22695051Swyllys return (KMF_ERR_BAD_PARAMETER);
22705051Swyllys else {
22715051Swyllys kmf_set_attr_at_index(new_attrlist, i,
22725051Swyllys KMF_KEY_FILENAME_ATTR, keyfile, strlen(keyfile));
22735051Swyllys i++;
22745051Swyllys }
22755051Swyllys
22765051Swyllys rv = OpenSSL_FindKey(handle, i, new_attrlist);
22773089Swyllys return (rv);
22783089Swyllys }
22793089Swyllys
22803089Swyllys KMF_RETURN
22813089Swyllys /*ARGSUSED*/
OpenSSL_DecryptData(KMF_HANDLE_T handle,KMF_KEY_HANDLE * key,KMF_OID * AlgOID,KMF_DATA * ciphertext,KMF_DATA * output)22823089Swyllys OpenSSL_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
22833089Swyllys KMF_OID *AlgOID, KMF_DATA *ciphertext,
22843089Swyllys KMF_DATA *output)
22853089Swyllys {
22863089Swyllys KMF_RETURN ret = KMF_OK;
22873089Swyllys RSA *rsa = NULL;
22883089Swyllys unsigned int in_len = 0, out_len = 0;
22893089Swyllys unsigned int total_decrypted = 0, modulus_len = 0;
22903089Swyllys uint8_t *in_data, *out_data;
22913089Swyllys int i, blocks;
22923089Swyllys
22933089Swyllys if (key == NULL || AlgOID == NULL ||
22943089Swyllys ciphertext == NULL || output == NULL ||
22953089Swyllys ciphertext->Data == NULL ||
22963089Swyllys output->Data == NULL)
22973089Swyllys return (KMF_ERR_BAD_PARAMETER);
22983089Swyllys
22993089Swyllys if (key->keyalg == KMF_RSA) {
23003089Swyllys rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)key->keyp);
23013089Swyllys modulus_len = RSA_size(rsa);
23023089Swyllys } else {
23033089Swyllys return (KMF_ERR_BAD_PARAMETER);
23043089Swyllys }
23053089Swyllys
23063089Swyllys blocks = ciphertext->Length/modulus_len;
23073089Swyllys out_data = output->Data;
23083089Swyllys in_data = ciphertext->Data;
23093089Swyllys out_len = modulus_len - 11;
23103089Swyllys in_len = modulus_len;
23113089Swyllys
23123089Swyllys for (i = 0; i < blocks; i++) {
23133089Swyllys out_len = RSA_private_decrypt(in_len,
23144315Swyllys in_data, out_data, rsa, RSA_PKCS1_PADDING);
23153089Swyllys
23163089Swyllys if (out_len == 0) {
23173089Swyllys ret = KMF_ERR_INTERNAL;
23183089Swyllys goto cleanup;
23193089Swyllys }
23203089Swyllys
23213089Swyllys out_data += out_len;
23223089Swyllys total_decrypted += out_len;
23233089Swyllys in_data += in_len;
23243089Swyllys }
23253089Swyllys
23263089Swyllys output->Length = total_decrypted;
23273089Swyllys
23283089Swyllys cleanup:
23293089Swyllys RSA_free(rsa);
23303089Swyllys if (ret != KMF_OK)
23313089Swyllys output->Length = 0;
23323089Swyllys
23333089Swyllys return (ret);
23343089Swyllys
23353089Swyllys }
23363089Swyllys
23373089Swyllys /*
23383089Swyllys * This function will create a certid from issuer_cert and user_cert.
23393089Swyllys * The caller should use OCSP_CERTID_free(OCSP_CERTID *) to deallocate
23403089Swyllys * certid memory after use.
23413089Swyllys */
23423089Swyllys static KMF_RETURN
create_certid(KMF_HANDLE_T handle,const KMF_DATA * issuer_cert,const KMF_DATA * user_cert,OCSP_CERTID ** certid)23433089Swyllys create_certid(KMF_HANDLE_T handle, const KMF_DATA *issuer_cert,
23443089Swyllys const KMF_DATA *user_cert, OCSP_CERTID **certid)
23453089Swyllys {
23463089Swyllys KMF_RETURN ret = KMF_OK;
23473089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
23483089Swyllys X509 *issuer = NULL;
23493089Swyllys X509 *cert = NULL;
23503089Swyllys unsigned char *ptmp;
23513089Swyllys
23523089Swyllys if (issuer_cert == NULL || user_cert == NULL) {
23533089Swyllys return (KMF_ERR_BAD_PARAMETER);
23543089Swyllys }
23553089Swyllys
23563089Swyllys /* convert the DER-encoded issuer cert to an internal X509 */
23573089Swyllys ptmp = issuer_cert->Data;
23583089Swyllys issuer = d2i_X509(NULL, (const uchar_t **)&ptmp,
23594315Swyllys issuer_cert->Length);
23603089Swyllys if (issuer == NULL) {
23613089Swyllys SET_ERROR(kmfh, ERR_get_error());
23623089Swyllys ret = KMF_ERR_OCSP_BAD_ISSUER;
23633089Swyllys goto end;
23643089Swyllys }
23653089Swyllys
23663089Swyllys /* convert the DER-encoded user cert to an internal X509 */
23673089Swyllys ptmp = user_cert->Data;
23683089Swyllys cert = d2i_X509(NULL, (const uchar_t **)&ptmp,
23694315Swyllys user_cert->Length);
23703089Swyllys if (cert == NULL) {
23713089Swyllys SET_ERROR(kmfh, ERR_get_error());
23723089Swyllys
23733089Swyllys ret = KMF_ERR_OCSP_BAD_CERT;
23743089Swyllys goto end;
23753089Swyllys }
23763089Swyllys
23773089Swyllys /* create a CERTID */
23783089Swyllys *certid = OCSP_cert_to_id(NULL, cert, issuer);
23793089Swyllys if (*certid == NULL) {
23803089Swyllys SET_ERROR(kmfh, ERR_get_error());
23813089Swyllys ret = KMF_ERR_OCSP_CERTID;
23823089Swyllys goto end;
23833089Swyllys }
23843089Swyllys
23853089Swyllys end:
23863089Swyllys if (issuer != NULL) {
23873089Swyllys X509_free(issuer);
23883089Swyllys }
23893089Swyllys
23903089Swyllys if (cert != NULL) {
23913089Swyllys X509_free(cert);
23923089Swyllys }
23933089Swyllys
23943089Swyllys return (ret);
23953089Swyllys }
23963089Swyllys
23973089Swyllys KMF_RETURN
OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)23985051Swyllys OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle,
23995051Swyllys int numattr, KMF_ATTRIBUTE *attrlist)
24003089Swyllys {
24013089Swyllys KMF_RETURN ret = KMF_OK;
24023089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
24033089Swyllys OCSP_CERTID *id = NULL;
24043089Swyllys OCSP_REQUEST *req = NULL;
24053089Swyllys BIO *derbio = NULL;
24065051Swyllys char *reqfile;
24075051Swyllys KMF_DATA *issuer_cert;
24085051Swyllys KMF_DATA *user_cert;
24095051Swyllys
24105051Swyllys user_cert = kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR,
24115051Swyllys attrlist, numattr);
24125051Swyllys if (user_cert == NULL)
24133089Swyllys return (KMF_ERR_BAD_PARAMETER);
24145051Swyllys
24155051Swyllys issuer_cert = kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR,
24165051Swyllys attrlist, numattr);
24175051Swyllys if (issuer_cert == NULL)
24185051Swyllys return (KMF_ERR_BAD_PARAMETER);
24195051Swyllys
24205051Swyllys reqfile = kmf_get_attr_ptr(KMF_OCSP_REQUEST_FILENAME_ATTR,
24215051Swyllys attrlist, numattr);
24225051Swyllys if (reqfile == NULL)
24235051Swyllys return (KMF_ERR_BAD_PARAMETER);
24245051Swyllys
24255051Swyllys ret = create_certid(handle, issuer_cert, user_cert, &id);
24263089Swyllys if (ret != KMF_OK) {
24273089Swyllys return (ret);
24283089Swyllys }
24293089Swyllys
24303089Swyllys /* Create an OCSP request */
24313089Swyllys req = OCSP_REQUEST_new();
24323089Swyllys if (req == NULL) {
24333089Swyllys SET_ERROR(kmfh, ERR_get_error());
24343089Swyllys ret = KMF_ERR_OCSP_CREATE_REQUEST;
24353089Swyllys goto end;
24363089Swyllys }
24373089Swyllys
24383089Swyllys if (!OCSP_request_add0_id(req, id)) {
24393089Swyllys ret = KMF_ERR_OCSP_CREATE_REQUEST;
24403089Swyllys goto end;
24413089Swyllys }
24423089Swyllys
24433089Swyllys /* Write the request to the output file with DER encoding */
24443089Swyllys derbio = BIO_new_file(reqfile, "wb");
24453089Swyllys if (!derbio) {
24463089Swyllys SET_ERROR(kmfh, ERR_get_error());
24473089Swyllys ret = KMF_ERR_OPEN_FILE;
24483089Swyllys goto end;
24493089Swyllys }
24503089Swyllys if (i2d_OCSP_REQUEST_bio(derbio, req) <= 0) {
24513089Swyllys ret = KMF_ERR_ENCODING;
24523089Swyllys }
24533089Swyllys
24543089Swyllys end:
24553089Swyllys /*
245611973Swyllys.ingersoll@sun.com * We don't need to free "id" explicitely, because OCSP_REQUEST_free()
245711673Sopensolaris@drydog.com * will also deallocate certid's space.
24583089Swyllys */
24593089Swyllys if (req != NULL) {
24603089Swyllys OCSP_REQUEST_free(req);
24613089Swyllys }
24623089Swyllys
24633089Swyllys if (derbio != NULL) {
24643089Swyllys (void) BIO_free(derbio);
24653089Swyllys }
24663089Swyllys
24673089Swyllys return (ret);
24683089Swyllys }
24693089Swyllys
24703089Swyllys /* ocsp_find_signer_sk() is copied from openssl source */
ocsp_find_signer_sk(STACK_OF (X509)* certs,OCSP_RESPID * id)24713089Swyllys static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id)
24723089Swyllys {
24733089Swyllys int i;
24743089Swyllys unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash;
24753089Swyllys
24763089Swyllys /* Easy if lookup by name */
24773089Swyllys if (id->type == V_OCSP_RESPID_NAME)
24783089Swyllys return (X509_find_by_subject(certs, id->value.byName));
24793089Swyllys
24803089Swyllys /* Lookup by key hash */
24813089Swyllys
24823089Swyllys /* If key hash isn't SHA1 length then forget it */
24833089Swyllys if (id->value.byKey->length != SHA_DIGEST_LENGTH)
24843089Swyllys return (NULL);
24853089Swyllys
24863089Swyllys keyhash = id->value.byKey->data;
24873089Swyllys /* Calculate hash of each key and compare */
24883089Swyllys for (i = 0; i < sk_X509_num(certs); i++) {
248911673Sopensolaris@drydog.com /* LINTED E_BAD_PTR_CAST_ALIGN */
24903089Swyllys X509 *x = sk_X509_value(certs, i);
24915536Swyllys /* Use pubkey_digest to get the key ID value */
24923089Swyllys (void) X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL);
24933089Swyllys if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH))
24943089Swyllys return (x);
24953089Swyllys }
24963089Swyllys return (NULL);
24973089Swyllys }
24983089Swyllys
24993089Swyllys /* ocsp_find_signer() is copied from openssl source */
250011673Sopensolaris@drydog.com /* ARGSUSED2 */
25013089Swyllys static int
ocsp_find_signer(X509 ** psigner,OCSP_BASICRESP * bs,STACK_OF (X509)* certs,X509_STORE * st,unsigned long flags)25023089Swyllys ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
25033089Swyllys X509_STORE *st, unsigned long flags)
25043089Swyllys {
25053089Swyllys X509 *signer;
25063089Swyllys OCSP_RESPID *rid = bs->tbsResponseData->responderId;
25073089Swyllys if ((signer = ocsp_find_signer_sk(certs, rid))) {
25083089Swyllys *psigner = signer;
25093089Swyllys return (2);
25103089Swyllys }
25113089Swyllys if (!(flags & OCSP_NOINTERN) &&
25123089Swyllys (signer = ocsp_find_signer_sk(bs->certs, rid))) {
25133089Swyllys *psigner = signer;
25143089Swyllys return (1);
25153089Swyllys }
25163089Swyllys /* Maybe lookup from store if by subject name */
25173089Swyllys
25183089Swyllys *psigner = NULL;
25193089Swyllys return (0);
25203089Swyllys }
25213089Swyllys
25223089Swyllys /*
25233089Swyllys * This function will verify the signature of a basic response, using
25243089Swyllys * the public key from the OCSP responder certificate.
25253089Swyllys */
25263089Swyllys static KMF_RETURN
check_response_signature(KMF_HANDLE_T handle,OCSP_BASICRESP * bs,KMF_DATA * signer_cert,KMF_DATA * issuer_cert)25273089Swyllys check_response_signature(KMF_HANDLE_T handle, OCSP_BASICRESP *bs,
25283089Swyllys KMF_DATA *signer_cert, KMF_DATA *issuer_cert)
25293089Swyllys {
25303089Swyllys KMF_RETURN ret = KMF_OK;
25313089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
25323089Swyllys STACK_OF(X509) *cert_stack = NULL;
25333089Swyllys X509 *signer = NULL;
25343089Swyllys X509 *issuer = NULL;
25353089Swyllys EVP_PKEY *skey = NULL;
25363089Swyllys unsigned char *ptmp;
25373089Swyllys
25383089Swyllys
25393089Swyllys if (bs == NULL || issuer_cert == NULL)
25403089Swyllys return (KMF_ERR_BAD_PARAMETER);
25413089Swyllys
25423089Swyllys /*
25433089Swyllys * Find the certificate that signed the basic response.
25443089Swyllys *
25453089Swyllys * If signer_cert is not NULL, we will use that as the signer cert.
25463089Swyllys * Otherwise, we will check if the issuer cert is actually the signer.
25473089Swyllys * If we still do not find a signer, we will look for it from the
25483089Swyllys * certificate list came with the response file.
25493089Swyllys */
25503089Swyllys if (signer_cert != NULL) {
25513089Swyllys ptmp = signer_cert->Data;
25523089Swyllys signer = d2i_X509(NULL, (const uchar_t **)&ptmp,
25533089Swyllys signer_cert->Length);
25543089Swyllys if (signer == NULL) {
25553089Swyllys SET_ERROR(kmfh, ERR_get_error());
25563089Swyllys ret = KMF_ERR_OCSP_BAD_SIGNER;
25573089Swyllys goto end;
25583089Swyllys }
25593089Swyllys } else {
25603089Swyllys /*
25613089Swyllys * Convert the issuer cert into X509 and push it into a
25623089Swyllys * stack to be used by ocsp_find_signer().
25633089Swyllys */
25643089Swyllys ptmp = issuer_cert->Data;
25653089Swyllys issuer = d2i_X509(NULL, (const uchar_t **)&ptmp,
25664315Swyllys issuer_cert->Length);
25673089Swyllys if (issuer == NULL) {
25683089Swyllys SET_ERROR(kmfh, ERR_get_error());
25693089Swyllys ret = KMF_ERR_OCSP_BAD_ISSUER;
25703089Swyllys goto end;
25713089Swyllys }
25723089Swyllys
25733089Swyllys if ((cert_stack = sk_X509_new_null()) == NULL) {
25743089Swyllys ret = KMF_ERR_INTERNAL;
25753089Swyllys goto end;
25763089Swyllys }
25773089Swyllys
25783089Swyllys if (sk_X509_push(cert_stack, issuer) == NULL) {
25793089Swyllys ret = KMF_ERR_INTERNAL;
25803089Swyllys goto end;
25813089Swyllys }
25823089Swyllys
25833089Swyllys ret = ocsp_find_signer(&signer, bs, cert_stack, NULL, 0);
25843089Swyllys if (!ret) {
25853089Swyllys /* can not find the signer */
25863089Swyllys ret = KMF_ERR_OCSP_BAD_SIGNER;
25873089Swyllys goto end;
25883089Swyllys }
25893089Swyllys }
25903089Swyllys
25913089Swyllys /* Verify the signature of the response */
25923089Swyllys skey = X509_get_pubkey(signer);
25933089Swyllys if (skey == NULL) {
25943089Swyllys ret = KMF_ERR_OCSP_BAD_SIGNER;
25953089Swyllys goto end;
25963089Swyllys }
25973089Swyllys
25983089Swyllys ret = OCSP_BASICRESP_verify(bs, skey, 0);
25993089Swyllys if (ret == 0) {
26003089Swyllys ret = KMF_ERR_OCSP_RESPONSE_SIGNATURE;
26013089Swyllys goto end;
26023089Swyllys }
26033089Swyllys
26043089Swyllys end:
26053089Swyllys if (issuer != NULL) {
26063089Swyllys X509_free(issuer);
26073089Swyllys }
26083089Swyllys
26093089Swyllys if (signer != NULL) {
26103089Swyllys X509_free(signer);
26113089Swyllys }
26123089Swyllys
26133089Swyllys if (skey != NULL) {
26143089Swyllys EVP_PKEY_free(skey);
26153089Swyllys }
26163089Swyllys
26173089Swyllys if (cert_stack != NULL) {
26183089Swyllys sk_X509_free(cert_stack);
26193089Swyllys }
26203089Swyllys
26213089Swyllys return (ret);
26223089Swyllys }
26233089Swyllys
26243089Swyllys
26253089Swyllys
26263089Swyllys KMF_RETURN
OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)26273089Swyllys OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle,
26285051Swyllys int numattr, KMF_ATTRIBUTE *attrlist)
26293089Swyllys {
26303089Swyllys KMF_RETURN ret = KMF_OK;
26313089Swyllys BIO *derbio = NULL;
26323089Swyllys OCSP_RESPONSE *resp = NULL;
26333089Swyllys OCSP_BASICRESP *bs = NULL;
26343089Swyllys OCSP_CERTID *id = NULL;
26353089Swyllys OCSP_SINGLERESP *single = NULL;
26363089Swyllys ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
26373089Swyllys int index, status, reason;
26385051Swyllys KMF_DATA *issuer_cert;
26395051Swyllys KMF_DATA *user_cert;
26405051Swyllys KMF_DATA *signer_cert;
26415051Swyllys KMF_DATA *response;
26425051Swyllys int *response_reason, *response_status, *cert_status;
26435051Swyllys boolean_t ignore_response_sign = B_FALSE; /* default is FALSE */
26445051Swyllys uint32_t response_lifetime;
26455051Swyllys
26465051Swyllys issuer_cert = kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR,
26475051Swyllys attrlist, numattr);
26485051Swyllys if (issuer_cert == NULL)
26495051Swyllys return (KMF_ERR_BAD_PARAMETER);
26505051Swyllys
26515051Swyllys user_cert = kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR,
26525051Swyllys attrlist, numattr);
26535051Swyllys if (user_cert == NULL)
26543089Swyllys return (KMF_ERR_BAD_PARAMETER);
26555051Swyllys
26565051Swyllys response = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_DATA_ATTR,
26575051Swyllys attrlist, numattr);
26585051Swyllys if (response == NULL)
26595051Swyllys return (KMF_ERR_BAD_PARAMETER);
26605051Swyllys
26615051Swyllys response_status = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_STATUS_ATTR,
26625051Swyllys attrlist, numattr);
26635051Swyllys if (response_status == NULL)
26643089Swyllys return (KMF_ERR_BAD_PARAMETER);
26655051Swyllys
26665051Swyllys response_reason = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_REASON_ATTR,
26675051Swyllys attrlist, numattr);
26685051Swyllys if (response_reason == NULL)
26695051Swyllys return (KMF_ERR_BAD_PARAMETER);
26705051Swyllys
26715051Swyllys cert_status = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_CERT_STATUS_ATTR,
26725051Swyllys attrlist, numattr);
26735051Swyllys if (cert_status == NULL)
26745051Swyllys return (KMF_ERR_BAD_PARAMETER);
26753089Swyllys
26763089Swyllys /* Read in the response */
26775051Swyllys derbio = BIO_new_mem_buf(response->Data, response->Length);
26783089Swyllys if (!derbio) {
26793089Swyllys ret = KMF_ERR_MEMORY;
26803089Swyllys return (ret);
26813089Swyllys }
26823089Swyllys
26833089Swyllys resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
26843089Swyllys if (resp == NULL) {
26853089Swyllys ret = KMF_ERR_OCSP_MALFORMED_RESPONSE;
26863089Swyllys goto end;
26873089Swyllys }
26883089Swyllys
26893089Swyllys /* Check the response status */
26903089Swyllys status = OCSP_response_status(resp);
26915051Swyllys *response_status = status;
26923089Swyllys if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
26933089Swyllys ret = KMF_ERR_OCSP_RESPONSE_STATUS;
26943089Swyllys goto end;
26953089Swyllys }
26963089Swyllys
26973089Swyllys #ifdef DEBUG
26983089Swyllys printf("Successfully checked the response file status.\n");
26993089Swyllys #endif /* DEBUG */
27003089Swyllys
27013089Swyllys /* Extract basic response */
27023089Swyllys bs = OCSP_response_get1_basic(resp);
27033089Swyllys if (bs == NULL) {
27043089Swyllys ret = KMF_ERR_OCSP_NO_BASIC_RESPONSE;
27053089Swyllys goto end;
27063089Swyllys }
27073089Swyllys
27083089Swyllys #ifdef DEBUG
27093089Swyllys printf("Successfully retrieved the basic response.\n");
27103089Swyllys #endif /* DEBUG */
27113089Swyllys
27123089Swyllys /* Check the basic response signature if required */
27135051Swyllys ret = kmf_get_attr(KMF_IGNORE_RESPONSE_SIGN_ATTR, attrlist, numattr,
27145051Swyllys (void *)&ignore_response_sign, NULL);
27155051Swyllys if (ret != KMF_OK)
27165051Swyllys ret = KMF_OK;
27175051Swyllys
27185051Swyllys signer_cert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR,
27195051Swyllys attrlist, numattr);
27205051Swyllys
27215051Swyllys if (ignore_response_sign == B_FALSE) {
27223089Swyllys ret = check_response_signature(handle, bs,
27235051Swyllys signer_cert, issuer_cert);
27243089Swyllys if (ret != KMF_OK)
27253089Swyllys goto end;
27263089Swyllys }
27273089Swyllys
27283089Swyllys #ifdef DEBUG
27293089Swyllys printf("Successfully verified the response signature.\n");
27303089Swyllys #endif /* DEBUG */
27313089Swyllys
27323089Swyllys /* Create a certid for the certificate in question */
27335051Swyllys ret = create_certid(handle, issuer_cert, user_cert, &id);
27343089Swyllys if (ret != KMF_OK) {
27353089Swyllys ret = KMF_ERR_OCSP_CERTID;
27363089Swyllys goto end;
27373089Swyllys }
27383089Swyllys
27393089Swyllys #ifdef DEBUG
27403089Swyllys printf("successfully created a certid for the cert.\n");
27413089Swyllys #endif /* DEBUG */
27423089Swyllys
27433089Swyllys /* Find the index of the single response for the certid */
27443089Swyllys index = OCSP_resp_find(bs, id, -1);
27453089Swyllys if (index < 0) {
27463089Swyllys /* cound not find this certificate in the response */
27473089Swyllys ret = KMF_ERR_OCSP_UNKNOWN_CERT;
27483089Swyllys goto end;
27493089Swyllys }
27503089Swyllys
27513089Swyllys #ifdef DEBUG
27523089Swyllys printf("Successfully found the single response index for the cert.\n");
27533089Swyllys #endif /* DEBUG */
27543089Swyllys
27553089Swyllys /* Retrieve the single response and get the cert status */
27563089Swyllys single = OCSP_resp_get0(bs, index);
27573089Swyllys status = OCSP_single_get0_status(single, &reason, &rev, &thisupd,
27583089Swyllys &nextupd);
27593089Swyllys if (status == V_OCSP_CERTSTATUS_GOOD) {
27605051Swyllys *cert_status = OCSP_GOOD;
27613089Swyllys } else if (status == V_OCSP_CERTSTATUS_UNKNOWN) {
27625051Swyllys *cert_status = OCSP_UNKNOWN;
27633089Swyllys } else { /* revoked */
27645051Swyllys *cert_status = OCSP_REVOKED;
27655051Swyllys *response_reason = reason;
27663089Swyllys }
27673089Swyllys ret = KMF_OK;
27683089Swyllys
27695051Swyllys /* resp. time is optional, so we don't care about the return code. */
27705051Swyllys (void) kmf_get_attr(KMF_RESPONSE_LIFETIME_ATTR, attrlist, numattr,
27715051Swyllys (void *)&response_lifetime, NULL);
27725051Swyllys
27733089Swyllys if (!OCSP_check_validity(thisupd, nextupd, 300,
27745051Swyllys response_lifetime)) {
27753089Swyllys ret = KMF_ERR_OCSP_STATUS_TIME_INVALID;
27763089Swyllys goto end;
27773089Swyllys }
27783089Swyllys
27793089Swyllys #ifdef DEBUG
27803089Swyllys printf("Successfully verify the time.\n");
27813089Swyllys #endif /* DEBUG */
27823089Swyllys
27833089Swyllys end:
27843089Swyllys if (derbio != NULL)
27853089Swyllys (void) BIO_free(derbio);
27863089Swyllys
27873089Swyllys if (resp != NULL)
27883089Swyllys OCSP_RESPONSE_free(resp);
27893089Swyllys
27903089Swyllys if (bs != NULL)
27913089Swyllys OCSP_BASICRESP_free(bs);
27923089Swyllys
27933089Swyllys if (id != NULL)
27943089Swyllys OCSP_CERTID_free(id);
27953089Swyllys
27963089Swyllys return (ret);
27973089Swyllys }
27983089Swyllys
27993089Swyllys static KMF_RETURN
fetch_key(KMF_HANDLE_T handle,char * path,KMF_KEY_CLASS keyclass,KMF_KEY_HANDLE * key)28003089Swyllys fetch_key(KMF_HANDLE_T handle, char *path,
28013089Swyllys KMF_KEY_CLASS keyclass, KMF_KEY_HANDLE *key)
28023089Swyllys {
28033089Swyllys KMF_RETURN rv = KMF_OK;
28045051Swyllys EVP_PKEY *pkey = NULL;
28053089Swyllys KMF_RAW_SYM_KEY *rkey = NULL;
28063089Swyllys
28073089Swyllys if (keyclass == KMF_ASYM_PRI ||
28083089Swyllys keyclass == KMF_ASYM_PUB) {
28093089Swyllys pkey = openssl_load_key(handle, path);
28103089Swyllys if (pkey == NULL) {
28113089Swyllys return (KMF_ERR_KEY_NOT_FOUND);
28123089Swyllys }
28133089Swyllys if (key != NULL) {
28143089Swyllys if (pkey->type == EVP_PKEY_RSA)
28153089Swyllys key->keyalg = KMF_RSA;
28163089Swyllys else if (pkey->type == EVP_PKEY_DSA)
28173089Swyllys key->keyalg = KMF_DSA;
28183089Swyllys
28193089Swyllys key->kstype = KMF_KEYSTORE_OPENSSL;
28203089Swyllys key->keyclass = keyclass;
28213089Swyllys key->keyp = (void *)pkey;
28223089Swyllys key->israw = FALSE;
28235536Swyllys if (path != NULL &&
28245536Swyllys ((key->keylabel = strdup(path)) == NULL)) {
28255536Swyllys EVP_PKEY_free(pkey);
28265536Swyllys return (KMF_ERR_MEMORY);
28275536Swyllys }
28283089Swyllys } else {
28293089Swyllys EVP_PKEY_free(pkey);
28303089Swyllys pkey = NULL;
28313089Swyllys }
28323089Swyllys } else if (keyclass == KMF_SYMMETRIC) {
28333089Swyllys KMF_ENCODE_FORMAT fmt;
28343089Swyllys /*
28353089Swyllys * If the file is a recognized format,
28363089Swyllys * then it is NOT a symmetric key.
28373089Swyllys */
28385051Swyllys rv = kmf_get_file_format(path, &fmt);
28393089Swyllys if (rv == KMF_OK || fmt != 0) {
28403089Swyllys return (KMF_ERR_KEY_NOT_FOUND);
28413089Swyllys } else if (rv == KMF_ERR_ENCODING) {
28423089Swyllys /*
28433089Swyllys * If we don't know the encoding,
28443089Swyllys * it is probably a symmetric key.
28453089Swyllys */
28463089Swyllys rv = KMF_OK;
28475051Swyllys } else if (rv == KMF_ERR_OPEN_FILE) {
28485051Swyllys return (KMF_ERR_KEY_NOT_FOUND);
28493089Swyllys }
28503089Swyllys
28513089Swyllys if (key != NULL) {
28523089Swyllys KMF_DATA keyvalue;
28533089Swyllys rkey = malloc(sizeof (KMF_RAW_SYM_KEY));
28543089Swyllys if (rkey == NULL) {
28553089Swyllys rv = KMF_ERR_MEMORY;
28563089Swyllys goto out;
28573089Swyllys }
28583089Swyllys
28593089Swyllys (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY));
28605051Swyllys rv = kmf_read_input_file(handle, path, &keyvalue);
28613089Swyllys if (rv != KMF_OK)
28623089Swyllys goto out;
28633089Swyllys
28643089Swyllys rkey->keydata.len = keyvalue.Length;
28653089Swyllys rkey->keydata.val = keyvalue.Data;
28663089Swyllys
28673089Swyllys key->kstype = KMF_KEYSTORE_OPENSSL;
28683089Swyllys key->keyclass = keyclass;
28693089Swyllys key->israw = TRUE;
28703089Swyllys key->keyp = (void *)rkey;
28715536Swyllys if (path != NULL &&
28725536Swyllys ((key->keylabel = strdup(path)) == NULL)) {
28735536Swyllys rv = KMF_ERR_MEMORY;
28745536Swyllys }
28753089Swyllys }
28763089Swyllys }
28773089Swyllys out:
28783089Swyllys if (rv != KMF_OK) {
28793089Swyllys if (rkey != NULL) {
28805051Swyllys kmf_free_raw_sym_key(rkey);
28813089Swyllys }
28823089Swyllys if (pkey != NULL)
28833089Swyllys EVP_PKEY_free(pkey);
28843089Swyllys
28853089Swyllys if (key != NULL) {
28863089Swyllys key->keyalg = KMF_KEYALG_NONE;
28873089Swyllys key->keyclass = KMF_KEYCLASS_NONE;
28883089Swyllys key->keyp = NULL;
28893089Swyllys }
28903089Swyllys }
28913089Swyllys
28923089Swyllys return (rv);
28933089Swyllys }
28943089Swyllys
28953089Swyllys KMF_RETURN
OpenSSL_FindKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)28965051Swyllys OpenSSL_FindKey(KMF_HANDLE_T handle,
28975051Swyllys int numattr, KMF_ATTRIBUTE *attrlist)
28983089Swyllys {
28993089Swyllys KMF_RETURN rv = KMF_OK;
29003089Swyllys char *fullpath = NULL;
29014025Swyllys uint32_t maxkeys;
29025051Swyllys KMF_KEY_HANDLE *key;
29035051Swyllys uint32_t *numkeys;
29045051Swyllys KMF_KEY_CLASS keyclass;
29055051Swyllys KMF_RAW_KEY_DATA *rawkey;
29065051Swyllys char *dirpath;
29075051Swyllys char *keyfile;
29085051Swyllys
29095051Swyllys if (handle == NULL)
29105051Swyllys return (KMF_ERR_BAD_PARAMETER);
29115051Swyllys
29125051Swyllys numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
29135051Swyllys if (numkeys == NULL)
29143089Swyllys return (KMF_ERR_BAD_PARAMETER);
29153089Swyllys
29165051Swyllys rv = kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr,
29175051Swyllys (void *)&keyclass, NULL);
29185051Swyllys if (rv != KMF_OK)
29195051Swyllys return (KMF_ERR_BAD_PARAMETER);
29205051Swyllys
29215051Swyllys if (keyclass != KMF_ASYM_PUB &&
29225051Swyllys keyclass != KMF_ASYM_PRI &&
29235051Swyllys keyclass != KMF_SYMMETRIC)
29243089Swyllys return (KMF_ERR_BAD_KEY_CLASS);
29253089Swyllys
29265051Swyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
29275051Swyllys keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
29285051Swyllys
29295051Swyllys fullpath = get_fullpath(dirpath, keyfile);
29303089Swyllys
29313089Swyllys if (fullpath == NULL)
29323089Swyllys return (KMF_ERR_BAD_PARAMETER);
29333089Swyllys
29344025Swyllys maxkeys = *numkeys;
29354025Swyllys if (maxkeys == 0)
29364025Swyllys maxkeys = 0xFFFFFFFF;
29373089Swyllys *numkeys = 0;
29383089Swyllys
29395051Swyllys key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
29405051Swyllys /* it is okay to have "keys" contains NULL */
29415051Swyllys
29425051Swyllys /*
29435051Swyllys * The caller may want a list of the raw key data as well.
29445051Swyllys * Useful for importing keys from a file into other keystores.
29455051Swyllys */
29465051Swyllys rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attrlist, numattr);
29475051Swyllys
29483089Swyllys if (isdir(fullpath)) {
29493089Swyllys DIR *dirp;
29503089Swyllys struct dirent *dp;
29513089Swyllys int n = 0;
29523089Swyllys
29533089Swyllys /* open all files in the directory and attempt to read them */
29543089Swyllys if ((dirp = opendir(fullpath)) == NULL) {
29553089Swyllys return (KMF_ERR_BAD_PARAMETER);
29563089Swyllys }
29573089Swyllys rewinddir(dirp);
29584025Swyllys while ((dp = readdir(dirp)) != NULL && n < maxkeys) {
29593089Swyllys if (strcmp(dp->d_name, ".") &&
29603089Swyllys strcmp(dp->d_name, "..")) {
29613089Swyllys char *fname;
29623089Swyllys
29633089Swyllys fname = get_fullpath(fullpath,
29644315Swyllys (char *)&dp->d_name);
29653089Swyllys
29663089Swyllys rv = fetch_key(handle, fname,
29675051Swyllys keyclass, key ? &key[n] : NULL);
29685051Swyllys
29695051Swyllys if (rv == KMF_OK) {
29705051Swyllys if (key != NULL && rawkey != NULL)
29715051Swyllys rv = convertToRawKey(
29725051Swyllys key[n].keyp, &rawkey[n]);
29733089Swyllys n++;
29745051Swyllys }
29753089Swyllys
29763089Swyllys if (rv != KMF_OK || key == NULL)
29773089Swyllys free(fname);
29783089Swyllys }
29793089Swyllys }
29803089Swyllys (void) closedir(dirp);
29813089Swyllys free(fullpath);
29823089Swyllys (*numkeys) = n;
29833089Swyllys } else {
29845051Swyllys rv = fetch_key(handle, fullpath, keyclass, key);
29853089Swyllys if (rv == KMF_OK)
29863089Swyllys (*numkeys) = 1;
29873089Swyllys
29883089Swyllys if (rv != KMF_OK || key == NULL)
29893089Swyllys free(fullpath);
29905051Swyllys
29915051Swyllys if (rv == KMF_OK && key != NULL && rawkey != NULL) {
29925051Swyllys rv = convertToRawKey(key->keyp, rawkey);
29935051Swyllys }
29943089Swyllys }
29953089Swyllys
29964025Swyllys if (rv == KMF_OK && (*numkeys) == 0)
29973089Swyllys rv = KMF_ERR_KEY_NOT_FOUND;
29985637Swyllys else if (rv == KMF_ERR_KEY_NOT_FOUND && (*numkeys) > 0)
29995637Swyllys rv = KMF_OK;
30003089Swyllys
30013089Swyllys return (rv);
30023089Swyllys }
30033089Swyllys
30043089Swyllys #define HANDLE_PK12_ERROR { \
30053089Swyllys SET_ERROR(kmfh, ERR_get_error()); \
30063089Swyllys rv = KMF_ERR_ENCODING; \
30073089Swyllys goto out; \
30083089Swyllys }
30093089Swyllys
30105536Swyllys static int
add_alias_to_bag(PKCS12_SAFEBAG * bag,X509 * xcert)30115536Swyllys add_alias_to_bag(PKCS12_SAFEBAG *bag, X509 *xcert)
30123089Swyllys {
30135536Swyllys if (xcert != NULL && xcert->aux != NULL &&
30145536Swyllys xcert->aux->alias != NULL) {
30155536Swyllys if (PKCS12_add_friendlyname_asc(bag,
30165536Swyllys (const char *)xcert->aux->alias->data,
30175536Swyllys xcert->aux->alias->length) == 0)
30185536Swyllys return (0);
30195536Swyllys }
30205536Swyllys return (1);
30215536Swyllys }
30225536Swyllys
30235536Swyllys static PKCS7 *
add_cert_to_safe(X509 * sslcert,KMF_CREDENTIAL * cred,uchar_t * keyid,unsigned int keyidlen)30245536Swyllys add_cert_to_safe(X509 *sslcert, KMF_CREDENTIAL *cred,
30255536Swyllys uchar_t *keyid, unsigned int keyidlen)
30265536Swyllys {
30275536Swyllys PKCS12_SAFEBAG *bag = NULL;
30285536Swyllys PKCS7 *cert_authsafe = NULL;
30295536Swyllys STACK_OF(PKCS12_SAFEBAG) *bag_stack;
30303089Swyllys
30313089Swyllys bag_stack = sk_PKCS12_SAFEBAG_new_null();
30323089Swyllys if (bag_stack == NULL)
30335536Swyllys return (NULL);
30345536Swyllys
30355536Swyllys /* Convert cert from X509 struct to PKCS#12 bag */
30365536Swyllys bag = PKCS12_x5092certbag(sslcert);
30375536Swyllys if (bag == NULL) {
30385536Swyllys goto out;
30395536Swyllys }
30405536Swyllys
30415536Swyllys /* Add the key id to the certificate bag. */
30425536Swyllys if (keyidlen > 0 && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) {
30435536Swyllys goto out;
30445536Swyllys }
30455536Swyllys
30465536Swyllys if (!add_alias_to_bag(bag, sslcert))
30475536Swyllys goto out;
30485536Swyllys
30495536Swyllys /* Pile it on the bag_stack. */
30505536Swyllys if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) {
30515536Swyllys goto out;
30525536Swyllys }
30535536Swyllys /* Turn bag_stack of certs into encrypted authsafe. */
30545536Swyllys cert_authsafe = PKCS12_pack_p7encdata(
30555536Swyllys NID_pbe_WithSHA1And40BitRC2_CBC,
30565536Swyllys cred->cred, cred->credlen, NULL, 0,
30575536Swyllys PKCS12_DEFAULT_ITER, bag_stack);
30585536Swyllys
30595536Swyllys out:
30605536Swyllys if (bag_stack != NULL)
30613089Swyllys sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
30625536Swyllys
30635536Swyllys return (cert_authsafe);
30645536Swyllys }
30655536Swyllys
30665536Swyllys static PKCS7 *
add_key_to_safe(EVP_PKEY * pkey,KMF_CREDENTIAL * cred,uchar_t * keyid,unsigned int keyidlen,char * label,int label_len)30675536Swyllys add_key_to_safe(EVP_PKEY *pkey, KMF_CREDENTIAL *cred,
30685536Swyllys uchar_t *keyid, unsigned int keyidlen,
30695536Swyllys char *label, int label_len)
30705536Swyllys {
30715536Swyllys PKCS8_PRIV_KEY_INFO *p8 = NULL;
30725536Swyllys STACK_OF(PKCS12_SAFEBAG) *bag_stack = NULL;
30735536Swyllys PKCS12_SAFEBAG *bag = NULL;
30745536Swyllys PKCS7 *key_authsafe = NULL;
30755536Swyllys
30765536Swyllys p8 = EVP_PKEY2PKCS8(pkey);
30775536Swyllys if (p8 == NULL) {
30785536Swyllys return (NULL);
30795536Swyllys }
30805536Swyllys /* Put the shrouded key into a PKCS#12 bag. */
30815536Swyllys bag = PKCS12_MAKE_SHKEYBAG(
30825536Swyllys NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
30835536Swyllys cred->cred, cred->credlen,
30845536Swyllys NULL, 0, PKCS12_DEFAULT_ITER, p8);
30855536Swyllys
30865536Swyllys /* Clean up the PKCS#8 shrouded key, don't need it now. */
30875536Swyllys PKCS8_PRIV_KEY_INFO_free(p8);
30885536Swyllys p8 = NULL;
30895536Swyllys
30905536Swyllys if (bag == NULL) {
30915536Swyllys return (NULL);
30925536Swyllys }
30935536Swyllys if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
30945536Swyllys goto out;
30955536Swyllys if (label != NULL && !PKCS12_add_friendlyname(bag, label, label_len))
30965536Swyllys goto out;
30975536Swyllys
30985536Swyllys /* Start a PKCS#12 safebag container for the private key. */
30995536Swyllys bag_stack = sk_PKCS12_SAFEBAG_new_null();
31005536Swyllys if (bag_stack == NULL)
31015536Swyllys goto out;
31025536Swyllys
31035536Swyllys /* Pile on the private key on the bag_stack. */
31045536Swyllys if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag))
31055536Swyllys goto out;
31065536Swyllys
31075536Swyllys key_authsafe = PKCS12_pack_p7data(bag_stack);
31085536Swyllys
31095536Swyllys out:
31105536Swyllys if (bag_stack != NULL)
31113089Swyllys sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
31125536Swyllys bag_stack = NULL;
31135536Swyllys return (key_authsafe);
31143089Swyllys }
31153089Swyllys
31163089Swyllys static EVP_PKEY *
ImportRawRSAKey(KMF_RAW_RSA_KEY * key)31173089Swyllys ImportRawRSAKey(KMF_RAW_RSA_KEY *key)
31183089Swyllys {
31193089Swyllys RSA *rsa = NULL;
31203089Swyllys EVP_PKEY *newkey = NULL;
31213089Swyllys
31223089Swyllys if ((rsa = RSA_new()) == NULL)
31233089Swyllys return (NULL);
31243089Swyllys
31253089Swyllys if ((rsa->n = BN_bin2bn(key->mod.val, key->mod.len, rsa->n)) == NULL)
31263089Swyllys return (NULL);
31273089Swyllys
31283089Swyllys if ((rsa->e = BN_bin2bn(key->pubexp.val, key->pubexp.len, rsa->e)) ==
31294315Swyllys NULL)
31303089Swyllys return (NULL);
31313089Swyllys
31323089Swyllys if (key->priexp.val != NULL)
31333089Swyllys if ((rsa->d = BN_bin2bn(key->priexp.val, key->priexp.len,
31344315Swyllys rsa->d)) == NULL)
31353089Swyllys return (NULL);
31363089Swyllys
31373089Swyllys if (key->prime1.val != NULL)
31383089Swyllys if ((rsa->p = BN_bin2bn(key->prime1.val, key->prime1.len,
31394315Swyllys rsa->p)) == NULL)
31403089Swyllys return (NULL);
31413089Swyllys
31423089Swyllys if (key->prime2.val != NULL)
31433089Swyllys if ((rsa->q = BN_bin2bn(key->prime2.val, key->prime2.len,
31444315Swyllys rsa->q)) == NULL)
31453089Swyllys return (NULL);
31463089Swyllys
31473089Swyllys if (key->exp1.val != NULL)
31483089Swyllys if ((rsa->dmp1 = BN_bin2bn(key->exp1.val, key->exp1.len,
31494315Swyllys rsa->dmp1)) == NULL)
31503089Swyllys return (NULL);
31513089Swyllys
31523089Swyllys if (key->exp2.val != NULL)
31533089Swyllys if ((rsa->dmq1 = BN_bin2bn(key->exp2.val, key->exp2.len,
31544315Swyllys rsa->dmq1)) == NULL)
31553089Swyllys return (NULL);
31563089Swyllys
31573089Swyllys if (key->coef.val != NULL)
31583089Swyllys if ((rsa->iqmp = BN_bin2bn(key->coef.val, key->coef.len,
31594315Swyllys rsa->iqmp)) == NULL)
31603089Swyllys return (NULL);
31613089Swyllys
31623089Swyllys if ((newkey = EVP_PKEY_new()) == NULL)
31633089Swyllys return (NULL);
31643089Swyllys
31653089Swyllys (void) EVP_PKEY_set1_RSA(newkey, rsa);
31663089Swyllys
31673089Swyllys /* The original key must be freed once here or it leaks memory */
31683089Swyllys RSA_free(rsa);
31693089Swyllys
31703089Swyllys return (newkey);
31713089Swyllys }
31723089Swyllys
31733089Swyllys static EVP_PKEY *
ImportRawDSAKey(KMF_RAW_DSA_KEY * key)31743089Swyllys ImportRawDSAKey(KMF_RAW_DSA_KEY *key)
31753089Swyllys {
31763089Swyllys DSA *dsa = NULL;
31773089Swyllys EVP_PKEY *newkey = NULL;
31783089Swyllys
31793089Swyllys if ((dsa = DSA_new()) == NULL)
31803089Swyllys return (NULL);
31813089Swyllys
31823089Swyllys if ((dsa->p = BN_bin2bn(key->prime.val, key->prime.len,
31834315Swyllys dsa->p)) == NULL)
31843089Swyllys return (NULL);
31853089Swyllys
31863089Swyllys if ((dsa->q = BN_bin2bn(key->subprime.val, key->subprime.len,
31874315Swyllys dsa->q)) == NULL)
31883089Swyllys return (NULL);
31893089Swyllys
31903089Swyllys if ((dsa->g = BN_bin2bn(key->base.val, key->base.len,
31914315Swyllys dsa->g)) == NULL)
31923089Swyllys return (NULL);
31933089Swyllys
31943089Swyllys if ((dsa->priv_key = BN_bin2bn(key->value.val, key->value.len,
31954315Swyllys dsa->priv_key)) == NULL)
31963089Swyllys return (NULL);
31973089Swyllys
31985051Swyllys if (key->pubvalue.val != NULL) {
31995051Swyllys if ((dsa->pub_key = BN_bin2bn(key->pubvalue.val,
32005051Swyllys key->pubvalue.len, dsa->pub_key)) == NULL)
32015051Swyllys return (NULL);
32025051Swyllys }
32035051Swyllys
32043089Swyllys if ((newkey = EVP_PKEY_new()) == NULL)
32053089Swyllys return (NULL);
32063089Swyllys
32073089Swyllys (void) EVP_PKEY_set1_DSA(newkey, dsa);
32083089Swyllys
32093089Swyllys /* The original key must be freed once here or it leaks memory */
32103089Swyllys DSA_free(dsa);
32113089Swyllys return (newkey);
32123089Swyllys }
32133089Swyllys
32145536Swyllys static EVP_PKEY *
raw_key_to_pkey(KMF_KEY_HANDLE * key)32155536Swyllys raw_key_to_pkey(KMF_KEY_HANDLE *key)
32165536Swyllys {
32175536Swyllys EVP_PKEY *pkey = NULL;
32185536Swyllys KMF_RAW_KEY_DATA *rawkey;
32195536Swyllys ASN1_TYPE *attr = NULL;
32205536Swyllys KMF_RETURN ret;
32215536Swyllys
32225536Swyllys if (key == NULL || !key->israw)
32235536Swyllys return (NULL);
32245536Swyllys
32255536Swyllys rawkey = (KMF_RAW_KEY_DATA *)key->keyp;
32265536Swyllys if (rawkey->keytype == KMF_RSA) {
32275536Swyllys pkey = ImportRawRSAKey(&rawkey->rawdata.rsa);
32285536Swyllys } else if (rawkey->keytype == KMF_DSA) {
32295536Swyllys pkey = ImportRawDSAKey(&rawkey->rawdata.dsa);
323011973Swyllys.ingersoll@sun.com } else if (rawkey->keytype == KMF_ECDSA) {
323111973Swyllys.ingersoll@sun.com /*
323211973Swyllys.ingersoll@sun.com * OpenSSL in Solaris does not support EC for
323311973Swyllys.ingersoll@sun.com * legal reasons
323411973Swyllys.ingersoll@sun.com */
323511973Swyllys.ingersoll@sun.com return (NULL);
32365536Swyllys } else {
32375536Swyllys /* wrong kind of key */
32385536Swyllys return (NULL);
32395536Swyllys }
32405536Swyllys
32415536Swyllys if (rawkey->label != NULL) {
32425536Swyllys if ((attr = ASN1_TYPE_new()) == NULL) {
32435536Swyllys EVP_PKEY_free(pkey);
32445536Swyllys return (NULL);
32455536Swyllys }
32465536Swyllys attr->value.bmpstring = ASN1_STRING_type_new(V_ASN1_BMPSTRING);
32475536Swyllys (void) ASN1_STRING_set(attr->value.bmpstring, rawkey->label,
32485536Swyllys strlen(rawkey->label));
32495536Swyllys attr->type = V_ASN1_BMPSTRING;
32505536Swyllys attr->value.ptr = (char *)attr->value.bmpstring;
32515536Swyllys ret = set_pkey_attrib(pkey, attr, NID_friendlyName);
32525536Swyllys if (ret != KMF_OK) {
32535536Swyllys EVP_PKEY_free(pkey);
32545536Swyllys ASN1_TYPE_free(attr);
32555536Swyllys return (NULL);
32565536Swyllys }
32575536Swyllys }
32585536Swyllys if (rawkey->id.Data != NULL) {
32595536Swyllys if ((attr = ASN1_TYPE_new()) == NULL) {
32605536Swyllys EVP_PKEY_free(pkey);
32615536Swyllys return (NULL);
32625536Swyllys }
32635536Swyllys attr->value.octet_string =
32645536Swyllys ASN1_STRING_type_new(V_ASN1_OCTET_STRING);
32655536Swyllys attr->type = V_ASN1_OCTET_STRING;
32665536Swyllys (void) ASN1_STRING_set(attr->value.octet_string,
32675536Swyllys rawkey->id.Data, rawkey->id.Length);
32685536Swyllys attr->value.ptr = (char *)attr->value.octet_string;
32695536Swyllys ret = set_pkey_attrib(pkey, attr, NID_localKeyID);
32705536Swyllys if (ret != KMF_OK) {
32715536Swyllys EVP_PKEY_free(pkey);
32725536Swyllys ASN1_TYPE_free(attr);
32735536Swyllys return (NULL);
32745536Swyllys }
32755536Swyllys }
32765536Swyllys return (pkey);
32775536Swyllys }
32785536Swyllys
32795536Swyllys /*
32805536Swyllys * Search a list of private keys to find one that goes with the certificate.
32815536Swyllys */
32825536Swyllys static EVP_PKEY *
find_matching_key(X509 * xcert,int numkeys,KMF_KEY_HANDLE * keylist)32835536Swyllys find_matching_key(X509 *xcert, int numkeys, KMF_KEY_HANDLE *keylist)
32845536Swyllys {
32855536Swyllys int i;
32865536Swyllys EVP_PKEY *pkey = NULL;
32875536Swyllys
32885536Swyllys if (numkeys == 0 || keylist == NULL || xcert == NULL)
32895536Swyllys return (NULL);
32905536Swyllys for (i = 0; i < numkeys; i++) {
32915536Swyllys if (keylist[i].israw)
32925536Swyllys pkey = raw_key_to_pkey(&keylist[i]);
32935536Swyllys else
32945536Swyllys pkey = (EVP_PKEY *)keylist[i].keyp;
32955536Swyllys if (pkey != NULL) {
32965536Swyllys if (X509_check_private_key(xcert, pkey)) {
32975536Swyllys return (pkey);
32985536Swyllys } else {
32995536Swyllys EVP_PKEY_free(pkey);
33005536Swyllys pkey = NULL;
33015536Swyllys }
33025536Swyllys }
33035536Swyllys }
33045536Swyllys return (pkey);
33055536Swyllys }
33065536Swyllys
33073089Swyllys static KMF_RETURN
local_export_pk12(KMF_HANDLE_T handle,KMF_CREDENTIAL * cred,int numcerts,KMF_X509_DER_CERT * certlist,int numkeys,KMF_KEY_HANDLE * keylist,char * filename)33085536Swyllys local_export_pk12(KMF_HANDLE_T handle,
33093089Swyllys KMF_CREDENTIAL *cred,
33103089Swyllys int numcerts, KMF_X509_DER_CERT *certlist,
33113089Swyllys int numkeys, KMF_KEY_HANDLE *keylist,
33123089Swyllys char *filename)
33133089Swyllys {
33143089Swyllys KMF_RETURN rv = KMF_OK;
33153089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
33163089Swyllys BIO *bio = NULL;
33175536Swyllys PKCS7 *cert_authsafe = NULL;
33185536Swyllys PKCS7 *key_authsafe = NULL;
33195536Swyllys STACK_OF(PKCS7) *authsafe_stack = NULL;
33205536Swyllys PKCS12 *p12_elem = NULL;
33213089Swyllys int i;
33223089Swyllys
33235536Swyllys if (numcerts == 0 && numkeys == 0)
33245536Swyllys return (KMF_ERR_BAD_PARAMETER);
33255536Swyllys
33263089Swyllys /*
33273089Swyllys * Open the output file.
33283089Swyllys */
33293089Swyllys if ((bio = BIO_new_file(filename, "wb")) == NULL) {
33303089Swyllys SET_ERROR(kmfh, ERR_get_error());
33313089Swyllys rv = KMF_ERR_OPEN_FILE;
33323089Swyllys goto cleanup;
33333089Swyllys }
33343089Swyllys
33355536Swyllys /* Start a PKCS#7 stack. */
33365536Swyllys authsafe_stack = sk_PKCS7_new_null();
33375536Swyllys if (authsafe_stack == NULL) {
33385536Swyllys rv = KMF_ERR_MEMORY;
33395536Swyllys goto cleanup;
33405536Swyllys }
33415536Swyllys if (numcerts > 0) {
33423089Swyllys for (i = 0; rv == KMF_OK && i < numcerts; i++) {
33433089Swyllys const uchar_t *p = certlist[i].certificate.Data;
33443089Swyllys long len = certlist[i].certificate.Length;
33455536Swyllys X509 *xcert = NULL;
33465536Swyllys EVP_PKEY *pkey = NULL;
33475536Swyllys unsigned char keyid[EVP_MAX_MD_SIZE];
33485536Swyllys unsigned int keyidlen = 0;
33493089Swyllys
33503089Swyllys xcert = d2i_X509(NULL, &p, len);
33513089Swyllys if (xcert == NULL) {
33523089Swyllys SET_ERROR(kmfh, ERR_get_error());
33533089Swyllys rv = KMF_ERR_ENCODING;
33543089Swyllys }
33555536Swyllys if (certlist[i].kmf_private.label != NULL) {
33565536Swyllys /* Set alias attribute */
33575536Swyllys (void) X509_alias_set1(xcert,
33585536Swyllys (uchar_t *)certlist[i].kmf_private.label,
33595536Swyllys strlen(certlist[i].kmf_private.label));
33605536Swyllys }
33615536Swyllys /* Check if there is a key corresponding to this cert */
33625536Swyllys pkey = find_matching_key(xcert, numkeys, keylist);
33635536Swyllys
33645536Swyllys /*
33655536Swyllys * If key is found, get fingerprint and create a
33665536Swyllys * safebag.
33675536Swyllys */
33685536Swyllys if (pkey != NULL) {
33695536Swyllys (void) X509_digest(xcert, EVP_sha1(),
33705536Swyllys keyid, &keyidlen);
33715536Swyllys key_authsafe = add_key_to_safe(pkey, cred,
33725536Swyllys keyid, keyidlen,
33735536Swyllys certlist[i].kmf_private.label,
33745536Swyllys (certlist[i].kmf_private.label ?
33755536Swyllys strlen(certlist[i].kmf_private.label) : 0));
33765536Swyllys
33775536Swyllys if (key_authsafe == NULL) {
33785536Swyllys X509_free(xcert);
33795536Swyllys EVP_PKEY_free(pkey);
33805536Swyllys goto cleanup;
33815536Swyllys }
33825536Swyllys /* Put the key safe into the Auth Safe */
33835536Swyllys if (!sk_PKCS7_push(authsafe_stack,
33845536Swyllys key_authsafe)) {
33855536Swyllys X509_free(xcert);
33865536Swyllys EVP_PKEY_free(pkey);
33875536Swyllys goto cleanup;
33885536Swyllys }
33895536Swyllys }
33905536Swyllys
33915536Swyllys /* create a certificate safebag */
33925536Swyllys cert_authsafe = add_cert_to_safe(xcert, cred, keyid,
33935536Swyllys keyidlen);
33945536Swyllys if (cert_authsafe == NULL) {
33953089Swyllys X509_free(xcert);
33965536Swyllys EVP_PKEY_free(pkey);
33975536Swyllys goto cleanup;
33985536Swyllys }
33995536Swyllys if (!sk_PKCS7_push(authsafe_stack, cert_authsafe)) {
34005536Swyllys X509_free(xcert);
34015536Swyllys EVP_PKEY_free(pkey);
34025536Swyllys goto cleanup;
34035536Swyllys }
34045536Swyllys
34055536Swyllys X509_free(xcert);
34063089Swyllys if (pkey)
34073089Swyllys EVP_PKEY_free(pkey);
34083089Swyllys }
34095536Swyllys } else if (numcerts == 0 && numkeys > 0) {
34105536Swyllys /*
34115536Swyllys * If only adding keys to the file.
34125536Swyllys */
34135536Swyllys for (i = 0; i < numkeys; i++) {
34145536Swyllys EVP_PKEY *pkey = NULL;
34155536Swyllys
34165536Swyllys if (keylist[i].israw)
34175536Swyllys pkey = raw_key_to_pkey(&keylist[i]);
34185536Swyllys else
34195536Swyllys pkey = (EVP_PKEY *)keylist[i].keyp;
34205536Swyllys
34215536Swyllys if (pkey == NULL)
34225536Swyllys continue;
34235536Swyllys
34245536Swyllys key_authsafe = add_key_to_safe(pkey, cred,
34255536Swyllys NULL, 0, NULL, 0);
34265536Swyllys
34275536Swyllys if (key_authsafe == NULL) {
34285536Swyllys EVP_PKEY_free(pkey);
34295536Swyllys goto cleanup;
34305536Swyllys }
34315536Swyllys if (!sk_PKCS7_push(authsafe_stack, key_authsafe)) {
34325536Swyllys EVP_PKEY_free(pkey);
34335536Swyllys goto cleanup;
34345536Swyllys }
34355536Swyllys }
34365536Swyllys }
34375536Swyllys p12_elem = PKCS12_init(NID_pkcs7_data);
34385536Swyllys if (p12_elem == NULL) {
34395536Swyllys goto cleanup;
34405536Swyllys }
34415536Swyllys
34425536Swyllys /* Put the PKCS#7 stack into the PKCS#12 element. */
34435536Swyllys if (!PKCS12_pack_authsafes(p12_elem, authsafe_stack)) {
34445536Swyllys goto cleanup;
34455536Swyllys }
34465536Swyllys
34475536Swyllys /* Set the integrity MAC on the PKCS#12 element. */
34485536Swyllys if (!PKCS12_set_mac(p12_elem, cred->cred, cred->credlen,
34495536Swyllys NULL, 0, PKCS12_DEFAULT_ITER, NULL)) {
34505536Swyllys goto cleanup;
34515536Swyllys }
34525536Swyllys
34535536Swyllys /* Write the PKCS#12 element to the export file. */
34545536Swyllys if (!i2d_PKCS12_bio(bio, p12_elem)) {
34555536Swyllys goto cleanup;
34565536Swyllys }
34575536Swyllys PKCS12_free(p12_elem);
34583089Swyllys
34593089Swyllys cleanup:
34605536Swyllys /* Clear away the PKCS#7 stack, we're done with it. */
34615536Swyllys if (authsafe_stack)
34625536Swyllys sk_PKCS7_pop_free(authsafe_stack, PKCS7_free);
34633089Swyllys
34643089Swyllys if (bio != NULL)
34653089Swyllys (void) BIO_free_all(bio);
34663089Swyllys
34673089Swyllys return (rv);
34683089Swyllys }
34693089Swyllys
34703089Swyllys KMF_RETURN
openssl_build_pk12(KMF_HANDLE_T handle,int numcerts,KMF_X509_DER_CERT * certlist,int numkeys,KMF_KEY_HANDLE * keylist,KMF_CREDENTIAL * p12cred,char * filename)34715051Swyllys openssl_build_pk12(KMF_HANDLE_T handle, int numcerts,
34725051Swyllys KMF_X509_DER_CERT *certlist, int numkeys, KMF_KEY_HANDLE *keylist,
34735051Swyllys KMF_CREDENTIAL *p12cred, char *filename)
34745051Swyllys {
34755051Swyllys KMF_RETURN rv;
34765051Swyllys
34775051Swyllys if (certlist == NULL && keylist == NULL)
34785051Swyllys return (KMF_ERR_BAD_PARAMETER);
34795051Swyllys
34805536Swyllys rv = local_export_pk12(handle, p12cred, numcerts, certlist,
34815051Swyllys numkeys, keylist, filename);
34825051Swyllys
34835051Swyllys return (rv);
34845051Swyllys }
34855051Swyllys
34865051Swyllys KMF_RETURN
OpenSSL_ExportPK12(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)34875051Swyllys OpenSSL_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
34883089Swyllys {
34893089Swyllys KMF_RETURN rv;
34903089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
34913089Swyllys char *fullpath = NULL;
34925051Swyllys char *dirpath = NULL;
34935051Swyllys char *certfile = NULL;
34945051Swyllys char *keyfile = NULL;
34955051Swyllys char *filename = NULL;
34965051Swyllys KMF_CREDENTIAL *p12cred = NULL;
34975536Swyllys KMF_X509_DER_CERT certdata;
34985536Swyllys KMF_KEY_HANDLE key;
34995536Swyllys int gotkey = 0;
35005536Swyllys int gotcert = 0;
35015051Swyllys
35025051Swyllys if (handle == NULL)
35035051Swyllys return (KMF_ERR_BAD_PARAMETER);
35043089Swyllys
35053089Swyllys /*
35063089Swyllys * First, find the certificate.
35073089Swyllys */
35085051Swyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
35095051Swyllys certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
35105051Swyllys if (certfile != NULL) {
35115051Swyllys fullpath = get_fullpath(dirpath, certfile);
35123089Swyllys if (fullpath == NULL)
35133089Swyllys return (KMF_ERR_BAD_PARAMETER);
35143089Swyllys
35153089Swyllys if (isdir(fullpath)) {
35163089Swyllys free(fullpath);
35173089Swyllys return (KMF_ERR_AMBIGUOUS_PATHNAME);
35183089Swyllys }
35193089Swyllys
35205536Swyllys (void) memset(&certdata, 0, sizeof (certdata));
35215536Swyllys rv = kmf_load_cert(kmfh, NULL, NULL, NULL, NULL,
35225536Swyllys fullpath, &certdata.certificate);
35233089Swyllys if (rv != KMF_OK)
35243089Swyllys goto end;
35255051Swyllys
35265536Swyllys gotcert++;
35275536Swyllys certdata.kmf_private.keystore_type = KMF_KEYSTORE_OPENSSL;
35285051Swyllys free(fullpath);
35293089Swyllys }
35303089Swyllys
35313089Swyllys /*
35323089Swyllys * Now find the private key.
35333089Swyllys */
35345051Swyllys keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
35355051Swyllys if (keyfile != NULL) {
35365051Swyllys fullpath = get_fullpath(dirpath, keyfile);
35373089Swyllys if (fullpath == NULL)
35383089Swyllys return (KMF_ERR_BAD_PARAMETER);
35393089Swyllys
35403089Swyllys if (isdir(fullpath)) {
35413089Swyllys free(fullpath);
35423089Swyllys return (KMF_ERR_AMBIGUOUS_PATHNAME);
35433089Swyllys }
35443089Swyllys
35455536Swyllys (void) memset(&key, 0, sizeof (KMF_KEY_HANDLE));
35465536Swyllys rv = fetch_key(handle, fullpath, KMF_ASYM_PRI, &key);
35475536Swyllys if (rv != KMF_OK)
35483089Swyllys goto end;
35495536Swyllys gotkey++;
35503089Swyllys }
35513089Swyllys
35523089Swyllys /*
35533089Swyllys * Open the output file.
35543089Swyllys */
35555051Swyllys filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist,
35565051Swyllys numattr);
35575051Swyllys if (filename == NULL) {
35585051Swyllys rv = KMF_ERR_BAD_PARAMETER;
35595051Swyllys goto end;
35605051Swyllys }
35615051Swyllys
35623089Swyllys /* Stick the key and the cert into a PKCS#12 file */
35635051Swyllys p12cred = kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr);
35645051Swyllys if (p12cred == NULL) {
35655051Swyllys rv = KMF_ERR_BAD_PARAMETER;
35665051Swyllys goto end;
35675051Swyllys }
35685051Swyllys
35695536Swyllys rv = local_export_pk12(handle, p12cred, 1, &certdata,
35705536Swyllys 1, &key, filename);
35713089Swyllys
35723089Swyllys end:
35733089Swyllys if (fullpath)
35743089Swyllys free(fullpath);
35755536Swyllys
35765536Swyllys if (gotcert)
35775536Swyllys kmf_free_kmf_cert(handle, &certdata);
35785536Swyllys if (gotkey)
35795536Swyllys kmf_free_kmf_key(handle, &key);
35803089Swyllys return (rv);
35813089Swyllys }
35823089Swyllys
35833408Swyllys /*
35843408Swyllys * Helper function to extract keys and certificates from
35853408Swyllys * a single PEM file. Typically the file should contain a
35863408Swyllys * private key and an associated public key wrapped in an x509 cert.
35873408Swyllys * However, the file may be just a list of X509 certs with no keys.
35883408Swyllys */
35893408Swyllys static KMF_RETURN
extract_pem(KMF_HANDLE * kmfh,char * issuer,char * subject,KMF_BIGINT * serial,char * filename,CK_UTF8CHAR * pin,CK_ULONG pinlen,EVP_PKEY ** priv_key,KMF_DATA ** certs,int * numcerts)35905051Swyllys extract_pem(KMF_HANDLE *kmfh,
35915051Swyllys char *issuer, char *subject, KMF_BIGINT *serial,
35923754Swyllys char *filename, CK_UTF8CHAR *pin,
35933408Swyllys CK_ULONG pinlen, EVP_PKEY **priv_key, KMF_DATA **certs,
35943408Swyllys int *numcerts)
359511673Sopensolaris@drydog.com /* ARGSUSED6 */
35963408Swyllys {
35973408Swyllys KMF_RETURN rv = KMF_OK;
35983408Swyllys FILE *fp;
35994315Swyllys STACK_OF(X509_INFO) *x509_info_stack = NULL;
36003754Swyllys int i, ncerts = 0, matchcerts = 0;
36013408Swyllys EVP_PKEY *pkey = NULL;
36023408Swyllys X509_INFO *info;
36033408Swyllys X509 *x;
36045536Swyllys X509_INFO **cert_infos = NULL;
36053408Swyllys KMF_DATA *certlist = NULL;
36063408Swyllys
36073408Swyllys if (priv_key)
36083408Swyllys *priv_key = NULL;
36093408Swyllys if (certs)
36103408Swyllys *certs = NULL;
36113408Swyllys fp = fopen(filename, "r");
36125536Swyllys if (fp == NULL)
36133408Swyllys return (KMF_ERR_OPEN_FILE);
36145536Swyllys
36153408Swyllys x509_info_stack = PEM_X509_INFO_read(fp, NULL, NULL, pin);
36163408Swyllys if (x509_info_stack == NULL) {
36173408Swyllys (void) fclose(fp);
36183408Swyllys return (KMF_ERR_ENCODING);
36193408Swyllys }
36205536Swyllys cert_infos = (X509_INFO **)malloc(sk_X509_INFO_num(x509_info_stack) *
36215536Swyllys sizeof (X509_INFO *));
36225536Swyllys if (cert_infos == NULL) {
36235536Swyllys (void) fclose(fp);
36245536Swyllys rv = KMF_ERR_MEMORY;
36255536Swyllys goto err;
36265536Swyllys }
36275536Swyllys
36285536Swyllys for (i = 0; i < sk_X509_INFO_num(x509_info_stack); i++) {
362911673Sopensolaris@drydog.com /* LINTED E_BAD_PTR_CAST_ALIGN */
36304315Swyllys cert_infos[ncerts] = sk_X509_INFO_value(x509_info_stack, i);
36313408Swyllys ncerts++;
36323408Swyllys }
36333408Swyllys
36343408Swyllys if (ncerts == 0) {
36353408Swyllys (void) fclose(fp);
36364315Swyllys rv = KMF_ERR_CERT_NOT_FOUND;
36374315Swyllys goto err;
36383408Swyllys }
36393408Swyllys
36403408Swyllys if (priv_key != NULL) {
36413408Swyllys rewind(fp);
36423408Swyllys pkey = PEM_read_PrivateKey(fp, NULL, NULL, pin);
36433408Swyllys }
36443408Swyllys (void) fclose(fp);
36453408Swyllys
36463408Swyllys x = cert_infos[ncerts - 1]->x509;
36473408Swyllys /*
36483408Swyllys * Make sure the private key matchs the last cert in the file.
36493408Swyllys */
36503408Swyllys if (pkey != NULL && !X509_check_private_key(x, pkey)) {
36513408Swyllys EVP_PKEY_free(pkey);
36524315Swyllys rv = KMF_ERR_KEY_MISMATCH;
36534315Swyllys goto err;
36543408Swyllys }
36553408Swyllys
365611673Sopensolaris@drydog.com certlist = (KMF_DATA *)calloc(ncerts, sizeof (KMF_DATA));
36573408Swyllys if (certlist == NULL) {
36583408Swyllys if (pkey != NULL)
36593408Swyllys EVP_PKEY_free(pkey);
36604315Swyllys rv = KMF_ERR_MEMORY;
36614315Swyllys goto err;
36623408Swyllys }
36633408Swyllys
36643408Swyllys /*
36653408Swyllys * Convert all of the certs to DER format.
36663408Swyllys */
36673754Swyllys matchcerts = 0;
36683408Swyllys for (i = 0; rv == KMF_OK && certs != NULL && i < ncerts; i++) {
36693754Swyllys boolean_t match = FALSE;
36703408Swyllys info = cert_infos[ncerts - 1 - i];
36713408Swyllys
36725051Swyllys rv = check_cert(info->x509, issuer, subject, serial, &match);
36735051Swyllys if (rv != KMF_OK || match != TRUE) {
36745051Swyllys rv = KMF_OK;
36755051Swyllys continue;
36763754Swyllys }
36773754Swyllys
36783754Swyllys rv = ssl_cert2KMFDATA(kmfh, info->x509,
36793754Swyllys &certlist[matchcerts++]);
36803408Swyllys
36813408Swyllys if (rv != KMF_OK) {
368211973Swyllys.ingersoll@sun.com int j;
368311973Swyllys.ingersoll@sun.com for (j = 0; j < matchcerts; j++)
368411973Swyllys.ingersoll@sun.com kmf_free_data(&certlist[j]);
36853408Swyllys free(certlist);
36863408Swyllys certlist = NULL;
36873754Swyllys ncerts = matchcerts = 0;
36883408Swyllys }
36893408Swyllys }
36903408Swyllys
36913408Swyllys if (numcerts != NULL)
36923754Swyllys *numcerts = matchcerts;
369311673Sopensolaris@drydog.com
369411973Swyllys.ingersoll@sun.com if (certs != NULL)
36953408Swyllys *certs = certlist;
369611973Swyllys.ingersoll@sun.com else if (certlist != NULL) {
369711973Swyllys.ingersoll@sun.com for (i = 0; i < ncerts; i++)
369811973Swyllys.ingersoll@sun.com kmf_free_data(&certlist[i]);
369911673Sopensolaris@drydog.com free(certlist);
370011673Sopensolaris@drydog.com certlist = NULL;
370111673Sopensolaris@drydog.com }
37023408Swyllys
37033408Swyllys if (priv_key == NULL && pkey != NULL)
37043408Swyllys EVP_PKEY_free(pkey);
37053408Swyllys else if (priv_key != NULL && pkey != NULL)
37063408Swyllys *priv_key = pkey;
37073408Swyllys
37084315Swyllys err:
37094315Swyllys /* Cleanup the stack of X509 info records */
37104315Swyllys for (i = 0; i < sk_X509_INFO_num(x509_info_stack); i++) {
371111673Sopensolaris@drydog.com /* LINTED E_BAD_PTR_CAST_ALIGN */
37124315Swyllys info = (X509_INFO *)sk_X509_INFO_value(x509_info_stack, i);
37134315Swyllys X509_INFO_free(info);
37144315Swyllys }
37154315Swyllys if (x509_info_stack)
37164315Swyllys sk_X509_INFO_free(x509_info_stack);
37174315Swyllys
37185536Swyllys if (cert_infos != NULL)
37195536Swyllys free(cert_infos);
37205536Swyllys
37213408Swyllys return (rv);
37223408Swyllys }
37233408Swyllys
37245536Swyllys static KMF_RETURN
openssl_parse_bags(STACK_OF (PKCS12_SAFEBAG)* bags,char * pin,STACK_OF (EVP_PKEY)* keys,STACK_OF (X509)* certs)37255536Swyllys openssl_parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *pin,
37265536Swyllys STACK_OF(EVP_PKEY) *keys, STACK_OF(X509) *certs)
37275536Swyllys {
37285536Swyllys KMF_RETURN ret;
37295536Swyllys int i;
37305536Swyllys
37315536Swyllys for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
373211673Sopensolaris@drydog.com /* LINTED E_BAD_PTR_CAST_ALIGN */
37335536Swyllys PKCS12_SAFEBAG *bag = sk_PKCS12_SAFEBAG_value(bags, i);
37345536Swyllys ret = openssl_parse_bag(bag, pin, (pin ? strlen(pin) : 0),
37355536Swyllys keys, certs);
37365536Swyllys
37375536Swyllys if (ret != KMF_OK)
37385536Swyllys return (ret);
37395536Swyllys }
37405536Swyllys
37415536Swyllys return (ret);
37425536Swyllys }
37435536Swyllys
37445536Swyllys static KMF_RETURN
set_pkey_attrib(EVP_PKEY * pkey,ASN1_TYPE * attrib,int nid)37455536Swyllys set_pkey_attrib(EVP_PKEY *pkey, ASN1_TYPE *attrib, int nid)
37465536Swyllys {
37475536Swyllys X509_ATTRIBUTE *attr = NULL;
37485536Swyllys
37495536Swyllys if (pkey == NULL || attrib == NULL)
37505536Swyllys return (KMF_ERR_BAD_PARAMETER);
37515536Swyllys
37525536Swyllys if (pkey->attributes == NULL) {
37535536Swyllys pkey->attributes = sk_X509_ATTRIBUTE_new_null();
37545536Swyllys if (pkey->attributes == NULL)
37555536Swyllys return (KMF_ERR_MEMORY);
37565536Swyllys }
37575536Swyllys attr = X509_ATTRIBUTE_create(nid, attrib->type, attrib->value.ptr);
37585536Swyllys if (attr != NULL) {
37595536Swyllys int i;
37605536Swyllys X509_ATTRIBUTE *a;
37615536Swyllys for (i = 0;
37625536Swyllys i < sk_X509_ATTRIBUTE_num(pkey->attributes); i++) {
376311973Swyllys.ingersoll@sun.com /* LINTED E_BAD_PTR_CASE_ALIGN */
37645536Swyllys a = sk_X509_ATTRIBUTE_value(pkey->attributes, i);
37655536Swyllys if (OBJ_obj2nid(a->object) == nid) {
37665536Swyllys X509_ATTRIBUTE_free(a);
376711673Sopensolaris@drydog.com /* LINTED E_BAD_PTR_CAST_ALIGN */
37685536Swyllys sk_X509_ATTRIBUTE_set(pkey->attributes,
37695536Swyllys i, attr);
37705536Swyllys return (KMF_OK);
37715536Swyllys }
37725536Swyllys }
37735536Swyllys if (sk_X509_ATTRIBUTE_push(pkey->attributes, attr) == NULL) {
37745536Swyllys X509_ATTRIBUTE_free(attr);
37755536Swyllys return (KMF_ERR_MEMORY);
37765536Swyllys }
37775536Swyllys } else {
37785536Swyllys return (KMF_ERR_MEMORY);
37795536Swyllys }
37805536Swyllys
37815536Swyllys return (KMF_OK);
37825536Swyllys }
37835536Swyllys
37845536Swyllys static KMF_RETURN
openssl_parse_bag(PKCS12_SAFEBAG * bag,char * pass,int passlen,STACK_OF (EVP_PKEY)* keylist,STACK_OF (X509)* certlist)37855536Swyllys openssl_parse_bag(PKCS12_SAFEBAG *bag, char *pass, int passlen,
37865536Swyllys STACK_OF(EVP_PKEY) *keylist, STACK_OF(X509) *certlist)
37875536Swyllys {
37885536Swyllys KMF_RETURN ret = KMF_OK;
37895536Swyllys PKCS8_PRIV_KEY_INFO *p8 = NULL;
37905536Swyllys EVP_PKEY *pkey = NULL;
37915536Swyllys X509 *xcert = NULL;
37925536Swyllys ASN1_TYPE *keyid = NULL;
37935536Swyllys ASN1_TYPE *fname = NULL;
37945536Swyllys uchar_t *data = NULL;
37955536Swyllys
37965536Swyllys keyid = PKCS12_get_attr(bag, NID_localKeyID);
37975536Swyllys fname = PKCS12_get_attr(bag, NID_friendlyName);
37985536Swyllys
37995536Swyllys switch (M_PKCS12_bag_type(bag)) {
38005536Swyllys case NID_keyBag:
38015536Swyllys if (keylist == NULL)
38025536Swyllys goto end;
38035536Swyllys pkey = EVP_PKCS82PKEY(bag->value.keybag);
38045536Swyllys if (pkey == NULL)
38055536Swyllys ret = KMF_ERR_PKCS12_FORMAT;
38065536Swyllys
38075536Swyllys break;
38085536Swyllys case NID_pkcs8ShroudedKeyBag:
38095536Swyllys if (keylist == NULL)
38105536Swyllys goto end;
38115536Swyllys p8 = M_PKCS12_decrypt_skey(bag, pass, passlen);
38125536Swyllys if (p8 == NULL)
38135536Swyllys return (KMF_ERR_AUTH_FAILED);
38145536Swyllys pkey = EVP_PKCS82PKEY(p8);
38155536Swyllys PKCS8_PRIV_KEY_INFO_free(p8);
38165536Swyllys if (pkey == NULL)
38175536Swyllys ret = KMF_ERR_PKCS12_FORMAT;
38185536Swyllys break;
38195536Swyllys case NID_certBag:
38205536Swyllys if (certlist == NULL)
38215536Swyllys goto end;
38225536Swyllys if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate)
38235536Swyllys return (KMF_ERR_PKCS12_FORMAT);
38245536Swyllys xcert = M_PKCS12_certbag2x509(bag);
38255536Swyllys if (xcert == NULL) {
38265536Swyllys ret = KMF_ERR_PKCS12_FORMAT;
38275536Swyllys goto end;
38285536Swyllys }
38295536Swyllys if (keyid != NULL) {
38305536Swyllys if (X509_keyid_set1(xcert,
38315536Swyllys keyid->value.octet_string->data,
38325536Swyllys keyid->value.octet_string->length) == 0) {
38335536Swyllys ret = KMF_ERR_PKCS12_FORMAT;
38345536Swyllys goto end;
38355536Swyllys }
38365536Swyllys }
38375536Swyllys if (fname != NULL) {
38385536Swyllys int len, r;
38395536Swyllys len = ASN1_STRING_to_UTF8(&data,
38405536Swyllys fname->value.asn1_string);
38415536Swyllys if (len > 0 && data != NULL) {
38425536Swyllys r = X509_alias_set1(xcert, data, len);
38435536Swyllys if (r == NULL) {
38445536Swyllys ret = KMF_ERR_PKCS12_FORMAT;
38455536Swyllys goto end;
38465536Swyllys }
38475536Swyllys } else {
38485536Swyllys ret = KMF_ERR_PKCS12_FORMAT;
38495536Swyllys goto end;
38505536Swyllys }
38515536Swyllys }
38525536Swyllys if (sk_X509_push(certlist, xcert) == 0)
38535536Swyllys ret = KMF_ERR_MEMORY;
38545536Swyllys else
38555536Swyllys xcert = NULL;
38565536Swyllys break;
38575536Swyllys case NID_safeContentsBag:
38585536Swyllys return (openssl_parse_bags(bag->value.safes, pass,
38595536Swyllys keylist, certlist));
38605536Swyllys default:
38615536Swyllys ret = KMF_ERR_PKCS12_FORMAT;
38625536Swyllys break;
38635536Swyllys }
38645536Swyllys
38655536Swyllys /*
38665536Swyllys * Set the ID and/or FriendlyName attributes on the key.
38675536Swyllys * If converting to PKCS11 objects, these can translate to CKA_ID
38685536Swyllys * and CKA_LABEL values.
38695536Swyllys */
38705536Swyllys if (pkey != NULL && ret == KMF_OK) {
38715536Swyllys ASN1_TYPE *attr = NULL;
38725536Swyllys if (keyid != NULL && keyid->type == V_ASN1_OCTET_STRING) {
38735536Swyllys if ((attr = ASN1_TYPE_new()) == NULL)
38745536Swyllys return (KMF_ERR_MEMORY);
38755536Swyllys attr->value.octet_string =
38765536Swyllys ASN1_STRING_dup(keyid->value.octet_string);
38775536Swyllys attr->type = V_ASN1_OCTET_STRING;
38785536Swyllys attr->value.ptr = (char *)attr->value.octet_string;
38795536Swyllys ret = set_pkey_attrib(pkey, attr, NID_localKeyID);
38805536Swyllys OPENSSL_free(attr);
38815536Swyllys }
38825536Swyllys
38835536Swyllys if (ret == KMF_OK && fname != NULL &&
38845536Swyllys fname->type == V_ASN1_BMPSTRING) {
38855536Swyllys if ((attr = ASN1_TYPE_new()) == NULL)
38865536Swyllys return (KMF_ERR_MEMORY);
38875536Swyllys attr->value.bmpstring =
38885536Swyllys ASN1_STRING_dup(fname->value.bmpstring);
38895536Swyllys attr->type = V_ASN1_BMPSTRING;
38905536Swyllys attr->value.ptr = (char *)attr->value.bmpstring;
38915536Swyllys ret = set_pkey_attrib(pkey, attr, NID_friendlyName);
38925536Swyllys OPENSSL_free(attr);
38935536Swyllys }
38945536Swyllys
38955536Swyllys if (ret == KMF_OK && keylist != NULL &&
38965536Swyllys sk_EVP_PKEY_push(keylist, pkey) == 0)
38975536Swyllys ret = KMF_ERR_MEMORY;
38985536Swyllys }
38995536Swyllys if (ret == KMF_OK && keylist != NULL)
39005536Swyllys pkey = NULL;
39015536Swyllys end:
39025536Swyllys if (pkey != NULL)
39035536Swyllys EVP_PKEY_free(pkey);
39045536Swyllys if (xcert != NULL)
39055536Swyllys X509_free(xcert);
39065536Swyllys if (data != NULL)
39075536Swyllys OPENSSL_free(data);
39085536Swyllys
39095536Swyllys return (ret);
39105536Swyllys }
39115536Swyllys
39125536Swyllys static KMF_RETURN
openssl_pkcs12_parse(PKCS12 * p12,char * pin,STACK_OF (EVP_PKEY)* keys,STACK_OF (X509)* certs,STACK_OF (X509)* ca)39135536Swyllys openssl_pkcs12_parse(PKCS12 *p12, char *pin,
39145536Swyllys STACK_OF(EVP_PKEY) *keys,
39155536Swyllys STACK_OF(X509) *certs,
39165536Swyllys STACK_OF(X509) *ca)
391711673Sopensolaris@drydog.com /* ARGSUSED3 */
39185536Swyllys {
39195536Swyllys KMF_RETURN ret = KMF_OK;
39205536Swyllys STACK_OF(PKCS7) *asafes = NULL;
39215536Swyllys STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
39225536Swyllys int i, bagnid;
39235536Swyllys PKCS7 *p7;
39245536Swyllys
39255536Swyllys if (p12 == NULL || (keys == NULL && certs == NULL))
39265536Swyllys return (KMF_ERR_BAD_PARAMETER);
39275536Swyllys
39285536Swyllys if (pin == NULL || *pin == NULL) {
39295536Swyllys if (PKCS12_verify_mac(p12, NULL, 0)) {
39305536Swyllys pin = NULL;
39315536Swyllys } else if (PKCS12_verify_mac(p12, "", 0)) {
39325536Swyllys pin = "";
39335536Swyllys } else {
39345536Swyllys return (KMF_ERR_AUTH_FAILED);
39355536Swyllys }
39365536Swyllys } else if (!PKCS12_verify_mac(p12, pin, -1)) {
39375536Swyllys return (KMF_ERR_AUTH_FAILED);
39385536Swyllys }
39395536Swyllys
39405536Swyllys if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL)
39415536Swyllys return (KMF_ERR_PKCS12_FORMAT);
39425536Swyllys
39435536Swyllys for (i = 0; ret == KMF_OK && i < sk_PKCS7_num(asafes); i++) {
39445536Swyllys bags = NULL;
394511673Sopensolaris@drydog.com /* LINTED E_BAD_PTR_CAST_ALIGN */
39465536Swyllys p7 = sk_PKCS7_value(asafes, i);
39475536Swyllys bagnid = OBJ_obj2nid(p7->type);
39485536Swyllys
39495536Swyllys if (bagnid == NID_pkcs7_data) {
39505536Swyllys bags = PKCS12_unpack_p7data(p7);
39515536Swyllys } else if (bagnid == NID_pkcs7_encrypted) {
39525536Swyllys bags = PKCS12_unpack_p7encdata(p7, pin,
39535536Swyllys (pin ? strlen(pin) : 0));
39545536Swyllys } else {
39555536Swyllys continue;
39565536Swyllys }
39575536Swyllys if (bags == NULL) {
39585536Swyllys ret = KMF_ERR_PKCS12_FORMAT;
39595536Swyllys goto out;
39605536Swyllys }
39615536Swyllys
39625536Swyllys if (openssl_parse_bags(bags, pin, keys, certs) != KMF_OK)
39635536Swyllys ret = KMF_ERR_PKCS12_FORMAT;
39645536Swyllys
39655536Swyllys sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
39665536Swyllys }
39675536Swyllys out:
39685536Swyllys if (asafes != NULL)
39695536Swyllys sk_PKCS7_pop_free(asafes, PKCS7_free);
39705536Swyllys
39715536Swyllys return (ret);
39725536Swyllys }
39735536Swyllys
39743089Swyllys /*
39753089Swyllys * Helper function to decrypt and parse PKCS#12 import file.
39763089Swyllys */
39773089Swyllys static KMF_RETURN
extract_pkcs12(BIO * fbio,CK_UTF8CHAR * pin,CK_ULONG pinlen,STACK_OF (EVP_PKEY)** priv_key,STACK_OF (X509)** certs,STACK_OF (X509)** ca)39783089Swyllys extract_pkcs12(BIO *fbio, CK_UTF8CHAR *pin, CK_ULONG pinlen,
39795536Swyllys STACK_OF(EVP_PKEY) **priv_key, STACK_OF(X509) **certs,
39805536Swyllys STACK_OF(X509) **ca)
398111673Sopensolaris@drydog.com /* ARGSUSED2 */
39823089Swyllys {
39835536Swyllys PKCS12 *pk12, *pk12_tmp;
39845536Swyllys STACK_OF(EVP_PKEY) *pkeylist = NULL;
39855536Swyllys STACK_OF(X509) *xcertlist = NULL;
39865536Swyllys STACK_OF(X509) *cacertlist = NULL;
39873089Swyllys
39883089Swyllys if ((pk12 = PKCS12_new()) == NULL) {
39893089Swyllys return (KMF_ERR_MEMORY);
39903089Swyllys }
39913089Swyllys
39923089Swyllys if ((pk12_tmp = d2i_PKCS12_bio(fbio, &pk12)) == NULL) {
39933089Swyllys /* This is ok; it seems to mean there is no more to read. */
39943089Swyllys if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_ASN1 &&
39953089Swyllys ERR_GET_REASON(ERR_peek_error()) == ASN1_R_HEADER_TOO_LONG)
39963089Swyllys goto end_extract_pkcs12;
39973089Swyllys
39983089Swyllys PKCS12_free(pk12);
39993089Swyllys return (KMF_ERR_PKCS12_FORMAT);
40003089Swyllys }
40013089Swyllys pk12 = pk12_tmp;
40023089Swyllys
40035536Swyllys xcertlist = sk_X509_new_null();
40045536Swyllys if (xcertlist == NULL) {
40055536Swyllys PKCS12_free(pk12);
40065536Swyllys return (KMF_ERR_MEMORY);
40075536Swyllys }
40085536Swyllys pkeylist = sk_EVP_PKEY_new_null();
40095536Swyllys if (pkeylist == NULL) {
40105536Swyllys sk_X509_pop_free(xcertlist, X509_free);
40115536Swyllys PKCS12_free(pk12);
40125536Swyllys return (KMF_ERR_MEMORY);
40135536Swyllys }
40145536Swyllys
40155536Swyllys if (openssl_pkcs12_parse(pk12, (char *)pin, pkeylist, xcertlist,
40165536Swyllys cacertlist) != KMF_OK) {
40175536Swyllys sk_X509_pop_free(xcertlist, X509_free);
40185536Swyllys sk_EVP_PKEY_pop_free(pkeylist, EVP_PKEY_free);
40193089Swyllys PKCS12_free(pk12);
40203089Swyllys return (KMF_ERR_PKCS12_FORMAT);
40213089Swyllys }
40223089Swyllys
40235536Swyllys if (priv_key && pkeylist)
40245536Swyllys *priv_key = pkeylist;
40255536Swyllys else if (pkeylist)
40265536Swyllys sk_EVP_PKEY_pop_free(pkeylist, EVP_PKEY_free);
40275536Swyllys if (certs && xcertlist)
40285536Swyllys *certs = xcertlist;
40295536Swyllys else if (xcertlist)
40305536Swyllys sk_X509_pop_free(xcertlist, X509_free);
40315536Swyllys if (ca && cacertlist)
40325536Swyllys *ca = cacertlist;
40335536Swyllys else if (cacertlist)
40345536Swyllys sk_X509_pop_free(cacertlist, X509_free);
40355536Swyllys
40363089Swyllys end_extract_pkcs12:
40373089Swyllys
40383089Swyllys PKCS12_free(pk12);
40393089Swyllys return (KMF_OK);
40403089Swyllys }
40413089Swyllys
40423089Swyllys static KMF_RETURN
sslBN2KMFBN(BIGNUM * from,KMF_BIGINT * to)40433089Swyllys sslBN2KMFBN(BIGNUM *from, KMF_BIGINT *to)
40443089Swyllys {
40453089Swyllys KMF_RETURN rv = KMF_OK;
40463089Swyllys uint32_t sz;
40473089Swyllys
40483089Swyllys sz = BN_num_bytes(from);
40493089Swyllys to->val = (uchar_t *)malloc(sz);
40503089Swyllys if (to->val == NULL)
40513089Swyllys return (KMF_ERR_MEMORY);
40523089Swyllys
40533089Swyllys if ((to->len = BN_bn2bin(from, to->val)) != sz) {
40543089Swyllys free(to->val);
40553089Swyllys to->val = NULL;
40563089Swyllys to->len = 0;
40573089Swyllys rv = KMF_ERR_MEMORY;
40583089Swyllys }
40593089Swyllys
40603089Swyllys return (rv);
40613089Swyllys }
40623089Swyllys
40633089Swyllys static KMF_RETURN
exportRawRSAKey(RSA * rsa,KMF_RAW_KEY_DATA * key)40643089Swyllys exportRawRSAKey(RSA *rsa, KMF_RAW_KEY_DATA *key)
40653089Swyllys {
40663089Swyllys KMF_RETURN rv;
40673089Swyllys KMF_RAW_RSA_KEY *kmfkey = &key->rawdata.rsa;
40683089Swyllys
40693089Swyllys (void) memset(kmfkey, 0, sizeof (KMF_RAW_RSA_KEY));
40703089Swyllys if ((rv = sslBN2KMFBN(rsa->n, &kmfkey->mod)) != KMF_OK)
40713089Swyllys goto cleanup;
40723089Swyllys
40733089Swyllys if ((rv = sslBN2KMFBN(rsa->e, &kmfkey->pubexp)) != KMF_OK)
40743089Swyllys goto cleanup;
40753089Swyllys
40763089Swyllys if (rsa->d != NULL)
40773089Swyllys if ((rv = sslBN2KMFBN(rsa->d, &kmfkey->priexp)) != KMF_OK)
40783089Swyllys goto cleanup;
40793089Swyllys
40803089Swyllys if (rsa->p != NULL)
40813089Swyllys if ((rv = sslBN2KMFBN(rsa->p, &kmfkey->prime1)) != KMF_OK)
40823089Swyllys goto cleanup;
40833089Swyllys
40843089Swyllys if (rsa->q != NULL)
40853089Swyllys if ((rv = sslBN2KMFBN(rsa->q, &kmfkey->prime2)) != KMF_OK)
40863089Swyllys goto cleanup;
40873089Swyllys
40883089Swyllys if (rsa->dmp1 != NULL)
40893089Swyllys if ((rv = sslBN2KMFBN(rsa->dmp1, &kmfkey->exp1)) != KMF_OK)
40903089Swyllys goto cleanup;
40913089Swyllys
40923089Swyllys if (rsa->dmq1 != NULL)
40933089Swyllys if ((rv = sslBN2KMFBN(rsa->dmq1, &kmfkey->exp2)) != KMF_OK)
40943089Swyllys goto cleanup;
40953089Swyllys
40963089Swyllys if (rsa->iqmp != NULL)
40973089Swyllys if ((rv = sslBN2KMFBN(rsa->iqmp, &kmfkey->coef)) != KMF_OK)
40983089Swyllys goto cleanup;
40993089Swyllys cleanup:
41003089Swyllys if (rv != KMF_OK)
41015051Swyllys kmf_free_raw_key(key);
41023089Swyllys else
41033089Swyllys key->keytype = KMF_RSA;
41043089Swyllys
41053089Swyllys /*
41063089Swyllys * Free the reference to this key, SSL will not actually free
41073089Swyllys * the memory until the refcount == 0, so this is safe.
41083089Swyllys */
41093089Swyllys RSA_free(rsa);
41103089Swyllys
41113089Swyllys return (rv);
41123089Swyllys }
41133089Swyllys
41143089Swyllys static KMF_RETURN
exportRawDSAKey(DSA * dsa,KMF_RAW_KEY_DATA * key)41153089Swyllys exportRawDSAKey(DSA *dsa, KMF_RAW_KEY_DATA *key)
41163089Swyllys {
41173089Swyllys KMF_RETURN rv;
41183089Swyllys KMF_RAW_DSA_KEY *kmfkey = &key->rawdata.dsa;
41193089Swyllys
41203089Swyllys (void) memset(kmfkey, 0, sizeof (KMF_RAW_DSA_KEY));
41213089Swyllys if ((rv = sslBN2KMFBN(dsa->p, &kmfkey->prime)) != KMF_OK)
41223089Swyllys goto cleanup;
41233089Swyllys
41243089Swyllys if ((rv = sslBN2KMFBN(dsa->q, &kmfkey->subprime)) != KMF_OK)
41253089Swyllys goto cleanup;
41263089Swyllys
41273089Swyllys if ((rv = sslBN2KMFBN(dsa->g, &kmfkey->base)) != KMF_OK)
41283089Swyllys goto cleanup;
41293089Swyllys
41303089Swyllys if ((rv = sslBN2KMFBN(dsa->priv_key, &kmfkey->value)) != KMF_OK)
41313089Swyllys goto cleanup;
41323089Swyllys
41333089Swyllys cleanup:
41343089Swyllys if (rv != KMF_OK)
41355051Swyllys kmf_free_raw_key(key);
41363089Swyllys else
41373089Swyllys key->keytype = KMF_DSA;
41383089Swyllys
41393089Swyllys /*
41403089Swyllys * Free the reference to this key, SSL will not actually free
41413089Swyllys * the memory until the refcount == 0, so this is safe.
41423089Swyllys */
41433089Swyllys DSA_free(dsa);
41443089Swyllys
41453089Swyllys return (rv);
41463089Swyllys }
41473089Swyllys
41483089Swyllys static KMF_RETURN
add_cert_to_list(KMF_HANDLE * kmfh,X509 * sslcert,KMF_X509_DER_CERT ** certlist,int * ncerts)41493089Swyllys add_cert_to_list(KMF_HANDLE *kmfh, X509 *sslcert,
41505536Swyllys KMF_X509_DER_CERT **certlist, int *ncerts)
41513089Swyllys {
41523089Swyllys KMF_RETURN rv = KMF_OK;
41535536Swyllys KMF_X509_DER_CERT *list = (*certlist);
41545536Swyllys KMF_X509_DER_CERT cert;
41553089Swyllys int n = (*ncerts);
41563089Swyllys
41573089Swyllys if (list == NULL) {
41585536Swyllys list = (KMF_X509_DER_CERT *)malloc(sizeof (KMF_X509_DER_CERT));
41593089Swyllys } else {
41605536Swyllys list = (KMF_X509_DER_CERT *)realloc(list,
41615536Swyllys sizeof (KMF_X509_DER_CERT) * (n + 1));
41623089Swyllys }
41633089Swyllys
41643089Swyllys if (list == NULL)
41653089Swyllys return (KMF_ERR_MEMORY);
41663089Swyllys
41675536Swyllys (void) memset(&cert, 0, sizeof (cert));
41685536Swyllys rv = ssl_cert2KMFDATA(kmfh, sslcert, &cert.certificate);
41693089Swyllys if (rv == KMF_OK) {
41705536Swyllys int len = 0;
41715536Swyllys /* Get the alias name for the cert if there is one */
41725536Swyllys char *a = (char *)X509_alias_get0(sslcert, &len);
41735536Swyllys if (a != NULL)
41745536Swyllys cert.kmf_private.label = strdup(a);
41755536Swyllys cert.kmf_private.keystore_type = KMF_KEYSTORE_OPENSSL;
41765536Swyllys
41773089Swyllys list[n] = cert;
41783089Swyllys (*ncerts) = n + 1;
41793089Swyllys
41803089Swyllys *certlist = list;
41813089Swyllys } else {
41823089Swyllys free(list);
41833089Swyllys }
41843089Swyllys
41853089Swyllys return (rv);
41863089Swyllys }
41873089Swyllys
41883089Swyllys static KMF_RETURN
add_key_to_list(KMF_RAW_KEY_DATA ** keylist,KMF_RAW_KEY_DATA * newkey,int * nkeys)41893089Swyllys add_key_to_list(KMF_RAW_KEY_DATA **keylist,
41903089Swyllys KMF_RAW_KEY_DATA *newkey, int *nkeys)
41913089Swyllys {
41923089Swyllys KMF_RAW_KEY_DATA *list = (*keylist);
41933089Swyllys int n = (*nkeys);
41943089Swyllys
41953089Swyllys if (list == NULL) {
41963089Swyllys list = (KMF_RAW_KEY_DATA *)malloc(sizeof (KMF_RAW_KEY_DATA));
41973089Swyllys } else {
41983089Swyllys list = (KMF_RAW_KEY_DATA *)realloc(list,
41994315Swyllys sizeof (KMF_RAW_KEY_DATA) * (n + 1));
42003089Swyllys }
42013089Swyllys
42023089Swyllys if (list == NULL)
42033089Swyllys return (KMF_ERR_MEMORY);
42043089Swyllys
42053089Swyllys list[n] = *newkey;
42063089Swyllys (*nkeys) = n + 1;
42073089Swyllys
42083089Swyllys *keylist = list;
42093089Swyllys
42103089Swyllys return (KMF_OK);
42113089Swyllys }
42123089Swyllys
42135536Swyllys static X509_ATTRIBUTE *
find_attr(STACK_OF (X509_ATTRIBUTE)* attrs,int nid)42145536Swyllys find_attr(STACK_OF(X509_ATTRIBUTE) *attrs, int nid)
42155536Swyllys {
42165536Swyllys X509_ATTRIBUTE *a;
42175536Swyllys int i;
42185536Swyllys
42195536Swyllys if (attrs == NULL)
42205536Swyllys return (NULL);
42215536Swyllys
42225536Swyllys for (i = 0; i < sk_X509_ATTRIBUTE_num(attrs); i++) {
422311673Sopensolaris@drydog.com /* LINTED E_BAD_PTR_CAST_ALIGN */
42245536Swyllys a = sk_X509_ATTRIBUTE_value(attrs, i);
42255536Swyllys if (OBJ_obj2nid(a->object) == nid)
42265536Swyllys return (a);
42275536Swyllys }
42285536Swyllys return (NULL);
42295536Swyllys }
42305536Swyllys
42315051Swyllys static KMF_RETURN
convertToRawKey(EVP_PKEY * pkey,KMF_RAW_KEY_DATA * key)42325051Swyllys convertToRawKey(EVP_PKEY *pkey, KMF_RAW_KEY_DATA *key)
42335051Swyllys {
42345051Swyllys KMF_RETURN rv = KMF_OK;
42355536Swyllys X509_ATTRIBUTE *attr;
42365051Swyllys
42375051Swyllys if (pkey == NULL || key == NULL)
42385051Swyllys return (KMF_ERR_BAD_PARAMETER);
42395051Swyllys /* Convert SSL key to raw key */
42405051Swyllys switch (pkey->type) {
42415051Swyllys case EVP_PKEY_RSA:
42425051Swyllys rv = exportRawRSAKey(EVP_PKEY_get1_RSA(pkey),
42435051Swyllys key);
42445051Swyllys if (rv != KMF_OK)
42455051Swyllys return (rv);
42465051Swyllys break;
42475051Swyllys case EVP_PKEY_DSA:
42485051Swyllys rv = exportRawDSAKey(EVP_PKEY_get1_DSA(pkey),
42495051Swyllys key);
42505051Swyllys if (rv != KMF_OK)
42515051Swyllys return (rv);
42525051Swyllys break;
42535051Swyllys default:
42545051Swyllys return (KMF_ERR_BAD_PARAMETER);
42555051Swyllys }
42565536Swyllys /*
42575536Swyllys * If friendlyName, add it to record.
42585536Swyllys */
42595536Swyllys attr = find_attr(pkey->attributes, NID_friendlyName);
42605536Swyllys if (attr != NULL) {
42615536Swyllys ASN1_TYPE *ty = NULL;
42625536Swyllys int numattr = sk_ASN1_TYPE_num(attr->value.set);
42635536Swyllys if (attr->single == 0 && numattr > 0) {
426411673Sopensolaris@drydog.com /* LINTED E_BAD_PTR_CAST_ALIGN */
42655536Swyllys ty = sk_ASN1_TYPE_value(attr->value.set, 0);
42665536Swyllys }
42675536Swyllys if (ty != NULL) {
42685536Swyllys key->label = uni2asc(ty->value.bmpstring->data,
42695536Swyllys ty->value.bmpstring->length);
42705536Swyllys }
42715536Swyllys } else {
42725536Swyllys key->label = NULL;
42735536Swyllys }
42745536Swyllys
42755536Swyllys /*
42765536Swyllys * If KeyID, add it to record as a KMF_DATA object.
42775536Swyllys */
42785536Swyllys attr = find_attr(pkey->attributes, NID_localKeyID);
42795536Swyllys if (attr != NULL) {
42805536Swyllys ASN1_TYPE *ty = NULL;
42815536Swyllys int numattr = sk_ASN1_TYPE_num(attr->value.set);
42825536Swyllys if (attr->single == 0 && numattr > 0) {
428311673Sopensolaris@drydog.com /* LINTED E_BAD_PTR_CAST_ALIGN */
42845536Swyllys ty = sk_ASN1_TYPE_value(attr->value.set, 0);
42855536Swyllys }
42865536Swyllys key->id.Data = (uchar_t *)malloc(
42875536Swyllys ty->value.octet_string->length);
42885536Swyllys if (key->id.Data == NULL)
42895536Swyllys return (KMF_ERR_MEMORY);
42905536Swyllys (void) memcpy(key->id.Data, ty->value.octet_string->data,
42915536Swyllys ty->value.octet_string->length);
42925536Swyllys key->id.Length = ty->value.octet_string->length;
42935536Swyllys } else {
42945536Swyllys (void) memset(&key->id, 0, sizeof (KMF_DATA));
42955536Swyllys }
42965051Swyllys
42975051Swyllys return (rv);
42985051Swyllys }
42993089Swyllys
43003089Swyllys static KMF_RETURN
convertPK12Objects(KMF_HANDLE * kmfh,STACK_OF (EVP_PKEY)* sslkeys,STACK_OF (X509)* sslcert,STACK_OF (X509)* sslcacerts,KMF_RAW_KEY_DATA ** keylist,int * nkeys,KMF_X509_DER_CERT ** certlist,int * ncerts)43013089Swyllys convertPK12Objects(
43023089Swyllys KMF_HANDLE *kmfh,
43035536Swyllys STACK_OF(EVP_PKEY) *sslkeys,
43045536Swyllys STACK_OF(X509) *sslcert,
43055536Swyllys STACK_OF(X509) *sslcacerts,
43063089Swyllys KMF_RAW_KEY_DATA **keylist, int *nkeys,
43075536Swyllys KMF_X509_DER_CERT **certlist, int *ncerts)
43083089Swyllys {
43093089Swyllys KMF_RETURN rv = KMF_OK;
43103089Swyllys KMF_RAW_KEY_DATA key;
43113089Swyllys int i;
43123089Swyllys
43135536Swyllys for (i = 0; sslkeys != NULL && i < sk_EVP_PKEY_num(sslkeys); i++) {
431411673Sopensolaris@drydog.com /* LINTED E_BAD_PTR_CAST_ALIGN */
43155536Swyllys EVP_PKEY *pkey = sk_EVP_PKEY_value(sslkeys, i);
43165536Swyllys rv = convertToRawKey(pkey, &key);
43175051Swyllys if (rv == KMF_OK)
43185051Swyllys rv = add_key_to_list(keylist, &key, nkeys);
43195051Swyllys
43203089Swyllys if (rv != KMF_OK)
43213089Swyllys return (rv);
43223089Swyllys }
43233089Swyllys
43243089Swyllys /* Now add the certificate to the certlist */
43255536Swyllys for (i = 0; sslcert != NULL && i < sk_X509_num(sslcert); i++) {
432611673Sopensolaris@drydog.com /* LINTED E_BAD_PTR_CAST_ALIGN */
43275536Swyllys X509 *cert = sk_X509_value(sslcert, i);
43285536Swyllys rv = add_cert_to_list(kmfh, cert, certlist, ncerts);
43293089Swyllys if (rv != KMF_OK)
43303089Swyllys return (rv);
43313089Swyllys }
43323089Swyllys
43333089Swyllys /* Also add any included CA certs to the list */
43343408Swyllys for (i = 0; sslcacerts != NULL && i < sk_X509_num(sslcacerts); i++) {
43353089Swyllys X509 *c;
43363089Swyllys /*
43373089Swyllys * sk_X509_value() is macro that embeds a cast to (X509 *).
43383089Swyllys * Here it translates into ((X509 *)sk_value((ca), (i))).
43393089Swyllys * Lint is complaining about the embedded casting, and
43403089Swyllys * to fix it, you need to fix openssl header files.
43413089Swyllys */
43423089Swyllys /* LINTED E_BAD_PTR_CAST_ALIGN */
43433089Swyllys c = sk_X509_value(sslcacerts, i);
43443089Swyllys
43453089Swyllys /* Now add the ca cert to the certlist */
43463089Swyllys rv = add_cert_to_list(kmfh, c, certlist, ncerts);
43473089Swyllys if (rv != KMF_OK)
43483089Swyllys return (rv);
43493089Swyllys }
43503089Swyllys return (rv);
43513089Swyllys }
43523089Swyllys
43533089Swyllys KMF_RETURN
openssl_import_objects(KMF_HANDLE * kmfh,char * filename,KMF_CREDENTIAL * cred,KMF_X509_DER_CERT ** certlist,int * ncerts,KMF_RAW_KEY_DATA ** keylist,int * nkeys)43545051Swyllys openssl_import_objects(KMF_HANDLE *kmfh,
43553408Swyllys char *filename, KMF_CREDENTIAL *cred,
43565536Swyllys KMF_X509_DER_CERT **certlist, int *ncerts,
43573408Swyllys KMF_RAW_KEY_DATA **keylist, int *nkeys)
43583408Swyllys {
43593408Swyllys KMF_RETURN rv = KMF_OK;
43603408Swyllys KMF_ENCODE_FORMAT format;
43615051Swyllys BIO *bio = NULL;
43625536Swyllys STACK_OF(EVP_PKEY) *privkeys = NULL;
43635536Swyllys STACK_OF(X509) *certs = NULL;
43645536Swyllys STACK_OF(X509) *cacerts = NULL;
43653408Swyllys
43663408Swyllys /*
43673408Swyllys * auto-detect the file format, regardless of what
43683408Swyllys * the 'format' parameters in the params say.
43693408Swyllys */
43705051Swyllys rv = kmf_get_file_format(filename, &format);
43713408Swyllys if (rv != KMF_OK) {
43723408Swyllys return (rv);
43733408Swyllys }
43743408Swyllys
43755051Swyllys /* This function only works for PEM or PKCS#12 files */
43763408Swyllys if (format != KMF_FORMAT_PEM &&
43775051Swyllys format != KMF_FORMAT_PEM_KEYPAIR &&
43785051Swyllys format != KMF_FORMAT_PKCS12)
43793408Swyllys return (KMF_ERR_ENCODING);
43803408Swyllys
43813408Swyllys *certlist = NULL;
43823408Swyllys *keylist = NULL;
43833408Swyllys *ncerts = 0;
43843408Swyllys *nkeys = 0;
43855051Swyllys
43865051Swyllys if (format == KMF_FORMAT_PKCS12) {
43875051Swyllys bio = BIO_new_file(filename, "rb");
43885051Swyllys if (bio == NULL) {
43895051Swyllys SET_ERROR(kmfh, ERR_get_error());
43905051Swyllys rv = KMF_ERR_OPEN_FILE;
43915051Swyllys goto end;
43925051Swyllys }
43935051Swyllys
43945051Swyllys rv = extract_pkcs12(bio, (uchar_t *)cred->cred,
43955536Swyllys (uint32_t)cred->credlen, &privkeys, &certs, &cacerts);
43965051Swyllys
43975051Swyllys if (rv == KMF_OK)
43985051Swyllys /* Convert keys and certs to exportable format */
43995536Swyllys rv = convertPK12Objects(kmfh, privkeys, certs, cacerts,
44005051Swyllys keylist, nkeys, certlist, ncerts);
44015051Swyllys } else {
44025536Swyllys EVP_PKEY *pkey;
44035536Swyllys KMF_DATA *certdata = NULL;
44045536Swyllys KMF_X509_DER_CERT *kmfcerts = NULL;
44055536Swyllys int i;
44065051Swyllys rv = extract_pem(kmfh, NULL, NULL, NULL, filename,
44075051Swyllys (uchar_t *)cred->cred, (uint32_t)cred->credlen,
44085536Swyllys &pkey, &certdata, ncerts);
44095051Swyllys
44105051Swyllys /* Reached end of import file? */
44115536Swyllys if (rv == KMF_OK && pkey != NULL) {
44125536Swyllys privkeys = sk_EVP_PKEY_new_null();
44135536Swyllys if (privkeys == NULL) {
44145536Swyllys rv = KMF_ERR_MEMORY;
44155536Swyllys goto end;
44165536Swyllys }
44175536Swyllys (void) sk_EVP_PKEY_push(privkeys, pkey);
44185536Swyllys /* convert the certificate list here */
44195536Swyllys if (*ncerts > 0 && certlist != NULL) {
442011973Swyllys.ingersoll@sun.com kmfcerts = (KMF_X509_DER_CERT *)calloc(*ncerts,
44215536Swyllys sizeof (KMF_X509_DER_CERT));
44225536Swyllys if (kmfcerts == NULL) {
44235536Swyllys rv = KMF_ERR_MEMORY;
44245536Swyllys goto end;
44255536Swyllys }
44265536Swyllys for (i = 0; i < *ncerts; i++) {
44275536Swyllys kmfcerts[i].certificate = certdata[i];
44285536Swyllys kmfcerts[i].kmf_private.keystore_type =
44295536Swyllys KMF_KEYSTORE_OPENSSL;
44305536Swyllys }
44315536Swyllys *certlist = kmfcerts;
44325536Swyllys }
44335536Swyllys /*
44345536Swyllys * Convert keys to exportable format, the certs
44355536Swyllys * are already OK.
44365536Swyllys */
44375536Swyllys rv = convertPK12Objects(kmfh, privkeys, NULL, NULL,
44385051Swyllys keylist, nkeys, NULL, NULL);
44395536Swyllys }
44405536Swyllys }
44413408Swyllys end:
44425051Swyllys if (bio != NULL)
44433089Swyllys (void) BIO_free(bio);
44443089Swyllys
44455536Swyllys if (privkeys)
44465536Swyllys sk_EVP_PKEY_pop_free(privkeys, EVP_PKEY_free);
44475536Swyllys if (certs)
44485536Swyllys sk_X509_pop_free(certs, X509_free);
44495051Swyllys if (cacerts)
44505536Swyllys sk_X509_pop_free(cacerts, X509_free);
44515051Swyllys
44523089Swyllys return (rv);
44533089Swyllys }
44543089Swyllys
44553089Swyllys static KMF_RETURN
create_deskey(DES_cblock ** deskey)44563089Swyllys create_deskey(DES_cblock **deskey)
44573089Swyllys {
44583089Swyllys DES_cblock *key;
44593089Swyllys
44603089Swyllys key = (DES_cblock *) malloc(sizeof (DES_cblock));
44613089Swyllys if (key == NULL) {
44623089Swyllys return (KMF_ERR_MEMORY);
44633089Swyllys }
44643089Swyllys
44653089Swyllys if (DES_random_key(key) == 0) {
44663089Swyllys free(key);
44673089Swyllys return (KMF_ERR_KEYGEN_FAILED);
44683089Swyllys }
44693089Swyllys
44703089Swyllys *deskey = key;
44713089Swyllys return (KMF_OK);
44723089Swyllys }
44733089Swyllys
44743089Swyllys #define KEYGEN_RETRY 3
44753089Swyllys #define DES3_KEY_SIZE 24
44763089Swyllys
44773089Swyllys static KMF_RETURN
create_des3key(unsigned char ** des3key)44783089Swyllys create_des3key(unsigned char **des3key)
44793089Swyllys {
44803089Swyllys KMF_RETURN ret = KMF_OK;
44813089Swyllys DES_cblock *deskey1 = NULL;
44823089Swyllys DES_cblock *deskey2 = NULL;
44833089Swyllys DES_cblock *deskey3 = NULL;
44843089Swyllys unsigned char *newkey = NULL;
44853089Swyllys int retry;
44863089Swyllys
44873089Swyllys if ((newkey = malloc(DES3_KEY_SIZE)) == NULL) {
44883089Swyllys return (KMF_ERR_MEMORY);
44893089Swyllys }
44903089Swyllys
44913089Swyllys /* create the 1st DES key */
44923089Swyllys if ((ret = create_deskey(&deskey1)) != KMF_OK) {
44933089Swyllys goto out;
44943089Swyllys }
44953089Swyllys
44963089Swyllys /*
44973089Swyllys * Create the 2nd DES key and make sure its value is different
44983089Swyllys * from the 1st DES key.
44993089Swyllys */
45003089Swyllys retry = 0;
45013089Swyllys do {
45023089Swyllys if (deskey2 != NULL) {
45033089Swyllys free(deskey2);
45043089Swyllys deskey2 = NULL;
45053089Swyllys }
45063089Swyllys
45073089Swyllys if ((ret = create_deskey(&deskey2)) != KMF_OK) {
45083089Swyllys goto out;
45093089Swyllys }
45103089Swyllys
45113089Swyllys if (memcmp((const void *) deskey1, (const void *) deskey2, 8)
45123089Swyllys == 0) {
45133089Swyllys ret = KMF_ERR_KEYGEN_FAILED;
45143089Swyllys retry++;
45153089Swyllys }
45163089Swyllys } while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY);
45173089Swyllys
45183089Swyllys if (ret != KMF_OK) {
45193089Swyllys goto out;
45203089Swyllys }
45213089Swyllys
45223089Swyllys /*
45233089Swyllys * Create the 3rd DES key and make sure its value is different
45243089Swyllys * from the 2nd DES key.
45253089Swyllys */
45263089Swyllys retry = 0;
45273089Swyllys do {
45283089Swyllys if (deskey3 != NULL) {
45293089Swyllys free(deskey3);
45303089Swyllys deskey3 = NULL;
45313089Swyllys }
45323089Swyllys
45333089Swyllys if ((ret = create_deskey(&deskey3)) != KMF_OK) {
45343089Swyllys goto out;
45353089Swyllys }
45363089Swyllys
45373089Swyllys if (memcmp((const void *)deskey2, (const void *)deskey3, 8)
45383089Swyllys == 0) {
45393089Swyllys ret = KMF_ERR_KEYGEN_FAILED;
45403089Swyllys retry++;
45413089Swyllys }
45423089Swyllys } while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY);
45433089Swyllys
45443089Swyllys if (ret != KMF_OK) {
45453089Swyllys goto out;
45463089Swyllys }
45473089Swyllys
45483089Swyllys /* Concatenate 3 DES keys into a DES3 key */
45493089Swyllys (void) memcpy((void *)newkey, (const void *)deskey1, 8);
45503089Swyllys (void) memcpy((void *)(newkey + 8), (const void *)deskey2, 8);
45513089Swyllys (void) memcpy((void *)(newkey + 16), (const void *)deskey3, 8);
45523089Swyllys *des3key = newkey;
45533089Swyllys
45543089Swyllys out:
45553089Swyllys if (deskey1 != NULL)
45563089Swyllys free(deskey1);
45573089Swyllys
45583089Swyllys if (deskey2 != NULL)
45593089Swyllys free(deskey2);
45603089Swyllys
45613089Swyllys if (deskey3 != NULL)
45623089Swyllys free(deskey3);
45633089Swyllys
45643089Swyllys if (ret != KMF_OK && newkey != NULL)
45653089Swyllys free(newkey);
45663089Swyllys
45673089Swyllys return (ret);
45683089Swyllys }
45693089Swyllys
45703089Swyllys KMF_RETURN
OpenSSL_CreateSymKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)45715051Swyllys OpenSSL_CreateSymKey(KMF_HANDLE_T handle,
45725051Swyllys int numattr, KMF_ATTRIBUTE *attrlist)
45733089Swyllys {
45743089Swyllys KMF_RETURN ret = KMF_OK;
45753089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
45763089Swyllys char *fullpath = NULL;
45773089Swyllys KMF_RAW_SYM_KEY *rkey = NULL;
45783089Swyllys DES_cblock *deskey = NULL;
45793089Swyllys unsigned char *des3key = NULL;
45803089Swyllys unsigned char *random = NULL;
45813089Swyllys int fd = -1;
45825051Swyllys KMF_KEY_HANDLE *symkey;
45835051Swyllys KMF_KEY_ALG keytype;
45845051Swyllys uint32_t keylen;
45855051Swyllys uint32_t keylen_size = sizeof (keylen);
45865051Swyllys char *dirpath;
45875051Swyllys char *keyfile;
45883089Swyllys
45893089Swyllys if (kmfh == NULL)
45903089Swyllys return (KMF_ERR_UNINITIALIZED);
45913089Swyllys
45925051Swyllys symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
45935051Swyllys if (symkey == NULL)
45945051Swyllys return (KMF_ERR_BAD_PARAMETER);
45955051Swyllys
45965051Swyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
45975051Swyllys
45985051Swyllys keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
45995051Swyllys if (keyfile == NULL)
46003089Swyllys return (KMF_ERR_BAD_PARAMETER);
46015051Swyllys
46025051Swyllys ret = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
46035051Swyllys (void *)&keytype, NULL);
46045051Swyllys if (ret != KMF_OK)
46055051Swyllys return (KMF_ERR_BAD_PARAMETER);
46065051Swyllys
46075051Swyllys ret = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
46085051Swyllys &keylen, &keylen_size);
46095051Swyllys if (ret == KMF_ERR_ATTR_NOT_FOUND &&
46105051Swyllys (keytype == KMF_DES || keytype == KMF_DES3))
46115051Swyllys /* keylength is not required for DES and 3DES */
46125051Swyllys ret = KMF_OK;
46135051Swyllys if (ret != KMF_OK)
46145051Swyllys return (KMF_ERR_BAD_PARAMETER);
46155051Swyllys
46165051Swyllys fullpath = get_fullpath(dirpath, keyfile);
46173089Swyllys if (fullpath == NULL)
46183089Swyllys return (KMF_ERR_BAD_PARAMETER);
46193089Swyllys
46203089Swyllys /* If the requested file exists, return an error */
46215051Swyllys if (test_for_file(fullpath, 0400) == 1) {
46223089Swyllys free(fullpath);
46233089Swyllys return (KMF_ERR_DUPLICATE_KEYFILE);
46243089Swyllys }
46253089Swyllys
46263089Swyllys fd = open(fullpath, O_CREAT|O_TRUNC|O_RDWR, 0400);
46273089Swyllys if (fd == -1) {
46283089Swyllys ret = KMF_ERR_OPEN_FILE;
46293089Swyllys goto out;
46303089Swyllys }
46313089Swyllys
46323089Swyllys rkey = malloc(sizeof (KMF_RAW_SYM_KEY));
46333089Swyllys if (rkey == NULL) {
46343089Swyllys ret = KMF_ERR_MEMORY;
46353089Swyllys goto out;
46363089Swyllys }
46373089Swyllys (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY));
46383089Swyllys
46395051Swyllys if (keytype == KMF_DES) {
46403089Swyllys if ((ret = create_deskey(&deskey)) != KMF_OK) {
46413089Swyllys goto out;
46423089Swyllys }
46433089Swyllys rkey->keydata.val = (uchar_t *)deskey;
46443089Swyllys rkey->keydata.len = 8;
46453089Swyllys
46463089Swyllys symkey->keyalg = KMF_DES;
46473089Swyllys
46485051Swyllys } else if (keytype == KMF_DES3) {
46493089Swyllys if ((ret = create_des3key(&des3key)) != KMF_OK) {
46503089Swyllys goto out;
46513089Swyllys }
46523089Swyllys rkey->keydata.val = (uchar_t *)des3key;
46533089Swyllys rkey->keydata.len = DES3_KEY_SIZE;
46543089Swyllys symkey->keyalg = KMF_DES3;
46553825Swyllys
46565051Swyllys } else if (keytype == KMF_AES || keytype == KMF_RC4 ||
46575051Swyllys keytype == KMF_GENERIC_SECRET) {
46583089Swyllys int bytes;
46593089Swyllys
46605051Swyllys if (keylen % 8 != 0) {
46613089Swyllys ret = KMF_ERR_BAD_KEY_SIZE;
46623089Swyllys goto out;
46633089Swyllys }
46643089Swyllys
46655051Swyllys if (keytype == KMF_AES) {
46665051Swyllys if (keylen != 128 &&
46675051Swyllys keylen != 192 &&
46685051Swyllys keylen != 256) {
46693089Swyllys ret = KMF_ERR_BAD_KEY_SIZE;
46703089Swyllys goto out;
46713089Swyllys }
46723089Swyllys }
46733089Swyllys
46745051Swyllys bytes = keylen/8;
46753089Swyllys random = malloc(bytes);
46763089Swyllys if (random == NULL) {
46773089Swyllys ret = KMF_ERR_MEMORY;
46783089Swyllys goto out;
46793089Swyllys }
46803089Swyllys if (RAND_bytes(random, bytes) != 1) {
46813089Swyllys ret = KMF_ERR_KEYGEN_FAILED;
46823089Swyllys goto out;
46833089Swyllys }
46843089Swyllys
46853089Swyllys rkey->keydata.val = (uchar_t *)random;
46863089Swyllys rkey->keydata.len = bytes;
46875051Swyllys symkey->keyalg = keytype;
46883089Swyllys
46893089Swyllys } else {
46903089Swyllys ret = KMF_ERR_BAD_KEY_TYPE;
46913089Swyllys goto out;
46923089Swyllys }
46933089Swyllys
46943089Swyllys (void) write(fd, (const void *) rkey->keydata.val, rkey->keydata.len);
46953089Swyllys
46963089Swyllys symkey->kstype = KMF_KEYSTORE_OPENSSL;
46973089Swyllys symkey->keyclass = KMF_SYMMETRIC;
46983089Swyllys symkey->keylabel = (char *)fullpath;
46993089Swyllys symkey->israw = TRUE;
47003089Swyllys symkey->keyp = rkey;
47013089Swyllys
47023089Swyllys out:
47033089Swyllys if (fd != -1)
47043089Swyllys (void) close(fd);
47053089Swyllys
47063089Swyllys if (ret != KMF_OK && fullpath != NULL) {
47073089Swyllys free(fullpath);
47083089Swyllys }
47093089Swyllys if (ret != KMF_OK) {
47105051Swyllys kmf_free_raw_sym_key(rkey);
47113089Swyllys symkey->keyp = NULL;
47123089Swyllys symkey->keyalg = KMF_KEYALG_NONE;
47133089Swyllys }
47143089Swyllys
47153089Swyllys return (ret);
47163089Swyllys }
47173089Swyllys
47183089Swyllys /*
47193089Swyllys * Check a file to see if it is a CRL file with PEM or DER format.
47203089Swyllys * If success, return its format in the "pformat" argument.
47213089Swyllys */
47223089Swyllys KMF_RETURN
OpenSSL_IsCRLFile(KMF_HANDLE_T handle,char * filename,int * pformat)47233089Swyllys OpenSSL_IsCRLFile(KMF_HANDLE_T handle, char *filename, int *pformat)
47243089Swyllys {
47253089Swyllys KMF_RETURN ret = KMF_OK;
47263089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
47273089Swyllys BIO *bio = NULL;
47283089Swyllys X509_CRL *xcrl = NULL;
47293089Swyllys
47303089Swyllys if (filename == NULL) {
47313089Swyllys return (KMF_ERR_BAD_PARAMETER);
47323089Swyllys }
47333089Swyllys
47343089Swyllys bio = BIO_new_file(filename, "rb");
47353089Swyllys if (bio == NULL) {
47363089Swyllys SET_ERROR(kmfh, ERR_get_error());
47373089Swyllys ret = KMF_ERR_OPEN_FILE;
47383089Swyllys goto out;
47393089Swyllys }
47403089Swyllys
47413089Swyllys if ((xcrl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)) != NULL) {
47423089Swyllys *pformat = KMF_FORMAT_PEM;
47433089Swyllys goto out;
47443089Swyllys }
47453089Swyllys (void) BIO_free(bio);
47463089Swyllys
47473089Swyllys /*
47483089Swyllys * Now try to read it as raw DER data.
47493089Swyllys */
47503089Swyllys bio = BIO_new_file(filename, "rb");
47513089Swyllys if (bio == NULL) {
47523089Swyllys SET_ERROR(kmfh, ERR_get_error());
47533089Swyllys ret = KMF_ERR_OPEN_FILE;
47543089Swyllys goto out;
47553089Swyllys }
47563089Swyllys
47573089Swyllys if ((xcrl = d2i_X509_CRL_bio(bio, NULL)) != NULL) {
47583089Swyllys *pformat = KMF_FORMAT_ASN1;
47593089Swyllys } else {
47603089Swyllys ret = KMF_ERR_BAD_CRLFILE;
47613089Swyllys }
47623089Swyllys
47633089Swyllys out:
47643089Swyllys if (bio != NULL)
47653089Swyllys (void) BIO_free(bio);
47663089Swyllys
47673089Swyllys if (xcrl != NULL)
47683089Swyllys X509_CRL_free(xcrl);
47693089Swyllys
47703089Swyllys return (ret);
47713089Swyllys }
47723089Swyllys
47733089Swyllys KMF_RETURN
OpenSSL_GetSymKeyValue(KMF_HANDLE_T handle,KMF_KEY_HANDLE * symkey,KMF_RAW_SYM_KEY * rkey)47743089Swyllys OpenSSL_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey,
47753089Swyllys KMF_RAW_SYM_KEY *rkey)
47763089Swyllys {
47773089Swyllys KMF_RETURN rv = KMF_OK;
47783089Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
47793089Swyllys KMF_DATA keyvalue;
47803089Swyllys
47813089Swyllys if (kmfh == NULL)
47823089Swyllys return (KMF_ERR_UNINITIALIZED);
47833089Swyllys
47843089Swyllys if (symkey == NULL || rkey == NULL)
47853089Swyllys return (KMF_ERR_BAD_PARAMETER);
47863089Swyllys else if (symkey->keyclass != KMF_SYMMETRIC)
47873089Swyllys return (KMF_ERR_BAD_KEY_CLASS);
47883089Swyllys
47893089Swyllys if (symkey->israw) {
47903089Swyllys KMF_RAW_SYM_KEY *rawkey = (KMF_RAW_SYM_KEY *)symkey->keyp;
47913089Swyllys
47923089Swyllys if (rawkey == NULL ||
47933089Swyllys rawkey->keydata.val == NULL ||
47943089Swyllys rawkey->keydata.len == 0)
47953089Swyllys return (KMF_ERR_BAD_KEYHANDLE);
47963089Swyllys
47973089Swyllys rkey->keydata.len = rawkey->keydata.len;
47983089Swyllys if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL)
47993089Swyllys return (KMF_ERR_MEMORY);
48003089Swyllys (void) memcpy(rkey->keydata.val, rawkey->keydata.val,
48013089Swyllys rkey->keydata.len);
48023089Swyllys } else {
48035051Swyllys rv = kmf_read_input_file(handle, symkey->keylabel, &keyvalue);
48043089Swyllys if (rv != KMF_OK)
48053089Swyllys return (rv);
48063089Swyllys rkey->keydata.len = keyvalue.Length;
48073089Swyllys rkey->keydata.val = keyvalue.Data;
48083089Swyllys }
48093089Swyllys
48103089Swyllys return (rv);
48113089Swyllys }
48123754Swyllys
48133754Swyllys /*
48145051Swyllys * substitute for the unsafe access(2) function.
48155051Swyllys * If the file in question already exists, return 1.
48165051Swyllys * else 0. If an error occurs during testing (other
48175051Swyllys * than EEXIST), return -1.
48185051Swyllys */
48195051Swyllys static int
test_for_file(char * filename,mode_t mode)48205051Swyllys test_for_file(char *filename, mode_t mode)
48215051Swyllys {
48225051Swyllys int fd;
48235051Swyllys
48245051Swyllys /*
48255051Swyllys * Try to create the file with the EXCL flag.
48265051Swyllys * The call should fail if the file exists.
48275051Swyllys */
48285051Swyllys fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, mode);
48295051Swyllys if (fd == -1 && errno == EEXIST)
48305051Swyllys return (1);
48315051Swyllys else if (fd == -1) /* some other error */
48325051Swyllys return (-1);
48335051Swyllys
48345051Swyllys /* The file did NOT exist. Delete the testcase. */
48355051Swyllys (void) close(fd);
48365051Swyllys (void) unlink(filename);
48375051Swyllys return (0);
48385051Swyllys }
48395051Swyllys
48405051Swyllys KMF_RETURN
OpenSSL_StoreKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)48415051Swyllys OpenSSL_StoreKey(KMF_HANDLE_T handle, int numattr,
48425051Swyllys KMF_ATTRIBUTE *attrlist)
48435051Swyllys {
48445051Swyllys KMF_RETURN rv = KMF_OK;
48455051Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
48465051Swyllys KMF_KEY_HANDLE *pubkey = NULL, *prikey = NULL;
48475051Swyllys KMF_RAW_KEY_DATA *rawkey;
48485051Swyllys EVP_PKEY *pkey = NULL;
48495051Swyllys KMF_ENCODE_FORMAT format = KMF_FORMAT_PEM;
48505051Swyllys KMF_CREDENTIAL cred = {NULL, 0};
48515051Swyllys BIO *out = NULL;
48525051Swyllys int keys = 0;
48535051Swyllys char *fullpath = NULL;
48545051Swyllys char *keyfile = NULL;
48555051Swyllys char *dirpath = NULL;
48565051Swyllys
48575051Swyllys pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr);
48585051Swyllys if (pubkey != NULL)
48595051Swyllys keys++;
48605051Swyllys
48615051Swyllys prikey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr);
48625051Swyllys if (prikey != NULL)
48635051Swyllys keys++;
48645051Swyllys
48655051Swyllys rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attrlist, numattr);
48665051Swyllys if (rawkey != NULL)
48675051Swyllys keys++;
48685051Swyllys
48695051Swyllys /*
48705051Swyllys * Exactly 1 type of key must be passed to this function.
48715051Swyllys */
48725051Swyllys if (keys != 1)
48735051Swyllys return (KMF_ERR_BAD_PARAMETER);
48745051Swyllys
48755051Swyllys keyfile = (char *)kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist,
48765051Swyllys numattr);
48775051Swyllys if (keyfile == NULL)
48785051Swyllys return (KMF_ERR_BAD_PARAMETER);
48795051Swyllys
48805051Swyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
48815051Swyllys
48825051Swyllys fullpath = get_fullpath(dirpath, keyfile);
48835051Swyllys
48845051Swyllys /* Once we have the full path, we don't need the pieces */
48855051Swyllys if (fullpath == NULL)
48865051Swyllys return (KMF_ERR_BAD_PARAMETER);
48875051Swyllys
48885051Swyllys /* If the requested file exists, return an error */
48895051Swyllys if (test_for_file(fullpath, 0400) == 1) {
48905051Swyllys free(fullpath);
48915051Swyllys return (KMF_ERR_DUPLICATE_KEYFILE);
48925051Swyllys }
48935051Swyllys
48945051Swyllys rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
48955051Swyllys &format, NULL);
48965051Swyllys if (rv != KMF_OK)
48975051Swyllys /* format is optional. */
48985051Swyllys rv = KMF_OK;
48995051Swyllys
49005051Swyllys /* CRED is not required for OpenSSL files */
49015051Swyllys (void) kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
49025051Swyllys &cred, NULL);
49035051Swyllys
49045051Swyllys /* Store the private key to the keyfile */
49055051Swyllys out = BIO_new_file(fullpath, "wb");
49065051Swyllys if (out == NULL) {
49075051Swyllys SET_ERROR(kmfh, ERR_get_error());
49085051Swyllys rv = KMF_ERR_OPEN_FILE;
49095051Swyllys goto end;
49105051Swyllys }
49115051Swyllys
49125051Swyllys if (prikey != NULL && prikey->keyp != NULL) {
49135051Swyllys if (prikey->keyalg == KMF_RSA ||
49145051Swyllys prikey->keyalg == KMF_DSA) {
49155051Swyllys pkey = (EVP_PKEY *)prikey->keyp;
49165051Swyllys
49175051Swyllys rv = ssl_write_key(kmfh, format,
49185051Swyllys out, &cred, pkey, TRUE);
49195051Swyllys
49205051Swyllys if (rv == KMF_OK && prikey->keylabel == NULL) {
49215051Swyllys prikey->keylabel = strdup(fullpath);
49225051Swyllys if (prikey->keylabel == NULL)
49235051Swyllys rv = KMF_ERR_MEMORY;
49245051Swyllys }
49255051Swyllys }
49265051Swyllys } else if (pubkey != NULL && pubkey->keyp != NULL) {
49275051Swyllys if (pubkey->keyalg == KMF_RSA ||
49285051Swyllys pubkey->keyalg == KMF_DSA) {
49295051Swyllys pkey = (EVP_PKEY *)pubkey->keyp;
49305051Swyllys
49315051Swyllys rv = ssl_write_key(kmfh, format,
49325051Swyllys out, &cred, pkey, FALSE);
49335051Swyllys
49345051Swyllys if (rv == KMF_OK && pubkey->keylabel == NULL) {
49355051Swyllys pubkey->keylabel = strdup(fullpath);
49365051Swyllys if (pubkey->keylabel == NULL)
49375051Swyllys rv = KMF_ERR_MEMORY;
49385051Swyllys }
49395051Swyllys }
49405051Swyllys } else if (rawkey != NULL) {
49415051Swyllys if (rawkey->keytype == KMF_RSA) {
49425051Swyllys pkey = ImportRawRSAKey(&rawkey->rawdata.rsa);
49435051Swyllys } else if (rawkey->keytype == KMF_DSA) {
49445051Swyllys pkey = ImportRawDSAKey(&rawkey->rawdata.dsa);
49455051Swyllys } else {
49465051Swyllys rv = KMF_ERR_BAD_PARAMETER;
49475051Swyllys }
49485536Swyllys if (pkey != NULL) {
49495637Swyllys KMF_KEY_CLASS kclass = KMF_ASYM_PRI;
49505637Swyllys
49515637Swyllys rv = kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr,
49525637Swyllys (void *)&kclass, NULL);
49535637Swyllys if (rv != KMF_OK)
49545637Swyllys rv = KMF_OK;
49555536Swyllys rv = ssl_write_key(kmfh, format, out,
49565637Swyllys &cred, pkey, (kclass == KMF_ASYM_PRI));
49575536Swyllys EVP_PKEY_free(pkey);
49585536Swyllys }
49595051Swyllys }
49605051Swyllys
49615051Swyllys end:
49625051Swyllys
49635051Swyllys if (out)
49645051Swyllys (void) BIO_free(out);
49655051Swyllys
49665536Swyllys
49675051Swyllys if (rv == KMF_OK)
49685051Swyllys (void) chmod(fullpath, 0400);
49695051Swyllys
49705051Swyllys free(fullpath);
49715051Swyllys return (rv);
49725051Swyllys }
49735051Swyllys
49745051Swyllys KMF_RETURN
OpenSSL_ImportCRL(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)49755051Swyllys OpenSSL_ImportCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
49765051Swyllys {
49775051Swyllys KMF_RETURN ret = KMF_OK;
49785051Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
49795051Swyllys X509_CRL *xcrl = NULL;
49805051Swyllys X509 *xcert = NULL;
49815051Swyllys EVP_PKEY *pkey;
49825051Swyllys KMF_ENCODE_FORMAT format;
49835051Swyllys BIO *in = NULL, *out = NULL;
49845051Swyllys int openssl_ret = 0;
49855051Swyllys KMF_ENCODE_FORMAT outformat;
49865051Swyllys boolean_t crlcheck = FALSE;
49875051Swyllys char *certfile, *dirpath, *crlfile, *incrl, *outcrl, *outcrlfile;
49885051Swyllys
49895051Swyllys if (numattr == 0 || attrlist == NULL) {
49905051Swyllys return (KMF_ERR_BAD_PARAMETER);
49915051Swyllys }
49925051Swyllys
49935051Swyllys /* CRL check is optional */
49945051Swyllys (void) kmf_get_attr(KMF_CRL_CHECK_ATTR, attrlist, numattr,
49955051Swyllys &crlcheck, NULL);
49965051Swyllys
49975051Swyllys certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
49985051Swyllys if (crlcheck == B_TRUE && certfile == NULL) {
49995051Swyllys return (KMF_ERR_BAD_CERTFILE);
50005051Swyllys }
50015051Swyllys
50025051Swyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
50035051Swyllys incrl = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, attrlist, numattr);
50045051Swyllys outcrl = kmf_get_attr_ptr(KMF_CRL_OUTFILE_ATTR, attrlist, numattr);
50055051Swyllys
50065051Swyllys crlfile = get_fullpath(dirpath, incrl);
50075051Swyllys
50085051Swyllys if (crlfile == NULL)
50095051Swyllys return (KMF_ERR_BAD_CRLFILE);
50105051Swyllys
50115051Swyllys outcrlfile = get_fullpath(dirpath, outcrl);
50125051Swyllys if (outcrlfile == NULL)
50135051Swyllys return (KMF_ERR_BAD_CRLFILE);
50145051Swyllys
50155051Swyllys if (isdir(outcrlfile)) {
50165051Swyllys free(outcrlfile);
50175051Swyllys return (KMF_ERR_BAD_CRLFILE);
50185051Swyllys }
50195051Swyllys
50205051Swyllys ret = kmf_is_crl_file(handle, crlfile, &format);
50215051Swyllys if (ret != KMF_OK) {
50225051Swyllys free(outcrlfile);
50235051Swyllys return (ret);
50245051Swyllys }
50255051Swyllys
50265051Swyllys in = BIO_new_file(crlfile, "rb");
50275051Swyllys if (in == NULL) {
50285051Swyllys SET_ERROR(kmfh, ERR_get_error());
50295051Swyllys ret = KMF_ERR_OPEN_FILE;
50305051Swyllys goto end;
50315051Swyllys }
50325051Swyllys
50335051Swyllys if (format == KMF_FORMAT_ASN1) {
50345051Swyllys xcrl = d2i_X509_CRL_bio(in, NULL);
50355051Swyllys } else if (format == KMF_FORMAT_PEM) {
50365051Swyllys xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
50375051Swyllys }
50385051Swyllys
50395051Swyllys if (xcrl == NULL) {
50405051Swyllys SET_ERROR(kmfh, ERR_get_error());
50415051Swyllys ret = KMF_ERR_BAD_CRLFILE;
50425051Swyllys goto end;
50435051Swyllys }
50445051Swyllys
50455051Swyllys /* If bypasscheck is specified, no need to verify. */
50465051Swyllys if (crlcheck == B_FALSE)
50475051Swyllys goto output;
50485051Swyllys
50495051Swyllys ret = kmf_is_cert_file(handle, certfile, &format);
50505051Swyllys if (ret != KMF_OK)
50515051Swyllys goto end;
50525051Swyllys
50535051Swyllys /* Read in the CA cert file and convert to X509 */
50545051Swyllys if (BIO_read_filename(in, certfile) <= 0) {
50555051Swyllys SET_ERROR(kmfh, ERR_get_error());
50565051Swyllys ret = KMF_ERR_OPEN_FILE;
50575051Swyllys goto end;
50585051Swyllys }
50595051Swyllys
50605051Swyllys if (format == KMF_FORMAT_ASN1) {
50615051Swyllys xcert = d2i_X509_bio(in, NULL);
50625051Swyllys } else if (format == KMF_FORMAT_PEM) {
50635051Swyllys xcert = PEM_read_bio_X509(in, NULL, NULL, NULL);
50645051Swyllys } else {
50655051Swyllys ret = KMF_ERR_BAD_CERT_FORMAT;
50665051Swyllys goto end;
50675051Swyllys }
50685051Swyllys
50695051Swyllys if (xcert == NULL) {
50705051Swyllys SET_ERROR(kmfh, ERR_get_error());
50715051Swyllys ret = KMF_ERR_BAD_CERT_FORMAT;
50725051Swyllys goto end;
50735051Swyllys }
50745051Swyllys /* Now get the public key from the CA cert */
50755051Swyllys pkey = X509_get_pubkey(xcert);
50765051Swyllys if (pkey == NULL) {
50775051Swyllys SET_ERROR(kmfh, ERR_get_error());
50785051Swyllys ret = KMF_ERR_BAD_CERTFILE;
50795051Swyllys goto end;
50805051Swyllys }
50815051Swyllys
50825051Swyllys /* Verify the CRL with the CA's public key */
50835051Swyllys openssl_ret = X509_CRL_verify(xcrl, pkey);
50845051Swyllys EVP_PKEY_free(pkey);
50855051Swyllys if (openssl_ret > 0) {
50865051Swyllys ret = KMF_OK; /* verify succeed */
50875051Swyllys } else {
50885051Swyllys SET_ERROR(kmfh, openssl_ret);
50895051Swyllys ret = KMF_ERR_BAD_CRLFILE;
50905051Swyllys }
50915051Swyllys
50925051Swyllys output:
50935051Swyllys ret = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
50945051Swyllys &outformat, NULL);
50955051Swyllys if (ret != KMF_OK) {
50965051Swyllys ret = KMF_OK;
50975051Swyllys outformat = KMF_FORMAT_PEM;
50985051Swyllys }
50995051Swyllys
51005051Swyllys out = BIO_new_file(outcrlfile, "wb");
51015051Swyllys if (out == NULL) {
51025051Swyllys SET_ERROR(kmfh, ERR_get_error());
51035051Swyllys ret = KMF_ERR_OPEN_FILE;
51045051Swyllys goto end;
51055051Swyllys }
51065051Swyllys
51075051Swyllys if (outformat == KMF_FORMAT_ASN1) {
51085051Swyllys openssl_ret = (int)i2d_X509_CRL_bio(out, xcrl);
51095051Swyllys } else if (outformat == KMF_FORMAT_PEM) {
51105051Swyllys openssl_ret = PEM_write_bio_X509_CRL(out, xcrl);
51115051Swyllys } else {
51125051Swyllys ret = KMF_ERR_BAD_PARAMETER;
51135051Swyllys goto end;
51145051Swyllys }
51155051Swyllys
51165051Swyllys if (openssl_ret <= 0) {
51175051Swyllys SET_ERROR(kmfh, ERR_get_error());
51185051Swyllys ret = KMF_ERR_WRITE_FILE;
51195051Swyllys } else {
51205051Swyllys ret = KMF_OK;
51215051Swyllys }
51225051Swyllys
51235051Swyllys end:
51245051Swyllys if (xcrl != NULL)
51255051Swyllys X509_CRL_free(xcrl);
51265051Swyllys
51275051Swyllys if (xcert != NULL)
51285051Swyllys X509_free(xcert);
51295051Swyllys
51305051Swyllys if (in != NULL)
51315051Swyllys (void) BIO_free(in);
51325051Swyllys
51335051Swyllys if (out != NULL)
51345051Swyllys (void) BIO_free(out);
51355051Swyllys
51365051Swyllys if (outcrlfile != NULL)
51375051Swyllys free(outcrlfile);
51385051Swyllys
51395051Swyllys return (ret);
51405051Swyllys }
51415051Swyllys
51425051Swyllys KMF_RETURN
OpenSSL_ListCRL(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)51435051Swyllys OpenSSL_ListCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
51445051Swyllys {
51455051Swyllys KMF_RETURN ret = KMF_OK;
51465051Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
51475051Swyllys X509_CRL *x = NULL;
51485051Swyllys KMF_ENCODE_FORMAT format;
51495051Swyllys char *crlfile = NULL;
51505051Swyllys BIO *in = NULL;
51515051Swyllys BIO *mem = NULL;
51525051Swyllys long len;
51535051Swyllys char *memptr;
51545051Swyllys char *data = NULL;
51555051Swyllys char **crldata;
51565051Swyllys char *crlfilename, *dirpath;
51575051Swyllys
51585051Swyllys if (numattr == 0 || attrlist == NULL) {
51595051Swyllys return (KMF_ERR_BAD_PARAMETER);
51605051Swyllys }
51615051Swyllys crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR,
51625051Swyllys attrlist, numattr);
51635051Swyllys if (crlfilename == NULL)
51645051Swyllys return (KMF_ERR_BAD_CRLFILE);
51655051Swyllys
51665051Swyllys crldata = (char **)kmf_get_attr_ptr(KMF_CRL_DATA_ATTR,
51675051Swyllys attrlist, numattr);
51685051Swyllys
51695051Swyllys if (crldata == NULL)
51705051Swyllys return (KMF_ERR_BAD_PARAMETER);
51715051Swyllys
51725051Swyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
51735051Swyllys
51745051Swyllys crlfile = get_fullpath(dirpath, crlfilename);
51755051Swyllys
51765051Swyllys if (crlfile == NULL)
51775051Swyllys return (KMF_ERR_BAD_CRLFILE);
51785051Swyllys
51795051Swyllys if (isdir(crlfile)) {
51805051Swyllys free(crlfile);
51815051Swyllys return (KMF_ERR_BAD_CRLFILE);
51825051Swyllys }
51835051Swyllys
51845051Swyllys ret = kmf_is_crl_file(handle, crlfile, &format);
51855051Swyllys if (ret != KMF_OK) {
51865051Swyllys free(crlfile);
51875051Swyllys return (ret);
51885051Swyllys }
51895051Swyllys
51905051Swyllys if (bio_err == NULL)
51915051Swyllys bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
51925051Swyllys
51935051Swyllys in = BIO_new_file(crlfile, "rb");
51945051Swyllys if (in == NULL) {
51955051Swyllys SET_ERROR(kmfh, ERR_get_error());
51965051Swyllys ret = KMF_ERR_OPEN_FILE;
51975051Swyllys goto end;
51985051Swyllys }
51995051Swyllys
52005051Swyllys if (format == KMF_FORMAT_ASN1) {
52015051Swyllys x = d2i_X509_CRL_bio(in, NULL);
52025051Swyllys } else if (format == KMF_FORMAT_PEM) {
52035051Swyllys x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
52045051Swyllys }
52055051Swyllys
52065051Swyllys if (x == NULL) { /* should not happen */
52075051Swyllys SET_ERROR(kmfh, ERR_get_error());
52085051Swyllys ret = KMF_ERR_OPEN_FILE;
52095051Swyllys goto end;
52105051Swyllys }
52115051Swyllys
52125051Swyllys mem = BIO_new(BIO_s_mem());
52135051Swyllys if (mem == NULL) {
52145051Swyllys SET_ERROR(kmfh, ERR_get_error());
52155051Swyllys ret = KMF_ERR_MEMORY;
52165051Swyllys goto end;
52175051Swyllys }
52185051Swyllys
52195051Swyllys (void) X509_CRL_print(mem, x);
52205051Swyllys len = BIO_get_mem_data(mem, &memptr);
52215051Swyllys if (len <= 0) {
52225051Swyllys SET_ERROR(kmfh, ERR_get_error());
52235051Swyllys ret = KMF_ERR_MEMORY;
52245051Swyllys goto end;
52255051Swyllys }
52265051Swyllys
52275051Swyllys data = malloc(len + 1);
52285051Swyllys if (data == NULL) {
52295051Swyllys ret = KMF_ERR_MEMORY;
52305051Swyllys goto end;
52315051Swyllys }
52325051Swyllys
52335051Swyllys (void) memcpy(data, memptr, len);
52345051Swyllys data[len] = '\0';
52355051Swyllys *crldata = data;
52365051Swyllys
52375051Swyllys end:
52385051Swyllys if (x != NULL)
52395051Swyllys X509_CRL_free(x);
52405051Swyllys
52415051Swyllys if (crlfile != NULL)
52425051Swyllys free(crlfile);
52435051Swyllys
52445051Swyllys if (in != NULL)
52455051Swyllys (void) BIO_free(in);
52465051Swyllys
52475051Swyllys if (mem != NULL)
52485051Swyllys (void) BIO_free(mem);
52495051Swyllys
52505051Swyllys return (ret);
52515051Swyllys }
52525051Swyllys
52535051Swyllys KMF_RETURN
OpenSSL_DeleteCRL(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)52545051Swyllys OpenSSL_DeleteCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
52555051Swyllys {
52565051Swyllys KMF_RETURN ret = KMF_OK;
52575051Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
52585051Swyllys KMF_ENCODE_FORMAT format;
52595051Swyllys char *crlfile = NULL;
52605051Swyllys BIO *in = NULL;
52615051Swyllys char *crlfilename, *dirpath;
52625051Swyllys
52635051Swyllys if (numattr == 0 || attrlist == NULL) {
52645051Swyllys return (KMF_ERR_BAD_PARAMETER);
52655051Swyllys }
52665051Swyllys
52675051Swyllys crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR,
52685051Swyllys attrlist, numattr);
52695051Swyllys
52705051Swyllys if (crlfilename == NULL)
52715051Swyllys return (KMF_ERR_BAD_CRLFILE);
52725051Swyllys
52735051Swyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
52745051Swyllys
52755051Swyllys crlfile = get_fullpath(dirpath, crlfilename);
52765051Swyllys
52775051Swyllys if (crlfile == NULL)
52785051Swyllys return (KMF_ERR_BAD_CRLFILE);
52795051Swyllys
52805051Swyllys if (isdir(crlfile)) {
52815051Swyllys ret = KMF_ERR_BAD_CRLFILE;
52825051Swyllys goto end;
52835051Swyllys }
52845051Swyllys
52855051Swyllys ret = kmf_is_crl_file(handle, crlfile, &format);
52865051Swyllys if (ret != KMF_OK)
52875051Swyllys goto end;
52885051Swyllys
52895051Swyllys if (unlink(crlfile) != 0) {
52905051Swyllys SET_SYS_ERROR(kmfh, errno);
52915051Swyllys ret = KMF_ERR_INTERNAL;
52925051Swyllys goto end;
52935051Swyllys }
52945051Swyllys
52955051Swyllys end:
52965051Swyllys if (in != NULL)
52975051Swyllys (void) BIO_free(in);
52985051Swyllys if (crlfile != NULL)
52995051Swyllys free(crlfile);
53005051Swyllys
53015051Swyllys return (ret);
53025051Swyllys }
53035051Swyllys
53045051Swyllys KMF_RETURN
OpenSSL_FindCertInCRL(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)53055051Swyllys OpenSSL_FindCertInCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
53065051Swyllys {
53075051Swyllys KMF_RETURN ret = KMF_OK;
53085051Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
53095051Swyllys KMF_ENCODE_FORMAT format;
53105051Swyllys BIO *in = NULL;
53115051Swyllys X509 *xcert = NULL;
53125051Swyllys X509_CRL *xcrl = NULL;
53135051Swyllys STACK_OF(X509_REVOKED) *revoke_stack = NULL;
53145051Swyllys X509_REVOKED *revoke;
53155051Swyllys int i;
53165051Swyllys char *crlfilename, *crlfile, *dirpath, *certfile;
53175051Swyllys
53185051Swyllys if (numattr == 0 || attrlist == NULL) {
53195051Swyllys return (KMF_ERR_BAD_PARAMETER);
53205051Swyllys }
53215051Swyllys
53225051Swyllys crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR,
53235051Swyllys attrlist, numattr);
53245051Swyllys
53255051Swyllys if (crlfilename == NULL)
53265051Swyllys return (KMF_ERR_BAD_CRLFILE);
53275051Swyllys
53285051Swyllys certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
53295051Swyllys if (certfile == NULL)
53305051Swyllys return (KMF_ERR_BAD_CRLFILE);
53315051Swyllys
53325051Swyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
53335051Swyllys
53345051Swyllys crlfile = get_fullpath(dirpath, crlfilename);
53355051Swyllys
53365051Swyllys if (crlfile == NULL)
53375051Swyllys return (KMF_ERR_BAD_CRLFILE);
53385051Swyllys
53395051Swyllys if (isdir(crlfile)) {
53405051Swyllys ret = KMF_ERR_BAD_CRLFILE;
53415051Swyllys goto end;
53425051Swyllys }
53435051Swyllys
53445051Swyllys ret = kmf_is_crl_file(handle, crlfile, &format);
53455051Swyllys if (ret != KMF_OK)
53465051Swyllys goto end;
53475051Swyllys
53485051Swyllys /* Read the CRL file and load it into a X509_CRL structure */
53495051Swyllys in = BIO_new_file(crlfilename, "rb");
53505051Swyllys if (in == NULL) {
53515051Swyllys SET_ERROR(kmfh, ERR_get_error());
53525051Swyllys ret = KMF_ERR_OPEN_FILE;
53535051Swyllys goto end;
53545051Swyllys }
53555051Swyllys
53565051Swyllys if (format == KMF_FORMAT_ASN1) {
53575051Swyllys xcrl = d2i_X509_CRL_bio(in, NULL);
53585051Swyllys } else if (format == KMF_FORMAT_PEM) {
53595051Swyllys xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
53605051Swyllys }
53615051Swyllys
53625051Swyllys if (xcrl == NULL) {
53635051Swyllys SET_ERROR(kmfh, ERR_get_error());
53645051Swyllys ret = KMF_ERR_BAD_CRLFILE;
53655051Swyllys goto end;
53665051Swyllys }
53675051Swyllys (void) BIO_free(in);
53685051Swyllys
53695051Swyllys /* Read the Certificate file and load it into a X509 structure */
53705051Swyllys ret = kmf_is_cert_file(handle, certfile, &format);
53715051Swyllys if (ret != KMF_OK)
53725051Swyllys goto end;
53735051Swyllys
53745051Swyllys in = BIO_new_file(certfile, "rb");
53755051Swyllys if (in == NULL) {
53765051Swyllys SET_ERROR(kmfh, ERR_get_error());
53775051Swyllys ret = KMF_ERR_OPEN_FILE;
53785051Swyllys goto end;
53795051Swyllys }
53805051Swyllys
53815051Swyllys if (format == KMF_FORMAT_ASN1) {
53825051Swyllys xcert = d2i_X509_bio(in, NULL);
53835051Swyllys } else if (format == KMF_FORMAT_PEM) {
53845051Swyllys xcert = PEM_read_bio_X509(in, NULL, NULL, NULL);
53855051Swyllys }
53865051Swyllys
53875051Swyllys if (xcert == NULL) {
53885051Swyllys SET_ERROR(kmfh, ERR_get_error());
53895051Swyllys ret = KMF_ERR_BAD_CERTFILE;
53905051Swyllys goto end;
53915051Swyllys }
53925051Swyllys
53935051Swyllys /* Check if the certificate and the CRL have same issuer */
53945051Swyllys if (X509_NAME_cmp(xcert->cert_info->issuer, xcrl->crl->issuer) != 0) {
53955051Swyllys ret = KMF_ERR_ISSUER;
53965051Swyllys goto end;
53975051Swyllys }
53985051Swyllys
53995051Swyllys /* Check to see if the certificate serial number is revoked */
54005051Swyllys revoke_stack = X509_CRL_get_REVOKED(xcrl);
54015051Swyllys if (sk_X509_REVOKED_num(revoke_stack) <= 0) {
54025051Swyllys /* No revoked certificates in the CRL file */
54035051Swyllys SET_ERROR(kmfh, ERR_get_error());
54045051Swyllys ret = KMF_ERR_EMPTY_CRL;
54055051Swyllys goto end;
54065051Swyllys }
54075051Swyllys
54085051Swyllys for (i = 0; i < sk_X509_REVOKED_num(revoke_stack); i++) {
540911673Sopensolaris@drydog.com /* LINTED E_BAD_PTR_CAST_ALIGN */
54105051Swyllys revoke = sk_X509_REVOKED_value(revoke_stack, i);
54115051Swyllys if (ASN1_INTEGER_cmp(xcert->cert_info->serialNumber,
54125051Swyllys revoke->serialNumber) == 0) {
54135051Swyllys break;
54145051Swyllys }
54155051Swyllys }
54165051Swyllys
54175051Swyllys if (i < sk_X509_REVOKED_num(revoke_stack)) {
54185051Swyllys ret = KMF_OK;
54195051Swyllys } else {
54205051Swyllys ret = KMF_ERR_NOT_REVOKED;
54215051Swyllys }
54225051Swyllys
54235051Swyllys end:
54245051Swyllys if (in != NULL)
54255051Swyllys (void) BIO_free(in);
54265051Swyllys if (xcrl != NULL)
54275051Swyllys X509_CRL_free(xcrl);
54285051Swyllys if (xcert != NULL)
54295051Swyllys X509_free(xcert);
54305051Swyllys
54315051Swyllys return (ret);
54325051Swyllys }
54335051Swyllys
54345051Swyllys KMF_RETURN
OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle,char * crlname,KMF_DATA * tacert)54355051Swyllys OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle, char *crlname, KMF_DATA *tacert)
54365051Swyllys {
54375051Swyllys KMF_RETURN ret = KMF_OK;
54385051Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
54395051Swyllys BIO *bcrl = NULL;
54405051Swyllys X509_CRL *xcrl = NULL;
54415051Swyllys X509 *xcert = NULL;
54425051Swyllys EVP_PKEY *pkey;
54435051Swyllys int sslret;
54445051Swyllys KMF_ENCODE_FORMAT crl_format;
54455051Swyllys unsigned char *p;
54465051Swyllys long len;
54475051Swyllys
54485051Swyllys if (handle == NULL || crlname == NULL || tacert == NULL) {
54495051Swyllys return (KMF_ERR_BAD_PARAMETER);
54505051Swyllys }
54515051Swyllys
54525051Swyllys ret = kmf_get_file_format(crlname, &crl_format);
54535051Swyllys if (ret != KMF_OK)
54545051Swyllys return (ret);
54555051Swyllys
54565051Swyllys bcrl = BIO_new_file(crlname, "rb");
54575051Swyllys if (bcrl == NULL) {
54585051Swyllys SET_ERROR(kmfh, ERR_get_error());
54595051Swyllys ret = KMF_ERR_OPEN_FILE;
54605051Swyllys goto cleanup;
54615051Swyllys }
54625051Swyllys
54635051Swyllys if (crl_format == KMF_FORMAT_ASN1) {
54645051Swyllys xcrl = d2i_X509_CRL_bio(bcrl, NULL);
54655051Swyllys } else if (crl_format == KMF_FORMAT_PEM) {
54665051Swyllys xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL);
54675051Swyllys } else {
54685051Swyllys ret = KMF_ERR_BAD_PARAMETER;
54695051Swyllys goto cleanup;
54705051Swyllys }
54715051Swyllys
54725051Swyllys if (xcrl == NULL) {
54735051Swyllys SET_ERROR(kmfh, ERR_get_error());
54745051Swyllys ret = KMF_ERR_BAD_CRLFILE;
54755051Swyllys goto cleanup;
54765051Swyllys }
54775051Swyllys
54785051Swyllys p = tacert->Data;
54795051Swyllys len = tacert->Length;
54805051Swyllys xcert = d2i_X509(NULL, (const uchar_t **)&p, len);
54815051Swyllys
54825051Swyllys if (xcert == NULL) {
54835051Swyllys SET_ERROR(kmfh, ERR_get_error());
54845051Swyllys ret = KMF_ERR_BAD_CERTFILE;
54855051Swyllys goto cleanup;
54865051Swyllys }
54875051Swyllys
54885051Swyllys /* Get issuer certificate public key */
54895051Swyllys pkey = X509_get_pubkey(xcert);
54905051Swyllys if (pkey == NULL) {
54915051Swyllys SET_ERROR(kmfh, ERR_get_error());
54925051Swyllys ret = KMF_ERR_BAD_CERT_FORMAT;
54935051Swyllys goto cleanup;
54945051Swyllys }
54955051Swyllys
54965051Swyllys /* Verify CRL signature */
54975051Swyllys sslret = X509_CRL_verify(xcrl, pkey);
54985051Swyllys EVP_PKEY_free(pkey);
54995051Swyllys if (sslret > 0) {
55005051Swyllys ret = KMF_OK;
55015051Swyllys } else {
55025051Swyllys SET_ERROR(kmfh, sslret);
55035051Swyllys ret = KMF_ERR_BAD_CRLFILE;
55045051Swyllys }
55055051Swyllys
55065051Swyllys cleanup:
55075051Swyllys if (bcrl != NULL)
55085051Swyllys (void) BIO_free(bcrl);
55095051Swyllys
55105051Swyllys if (xcrl != NULL)
55115051Swyllys X509_CRL_free(xcrl);
55125051Swyllys
55135051Swyllys if (xcert != NULL)
55145051Swyllys X509_free(xcert);
55155051Swyllys
55165051Swyllys return (ret);
55175051Swyllys
55185051Swyllys }
55195051Swyllys
55205051Swyllys KMF_RETURN
OpenSSL_CheckCRLDate(KMF_HANDLE_T handle,char * crlname)55215051Swyllys OpenSSL_CheckCRLDate(KMF_HANDLE_T handle, char *crlname)
55225051Swyllys {
55235051Swyllys KMF_RETURN ret = KMF_OK;
55245051Swyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
55255051Swyllys KMF_ENCODE_FORMAT crl_format;
55265051Swyllys BIO *bcrl = NULL;
55275051Swyllys X509_CRL *xcrl = NULL;
55285051Swyllys int i;
55295051Swyllys
55305051Swyllys if (handle == NULL || crlname == NULL) {
55315051Swyllys return (KMF_ERR_BAD_PARAMETER);
55325051Swyllys }
55335051Swyllys
55345051Swyllys ret = kmf_is_crl_file(handle, crlname, &crl_format);
55355051Swyllys if (ret != KMF_OK)
55365051Swyllys return (ret);
55375051Swyllys
55385051Swyllys bcrl = BIO_new_file(crlname, "rb");
55395536Swyllys if (bcrl == NULL) {
55405051Swyllys SET_ERROR(kmfh, ERR_get_error());
55415051Swyllys ret = KMF_ERR_OPEN_FILE;
55425051Swyllys goto cleanup;
55435051Swyllys }
55445051Swyllys
55455536Swyllys if (crl_format == KMF_FORMAT_ASN1)
55465051Swyllys xcrl = d2i_X509_CRL_bio(bcrl, NULL);
55475536Swyllys else if (crl_format == KMF_FORMAT_PEM)
55485051Swyllys xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL);
55495051Swyllys
55505051Swyllys if (xcrl == NULL) {
55515051Swyllys SET_ERROR(kmfh, ERR_get_error());
55525051Swyllys ret = KMF_ERR_BAD_CRLFILE;
55535051Swyllys goto cleanup;
55545051Swyllys }
55555051Swyllys i = X509_cmp_time(X509_CRL_get_lastUpdate(xcrl), NULL);
55565051Swyllys if (i >= 0) {
55575051Swyllys ret = KMF_ERR_VALIDITY_PERIOD;
55585051Swyllys goto cleanup;
55595051Swyllys }
55605051Swyllys if (X509_CRL_get_nextUpdate(xcrl)) {
55615051Swyllys i = X509_cmp_time(X509_CRL_get_nextUpdate(xcrl), NULL);
55625051Swyllys
55635051Swyllys if (i <= 0) {
55645051Swyllys ret = KMF_ERR_VALIDITY_PERIOD;
55655051Swyllys goto cleanup;
55665051Swyllys }
55675051Swyllys }
55685051Swyllys
55695051Swyllys ret = KMF_OK;
55705051Swyllys
55715051Swyllys cleanup:
55725051Swyllys if (bcrl != NULL)
55735051Swyllys (void) BIO_free(bcrl);
55745051Swyllys
55755051Swyllys if (xcrl != NULL)
55765051Swyllys X509_CRL_free(xcrl);
55775051Swyllys
55785051Swyllys return (ret);
55795051Swyllys }
5580