openssl_spi.c revision 30a5e8fa1253cb33980ee4514743cf683f584b4e
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * Use is subject to license terms.
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay */
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay/*
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * project 2000.
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay */
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay/*
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * ====================================================================
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * Redistribution and use in source and binary forms, with or without
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * modification, are permitted provided that the following conditions
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * are met:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * 1. Redistributions of source code must retain the above copyright
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * notice, this list of conditions and the following disclaimer.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * 2. Redistributions in binary form must reproduce the above copyright
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * notice, this list of conditions and the following disclaimer in
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * the documentation and/or other materials provided with the
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * distribution.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * 3. All advertising materials mentioning features or use of this
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * software must display the following acknowledgment:
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * "This product includes software developed by the OpenSSL Project
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * endorse or promote products derived from this software without
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * prior written permission. For written permission, please contact
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * licensing@OpenSSL.org.
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay *
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * 5. Products derived from this software may not be called "OpenSSL"
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * nor may "OpenSSL" appear in their names without prior written
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * permission of the OpenSSL Project.
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay *
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * 6. Redistributions of any form whatsoever must retain the following
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * acknowledgment:
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * "This product includes software developed by the OpenSSL Project
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay *
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * OF THE POSSIBILITY OF SUCH DAMAGE.
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * ====================================================================
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay *
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * This product includes cryptographic software written by Eric Young
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * (eay@cryptsoft.com). This product includes software written by Tim
9a7670889e9c36ec355371e6b02f2d9084f040dchaimay * Hudson (tjh@cryptsoft.com).
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#pragma ident "%Z%%M% %I% %E% SMI"
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys#include <stdlib.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <kmfapiP.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <ber_der.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <fcntl.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <sys/stat.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <dirent.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <cryptoutil.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <synch.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <thread.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/* OPENSSL related headers */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <openssl/bio.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <openssl/bn.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <openssl/asn1.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <openssl/err.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <openssl/bn.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <openssl/x509.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <openssl/rsa.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <openssl/dsa.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <openssl/x509v3.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <openssl/objects.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <openssl/pem.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <openssl/pkcs12.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <openssl/ocsp.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <openssl/des.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <openssl/rand.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#define PRINT_ANY_EXTENSION (\
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509_EXT_KEY_USAGE |\
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509_EXT_CERT_POLICIES |\
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509_EXT_SUBJALTNAME |\
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509_EXT_BASIC_CONSTRAINTS |\
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509_EXT_NAME_CONSTRAINTS |\
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509_EXT_POLICY_CONSTRAINTS |\
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509_EXT_EXT_KEY_USAGE |\
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509_EXT_INHIBIT_ANY_POLICY |\
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509_EXT_AUTH_KEY_ID |\
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509_EXT_SUBJ_KEY_ID |\
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509_EXT_POLICY_MAPPING)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic uchar_t P[] = { 0x00, 0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys 0xaa, 0x3d, 0x25, 0x75, 0x9b, 0xb0, 0x68, 0x69,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys 0xcb, 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d, 0x0c,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys 0xf7, 0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys 0xe5, 0xd0, 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys 0xaf, 0xc2, 0xe9, 0xad, 0xac, 0x32, 0xab, 0x7a,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys 0xac, 0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys 0xc2, 0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys 0x91 };
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic uchar_t Q[] = { 0x00, 0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys 0xee, 0x99, 0x3b, 0x4f, 0x2d, 0xed, 0x30, 0xf4,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys 0x8e, 0xda, 0xce, 0x91, 0x5f };
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic uchar_t G[] = { 0x00, 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys 0x13, 0x41, 0x31, 0x63, 0xa5, 0x5b, 0x4c, 0xb5,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys 0x00, 0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c, 0xef,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys 0xcb, 0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys 0x2e, 0x71, 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys 0xbf, 0x58, 0xe5, 0xb7, 0x95, 0x21, 0x92, 0x5c,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys 0x9c, 0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys 0x8c, 0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys 0x02 };
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#define SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_OPENSSL; \
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys h->lasterr.errcode = c;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#define SET_SYS_ERROR(h, c) h->lasterr.kstype = -1; h->lasterr.errcode = c;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysmutex_t init_lock = DEFAULTMUTEX;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic int ssl_initialized = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic BIO *bio_err = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic int
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllystest_for_file(char *, mode_t);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
71593db26bb6ef7b739cffe06d53bf990cac112cwyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysextract_pem(KMF_HANDLE *, char *, char *, KMF_BIGINT *, char *,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CK_UTF8CHAR *, CK_ULONG, EVP_PKEY **, KMF_DATA **, int *);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
71593db26bb6ef7b739cffe06d53bf990cac112cwyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_load_cert(KMF_HANDLE *, char *, char *, KMF_BIGINT *, KMF_CERT_VALIDITY,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *, KMF_DATA *);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysload_certs(KMF_HANDLE *, char *, char *, KMF_BIGINT *, KMF_CERT_VALIDITY,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *, KMF_DATA **, uint32_t *);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllysstatic KMF_RETURN
02744e811b15322c5f109827a116c33bfe3438b5wyllyssslBN2KMFBN(BIGNUM *, KMF_BIGINT *);
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllysstatic EVP_PKEY *
02744e811b15322c5f109827a116c33bfe3438b5wyllysImportRawRSAKey(KMF_RAW_RSA_KEY *);
02744e811b15322c5f109827a116c33bfe3438b5wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysconvertToRawKey(EVP_PKEY *, KMF_RAW_KEY_DATA *);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_FindCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysvoid
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_FreeKMFCert(KMF_HANDLE_T, KMF_X509_DER_CERT *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_StoreCert(KMF_HANDLE_T handle, int, KMF_ATTRIBUTE *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_DeleteCert(KMF_HANDLE_T handle, int, KMF_ATTRIBUTE *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_CreateKeypair(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_StoreKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_DATA *, KMF_DATA *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_DeleteKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_ImportCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_DeleteCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_ListCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_FindCertInCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_CertGetPrintable(KMF_HANDLE_T, const KMF_DATA *,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_PRINTABLE_ITEM, char *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_GetErrorString(KMF_HANDLE_T, char **);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_FindPrikeyByCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_DATA *, KMF_DATA *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_CreateOCSPRequest(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_FindKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_ExportPK12(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_CreateSymKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_VerifyCRLFile(KMF_HANDLE_T, char *, KMF_DATA *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_CheckCRLDate(KMF_HANDLE_T, char *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllysKMF_RETURN
02744e811b15322c5f109827a116c33bfe3438b5wyllysOpenSSL_VerifyDataWithCert(KMF_HANDLE_T, KMF_ALGORITHM_INDEX,
02744e811b15322c5f109827a116c33bfe3438b5wyllys KMF_DATA *, KMF_DATA *, KMF_DATA *);
02744e811b15322c5f109827a116c33bfe3438b5wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_PLUGIN_FUNCLIST openssl_plugin_table =
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys 1, /* Version */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys NULL, /* ConfigureKeystore */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys OpenSSL_FindCert,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys OpenSSL_FreeKMFCert,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys OpenSSL_StoreCert,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys NULL, /* ImportCert */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys OpenSSL_ImportCRL,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys OpenSSL_DeleteCert,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys OpenSSL_DeleteCRL,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys OpenSSL_CreateKeypair,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys OpenSSL_FindKey,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys OpenSSL_EncodePubKeyData,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys OpenSSL_SignData,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys OpenSSL_DeleteKey,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys OpenSSL_ListCRL,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys NULL, /* FindCRL */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys OpenSSL_FindCertInCRL,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys OpenSSL_GetErrorString,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys OpenSSL_FindPrikeyByCert,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys OpenSSL_DecryptData,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys OpenSSL_ExportPK12,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys OpenSSL_CreateSymKey,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys OpenSSL_GetSymKeyValue,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys NULL, /* SetTokenPin */
02744e811b15322c5f109827a116c33bfe3438b5wyllys OpenSSL_VerifyDataWithCert,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys OpenSSL_StoreKey,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys NULL /* Finalize */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys};
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic mutex_t *lock_cs;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic long *lock_count;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic void
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*ARGSUSED*/
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyslocking_cb(int mode, int type, char *file, int line)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (mode & CRYPTO_LOCK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) mutex_lock(&(lock_cs[type]));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys lock_count[type]++;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) mutex_unlock(&(lock_cs[type]));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic unsigned long
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysthread_id()
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return ((unsigned long)thr_self());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_PLUGIN_FUNCLIST *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_Plugin_Initialize()
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int i;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) mutex_lock(&init_lock);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (!ssl_initialized) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys OpenSSL_add_all_algorithms();
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Enable error strings for reporting */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ERR_load_crypto_strings();
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Add support for extension OIDs that are not yet in the
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * openssl default set.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) OBJ_create("2.5.29.30", "nameConstraints",
34acef6775bd2319a3708b750f10ccc4f1292562wyllys "X509v3 Name Constraints");
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) OBJ_create("2.5.29.33", "policyMappings",
34acef6775bd2319a3708b750f10ccc4f1292562wyllys "X509v3 Policy Mappings");
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) OBJ_create("2.5.29.36", "policyConstraints",
34acef6775bd2319a3708b750f10ccc4f1292562wyllys "X509v3 Policy Constraints");
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) OBJ_create("2.5.29.46", "freshestCRL",
34acef6775bd2319a3708b750f10ccc4f1292562wyllys "X509v3 Freshest CRL");
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) OBJ_create("2.5.29.54", "inhibitAnyPolicy",
34acef6775bd2319a3708b750f10ccc4f1292562wyllys "X509v3 Inhibit Any-Policy");
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Set up for thread-safe operation.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (mutex_t));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (lock_cs == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) mutex_unlock(&init_lock);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (long));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (lock_count == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys OPENSSL_free(lock_cs);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) mutex_unlock(&init_lock);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys for (i = 0; i < CRYPTO_num_locks(); i++) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys lock_count[i] = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) mutex_init(&lock_cs[i], USYNC_THREAD, NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CRYPTO_set_id_callback((unsigned long (*)())thread_id);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CRYPTO_set_locking_callback((void (*)())locking_cb);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ssl_initialized = 1;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) mutex_unlock(&init_lock);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (&openssl_plugin_table);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Convert an SSL DN to a KMF DN.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic KMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysget_x509_dn(X509_NAME *sslDN, KMF_X509_NAME *kmfDN)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_DATA derdata;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys uchar_t *tmp;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Convert to raw DER format */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys derdata.Length = i2d_X509_NAME(sslDN, NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((tmp = derdata.Data = (uchar_t *)OPENSSL_malloc(derdata.Length))
34acef6775bd2319a3708b750f10ccc4f1292562wyllys == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_MEMORY);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) i2d_X509_NAME(sslDN, &tmp);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Decode to KMF format */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = DerDecodeName(&derdata, kmfDN);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_BAD_CERT_FORMAT;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys OPENSSL_free(derdata.Data);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysint
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysisdir(char *path)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys struct stat s;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (stat(path, &s) == -1)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (0);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return ((s.st_mode & S_IFMT) == S_IFDIR);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic KMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysssl_cert2KMFDATA(KMF_HANDLE *kmfh, X509 *x509cert, KMF_DATA *cert)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys unsigned char *buf = NULL, *p;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int len;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Convert the X509 internal struct to DER encoded data
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((len = i2d_X509(x509cert, NULL)) < 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, ERR_get_error());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_BAD_CERT_FORMAT;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((buf = malloc(len)) == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_SYS_ERROR(kmfh, errno);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_MEMORY;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * i2d_X509 will increment the buf pointer so that we need to
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * save it.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys p = buf;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((len = i2d_X509(x509cert, &p)) < 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, ERR_get_error());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(buf);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_BAD_CERT_FORMAT;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* caller's responsibility to free it */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys cert->Data = buf;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys cert->Length = len;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyscleanup:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (buf)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(buf);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys cert->Data = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys cert->Length = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyscheck_cert(X509 *xcert, char *issuer, char *subject, KMF_BIGINT *serial,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys boolean_t *match)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys boolean_t findIssuer = FALSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys boolean_t findSubject = FALSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys boolean_t findSerial = FALSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509_NAME issuerDN, subjectDN;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509_NAME certIssuerDN, certSubjectDN;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *match = FALSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (xcert == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memset(&issuerDN, 0, sizeof (KMF_X509_NAME));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memset(&subjectDN, 0, sizeof (KMF_X509_NAME));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memset(&certIssuerDN, 0, sizeof (KMF_X509_NAME));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memset(&certSubjectDN, 0, sizeof (KMF_X509_NAME));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (issuer != NULL && strlen(issuer)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_dn_parser(issuer, &issuerDN);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = get_x509_dn(xcert->cert_info->issuer, &certIssuerDN);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_dn(&issuerDN);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys findIssuer = TRUE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (subject != NULL && strlen(subject)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_dn_parser(subject, &subjectDN);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_BAD_PARAMETER;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = get_x509_dn(xcert->cert_info->subject, &certSubjectDN);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_BAD_PARAMETER;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys findSubject = TRUE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (serial != NULL && serial->val != NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys findSerial = TRUE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (findSerial) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys BIGNUM *bn;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Comparing BIGNUMs is a pain! */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys bn = ASN1_INTEGER_to_BN(xcert->cert_info->serialNumber, NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (bn != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int bnlen = BN_num_bytes(bn);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (bnlen == serial->len) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys uchar_t *a = malloc(bnlen);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (a == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_MEMORY;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys BN_free(bn);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys bnlen = BN_bn2bin(bn, a);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *match = (memcmp(a, serial->val, serial->len) ==
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys 0);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(a);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys BN_free(bn);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (!(*match))
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (findIssuer) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *match = (kmf_compare_rdns(&issuerDN, &certIssuerDN) == 0);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((*match) == B_FALSE) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* stop checking and bail */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (findSubject) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *match = (kmf_compare_rdns(&subjectDN, &certSubjectDN) == 0);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((*match) == B_FALSE) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* stop checking and bail */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *match = TRUE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyscleanup:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (findIssuer) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_dn(&issuerDN);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_dn(&certIssuerDN);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (findSubject) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_dn(&subjectDN);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_dn(&certSubjectDN);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys/*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * This function loads a certificate file into an X509 data structure, and
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * checks if its issuer, subject or the serial number matches with those
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * values. If it matches, then return the X509 data structure.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic KMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysload_X509cert(KMF_HANDLE *kmfh,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *issuer, char *subject, KMF_BIGINT *serial,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *pathname, X509 **outcert)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys X509 *xcert = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys BIO *bcert = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys boolean_t match = FALSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_ENCODE_FORMAT format;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * auto-detect the file format, regardless of what
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * the 'format' parameters in the params say.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_get_file_format(pathname, &format);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv == KMF_ERR_OPEN_FILE)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_CERT_NOT_FOUND;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Not ASN1(DER) format */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((bcert = BIO_new_file(pathname, "rb")) == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, ERR_get_error());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_OPEN_FILE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (format == KMF_FORMAT_PEM)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys xcert = PEM_read_bio_X509_AUX(bcert, NULL, NULL, NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys else if (format == KMF_FORMAT_ASN1)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys xcert = d2i_X509_bio(bcert, NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys else if (format == KMF_FORMAT_PKCS12) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys PKCS12 *p12 = d2i_PKCS12_bio(bcert, NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (p12 != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) PKCS12_parse(p12, NULL, NULL, &xcert, NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys PKCS12_free(p12);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys p12 = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, ERR_get_error());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_BAD_CERT_FORMAT;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_BAD_PARAMETER;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (xcert == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, ERR_get_error());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_BAD_CERT_FORMAT;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (check_cert(xcert, issuer, subject, serial, &match) != KMF_OK ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys match == FALSE) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_CERT_NOT_FOUND;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (outcert != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *outcert = xcert;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyscleanup:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (bcert != NULL) (void) BIO_free(bcert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK && xcert != NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys X509_free(xcert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
71593db26bb6ef7b739cffe06d53bf990cac112cwyllysstatic int
71593db26bb6ef7b739cffe06d53bf990cac112cwyllysdatacmp(const void *a, const void *b)
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys{
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys KMF_DATA *adata = (KMF_DATA *)a;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys KMF_DATA *bdata = (KMF_DATA *)b;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys if (adata->Length > bdata->Length)
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys return (-1);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys if (adata->Length < bdata->Length)
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys return (1);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys return (0);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys}
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
71593db26bb6ef7b739cffe06d53bf990cac112cwyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysload_certs(KMF_HANDLE *kmfh, char *issuer, char *subject, KMF_BIGINT *serial,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_CERT_VALIDITY validity, char *pathname,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA **certlist, uint32_t *numcerts)
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys{
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys KMF_RETURN rv = KMF_OK;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys int i;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys KMF_DATA *certs = NULL;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys int nc = 0;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys int hits = 0;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys KMF_ENCODE_FORMAT format;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_get_file_format(pathname, &format);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys if (rv != KMF_OK) {
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys if (rv == KMF_ERR_OPEN_FILE)
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys rv = KMF_ERR_CERT_NOT_FOUND;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys return (rv);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys }
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys if (format == KMF_FORMAT_ASN1) {
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys /* load a single certificate */
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys certs = (KMF_DATA *)malloc(sizeof (KMF_DATA));
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys if (certs == NULL)
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys return (KMF_ERR_MEMORY);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys certs->Data = NULL;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys certs->Length = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_load_cert(kmfh, issuer, subject, serial, validity,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pathname, certs);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys if (rv == KMF_OK) {
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys *certlist = certs;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys *numcerts = 1;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys }
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys return (rv);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys } else if (format == KMF_FORMAT_PKCS12) {
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys /* We need a credential to access a PKCS#12 file */
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys rv = KMF_ERR_BAD_CERT_FORMAT;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys } else if (format == KMF_FORMAT_PEM ||
34acef6775bd2319a3708b750f10ccc4f1292562wyllys format != KMF_FORMAT_PEM_KEYPAIR) {
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys /* This function only works on PEM files */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = extract_pem(kmfh, issuer, subject, serial, pathname,
34acef6775bd2319a3708b750f10ccc4f1292562wyllys (uchar_t *)NULL, 0, NULL, &certs, &nc);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys } else {
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys return (KMF_ERR_ENCODING);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys }
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys if (rv != KMF_OK)
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys return (rv);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys for (i = 0; i < nc; i++) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (validity == KMF_NONEXPIRED_CERTS) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_check_cert_date(kmfh, &certs[i]);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (validity == KMF_EXPIRED_CERTS) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_check_cert_date(kmfh, &certs[i]);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys if (rv == KMF_OK)
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys rv = KMF_ERR_CERT_NOT_FOUND;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys if (rv == KMF_ERR_VALIDITY_PERIOD)
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys rv = KMF_OK;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys }
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys if (rv != KMF_OK) {
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys /* Remove this cert from the list by clearing it. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_data(&certs[i]);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys } else {
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys hits++; /* count valid certs found */
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys }
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys rv = KMF_OK;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys }
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys if (rv == KMF_OK && hits == 0) {
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys rv = KMF_ERR_CERT_NOT_FOUND;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys } else if (rv == KMF_OK && hits > 0) {
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys /*
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys * Sort the list of certs by length to put the cleared ones
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys * at the end so they don't get accessed by the caller.
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys */
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys qsort((void *)certs, nc, sizeof (KMF_DATA), datacmp);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys *certlist = certs;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys /* since we sorted the list, just return the number of hits */
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys *numcerts = hits;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys }
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys return (rv);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys}
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic KMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyskmf_load_cert(KMF_HANDLE *kmfh,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *issuer, char *subject, KMF_BIGINT *serial,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_CERT_VALIDITY validity,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *pathname,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *cert)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys X509 *x509cert = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = load_X509cert(kmfh, issuer, subject, serial, pathname, &x509cert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv == KMF_OK && x509cert != NULL && cert != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = ssl_cert2KMFDATA(kmfh, x509cert, cert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (validity == KMF_NONEXPIRED_CERTS) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_check_cert_date(kmfh, cert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (validity == KMF_EXPIRED_CERTS) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_check_cert_date(kmfh, cert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv == KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * This is a valid cert so skip it.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_CERT_NOT_FOUND;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv == KMF_ERR_VALIDITY_PERIOD) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * We want to return success when we
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * find an invalid cert.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyscleanup:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (x509cert != NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys X509_free(x509cert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllysstatic KMF_RETURN
02744e811b15322c5f109827a116c33bfe3438b5wyllysreadAltFormatPrivateKey(KMF_DATA *filedata, EVP_PKEY **pkey)
02744e811b15322c5f109827a116c33bfe3438b5wyllys{
02744e811b15322c5f109827a116c33bfe3438b5wyllys KMF_RETURN ret = KMF_OK;
02744e811b15322c5f109827a116c33bfe3438b5wyllys KMF_RAW_RSA_KEY rsa;
02744e811b15322c5f109827a116c33bfe3438b5wyllys BerElement *asn1 = NULL;
02744e811b15322c5f109827a116c33bfe3438b5wyllys BerValue filebuf;
02744e811b15322c5f109827a116c33bfe3438b5wyllys BerValue OID = { NULL, 0 };
02744e811b15322c5f109827a116c33bfe3438b5wyllys BerValue *Mod = NULL, *PubExp = NULL;
02744e811b15322c5f109827a116c33bfe3438b5wyllys BerValue *PriExp = NULL, *Prime1 = NULL, *Prime2 = NULL;
02744e811b15322c5f109827a116c33bfe3438b5wyllys BerValue *Coef = NULL;
02744e811b15322c5f109827a116c33bfe3438b5wyllys BIGNUM *D = NULL, *P = NULL, *Q = NULL, *COEF = NULL;
02744e811b15322c5f109827a116c33bfe3438b5wyllys BIGNUM *Exp1 = NULL, *Exp2 = NULL, *pminus1 = NULL;
02744e811b15322c5f109827a116c33bfe3438b5wyllys BIGNUM *qminus1 = NULL;
02744e811b15322c5f109827a116c33bfe3438b5wyllys BN_CTX *ctx = NULL;
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys *pkey = NULL;
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys filebuf.bv_val = (char *)filedata->Data;
02744e811b15322c5f109827a116c33bfe3438b5wyllys filebuf.bv_len = filedata->Length;
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys asn1 = kmfder_init(&filebuf);
02744e811b15322c5f109827a116c33bfe3438b5wyllys if (asn1 == NULL) {
02744e811b15322c5f109827a116c33bfe3438b5wyllys ret = KMF_ERR_MEMORY;
02744e811b15322c5f109827a116c33bfe3438b5wyllys goto out;
02744e811b15322c5f109827a116c33bfe3438b5wyllys }
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys if (kmfber_scanf(asn1, "{{Dn{IIIIII}}}",
34acef6775bd2319a3708b750f10ccc4f1292562wyllys &OID, &Mod, &PubExp, &PriExp, &Prime1,
34acef6775bd2319a3708b750f10ccc4f1292562wyllys &Prime2, &Coef) == -1) {
02744e811b15322c5f109827a116c33bfe3438b5wyllys ret = KMF_ERR_ENCODING;
02744e811b15322c5f109827a116c33bfe3438b5wyllys goto out;
02744e811b15322c5f109827a116c33bfe3438b5wyllys }
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys /*
02744e811b15322c5f109827a116c33bfe3438b5wyllys * We have to derive the 2 Exponents using Bignumber math.
02744e811b15322c5f109827a116c33bfe3438b5wyllys * Exp1 = PriExp mod (Prime1 - 1)
02744e811b15322c5f109827a116c33bfe3438b5wyllys * Exp2 = PriExp mod (Prime2 - 1)
02744e811b15322c5f109827a116c33bfe3438b5wyllys */
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys /* D = PrivateExponent */
02744e811b15322c5f109827a116c33bfe3438b5wyllys D = BN_bin2bn((const uchar_t *)PriExp->bv_val, PriExp->bv_len, D);
02744e811b15322c5f109827a116c33bfe3438b5wyllys if (D == NULL) {
02744e811b15322c5f109827a116c33bfe3438b5wyllys ret = KMF_ERR_MEMORY;
02744e811b15322c5f109827a116c33bfe3438b5wyllys goto out;
02744e811b15322c5f109827a116c33bfe3438b5wyllys }
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys /* P = Prime1 (first prime factor of Modulus) */
02744e811b15322c5f109827a116c33bfe3438b5wyllys P = BN_bin2bn((const uchar_t *)Prime1->bv_val, Prime1->bv_len, P);
02744e811b15322c5f109827a116c33bfe3438b5wyllys if (D == NULL) {
02744e811b15322c5f109827a116c33bfe3438b5wyllys ret = KMF_ERR_MEMORY;
02744e811b15322c5f109827a116c33bfe3438b5wyllys goto out;
02744e811b15322c5f109827a116c33bfe3438b5wyllys }
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys /* Q = Prime2 (second prime factor of Modulus) */
02744e811b15322c5f109827a116c33bfe3438b5wyllys Q = BN_bin2bn((const uchar_t *)Prime2->bv_val, Prime2->bv_len, Q);
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys if ((ctx = BN_CTX_new()) == NULL) {
02744e811b15322c5f109827a116c33bfe3438b5wyllys ret = KMF_ERR_MEMORY;
02744e811b15322c5f109827a116c33bfe3438b5wyllys goto out;
02744e811b15322c5f109827a116c33bfe3438b5wyllys }
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys /* Compute (P - 1) */
02744e811b15322c5f109827a116c33bfe3438b5wyllys pminus1 = BN_new();
02744e811b15322c5f109827a116c33bfe3438b5wyllys (void) BN_sub(pminus1, P, BN_value_one());
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys /* Exponent1 = D mod (P - 1) */
02744e811b15322c5f109827a116c33bfe3438b5wyllys Exp1 = BN_new();
02744e811b15322c5f109827a116c33bfe3438b5wyllys (void) BN_mod(Exp1, D, pminus1, ctx);
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys /* Compute (Q - 1) */
02744e811b15322c5f109827a116c33bfe3438b5wyllys qminus1 = BN_new();
02744e811b15322c5f109827a116c33bfe3438b5wyllys (void) BN_sub(qminus1, Q, BN_value_one());
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys /* Exponent2 = D mod (Q - 1) */
02744e811b15322c5f109827a116c33bfe3438b5wyllys Exp2 = BN_new();
02744e811b15322c5f109827a116c33bfe3438b5wyllys (void) BN_mod(Exp2, D, qminus1, ctx);
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys /* Coef = (Inverse Q) mod P */
02744e811b15322c5f109827a116c33bfe3438b5wyllys COEF = BN_new();
02744e811b15322c5f109827a116c33bfe3438b5wyllys (void) BN_mod_inverse(COEF, Q, P, ctx);
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys /* Convert back to KMF format */
02744e811b15322c5f109827a116c33bfe3438b5wyllys (void) memset(&rsa, 0, sizeof (rsa));
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys if ((ret = sslBN2KMFBN(Exp1, &rsa.exp1)) != KMF_OK)
02744e811b15322c5f109827a116c33bfe3438b5wyllys goto out;
02744e811b15322c5f109827a116c33bfe3438b5wyllys if ((ret = sslBN2KMFBN(Exp2, &rsa.exp2)) != KMF_OK)
02744e811b15322c5f109827a116c33bfe3438b5wyllys goto out;
02744e811b15322c5f109827a116c33bfe3438b5wyllys if ((ret = sslBN2KMFBN(COEF, &rsa.coef)) != KMF_OK)
02744e811b15322c5f109827a116c33bfe3438b5wyllys goto out;
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys rsa.mod.val = (uchar_t *)Mod->bv_val;
02744e811b15322c5f109827a116c33bfe3438b5wyllys rsa.mod.len = Mod->bv_len;
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys rsa.pubexp.val = (uchar_t *)PubExp->bv_val;
02744e811b15322c5f109827a116c33bfe3438b5wyllys rsa.pubexp.len = PubExp->bv_len;
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys rsa.priexp.val = (uchar_t *)PriExp->bv_val;
02744e811b15322c5f109827a116c33bfe3438b5wyllys rsa.priexp.len = PriExp->bv_len;
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys rsa.prime1.val = (uchar_t *)Prime1->bv_val;
02744e811b15322c5f109827a116c33bfe3438b5wyllys rsa.prime1.len = Prime1->bv_len;
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys rsa.prime2.val = (uchar_t *)Prime2->bv_val;
02744e811b15322c5f109827a116c33bfe3438b5wyllys rsa.prime2.len = Prime2->bv_len;
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys *pkey = ImportRawRSAKey(&rsa);
02744e811b15322c5f109827a116c33bfe3438b5wyllysout:
02744e811b15322c5f109827a116c33bfe3438b5wyllys if (asn1 != NULL)
02744e811b15322c5f109827a116c33bfe3438b5wyllys kmfber_free(asn1, 1);
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys if (OID.bv_val) {
02744e811b15322c5f109827a116c33bfe3438b5wyllys free(OID.bv_val);
02744e811b15322c5f109827a116c33bfe3438b5wyllys }
02744e811b15322c5f109827a116c33bfe3438b5wyllys if (PriExp)
02744e811b15322c5f109827a116c33bfe3438b5wyllys free(PriExp);
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys if (Mod)
02744e811b15322c5f109827a116c33bfe3438b5wyllys free(Mod);
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys if (PubExp)
02744e811b15322c5f109827a116c33bfe3438b5wyllys free(PubExp);
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys if (Coef) {
02744e811b15322c5f109827a116c33bfe3438b5wyllys (void) memset(Coef->bv_val, 0, Coef->bv_len);
02744e811b15322c5f109827a116c33bfe3438b5wyllys free(Coef->bv_val);
02744e811b15322c5f109827a116c33bfe3438b5wyllys free(Coef);
02744e811b15322c5f109827a116c33bfe3438b5wyllys }
02744e811b15322c5f109827a116c33bfe3438b5wyllys if (Prime1)
02744e811b15322c5f109827a116c33bfe3438b5wyllys free(Prime1);
02744e811b15322c5f109827a116c33bfe3438b5wyllys if (Prime2)
02744e811b15322c5f109827a116c33bfe3438b5wyllys free(Prime2);
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys if (ctx != NULL)
02744e811b15322c5f109827a116c33bfe3438b5wyllys BN_CTX_free(ctx);
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys if (D)
02744e811b15322c5f109827a116c33bfe3438b5wyllys BN_clear_free(D);
02744e811b15322c5f109827a116c33bfe3438b5wyllys if (P)
02744e811b15322c5f109827a116c33bfe3438b5wyllys BN_clear_free(P);
02744e811b15322c5f109827a116c33bfe3438b5wyllys if (Q)
02744e811b15322c5f109827a116c33bfe3438b5wyllys BN_clear_free(Q);
02744e811b15322c5f109827a116c33bfe3438b5wyllys if (pminus1)
02744e811b15322c5f109827a116c33bfe3438b5wyllys BN_clear_free(pminus1);
02744e811b15322c5f109827a116c33bfe3438b5wyllys if (qminus1)
02744e811b15322c5f109827a116c33bfe3438b5wyllys BN_clear_free(qminus1);
02744e811b15322c5f109827a116c33bfe3438b5wyllys if (Exp1)
02744e811b15322c5f109827a116c33bfe3438b5wyllys BN_clear_free(Exp1);
02744e811b15322c5f109827a116c33bfe3438b5wyllys if (Exp2)
02744e811b15322c5f109827a116c33bfe3438b5wyllys BN_clear_free(Exp2);
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys return (ret);
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys}
02744e811b15322c5f109827a116c33bfe3438b5wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic EVP_PKEY *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysopenssl_load_key(KMF_HANDLE_T handle, const char *file)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys BIO *keyfile = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys EVP_PKEY *pkey = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_ENCODE_FORMAT format;
02744e811b15322c5f109827a116c33bfe3438b5wyllys KMF_RETURN rv;
02744e811b15322c5f109827a116c33bfe3438b5wyllys KMF_DATA filedata;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (file == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (kmf_get_file_format((char *)file, &format) != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys keyfile = BIO_new_file(file, "rb");
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (keyfile == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys if (format == KMF_FORMAT_ASN1) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys pkey = d2i_PrivateKey_bio(keyfile, NULL);
02744e811b15322c5f109827a116c33bfe3438b5wyllys if (pkey == NULL) {
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys (void) BIO_free(keyfile);
02744e811b15322c5f109827a116c33bfe3438b5wyllys keyfile = NULL;
02744e811b15322c5f109827a116c33bfe3438b5wyllys /* Try odd ASN.1 variations */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_read_input_file(kmfh, (char *)file,
34acef6775bd2319a3708b750f10ccc4f1292562wyllys &filedata);
02744e811b15322c5f109827a116c33bfe3438b5wyllys if (rv == KMF_OK) {
02744e811b15322c5f109827a116c33bfe3438b5wyllys (void) readAltFormatPrivateKey(&filedata,
34acef6775bd2319a3708b750f10ccc4f1292562wyllys &pkey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_data(&filedata);
02744e811b15322c5f109827a116c33bfe3438b5wyllys }
02744e811b15322c5f109827a116c33bfe3438b5wyllys }
02744e811b15322c5f109827a116c33bfe3438b5wyllys } else if (format == KMF_FORMAT_PEM ||
34acef6775bd2319a3708b750f10ccc4f1292562wyllys format == KMF_FORMAT_PEM_KEYPAIR) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys pkey = PEM_read_bio_PrivateKey(keyfile, NULL, NULL, NULL);
02744e811b15322c5f109827a116c33bfe3438b5wyllys if (pkey == NULL) {
02744e811b15322c5f109827a116c33bfe3438b5wyllys KMF_DATA derdata;
02744e811b15322c5f109827a116c33bfe3438b5wyllys /*
02744e811b15322c5f109827a116c33bfe3438b5wyllys * Check if this is the alt. format
02744e811b15322c5f109827a116c33bfe3438b5wyllys * RSA private key file.
02744e811b15322c5f109827a116c33bfe3438b5wyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_read_input_file(kmfh, (char *)file,
34acef6775bd2319a3708b750f10ccc4f1292562wyllys &filedata);
02744e811b15322c5f109827a116c33bfe3438b5wyllys if (rv == KMF_OK) {
02744e811b15322c5f109827a116c33bfe3438b5wyllys uchar_t *d = NULL;
02744e811b15322c5f109827a116c33bfe3438b5wyllys int len;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_pem_to_der(filedata.Data,
34acef6775bd2319a3708b750f10ccc4f1292562wyllys filedata.Length, &d, &len);
02744e811b15322c5f109827a116c33bfe3438b5wyllys if (rv == KMF_OK && d != NULL) {
02744e811b15322c5f109827a116c33bfe3438b5wyllys derdata.Data = d;
02744e811b15322c5f109827a116c33bfe3438b5wyllys derdata.Length = (size_t)len;
02744e811b15322c5f109827a116c33bfe3438b5wyllys (void) readAltFormatPrivateKey(
34acef6775bd2319a3708b750f10ccc4f1292562wyllys &derdata, &pkey);
02744e811b15322c5f109827a116c33bfe3438b5wyllys free(d);
02744e811b15322c5f109827a116c33bfe3438b5wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_data(&filedata);
02744e811b15322c5f109827a116c33bfe3438b5wyllys }
02744e811b15322c5f109827a116c33bfe3438b5wyllys }
02744e811b15322c5f109827a116c33bfe3438b5wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysend:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (pkey == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, ERR_get_error());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (keyfile != NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) BIO_free(keyfile);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (pkey);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_FindCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
f482c776bc557f0256e776932c7842b9db390de1wyllys int i, n;
f482c776bc557f0256e776932c7842b9db390de1wyllys uint32_t maxcerts = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys uint32_t *num_certs;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_X509_DER_CERT *kmf_cert = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *dirpath = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *filename = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *fullpath = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *issuer = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *subject = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_BIGINT *serial = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_CERT_VALIDITY validity;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys num_certs = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (num_certs == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* num_certs should reference the size of kmf_cert */
f482c776bc557f0256e776932c7842b9db390de1wyllys maxcerts = *num_certs;
f482c776bc557f0256e776932c7842b9db390de1wyllys if (maxcerts == 0)
f482c776bc557f0256e776932c7842b9db390de1wyllys maxcerts = 0xFFFFFFFF;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *num_certs = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Get the optional returned certificate list */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_cert = kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * The dirpath attribute and the filename attribute can not be NULL
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * at the same time.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys filename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys fullpath = get_fullpath(dirpath, filename);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (fullpath == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Get optional search criteria attributes */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &validity, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys validity = KMF_ALL_CERTS;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (isdir(fullpath)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys DIR *dirp;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys struct dirent *dp;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
f482c776bc557f0256e776932c7842b9db390de1wyllys n = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* open all files in the directory and attempt to read them */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((dirp = opendir(fullpath)) == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys while ((dp = readdir(dirp)) != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *fname;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys KMF_DATA *certlist = NULL;
f482c776bc557f0256e776932c7842b9db390de1wyllys uint32_t loaded_certs = 0;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (strcmp(dp->d_name, ".") == 0 ||
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys strcmp(dp->d_name, "..") == 0)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys continue;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
34acef6775bd2319a3708b750f10ccc4f1292562wyllys fname = get_fullpath(fullpath, (char *)&dp->d_name);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = load_certs(kmfh, issuer, subject, serial,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys validity, fname, &certlist, &loaded_certs);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(fname);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys if (certlist != NULL) {
f482c776bc557f0256e776932c7842b9db390de1wyllys for (i = 0; i < loaded_certs; i++)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_data(&certlist[i]);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys free(certlist);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys continue;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* If load succeeds, add certdata to the list */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (kmf_cert != NULL) {
f482c776bc557f0256e776932c7842b9db390de1wyllys for (i = 0; i < loaded_certs &&
b4058258308bb6a33809f15962013af85f890c36wyllys n < maxcerts; i++) {
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys kmf_cert[n].certificate.Data =
34acef6775bd2319a3708b750f10ccc4f1292562wyllys certlist[i].Data;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys kmf_cert[n].certificate.Length =
34acef6775bd2319a3708b750f10ccc4f1292562wyllys certlist[i].Length;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys kmf_cert[n].kmf_private.keystore_type =
34acef6775bd2319a3708b750f10ccc4f1292562wyllys KMF_KEYSTORE_OPENSSL;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys kmf_cert[n].kmf_private.flags =
34acef6775bd2319a3708b750f10ccc4f1292562wyllys KMF_FLAG_CERT_VALID;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys kmf_cert[n].kmf_private.label =
34acef6775bd2319a3708b750f10ccc4f1292562wyllys strdup(fname);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys n++;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys }
b4058258308bb6a33809f15962013af85f890c36wyllys /*
b4058258308bb6a33809f15962013af85f890c36wyllys * If maxcerts < loaded_certs, clean up the
b4058258308bb6a33809f15962013af85f890c36wyllys * certs that were not used.
b4058258308bb6a33809f15962013af85f890c36wyllys */
f482c776bc557f0256e776932c7842b9db390de1wyllys for (; i < loaded_certs; i++)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_data(&certlist[i]);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
f482c776bc557f0256e776932c7842b9db390de1wyllys for (i = 0; i < loaded_certs; i++)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_data(&certlist[i]);
f482c776bc557f0256e776932c7842b9db390de1wyllys n += loaded_certs;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
f482c776bc557f0256e776932c7842b9db390de1wyllys free(certlist);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys free(fname);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (*num_certs) = n;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (*num_certs == 0)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_CERT_NOT_FOUND;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (*num_certs > 0)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysexit:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) closedir(dirp);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys KMF_DATA *certlist = NULL;
f482c776bc557f0256e776932c7842b9db390de1wyllys uint32_t loaded_certs = 0;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = load_certs(kmfh, issuer, subject, serial, validity,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys fullpath, &certlist, &loaded_certs);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(fullpath);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
f482c776bc557f0256e776932c7842b9db390de1wyllys n = 0;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys if (kmf_cert != NULL && certlist != NULL) {
f482c776bc557f0256e776932c7842b9db390de1wyllys for (i = 0; i < loaded_certs && i < maxcerts; i++) {
f482c776bc557f0256e776932c7842b9db390de1wyllys kmf_cert[n].certificate.Data =
34acef6775bd2319a3708b750f10ccc4f1292562wyllys certlist[i].Data;
f482c776bc557f0256e776932c7842b9db390de1wyllys kmf_cert[n].certificate.Length =
34acef6775bd2319a3708b750f10ccc4f1292562wyllys certlist[i].Length;
f482c776bc557f0256e776932c7842b9db390de1wyllys kmf_cert[n].kmf_private.keystore_type =
34acef6775bd2319a3708b750f10ccc4f1292562wyllys KMF_KEYSTORE_OPENSSL;
f482c776bc557f0256e776932c7842b9db390de1wyllys kmf_cert[n].kmf_private.flags =
34acef6775bd2319a3708b750f10ccc4f1292562wyllys KMF_FLAG_CERT_VALID;
f482c776bc557f0256e776932c7842b9db390de1wyllys kmf_cert[n].kmf_private.label =
34acef6775bd2319a3708b750f10ccc4f1292562wyllys strdup(fullpath);
f482c776bc557f0256e776932c7842b9db390de1wyllys n++;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys }
f482c776bc557f0256e776932c7842b9db390de1wyllys /* If maxcerts < loaded_certs, clean up */
f482c776bc557f0256e776932c7842b9db390de1wyllys for (; i < loaded_certs; i++)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_data(&certlist[i]);
f482c776bc557f0256e776932c7842b9db390de1wyllys } else if (certlist != NULL) {
f482c776bc557f0256e776932c7842b9db390de1wyllys for (i = 0; i < loaded_certs; i++)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_data(&certlist[i]);
f482c776bc557f0256e776932c7842b9db390de1wyllys n = loaded_certs;
f482c776bc557f0256e776932c7842b9db390de1wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (certlist != NULL)
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys free(certlist);
f482c776bc557f0256e776932c7842b9db390de1wyllys *num_certs = n;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys free(fullpath);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysvoid
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*ARGSUSED*/
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_FreeKMFCert(KMF_HANDLE_T handle,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509_DER_CERT *kmf_cert)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (kmf_cert != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (kmf_cert->certificate.Data != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(kmf_cert->certificate.Data);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys kmf_cert->certificate.Data = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys kmf_cert->certificate.Length = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (kmf_cert->kmf_private.label)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(kmf_cert->kmf_private.label);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys/*ARGSUSED*/
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_StoreCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *cert = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *outfilename = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *dirpath = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *fullpath = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_ENCODE_FORMAT format;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Get the cert data */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (cert == NULL || cert->Data == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Check the output filename and directory attributes. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys outfilename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (outfilename == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys fullpath = get_fullpath(dirpath, outfilename);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (fullpath == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_CERTFILE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Check the optional format attribute */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &format, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* If there is no format attribute, then default to PEM */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys format = KMF_FORMAT_PEM;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (format != KMF_FORMAT_ASN1 && format != KMF_FORMAT_PEM) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_CERT_FORMAT;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Store the certificate in the file with the specified format */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_create_cert_file(cert, format, fullpath);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysout:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (fullpath != NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(fullpath);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_DeleteCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN rv;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_DATA certdata = {NULL, 0};
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *dirpath = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *filename = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *fullpath = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *issuer = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *subject = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_BIGINT *serial = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_CERT_VALIDITY validity;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Get the DIRPATH and CERT_FILENAME attributes. They can not be
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * NULL at the same time.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys filename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys fullpath = get_fullpath(dirpath, filename);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (fullpath == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Get optional search criteria attributes */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &validity, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys validity = KMF_ALL_CERTS;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (isdir(fullpath)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys DIR *dirp;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys struct dirent *dp;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* open all files in the directory and attempt to read them */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((dirp = opendir(fullpath)) == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys while ((dp = readdir(dirp)) != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (strcmp(dp->d_name, ".") != 0 &&
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys strcmp(dp->d_name, "..") != 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *fname;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys fname = get_fullpath(fullpath,
34acef6775bd2319a3708b750f10ccc4f1292562wyllys (char *)&dp->d_name);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (fname == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_MEMORY;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_load_cert(kmfh, issuer, subject,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys serial, validity, fname, &certdata);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv == KMF_ERR_CERT_NOT_FOUND) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(fname);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (certdata.Data)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(certdata.Data);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys continue;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (rv != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(fname);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (unlink(fname) != 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_SYS_ERROR(kmfh, errno);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_INTERNAL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(fname);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(fname);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (certdata.Data)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(certdata.Data);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) closedir(dirp);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Just try to load a single certificate */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_load_cert(kmfh, issuer, subject, serial, validity,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys fullpath, &certdata);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv == KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (unlink(fullpath) != 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_SYS_ERROR(kmfh, errno);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_INTERNAL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysout:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (fullpath != NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(fullpath);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (certdata.Data)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(certdata.Data);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_DATA *keydata)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int n;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (key == NULL || keydata == NULL ||
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys key->keyp == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (key->keyalg == KMF_RSA) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys RSA *pubkey = EVP_PKEY_get1_RSA(key->keyp);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (!(n = i2d_RSA_PUBKEY(pubkey, &keydata->Data))) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, ERR_get_error());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_ENCODING);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys RSA_free(pubkey);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (key->keyalg == KMF_DSA) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys DSA *pubkey = EVP_PKEY_get1_DSA(key->keyp);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (!(n = i2d_DSA_PUBKEY(pubkey, &keydata->Data))) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, ERR_get_error());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_ENCODING);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys DSA_free(pubkey);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
34acef6775bd2319a3708b750f10ccc4f1292562wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys keydata->Length = n;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyscleanup:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (keydata->Data)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(keydata->Data);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys keydata->Data = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys keydata->Length = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysssl_write_key(KMF_HANDLE *kmfh, KMF_ENCODE_FORMAT format, BIO *out,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_CREDENTIAL *cred, EVP_PKEY *pkey, boolean_t private)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int rv = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys RSA *rsa;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys DSA *dsa;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys switch (format) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case KMF_FORMAT_ASN1:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (pkey->type == EVP_PKEY_RSA) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rsa = EVP_PKEY_get1_RSA(pkey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (private)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = i2d_RSAPrivateKey_bio(out, rsa);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys else
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = i2d_RSAPublicKey_bio(out, rsa);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys RSA_free(rsa);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (pkey->type == EVP_PKEY_DSA) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys dsa = EVP_PKEY_get1_DSA(pkey);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = i2d_DSAPrivateKey_bio(out, dsa);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys DSA_free(dsa);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv == 1) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case KMF_FORMAT_PEM:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (pkey->type == EVP_PKEY_RSA) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rsa = EVP_PKEY_get1_RSA(pkey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (private)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = PEM_write_bio_RSAPrivateKey(out,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rsa, NULL, NULL, 0, NULL,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (cred != NULL ? cred->cred : NULL));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys else
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = PEM_write_bio_RSAPublicKey(out,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rsa);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys RSA_free(rsa);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (pkey->type == EVP_PKEY_DSA) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys dsa = EVP_PKEY_get1_DSA(pkey);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = PEM_write_bio_DSAPrivateKey(out,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys dsa, NULL, NULL, 0, NULL,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (cred != NULL ? cred->cred : NULL));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys DSA_free(dsa);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv == 1) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys default:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_BAD_PARAMETER;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_CreateKeypair(KMF_HANDLE_T handle, int numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys uint32_t eValue = 0x010001;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys RSA *sslPrivKey = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys DSA *sslDSAKey = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys EVP_PKEY *eprikey = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys EVP_PKEY *epubkey = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys BIO *out = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_HANDLE *pubkey = NULL, *privkey = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys uint32_t keylen = 1024;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys uint32_t keylen_size = sizeof (uint32_t);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys boolean_t storekey = TRUE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_ALG keytype = KMF_RSA;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_get_attr(KMF_STOREKEY_BOOL_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &storekey, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* "storekey" is optional. Default is TRUE */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void *)&keytype, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* keytype is optional. KMF_RSA is default */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (pubkey == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys privkey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (privkey == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) memset(pubkey, 0, sizeof (KMF_KEY_HANDLE));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) memset(privkey, 0, sizeof (KMF_KEY_HANDLE));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys eprikey = EVP_PKEY_new();
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (eprikey == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, ERR_get_error());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_KEYGEN_FAILED;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys epubkey = EVP_PKEY_new();
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (epubkey == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, ERR_get_error());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_KEYGEN_FAILED;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (keytype == KMF_RSA) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_BIGINT *rsaexp = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rsaexp = kmf_get_attr_ptr(KMF_RSAEXP_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rsaexp != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rsaexp->len > 0 &&
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rsaexp->len <= sizeof (eValue) &&
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rsaexp->val != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*LINTED*/
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys eValue = *(uint32_t *)rsaexp->val;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_BAD_PARAMETER;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* RSA Exponent is optional. Default is 0x10001 */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &keylen, &keylen_size);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv == KMF_ERR_ATTR_NOT_FOUND)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* keylen is optional, default is 1024 */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_BAD_PARAMETER;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sslPrivKey = RSA_generate_key(keylen, eValue, NULL, NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (sslPrivKey == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, ERR_get_error());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_KEYGEN_FAILED;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) EVP_PKEY_set1_RSA(eprikey, sslPrivKey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys privkey->kstype = KMF_KEYSTORE_OPENSSL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys privkey->keyalg = KMF_RSA;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys privkey->keyclass = KMF_ASYM_PRI;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys privkey->israw = FALSE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys privkey->keyp = (void *)eprikey;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* OpenSSL derives the public key from the private */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) EVP_PKEY_set1_RSA(epubkey, sslPrivKey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pubkey->kstype = KMF_KEYSTORE_OPENSSL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pubkey->keyalg = KMF_RSA;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pubkey->israw = FALSE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pubkey->keyclass = KMF_ASYM_PUB;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pubkey->keyp = (void *)epubkey;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (keytype == KMF_DSA) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys DSA *dp;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys sslDSAKey = DSA_new();
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (sslDSAKey == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, ERR_get_error());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_MEMORY);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((sslDSAKey->p = BN_bin2bn(P, sizeof (P), sslDSAKey->p)) ==
34acef6775bd2319a3708b750f10ccc4f1292562wyllys NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, ERR_get_error());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_KEYGEN_FAILED;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((sslDSAKey->q = BN_bin2bn(Q, sizeof (Q), sslDSAKey->q)) ==
34acef6775bd2319a3708b750f10ccc4f1292562wyllys NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, ERR_get_error());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_KEYGEN_FAILED;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((sslDSAKey->g = BN_bin2bn(G, sizeof (G), sslDSAKey->g)) ==
34acef6775bd2319a3708b750f10ccc4f1292562wyllys NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, ERR_get_error());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_KEYGEN_FAILED;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (!DSA_generate_key(sslDSAKey)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, ERR_get_error());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_KEYGEN_FAILED;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys privkey->kstype = KMF_KEYSTORE_OPENSSL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys privkey->keyalg = KMF_DSA;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys privkey->keyclass = KMF_ASYM_PRI;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys privkey->israw = FALSE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (EVP_PKEY_set1_DSA(eprikey, sslDSAKey)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys privkey->keyp = (void *)eprikey;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_KEYGEN_FAILED;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys dp = DSA_new();
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Make a copy for the public key */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (dp != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((dp->p = BN_new()) == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_MEMORY;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys DSA_free(dp);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((dp->q = BN_new()) == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_MEMORY;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys BN_free(dp->p);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys DSA_free(dp);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((dp->g = BN_new()) == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_MEMORY;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys BN_free(dp->q);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys BN_free(dp->p);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys DSA_free(dp);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((dp->pub_key = BN_new()) == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_MEMORY;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys BN_free(dp->q);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys BN_free(dp->p);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys BN_free(dp->g);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys DSA_free(dp);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) BN_copy(dp->p, sslDSAKey->p);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) BN_copy(dp->q, sslDSAKey->q);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) BN_copy(dp->g, sslDSAKey->g);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) BN_copy(dp->pub_key, sslDSAKey->pub_key);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pubkey->kstype = KMF_KEYSTORE_OPENSSL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pubkey->keyalg = KMF_DSA;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pubkey->keyclass = KMF_ASYM_PUB;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pubkey->israw = FALSE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (EVP_PKEY_set1_DSA(epubkey, sslDSAKey)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pubkey->keyp = (void *)epubkey;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, ERR_get_error());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_KEYGEN_FAILED;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (storekey) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE storeattrs[4]; /* max. 4 attributes needed */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int i = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *keyfile = NULL, *dirpath = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ENCODE_FORMAT format;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Construct a new attribute arrray and call openssl_store_key
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(storeattrs, i, KMF_PRIVKEY_HANDLE_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys privkey, sizeof (privkey));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys i++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (dirpath != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys storeattrs[i].type = KMF_DIRPATH_ATTR;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys storeattrs[i].pValue = dirpath;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys storeattrs[i].valueLen = strlen(dirpath);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys i++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_OK; /* DIRPATH is optional */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (keyfile != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys storeattrs[i].type = KMF_KEY_FILENAME_ATTR;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys storeattrs[i].pValue = keyfile;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys storeattrs[i].valueLen = strlen(keyfile);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys i++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup; /* KEYFILE is required */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void *)&format, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv == KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys storeattrs[i].type = KMF_ENCODE_FORMAT_ATTR;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys storeattrs[i].pValue = &format;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys storeattrs[i].valueLen = sizeof (format);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys i++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = OpenSSL_StoreKey(handle, i, storeattrs);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyscleanup:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (eprikey != NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys EVP_PKEY_free(eprikey);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (epubkey != NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys EVP_PKEY_free(epubkey);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (pubkey->keylabel) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(pubkey->keylabel);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys pubkey->keylabel = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (privkey->keylabel) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(privkey->keylabel);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys privkey->keylabel = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys pubkey->keyp = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys privkey->keyp = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (sslPrivKey)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys RSA_free(sslPrivKey);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (sslDSAKey)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys DSA_free(sslDSAKey);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (out != NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) BIO_free(out);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_OID *AlgOID, KMF_DATA *tobesigned, KMF_DATA *output)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_ALGORITHM_INDEX AlgId;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys EVP_MD_CTX ctx;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys const EVP_MD *md;
02744e811b15322c5f109827a116c33bfe3438b5wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (key == NULL || AlgOID == NULL ||
34acef6775bd2319a3708b750f10ccc4f1292562wyllys tobesigned == NULL || output == NULL ||
34acef6775bd2319a3708b750f10ccc4f1292562wyllys tobesigned->Data == NULL ||
34acef6775bd2319a3708b750f10ccc4f1292562wyllys output->Data == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Map the OID to an OpenSSL algorithm */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys AlgId = x509_algoid_to_algid(AlgOID);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (AlgId == KMF_ALGID_NONE)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (key->keyalg == KMF_RSA) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys EVP_PKEY *pkey = (EVP_PKEY *)key->keyp;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys uchar_t *p;
02744e811b15322c5f109827a116c33bfe3438b5wyllys int len;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (AlgId == KMF_ALGID_MD5WithRSA)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys md = EVP_md5();
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys else if (AlgId == KMF_ALGID_MD2WithRSA)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys md = EVP_md2();
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys else if (AlgId == KMF_ALGID_SHA1WithRSA)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys md = EVP_sha1();
02744e811b15322c5f109827a116c33bfe3438b5wyllys else if (AlgId == KMF_ALGID_RSA)
02744e811b15322c5f109827a116c33bfe3438b5wyllys md = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys else
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys if ((md == NULL) && (AlgId == KMF_ALGID_RSA)) {
02744e811b15322c5f109827a116c33bfe3438b5wyllys RSA *rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)pkey);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys p = output->Data;
02744e811b15322c5f109827a116c33bfe3438b5wyllys if ((len = RSA_private_encrypt(tobesigned->Length,
34acef6775bd2319a3708b750f10ccc4f1292562wyllys tobesigned->Data, p, rsa,
34acef6775bd2319a3708b750f10ccc4f1292562wyllys RSA_PKCS1_PADDING)) <= 0) {
02744e811b15322c5f109827a116c33bfe3438b5wyllys SET_ERROR(kmfh, ERR_get_error());
02744e811b15322c5f109827a116c33bfe3438b5wyllys ret = KMF_ERR_INTERNAL;
02744e811b15322c5f109827a116c33bfe3438b5wyllys }
02744e811b15322c5f109827a116c33bfe3438b5wyllys output->Length = len;
02744e811b15322c5f109827a116c33bfe3438b5wyllys } else {
02744e811b15322c5f109827a116c33bfe3438b5wyllys (void) EVP_MD_CTX_init(&ctx);
02744e811b15322c5f109827a116c33bfe3438b5wyllys (void) EVP_SignInit_ex(&ctx, md, NULL);
02744e811b15322c5f109827a116c33bfe3438b5wyllys (void) EVP_SignUpdate(&ctx, tobesigned->Data,
34acef6775bd2319a3708b750f10ccc4f1292562wyllys (uint32_t)tobesigned->Length);
02744e811b15322c5f109827a116c33bfe3438b5wyllys len = (uint32_t)output->Length;
02744e811b15322c5f109827a116c33bfe3438b5wyllys p = output->Data;
02744e811b15322c5f109827a116c33bfe3438b5wyllys if (!EVP_SignFinal(&ctx, p, (uint32_t *)&len, pkey)) {
02744e811b15322c5f109827a116c33bfe3438b5wyllys SET_ERROR(kmfh, ERR_get_error());
02744e811b15322c5f109827a116c33bfe3438b5wyllys len = 0;
02744e811b15322c5f109827a116c33bfe3438b5wyllys ret = KMF_ERR_INTERNAL;
02744e811b15322c5f109827a116c33bfe3438b5wyllys }
02744e811b15322c5f109827a116c33bfe3438b5wyllys output->Length = len;
02744e811b15322c5f109827a116c33bfe3438b5wyllys (void) EVP_MD_CTX_cleanup(&ctx);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (key->keyalg == KMF_DSA) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys DSA *dsa = EVP_PKEY_get1_DSA(key->keyp);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys uchar_t hash[EVP_MAX_MD_SIZE];
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys uint32_t hashlen;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys DSA_SIG *dsasig;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * OpenSSL EVP_Sign operation automatically converts to
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * ASN.1 output so we do the operations separately so we
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * are assured of NOT getting ASN.1 output returned.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * KMF does not want ASN.1 encoded results because
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * not all mechanisms return ASN.1 encodings (PKCS#11
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * and NSS return raw signature data).
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys md = EVP_sha1();
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys EVP_MD_CTX_init(&ctx);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) EVP_DigestInit_ex(&ctx, md, NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) EVP_DigestUpdate(&ctx, tobesigned->Data,
34acef6775bd2319a3708b750f10ccc4f1292562wyllys tobesigned->Length);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) EVP_DigestFinal_ex(&ctx, hash, &hashlen);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) EVP_MD_CTX_cleanup(&ctx);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys dsasig = DSA_do_sign(hash, hashlen, dsa);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (dsasig != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int i;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys output->Length = i = BN_bn2bin(dsasig->r, output->Data);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys output->Length += BN_bn2bin(dsasig->s,
34acef6775bd2319a3708b750f10ccc4f1292562wyllys &output->Data[i]);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys DSA_SIG_free(dsasig);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, ERR_get_error());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyscleanup:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*ARGSUSED*/
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_DeleteKey(KMF_HANDLE_T handle,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN rv = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_HANDLE *key;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys boolean_t destroy = B_TRUE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (key == NULL || key->keyp == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void *)&destroy, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* "destroy" is optional. Default is TRUE */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (key->keyclass != KMF_ASYM_PUB &&
34acef6775bd2319a3708b750f10ccc4f1292562wyllys key->keyclass != KMF_ASYM_PRI &&
34acef6775bd2319a3708b750f10ccc4f1292562wyllys key->keyclass != KMF_SYMMETRIC)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_KEY_CLASS);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (key->keyclass == KMF_SYMMETRIC) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_raw_sym_key((KMF_RAW_SYM_KEY *)key->keyp);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys key->keyp = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (key->keyp != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys EVP_PKEY_free(key->keyp);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys key->keyp = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (key->keylabel != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys EVP_PKEY *pkey = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* If the file exists, make sure it is a proper key. */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys pkey = openssl_load_key(handle, key->keylabel);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (pkey == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(key->keylabel);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys key->keylabel = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_KEY_NOT_FOUND);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys EVP_PKEY_free(pkey);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (destroy) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (unlink(key->keylabel) != 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_SYS_ERROR(kmfh, errno);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_INTERNAL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (key->keylabel != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(key->keylabel);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys key->keylabel = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_GetErrorString(KMF_HANDLE_T handle, char **msgstr)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN ret = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char str[256]; /* OpenSSL needs at least 120 byte buffer */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ERR_error_string_n(kmfh->lasterr.errcode, str, sizeof (str));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (strlen(str)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *msgstr = (char *)strdup(str);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((*msgstr) == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_MEMORY;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *msgstr = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic int
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysext2NID(int kmfext)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys switch (kmfext) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_X509_EXT_KEY_USAGE:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (NID_key_usage);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (NID_private_key_usage_period);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_X509_EXT_CERT_POLICIES:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (NID_certificate_policies);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_X509_EXT_SUBJ_ALTNAME:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (NID_subject_alt_name);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_X509_EXT_ISSUER_ALTNAME:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (NID_issuer_alt_name);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_X509_EXT_BASIC_CONSTRAINTS:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (NID_basic_constraints);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_X509_EXT_EXT_KEY_USAGE:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (NID_ext_key_usage);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_X509_EXT_AUTH_KEY_ID:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (NID_authority_key_identifier);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_X509_EXT_CRL_DIST_POINTS:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (NID_crl_distribution_points);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_X509_EXT_SUBJ_KEY_ID:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (NID_subject_key_identifier);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_X509_EXT_POLICY_MAPPINGS:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (OBJ_sn2nid("policyMappings"));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_X509_EXT_NAME_CONSTRAINTS:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (OBJ_sn2nid("nameConstraints"));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_X509_EXT_POLICY_CONSTRAINTS:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (OBJ_sn2nid("policyConstraints"));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_X509_EXT_INHIBIT_ANY_POLICY:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (OBJ_sn2nid("inhibitAnyPolicy"));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_X509_EXT_FRESHEST_CRL:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (OBJ_sn2nid("freshestCRL"));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys default:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (NID_undef);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *pcert,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_PRINTABLE_ITEM flag, char *resultStr)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509 *xcert = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys unsigned char *outbuf = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys unsigned char *outbuf_p;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *tmpstr = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int j;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int ext_index, nid, len;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys BIO *mem = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys STACK *emlst = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509_EXTENSION *ex;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509_CINF *ci;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* copy cert data to outbuf */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys outbuf = malloc(pcert->Length);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (outbuf == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_MEMORY);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) memcpy(outbuf, pcert->Data, pcert->Length);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys outbuf_p = outbuf; /* use a temp pointer; required by openssl */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, pcert->Length);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (xcert == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_ENCODING;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys mem = BIO_new(BIO_s_mem());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (mem == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, ERR_get_error());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_MEMORY;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys switch (flag) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_CERT_ISSUER:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) X509_NAME_print_ex(mem, X509_get_issuer_name(xcert), 0,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys XN_FLAG_SEP_CPLUS_SPC);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_CERT_SUBJECT:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) X509_NAME_print_ex(mem, X509_get_subject_name(xcert), 0,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys XN_FLAG_SEP_CPLUS_SPC);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_CERT_VERSION:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys tmpstr = i2s_ASN1_INTEGER(NULL, xcert->cert_info->version);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) strncpy(resultStr, tmpstr, KMF_CERT_PRINTABLE_LEN);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys OPENSSL_free(tmpstr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys len = strlen(resultStr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_CERT_SERIALNUM:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (i2a_ASN1_INTEGER(mem, X509_get_serialNumber(xcert)) > 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) strcpy(resultStr, "0x");
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys len = BIO_gets(mem, &resultStr[2],
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_CERT_PRINTABLE_LEN - 2);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_CERT_NOTBEFORE:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) ASN1_TIME_print(mem, X509_get_notBefore(xcert));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_CERT_NOTAFTER:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) ASN1_TIME_print(mem, X509_get_notAfter(xcert));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_CERT_PUBKEY_DATA:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys EVP_PKEY *pkey = X509_get_pubkey(xcert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (pkey == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_ENCODING;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (pkey->type == EVP_PKEY_RSA) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) BIO_printf(mem,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys "RSA Public Key: (%d bit)\n",
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys BN_num_bits(pkey->pkey.rsa->n));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) RSA_print(mem, pkey->pkey.rsa, 0);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (pkey->type == EVP_PKEY_DSA) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) BIO_printf(mem,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys "%12sDSA Public Key:\n", "");
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) DSA_print(mem, pkey->pkey.dsa, 0);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) BIO_printf(mem,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys "%12sUnknown Public Key:\n", "");
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) BIO_printf(mem, "\n");
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys EVP_PKEY_free(pkey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys break;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_CERT_SIGNATURE_ALG:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_CERT_PUBKEY_ALG:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (flag == KMF_CERT_SIGNATURE_ALG) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys len = i2a_ASN1_OBJECT(mem,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys xcert->sig_alg->algorithm);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys len = i2a_ASN1_OBJECT(mem,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys xcert->cert_info->key->algor->algorithm);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (len > 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys len = BIO_read(mem, resultStr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_CERT_PRINTABLE_LEN);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys break;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_CERT_EMAIL:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys emlst = X509_get1_email(xcert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys for (j = 0; j < sk_num(emlst); j++)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) BIO_printf(mem, "%s\n", sk_value(emlst, j));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509_email_free(emlst);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys break;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_X509_EXT_ISSUER_ALTNAME:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_X509_EXT_SUBJ_ALTNAME:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_X509_EXT_KEY_USAGE:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_X509_EXT_CERT_POLICIES:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_X509_EXT_BASIC_CONSTRAINTS:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_X509_EXT_NAME_CONSTRAINTS:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_X509_EXT_POLICY_CONSTRAINTS:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_X509_EXT_EXT_KEY_USAGE:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_X509_EXT_INHIBIT_ANY_POLICY:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_X509_EXT_AUTH_KEY_ID:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_X509_EXT_SUBJ_KEY_ID:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_X509_EXT_POLICY_MAPPINGS:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_X509_EXT_CRL_DIST_POINTS:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_X509_EXT_FRESHEST_CRL:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys nid = ext2NID(flag);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (nid == NID_undef) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_EXTENSION_NOT_FOUND;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ci = xcert->cert_info;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ext_index = X509v3_get_ext_by_NID(ci->extensions, nid, -1);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ext_index == -1) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_EXTENSION_NOT_FOUND;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ex = X509v3_get_ext(ci->extensions, ext_index);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) i2a_ASN1_OBJECT(mem, X509_EXTENSION_get_object(ex));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (BIO_printf(mem, ": %s\n",
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509_EXTENSION_get_critical(ex) ? "critical" : "") <= 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_ENCODING;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (!X509V3_EXT_print(mem, ex, X509V3_EXT_DUMP_UNKNOWN, 4)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) BIO_printf(mem, "%*s", 4, "");
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) M_ASN1_OCTET_STRING_print(mem, ex->value);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (BIO_write(mem, "\n", 1) <= 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_ENCODING;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (len <= 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_ENCODING;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysout:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (outbuf != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(outbuf);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (xcert != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509_free(xcert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (mem != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) BIO_free(mem);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys/*ARGSUSED*/
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_FindPrikeyByCert(KMF_HANDLE_T handle, int numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN rv = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_CLASS keyclass = KMF_ASYM_PRI;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_HANDLE *key = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys uint32_t numkeys = 1; /* 1 key only */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *dirpath = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *keyfile = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE new_attrlist[16];
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int i = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * This is really just a FindKey operation, reuse the
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * FindKey function.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(new_attrlist, i,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys i++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(new_attrlist, i,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_COUNT_ATTR, &numkeys, sizeof (uint32_t));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys i++;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(new_attrlist, i,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEYCLASS_ATTR, &keyclass, sizeof (keyclass));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys i++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (key == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(new_attrlist, i,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_HANDLE_ATTR, key, sizeof (KMF_KEY_HANDLE));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys i++;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (dirpath != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(new_attrlist, i,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DIRPATH_ATTR, dirpath, strlen(dirpath));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys i++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (keyfile == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(new_attrlist, i,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_FILENAME_ATTR, keyfile, strlen(keyfile));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys i++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = OpenSSL_FindKey(handle, i, new_attrlist);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys}
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys/*ARGSUSED*/
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_OID *AlgOID, KMF_DATA *ciphertext,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *output)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys RSA *rsa = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys unsigned int in_len = 0, out_len = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys unsigned int total_decrypted = 0, modulus_len = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys uint8_t *in_data, *out_data;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int i, blocks;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (key == NULL || AlgOID == NULL ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ciphertext == NULL || output == NULL ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ciphertext->Data == NULL ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys output->Data == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (key->keyalg == KMF_RSA) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)key->keyp);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys modulus_len = RSA_size(rsa);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys blocks = ciphertext->Length/modulus_len;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys out_data = output->Data;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys in_data = ciphertext->Data;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys out_len = modulus_len - 11;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys in_len = modulus_len;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys for (i = 0; i < blocks; i++) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys out_len = RSA_private_decrypt(in_len,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys in_data, out_data, rsa, RSA_PKCS1_PADDING);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (out_len == 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_INTERNAL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys out_data += out_len;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys total_decrypted += out_len;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys in_data += in_len;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys output->Length = total_decrypted;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyscleanup:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys RSA_free(rsa);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys output->Length = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys/*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * This function will create a certid from issuer_cert and user_cert.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * The caller should use OCSP_CERTID_free(OCSP_CERTID *) to deallocate
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * certid memory after use.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyscreate_certid(KMF_HANDLE_T handle, const KMF_DATA *issuer_cert,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys const KMF_DATA *user_cert, OCSP_CERTID **certid)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509 *issuer = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509 *cert = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys unsigned char *ptmp;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (issuer_cert == NULL || user_cert == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* convert the DER-encoded issuer cert to an internal X509 */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ptmp = issuer_cert->Data;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys issuer = d2i_X509(NULL, (const uchar_t **)&ptmp,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys issuer_cert->Length);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (issuer == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_OCSP_BAD_ISSUER;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* convert the DER-encoded user cert to an internal X509 */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ptmp = user_cert->Data;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys cert = d2i_X509(NULL, (const uchar_t **)&ptmp,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys user_cert->Length);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (cert == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, ERR_get_error());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_OCSP_BAD_CERT;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto end;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* create a CERTID */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *certid = OCSP_cert_to_id(NULL, cert, issuer);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (*certid == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_OCSP_CERTID;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysend:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (issuer != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509_free(issuer);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (cert != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509_free(cert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys}
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int numattr, KMF_ATTRIBUTE *attrlist)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys OCSP_CERTID *id = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys OCSP_REQUEST *req = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys BIO *derbio = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *reqfile;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *issuer_cert;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *user_cert;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys user_cert = kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (user_cert == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys issuer_cert = kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (issuer_cert == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys reqfile = kmf_get_attr_ptr(KMF_OCSP_REQUEST_FILENAME_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (reqfile == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = create_certid(handle, issuer_cert, user_cert, &id);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Create an OCSP request */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys req = OCSP_REQUEST_new();
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (req == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_OCSP_CREATE_REQUEST;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (!OCSP_request_add0_id(req, id)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_OCSP_CREATE_REQUEST;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Write the request to the output file with DER encoding */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys derbio = BIO_new_file(reqfile, "wb");
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (!derbio) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_OPEN_FILE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (i2d_OCSP_REQUEST_bio(derbio, req) <= 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_ENCODING;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysend:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * We don't need to free "id" explicitely, because OCSP_REQUEST_free()
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * will deallocate certid's space also.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (req != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys OCSP_REQUEST_free(req);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (derbio != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) BIO_free(derbio);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys/* ocsp_find_signer_sk() is copied from openssl source */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int i;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Easy if lookup by name */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (id->type == V_OCSP_RESPID_NAME)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (X509_find_by_subject(certs, id->value.byName));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Lookup by key hash */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* If key hash isn't SHA1 length then forget it */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (id->value.byKey->length != SHA_DIGEST_LENGTH)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keyhash = id->value.byKey->data;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Calculate hash of each key and compare */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys for (i = 0; i < sk_X509_num(certs); i++) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*LINTED*/
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509 *x = sk_X509_value(certs, i);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH))
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (x);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys/* ocsp_find_signer() is copied from openssl source */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys/*ARGSUSED*/
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic int
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509_STORE *st, unsigned long flags)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509 *signer;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys OCSP_RESPID *rid = bs->tbsResponseData->responderId;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((signer = ocsp_find_signer_sk(certs, rid))) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *psigner = signer;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (2);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (!(flags & OCSP_NOINTERN) &&
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (signer = ocsp_find_signer_sk(bs->certs, rid))) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *psigner = signer;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (1);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Maybe lookup from store if by subject name */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *psigner = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (0);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys/*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * This function will verify the signature of a basic response, using
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * the public key from the OCSP responder certificate.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyscheck_response_signature(KMF_HANDLE_T handle, OCSP_BASICRESP *bs,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *signer_cert, KMF_DATA *issuer_cert)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys STACK_OF(X509) *cert_stack = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509 *signer = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509 *issuer = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys EVP_PKEY *skey = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys unsigned char *ptmp;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (bs == NULL || issuer_cert == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Find the certificate that signed the basic response.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * If signer_cert is not NULL, we will use that as the signer cert.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Otherwise, we will check if the issuer cert is actually the signer.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * If we still do not find a signer, we will look for it from the
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * certificate list came with the response file.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (signer_cert != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ptmp = signer_cert->Data;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys signer = d2i_X509(NULL, (const uchar_t **)&ptmp,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys signer_cert->Length);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (signer == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_OCSP_BAD_SIGNER;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Convert the issuer cert into X509 and push it into a
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * stack to be used by ocsp_find_signer().
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ptmp = issuer_cert->Data;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys issuer = d2i_X509(NULL, (const uchar_t **)&ptmp,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys issuer_cert->Length);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (issuer == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_OCSP_BAD_ISSUER;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((cert_stack = sk_X509_new_null()) == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_INTERNAL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (sk_X509_push(cert_stack, issuer) == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_INTERNAL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = ocsp_find_signer(&signer, bs, cert_stack, NULL, 0);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (!ret) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* can not find the signer */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_OCSP_BAD_SIGNER;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Verify the signature of the response */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys skey = X509_get_pubkey(signer);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (skey == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_OCSP_BAD_SIGNER;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = OCSP_BASICRESP_verify(bs, skey, 0);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret == 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_OCSP_RESPONSE_SIGNATURE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysend:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (issuer != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509_free(issuer);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (signer != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509_free(signer);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (skey != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys EVP_PKEY_free(skey);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (cert_stack != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sk_X509_free(cert_stack);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys BIO *derbio = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys OCSP_RESPONSE *resp = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys OCSP_BASICRESP *bs = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys OCSP_CERTID *id = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys OCSP_SINGLERESP *single = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int index, status, reason;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *issuer_cert;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *user_cert;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *signer_cert;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *response;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int *response_reason, *response_status, *cert_status;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys boolean_t ignore_response_sign = B_FALSE; /* default is FALSE */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys uint32_t response_lifetime;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys issuer_cert = kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (issuer_cert == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys user_cert = kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (user_cert == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys response = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_DATA_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (response == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys response_status = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_STATUS_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (response_status == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys response_reason = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_REASON_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (response_reason == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys cert_status = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_CERT_STATUS_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (cert_status == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Read in the response */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys derbio = BIO_new_mem_buf(response->Data, response->Length);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (!derbio) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_MEMORY;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (resp == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_OCSP_MALFORMED_RESPONSE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Check the response status */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys status = OCSP_response_status(resp);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *response_status = status;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_OCSP_RESPONSE_STATUS;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys#ifdef DEBUG
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys printf("Successfully checked the response file status.\n");
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys#endif /* DEBUG */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Extract basic response */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys bs = OCSP_response_get1_basic(resp);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (bs == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_OCSP_NO_BASIC_RESPONSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys#ifdef DEBUG
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys printf("Successfully retrieved the basic response.\n");
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys#endif /* DEBUG */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Check the basic response signature if required */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_attr(KMF_IGNORE_RESPONSE_SIGN_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void *)&ignore_response_sign, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys signer_cert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ignore_response_sign == B_FALSE) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = check_response_signature(handle, bs,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys signer_cert, issuer_cert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys#ifdef DEBUG
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys printf("Successfully verified the response signature.\n");
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys#endif /* DEBUG */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Create a certid for the certificate in question */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = create_certid(handle, issuer_cert, user_cert, &id);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_OCSP_CERTID;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys#ifdef DEBUG
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys printf("successfully created a certid for the cert.\n");
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys#endif /* DEBUG */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Find the index of the single response for the certid */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys index = OCSP_resp_find(bs, id, -1);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (index < 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* cound not find this certificate in the response */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_OCSP_UNKNOWN_CERT;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys#ifdef DEBUG
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys printf("Successfully found the single response index for the cert.\n");
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys#endif /* DEBUG */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Retrieve the single response and get the cert status */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys single = OCSP_resp_get0(bs, index);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys status = OCSP_single_get0_status(single, &reason, &rev, &thisupd,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &nextupd);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (status == V_OCSP_CERTSTATUS_GOOD) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *cert_status = OCSP_GOOD;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (status == V_OCSP_CERTSTATUS_UNKNOWN) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *cert_status = OCSP_UNKNOWN;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else { /* revoked */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *cert_status = OCSP_REVOKED;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *response_reason = reason;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* resp. time is optional, so we don't care about the return code. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) kmf_get_attr(KMF_RESPONSE_LIFETIME_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void *)&response_lifetime, NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (!OCSP_check_validity(thisupd, nextupd, 300,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys response_lifetime)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_OCSP_STATUS_TIME_INVALID;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys#ifdef DEBUG
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys printf("Successfully verify the time.\n");
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys#endif /* DEBUG */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysend:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (derbio != NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) BIO_free(derbio);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (resp != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys OCSP_RESPONSE_free(resp);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (bs != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys OCSP_BASICRESP_free(bs);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (id != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys OCSP_CERTID_free(id);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysfetch_key(KMF_HANDLE_T handle, char *path,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_CLASS keyclass, KMF_KEY_HANDLE *key)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN rv = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys EVP_PKEY *pkey = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RAW_SYM_KEY *rkey = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (keyclass == KMF_ASYM_PRI ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keyclass == KMF_ASYM_PUB) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pkey = openssl_load_key(handle, path);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (pkey == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_KEY_NOT_FOUND);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (key != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (pkey->type == EVP_PKEY_RSA)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key->keyalg = KMF_RSA;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys else if (pkey->type == EVP_PKEY_DSA)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key->keyalg = KMF_DSA;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key->kstype = KMF_KEYSTORE_OPENSSL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key->keyclass = keyclass;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key->keyp = (void *)pkey;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key->israw = FALSE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key->keylabel = path;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys EVP_PKEY_free(pkey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pkey = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (keyclass == KMF_SYMMETRIC) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ENCODE_FORMAT fmt;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * If the file is a recognized format,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * then it is NOT a symmetric key.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_get_file_format(path, &fmt);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv == KMF_OK || fmt != 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_KEY_NOT_FOUND);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (rv == KMF_ERR_ENCODING) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * If we don't know the encoding,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * it is probably a symmetric key.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (rv == KMF_ERR_OPEN_FILE) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_KEY_NOT_FOUND);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (key != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA keyvalue;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rkey = malloc(sizeof (KMF_RAW_SYM_KEY));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rkey == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_MEMORY;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_read_input_file(handle, path, &keyvalue);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rkey->keydata.len = keyvalue.Length;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rkey->keydata.val = keyvalue.Data;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key->kstype = KMF_KEYSTORE_OPENSSL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key->keyclass = keyclass;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key->israw = TRUE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key->keylabel = path;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key->keyp = (void *)rkey;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysout:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rkey != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_raw_sym_key(rkey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (pkey != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys EVP_PKEY_free(pkey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (key != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key->keyalg = KMF_KEYALG_NONE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key->keyclass = KMF_KEYCLASS_NONE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key->keyp = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_FindKey(KMF_HANDLE_T handle,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN rv = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *fullpath = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys uint32_t maxkeys;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_HANDLE *key;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys uint32_t *numkeys;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_CLASS keyclass;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RAW_KEY_DATA *rawkey;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *dirpath;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *keyfile;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (numkeys == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void *)&keyclass, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (keyclass != KMF_ASYM_PUB &&
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keyclass != KMF_ASYM_PRI &&
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keyclass != KMF_SYMMETRIC)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_KEY_CLASS);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys fullpath = get_fullpath(dirpath, keyfile);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (fullpath == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys maxkeys = *numkeys;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (maxkeys == 0)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys maxkeys = 0xFFFFFFFF;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *numkeys = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* it is okay to have "keys" contains NULL */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * The caller may want a list of the raw key data as well.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Useful for importing keys from a file into other keystores.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attrlist, numattr);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (isdir(fullpath)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys DIR *dirp;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys struct dirent *dp;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int n = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* open all files in the directory and attempt to read them */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((dirp = opendir(fullpath)) == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rewinddir(dirp);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys while ((dp = readdir(dirp)) != NULL && n < maxkeys) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (strcmp(dp->d_name, ".") &&
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys strcmp(dp->d_name, "..")) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *fname;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys fname = get_fullpath(fullpath,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (char *)&dp->d_name);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = fetch_key(handle, fname,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keyclass, key ? &key[n] : NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv == KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (key != NULL && rawkey != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = convertToRawKey(
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key[n].keyp, &rawkey[n]);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys n++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK || key == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(fname);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) closedir(dirp);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(fullpath);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (*numkeys) = n;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = fetch_key(handle, fullpath, keyclass, key);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv == KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (*numkeys) = 1;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK || key == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(fullpath);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv == KMF_OK && key != NULL && rawkey != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = convertToRawKey(key->keyp, rawkey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv == KMF_OK && (*numkeys) == 0)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_KEY_NOT_FOUND;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys#define HANDLE_PK12_ERROR { \
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error()); \
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_ENCODING; \
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out; \
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyswrite_pkcs12(KMF_HANDLE *kmfh,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys BIO *bio,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_CREDENTIAL *cred,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys EVP_PKEY *pkey,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509 *sslcert)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN rv = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys STACK_OF(PKCS12_SAFEBAG) *bag_stack = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PKCS12_SAFEBAG *bag = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PKCS7 *cert_authsafe = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PKCS8_PRIV_KEY_INFO *p8 = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PKCS7 *key_authsafe = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys STACK_OF(PKCS7) *authsafe_stack = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PKCS12 *p12_elem = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *lab = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int lab_len = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys unsigned char keyid[EVP_MAX_MD_SIZE];
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys unsigned int keyidlen = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Must have at least a cert OR a key */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (sslcert == NULL && pkey == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) memset(keyid, 0, sizeof (keyid));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Section 1:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * The first PKCS#12 container (safebag) will hold the certificates
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * associated with this key. The result of this section is a
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * PIN-encrypted PKCS#7 container (authsafe). If there are no
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * certificates, there is no point in creating the "safebag" or the
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * "authsafe" so we go to the next section.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (sslcert != NULL && pkey != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (X509_check_private_key(sslcert, pkey)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) X509_digest(sslcert, EVP_sha1(), keyid,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &keyidlen);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* The key doesn't match the cert */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys HANDLE_PK12_ERROR
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys bag_stack = sk_PKCS12_SAFEBAG_new_null();
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (bag_stack == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_MEMORY);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (sslcert != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Convert cert from X509 struct to PKCS#12 bag */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys bag = PKCS12_x5092certbag(sslcert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (bag == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys HANDLE_PK12_ERROR
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Add the key id to the certificate bag. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (keyidlen > 0 &&
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys !PKCS12_add_localkeyid(bag, keyid, keyidlen)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys HANDLE_PK12_ERROR
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Pile it on the bag_stack. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys HANDLE_PK12_ERROR
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys#if 0
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* No support for CA certs yet */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (cacerts != NULL && ncacerts > 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int i;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys for (i = 0; i < ncacerts; i++) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_X509_DER_CERT *c = &cacerts[i];
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509 *ca = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys uchar_t *p = (uchar_t *)c->certificate.Data;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ca = d2i_X509(NULL, &p, c->certificate.Length);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ca == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys HANDLE_PK12_ERROR
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Convert CA cert to PKCS#12 bag. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys bag = PKCS12_x5092certbag(ca);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (bag == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sk_PKCS12_SAFEBAG_pop_free(bag_stack,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PKCS12_SAFEBAG_free);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys HANDLE_PK12_ERROR
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Pile it onto the bag_stack. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys HANDLE_PK12_ERROR
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys#endif
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Turn bag_stack of certs into encrypted authsafe. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys cert_authsafe = PKCS12_pack_p7encdata(
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys NID_pbe_WithSHA1And40BitRC2_CBC,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys cred->cred, cred->credlen, NULL, 0,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PKCS12_DEFAULT_ITER, bag_stack);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Clear away this bag_stack, we're done with it. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys bag_stack = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (cert_authsafe == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys HANDLE_PK12_ERROR
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Section 2:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * The second PKCS#12 container (safebag) will hold the private key
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * that goes with the certificates above. The results of this section
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * is an unencrypted PKCS#7 container (authsafe). If there is no
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * private key, there is no point in creating the "safebag" or the
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * "authsafe" so we go to the next section.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (pkey != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys p8 = EVP_PKEY2PKCS8(pkey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (p8 == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys HANDLE_PK12_ERROR
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Put the shrouded key into a PKCS#12 bag. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys bag = PKCS12_MAKE_SHKEYBAG(
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys cred->cred, cred->credlen,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys NULL, 0, PKCS12_DEFAULT_ITER, p8);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Clean up the PKCS#8 shrouded key, don't need it now. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PKCS8_PRIV_KEY_INFO_free(p8);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys p8 = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (bag == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys HANDLE_PK12_ERROR
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (keyidlen &&
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys !PKCS12_add_localkeyid(bag, keyid, keyidlen)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys HANDLE_PK12_ERROR
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (lab != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (!PKCS12_add_friendlyname(bag,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (char *)lab, lab_len)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys HANDLE_PK12_ERROR
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Start a PKCS#12 safebag container for the private key. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys bag_stack = sk_PKCS12_SAFEBAG_new_null();
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (bag_stack == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys HANDLE_PK12_ERROR
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Pile on the private key on the bag_stack. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys HANDLE_PK12_ERROR
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key_authsafe = PKCS12_pack_p7data(bag_stack);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Clear away this bag_stack, we're done with it. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys bag_stack = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (key_authsafe == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys HANDLE_PK12_ERROR
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Section 3:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * This is where the two PKCS#7 containers, one for the certificates
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * and one for the private key, are put together into a PKCS#12
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * element. This final PKCS#12 element is written to the export file.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Start a PKCS#7 stack. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys authsafe_stack = sk_PKCS7_new_null();
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (authsafe_stack == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys HANDLE_PK12_ERROR
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (key_authsafe != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (!sk_PKCS7_push(authsafe_stack, key_authsafe)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys HANDLE_PK12_ERROR
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (cert_authsafe != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (!sk_PKCS7_push(authsafe_stack, cert_authsafe)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys HANDLE_PK12_ERROR
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys p12_elem = PKCS12_init(NID_pkcs7_data);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (p12_elem == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sk_PKCS7_pop_free(authsafe_stack, PKCS7_free);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys HANDLE_PK12_ERROR
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Put the PKCS#7 stack into the PKCS#12 element. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (!PKCS12_pack_authsafes(p12_elem, authsafe_stack)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys HANDLE_PK12_ERROR
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Clear away the PKCS#7 stack, we're done with it. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sk_PKCS7_pop_free(authsafe_stack, PKCS7_free);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys authsafe_stack = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Set the integrity MAC on the PKCS#12 element. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (!PKCS12_set_mac(p12_elem, cred->cred, cred->credlen,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys NULL, 0, PKCS12_DEFAULT_ITER, NULL)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys HANDLE_PK12_ERROR
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Write the PKCS#12 element to the export file. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (!i2d_PKCS12_bio(bio, p12_elem)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys HANDLE_PK12_ERROR
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PKCS12_free(p12_elem);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysout:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Clear away this bag_stack, we're done with it. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sk_PKCS7_pop_free(authsafe_stack, PKCS7_free);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic EVP_PKEY *
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysImportRawRSAKey(KMF_RAW_RSA_KEY *key)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys RSA *rsa = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys EVP_PKEY *newkey = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((rsa = RSA_new()) == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((rsa->n = BN_bin2bn(key->mod.val, key->mod.len, rsa->n)) == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((rsa->e = BN_bin2bn(key->pubexp.val, key->pubexp.len, rsa->e)) ==
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (key->priexp.val != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((rsa->d = BN_bin2bn(key->priexp.val, key->priexp.len,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rsa->d)) == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (key->prime1.val != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((rsa->p = BN_bin2bn(key->prime1.val, key->prime1.len,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rsa->p)) == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (key->prime2.val != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((rsa->q = BN_bin2bn(key->prime2.val, key->prime2.len,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rsa->q)) == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (key->exp1.val != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((rsa->dmp1 = BN_bin2bn(key->exp1.val, key->exp1.len,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rsa->dmp1)) == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (key->exp2.val != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((rsa->dmq1 = BN_bin2bn(key->exp2.val, key->exp2.len,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rsa->dmq1)) == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (key->coef.val != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((rsa->iqmp = BN_bin2bn(key->coef.val, key->coef.len,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rsa->iqmp)) == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((newkey = EVP_PKEY_new()) == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) EVP_PKEY_set1_RSA(newkey, rsa);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* The original key must be freed once here or it leaks memory */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys RSA_free(rsa);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (newkey);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic EVP_PKEY *
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysImportRawDSAKey(KMF_RAW_DSA_KEY *key)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys DSA *dsa = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys EVP_PKEY *newkey = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((dsa = DSA_new()) == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((dsa->p = BN_bin2bn(key->prime.val, key->prime.len,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys dsa->p)) == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((dsa->q = BN_bin2bn(key->subprime.val, key->subprime.len,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys dsa->q)) == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((dsa->g = BN_bin2bn(key->base.val, key->base.len,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys dsa->g)) == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((dsa->priv_key = BN_bin2bn(key->value.val, key->value.len,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys dsa->priv_key)) == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (NULL);
f482c776bc557f0256e776932c7842b9db390de1wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (key->pubvalue.val != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((dsa->pub_key = BN_bin2bn(key->pubvalue.val,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key->pubvalue.len, dsa->pub_key)) == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((newkey = EVP_PKEY_new()) == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) EVP_PKEY_set1_DSA(newkey, dsa);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* The original key must be freed once here or it leaks memory */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys DSA_free(dsa);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (newkey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys}
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysExportPK12FromRawData(KMF_HANDLE_T handle,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_CREDENTIAL *cred,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int numcerts, KMF_X509_DER_CERT *certlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int numkeys, KMF_KEY_HANDLE *keylist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *filename)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN rv = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys BIO *bio = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509 *xcert = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys EVP_PKEY *pkey = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int i;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Open the output file.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((bio = BIO_new_file(filename, "wb")) == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_OPEN_FILE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (numcerts > 0 && numkeys > 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys for (i = 0; rv == KMF_OK && i < numcerts; i++) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RAW_KEY_DATA *key = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys const uchar_t *p = certlist[i].certificate.Data;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys long len = certlist[i].certificate.Length;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (i < numkeys) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key = (KMF_RAW_KEY_DATA *)keylist[i].keyp;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (key->keytype == KMF_RSA) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pkey = ImportRawRSAKey(
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &key->rawdata.rsa);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (key->keytype == KMF_DSA) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pkey = ImportRawDSAKey(
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &key->rawdata.dsa);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_BAD_PARAMETER;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys xcert = d2i_X509(NULL, &p, len);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (xcert == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_ENCODING;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Stick the key and the cert into a PKCS#12 file */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = write_pkcs12(kmfh, bio, cred, pkey, xcert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (xcert)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509_free(xcert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (pkey)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys EVP_PKEY_free(pkey);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyscleanup:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (bio != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) BIO_free_all(bio);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysopenssl_build_pk12(KMF_HANDLE_T handle, int numcerts,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_X509_DER_CERT *certlist, int numkeys, KMF_KEY_HANDLE *keylist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_CREDENTIAL *p12cred, char *filename)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN rv;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (certlist == NULL && keylist == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = ExportPK12FromRawData(handle, p12cred, numcerts, certlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numkeys, keylist, filename);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN rv;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys BIO *bio = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509 *xcert = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *fullpath = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys EVP_PKEY *pkey = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *dirpath = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *certfile = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *keyfile = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *filename = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_CREDENTIAL *p12cred = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * First, find the certificate.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (certfile != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys fullpath = get_fullpath(dirpath, certfile);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (fullpath == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (isdir(fullpath)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(fullpath);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_AMBIGUOUS_PATHNAME);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = load_X509cert(kmfh, NULL, NULL, NULL, fullpath, &xcert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(fullpath);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Now find the private key.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (keyfile != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys fullpath = get_fullpath(dirpath, keyfile);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (fullpath == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (isdir(fullpath)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(fullpath);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_AMBIGUOUS_PATHNAME);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pkey = openssl_load_key(handle, fullpath);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (pkey == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_KEY_NOT_FOUND;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Open the output file.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (filename == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_BAD_PARAMETER;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((bio = BIO_new_file(filename, "wb")) == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_OPEN_FILE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Stick the key and the cert into a PKCS#12 file */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys p12cred = kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (p12cred == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_BAD_PARAMETER;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = write_pkcs12(kmfh, bio, p12cred, pkey, xcert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysend:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (fullpath)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(fullpath);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (xcert)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509_free(xcert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (pkey)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys EVP_PKEY_free(pkey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (bio)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) BIO_free(bio);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys}
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys#define MAX_CHAIN_LENGTH 100
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys/*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Helper function to extract keys and certificates from
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * a single PEM file. Typically the file should contain a
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * private key and an associated public key wrapped in an x509 cert.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * However, the file may be just a list of X509 certs with no keys.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysextract_pem(KMF_HANDLE *kmfh,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *issuer, char *subject, KMF_BIGINT *serial,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *filename, CK_UTF8CHAR *pin,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CK_ULONG pinlen, EVP_PKEY **priv_key, KMF_DATA **certs,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int *numcerts)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys/* ARGSUSED */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN rv = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys FILE *fp;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys STACK_OF(X509_INFO) *x509_info_stack = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int i, ncerts = 0, matchcerts = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys EVP_PKEY *pkey = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509_INFO *info;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509 *x;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509_INFO *cert_infos[MAX_CHAIN_LENGTH];
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *certlist = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (priv_key)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *priv_key = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (certs)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *certs = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys fp = fopen(filename, "r");
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (fp == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_OPEN_FILE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys x509_info_stack = PEM_X509_INFO_read(fp, NULL, NULL, pin);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (x509_info_stack == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) fclose(fp);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_ENCODING);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys for (i = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys i < sk_X509_INFO_num(x509_info_stack) && i < MAX_CHAIN_LENGTH;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys i++) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* LINTED */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys cert_infos[ncerts] = sk_X509_INFO_value(x509_info_stack, i);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ncerts++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ncerts == 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) fclose(fp);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_CERT_NOT_FOUND;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto err;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (priv_key != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rewind(fp);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pkey = PEM_read_PrivateKey(fp, NULL, NULL, pin);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) fclose(fp);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys x = cert_infos[ncerts - 1]->x509;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Make sure the private key matchs the last cert in the file.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (pkey != NULL && !X509_check_private_key(x, pkey)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys EVP_PKEY_free(pkey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_KEY_MISMATCH;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto err;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys certlist = (KMF_DATA *)malloc(ncerts * sizeof (KMF_DATA));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (certlist == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (pkey != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys EVP_PKEY_free(pkey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_MEMORY;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto err;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Convert all of the certs to DER format.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys matchcerts = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys for (i = 0; rv == KMF_OK && certs != NULL && i < ncerts; i++) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys boolean_t match = FALSE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys info = cert_infos[ncerts - 1 - i];
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = check_cert(info->x509, issuer, subject, serial, &match);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK || match != TRUE) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys continue;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = ssl_cert2KMFDATA(kmfh, info->x509,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &certlist[matchcerts++]);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(certlist);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys certlist = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ncerts = matchcerts = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (numcerts != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *numcerts = matchcerts;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (certs != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *certs = certlist;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (priv_key == NULL && pkey != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys EVP_PKEY_free(pkey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys else if (priv_key != NULL && pkey != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *priv_key = pkey;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyserr:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Cleanup the stack of X509 info records */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys for (i = 0; i < sk_X509_INFO_num(x509_info_stack); i++) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*LINTED*/
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys info = (X509_INFO *)sk_X509_INFO_value(x509_info_stack, i);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509_INFO_free(info);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (x509_info_stack)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sk_X509_INFO_free(x509_info_stack);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys}
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys/*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Helper function to decrypt and parse PKCS#12 import file.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysextract_pkcs12(BIO *fbio, CK_UTF8CHAR *pin, CK_ULONG pinlen,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys EVP_PKEY **priv_key, X509 **cert, STACK_OF(X509) **ca)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys/* ARGSUSED */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PKCS12 *pk12, *pk12_tmp;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys EVP_PKEY *temp_pkey = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509 *temp_cert = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys STACK_OF(X509) *temp_ca = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((pk12 = PKCS12_new()) == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_MEMORY);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((pk12_tmp = d2i_PKCS12_bio(fbio, &pk12)) == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* This is ok; it seems to mean there is no more to read. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_ASN1 &&
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ERR_GET_REASON(ERR_peek_error()) == ASN1_R_HEADER_TOO_LONG)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end_extract_pkcs12;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PKCS12_free(pk12);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_PKCS12_FORMAT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pk12 = pk12_tmp;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (PKCS12_parse(pk12, (char *)pin, &temp_pkey, &temp_cert,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &temp_ca) <= 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PKCS12_free(pk12);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_PKCS12_FORMAT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysend_extract_pkcs12:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *priv_key = temp_pkey;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *cert = temp_cert;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *ca = temp_ca;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys PKCS12_free(pk12);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_OK);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyssslBN2KMFBN(BIGNUM *from, KMF_BIGINT *to)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN rv = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys uint32_t sz;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sz = BN_num_bytes(from);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys to->val = (uchar_t *)malloc(sz);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (to->val == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_MEMORY);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((to->len = BN_bn2bin(from, to->val)) != sz) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(to->val);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys to->val = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys to->len = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_MEMORY;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysexportRawRSAKey(RSA *rsa, KMF_RAW_KEY_DATA *key)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN rv;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RAW_RSA_KEY *kmfkey = &key->rawdata.rsa;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) memset(kmfkey, 0, sizeof (KMF_RAW_RSA_KEY));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((rv = sslBN2KMFBN(rsa->n, &kmfkey->mod)) != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((rv = sslBN2KMFBN(rsa->e, &kmfkey->pubexp)) != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rsa->d != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((rv = sslBN2KMFBN(rsa->d, &kmfkey->priexp)) != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rsa->p != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((rv = sslBN2KMFBN(rsa->p, &kmfkey->prime1)) != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rsa->q != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((rv = sslBN2KMFBN(rsa->q, &kmfkey->prime2)) != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rsa->dmp1 != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((rv = sslBN2KMFBN(rsa->dmp1, &kmfkey->exp1)) != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rsa->dmq1 != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((rv = sslBN2KMFBN(rsa->dmq1, &kmfkey->exp2)) != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rsa->iqmp != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((rv = sslBN2KMFBN(rsa->iqmp, &kmfkey->coef)) != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyscleanup:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_raw_key(key);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys else
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key->keytype = KMF_RSA;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Free the reference to this key, SSL will not actually free
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * the memory until the refcount == 0, so this is safe.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys RSA_free(rsa);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysexportRawDSAKey(DSA *dsa, KMF_RAW_KEY_DATA *key)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN rv;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RAW_DSA_KEY *kmfkey = &key->rawdata.dsa;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) memset(kmfkey, 0, sizeof (KMF_RAW_DSA_KEY));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((rv = sslBN2KMFBN(dsa->p, &kmfkey->prime)) != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((rv = sslBN2KMFBN(dsa->q, &kmfkey->subprime)) != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((rv = sslBN2KMFBN(dsa->g, &kmfkey->base)) != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((rv = sslBN2KMFBN(dsa->priv_key, &kmfkey->value)) != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyscleanup:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_raw_key(key);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys else
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key->keytype = KMF_DSA;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Free the reference to this key, SSL will not actually free
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * the memory until the refcount == 0, so this is safe.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys DSA_free(dsa);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysadd_cert_to_list(KMF_HANDLE *kmfh, X509 *sslcert,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA **certlist, int *ncerts)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN rv = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *list = (*certlist);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA cert;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int n = (*ncerts);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (list == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys list = (KMF_DATA *)malloc(sizeof (KMF_DATA));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys list = (KMF_DATA *)realloc(list, sizeof (KMF_DATA) * (n + 1));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (list == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_MEMORY);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = ssl_cert2KMFDATA(kmfh, sslcert, &cert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv == KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys list[n] = cert;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (*ncerts) = n + 1;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *certlist = list;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(list);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysadd_key_to_list(KMF_RAW_KEY_DATA **keylist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RAW_KEY_DATA *newkey, int *nkeys)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RAW_KEY_DATA *list = (*keylist);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int n = (*nkeys);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (list == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys list = (KMF_RAW_KEY_DATA *)malloc(sizeof (KMF_RAW_KEY_DATA));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys list = (KMF_RAW_KEY_DATA *)realloc(list,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sizeof (KMF_RAW_KEY_DATA) * (n + 1));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (list == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_MEMORY);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys list[n] = *newkey;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (*nkeys) = n + 1;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *keylist = list;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_OK);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysconvertToRawKey(EVP_PKEY *pkey, KMF_RAW_KEY_DATA *key)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (pkey == NULL || key == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Convert SSL key to raw key */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys switch (pkey->type) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case EVP_PKEY_RSA:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = exportRawRSAKey(EVP_PKEY_get1_RSA(pkey),
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys break;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case EVP_PKEY_DSA:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = exportRawDSAKey(EVP_PKEY_get1_DSA(pkey),
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys break;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys default:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
71593db26bb6ef7b739cffe06d53bf990cac112cwyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysconvertPK12Objects(
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_HANDLE *kmfh,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys EVP_PKEY *sslkey, X509 *sslcert, STACK_OF(X509) *sslcacerts,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RAW_KEY_DATA **keylist, int *nkeys,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA **certlist, int *ncerts)
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys{
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys KMF_RETURN rv = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RAW_KEY_DATA key;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int i;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (sslkey != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = convertToRawKey(sslkey, &key);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv == KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = add_key_to_list(keylist, &key, nkeys);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys }
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Now add the certificate to the certlist */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (sslcert != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = add_cert_to_list(kmfh, sslcert, certlist, ncerts);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys }
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Also add any included CA certs to the list */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys for (i = 0; sslcacerts != NULL && i < sk_X509_num(sslcacerts); i++) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509 *c;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * sk_X509_value() is macro that embeds a cast to (X509 *).
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Here it translates into ((X509 *)sk_value((ca), (i))).
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Lint is complaining about the embedded casting, and
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * to fix it, you need to fix openssl header files.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* LINTED E_BAD_PTR_CAST_ALIGN */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys c = sk_X509_value(sslcacerts, i);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Now add the ca cert to the certlist */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = add_cert_to_list(kmfh, c, certlist, ncerts);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys}
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysopenssl_import_objects(KMF_HANDLE *kmfh,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *filename, KMF_CREDENTIAL *cred,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA **certlist, int *ncerts,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RAW_KEY_DATA **keylist, int *nkeys)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN rv = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys EVP_PKEY *privkey = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ENCODE_FORMAT format;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys BIO *bio = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509 *cert = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys STACK_OF(X509) *cacerts = NULL;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * auto-detect the file format, regardless of what
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * the 'format' parameters in the params say.
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_get_file_format(filename, &format);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys }
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* This function only works for PEM or PKCS#12 files */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (format != KMF_FORMAT_PEM &&
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys format != KMF_FORMAT_PEM_KEYPAIR &&
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys format != KMF_FORMAT_PKCS12)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_ENCODING);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *certlist = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *keylist = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *ncerts = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *nkeys = 0;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (format == KMF_FORMAT_PKCS12) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys bio = BIO_new_file(filename, "rb");
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (bio == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_OPEN_FILE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
02744e811b15322c5f109827a116c33bfe3438b5wyllys }
02744e811b15322c5f109827a116c33bfe3438b5wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = extract_pkcs12(bio, (uchar_t *)cred->cred,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (uint32_t)cred->credlen, &privkey, &cert, &cacerts);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv == KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Convert keys and certs to exportable format */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = convertPK12Objects(kmfh, privkey, cert, cacerts,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keylist, nkeys, certlist, ncerts);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = extract_pem(kmfh, NULL, NULL, NULL, filename,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (uchar_t *)cred->cred, (uint32_t)cred->credlen,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &privkey, certlist, ncerts);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Reached end of import file? */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv == KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Convert keys and certs to exportable format */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = convertPK12Objects(kmfh, privkey, NULL, NULL,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keylist, nkeys, NULL, NULL);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys }
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysend:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (privkey)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys EVP_PKEY_free(privkey);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (bio != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) BIO_free(bio);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (cert)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509_free(cert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (cacerts)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sk_X509_free(cacerts);
34acef6775bd2319a3708b750f10ccc4f1292562wyllys
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys return (rv);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys}
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyscreate_deskey(DES_cblock **deskey)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys DES_cblock *key;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key = (DES_cblock *) malloc(sizeof (DES_cblock));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (key == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_MEMORY);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (DES_random_key(key) == 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(key);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_KEYGEN_FAILED);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *deskey = key;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_OK);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys#define KEYGEN_RETRY 3
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys#define DES3_KEY_SIZE 24
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyscreate_des3key(unsigned char **des3key)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys DES_cblock *deskey1 = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys DES_cblock *deskey2 = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys DES_cblock *deskey3 = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys unsigned char *newkey = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int retry;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((newkey = malloc(DES3_KEY_SIZE)) == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_MEMORY);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* create the 1st DES key */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((ret = create_deskey(&deskey1)) != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Create the 2nd DES key and make sure its value is different
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * from the 1st DES key.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys retry = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys do {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (deskey2 != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(deskey2);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys deskey2 = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((ret = create_deskey(&deskey2)) != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (memcmp((const void *) deskey1, (const void *) deskey2, 8)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys == 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_KEYGEN_FAILED;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys retry++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Create the 3rd DES key and make sure its value is different
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * from the 2nd DES key.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys retry = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys do {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (deskey3 != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(deskey3);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys deskey3 = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((ret = create_deskey(&deskey3)) != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (memcmp((const void *)deskey2, (const void *)deskey3, 8)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys == 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_KEYGEN_FAILED;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys retry++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Concatenate 3 DES keys into a DES3 key */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) memcpy((void *)newkey, (const void *)deskey1, 8);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) memcpy((void *)(newkey + 8), (const void *)deskey2, 8);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) memcpy((void *)(newkey + 16), (const void *)deskey3, 8);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *des3key = newkey;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysout:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (deskey1 != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(deskey1);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (deskey2 != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(deskey2);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (deskey3 != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(deskey3);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK && newkey != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(newkey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_CreateSymKey(KMF_HANDLE_T handle,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *fullpath = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RAW_SYM_KEY *rkey = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys DES_cblock *deskey = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys unsigned char *des3key = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys unsigned char *random = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int fd = -1;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_HANDLE *symkey;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_ALG keytype;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys uint32_t keylen;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys uint32_t keylen_size = sizeof (keylen);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *dirpath;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *keyfile;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (kmfh == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_UNINITIALIZED);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (symkey == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (keyfile == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void *)&keytype, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &keylen, &keylen_size);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret == KMF_ERR_ATTR_NOT_FOUND &&
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (keytype == KMF_DES || keytype == KMF_DES3))
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* keylength is not required for DES and 3DES */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys fullpath = get_fullpath(dirpath, keyfile);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (fullpath == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* If the requested file exists, return an error */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (test_for_file(fullpath, 0400) == 1) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(fullpath);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_DUPLICATE_KEYFILE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys fd = open(fullpath, O_CREAT|O_TRUNC|O_RDWR, 0400);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (fd == -1) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_OPEN_FILE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rkey = malloc(sizeof (KMF_RAW_SYM_KEY));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rkey == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_MEMORY;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (keytype == KMF_DES) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((ret = create_deskey(&deskey)) != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rkey->keydata.val = (uchar_t *)deskey;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rkey->keydata.len = 8;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys symkey->keyalg = KMF_DES;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (keytype == KMF_DES3) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((ret = create_des3key(&des3key)) != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rkey->keydata.val = (uchar_t *)des3key;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rkey->keydata.len = DES3_KEY_SIZE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys symkey->keyalg = KMF_DES3;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (keytype == KMF_AES || keytype == KMF_RC4 ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keytype == KMF_GENERIC_SECRET) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int bytes;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (keylen % 8 != 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_KEY_SIZE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (keytype == KMF_AES) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (keylen != 128 &&
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keylen != 192 &&
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keylen != 256) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_KEY_SIZE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys bytes = keylen/8;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys random = malloc(bytes);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (random == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_MEMORY;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (RAND_bytes(random, bytes) != 1) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_KEYGEN_FAILED;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rkey->keydata.val = (uchar_t *)random;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rkey->keydata.len = bytes;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys symkey->keyalg = keytype;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_KEY_TYPE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) write(fd, (const void *) rkey->keydata.val, rkey->keydata.len);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys symkey->kstype = KMF_KEYSTORE_OPENSSL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys symkey->keyclass = KMF_SYMMETRIC;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys symkey->keylabel = (char *)fullpath;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys symkey->israw = TRUE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys symkey->keyp = rkey;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysout:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (fd != -1)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) close(fd);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK && fullpath != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(fullpath);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_raw_sym_key(rkey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys symkey->keyp = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys symkey->keyalg = KMF_KEYALG_NONE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys/*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Check a file to see if it is a CRL file with PEM or DER format.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * If success, return its format in the "pformat" argument.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_IsCRLFile(KMF_HANDLE_T handle, char *filename, int *pformat)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys BIO *bio = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509_CRL *xcrl = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (filename == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys bio = BIO_new_file(filename, "rb");
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (bio == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_OPEN_FILE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((xcrl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)) != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *pformat = KMF_FORMAT_PEM;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) BIO_free(bio);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Now try to read it as raw DER data.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys bio = BIO_new_file(filename, "rb");
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (bio == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_OPEN_FILE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((xcrl = d2i_X509_CRL_bio(bio, NULL)) != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *pformat = KMF_FORMAT_ASN1;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_CRLFILE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysout:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (bio != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) BIO_free(bio);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (xcrl != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509_CRL_free(xcrl);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys}
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys/*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Check a file to see if it is a certficate file with PEM or DER format.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * If success, return its format in the pformat argument.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_IsCertFile(KMF_HANDLE_T handle, char *filename,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ENCODE_FORMAT *pformat)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys BIO *bio = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509 *xcert = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (filename == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_file_format(filename, pformat);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys bio = BIO_new_file(filename, "rb");
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (bio == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_OPEN_FILE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((*pformat) == KMF_FORMAT_PEM) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((xcert = PEM_read_bio_X509(bio, NULL,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys NULL, NULL)) == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_CERTFILE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if ((*pformat) == KMF_FORMAT_ASN1) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((xcert = d2i_X509_bio(bio, NULL)) == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_CERTFILE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_CERTFILE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysout:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (bio != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) BIO_free(bio);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (xcert != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509_free(xcert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RAW_SYM_KEY *rkey)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN rv = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA keyvalue;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (kmfh == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_UNINITIALIZED);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (symkey == NULL || rkey == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys else if (symkey->keyclass != KMF_SYMMETRIC)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_KEY_CLASS);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (symkey->israw) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RAW_SYM_KEY *rawkey = (KMF_RAW_SYM_KEY *)symkey->keyp;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rawkey == NULL ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rawkey->keydata.val == NULL ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rawkey->keydata.len == 0)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_KEYHANDLE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rkey->keydata.len = rawkey->keydata.len;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_MEMORY);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) memcpy(rkey->keydata.val, rawkey->keydata.val,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rkey->keydata.len);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_read_input_file(handle, symkey->keylabel, &keyvalue);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rkey->keydata.len = keyvalue.Length;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rkey->keydata.val = keyvalue.Data;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys/*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * id-sha1 OBJECT IDENTIFIER ::= {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * iso(1) identified-organization(3) oiw(14) secsig(3)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * algorithms(2) 26
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys#define ASN1_SHA1_OID_PREFIX_LEN 15
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic uchar_t SHA1_DER_PREFIX[ASN1_SHA1_OID_PREFIX_LEN] = {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys 0x30, 0x21, 0x30, 0x09,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys 0x06, 0x05, 0x2b, 0x0e,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys 0x03, 0x02, 0x1a, 0x05,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys 0x00, 0x04, 0x14
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys};
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys/*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * id-md2 OBJECT IDENTIFIER ::= {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 2
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys#define ASN1_MD2_OID_PREFIX_LEN 18
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic uchar_t MD2_DER_PREFIX[ASN1_MD2_OID_PREFIX_LEN] = {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys 0x30, 0x20, 0x30, 0x0c,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys 0x06, 0x08, 0x2a, 0x86,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys 0x48, 0x86, 0xf7, 0x0d,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys 0x02, 0x02, 0x05, 0x00,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys 0x04, 0x10
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys};
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys/*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * id-md5 OBJECT IDENTIFIER ::= {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 5
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys#define ASN1_MD5_OID_PREFIX_LEN 18
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic uchar_t MD5_DER_PREFIX[ASN1_MD5_OID_PREFIX_LEN] = {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys 0x30, 0x20, 0x30, 0x0c,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys 0x06, 0x08, 0x2a, 0x86,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys 0x48, 0x86, 0xf7, 0x0d,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys 0x02, 0x05, 0x05, 0x00,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys 0x04, 0x10
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys};
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
71593db26bb6ef7b739cffe06d53bf990cac112cwyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_VerifyDataWithCert(KMF_HANDLE_T handle,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ALGORITHM_INDEX algid, KMF_DATA *indata,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *insig, KMF_DATA *cert)
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509 *xcert = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys EVP_PKEY *pkey = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys uchar_t *p;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys uchar_t *rsaout = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys uchar_t *pfx = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys const EVP_MD *md;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int pfxlen = 0, len;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL || indata == NULL ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys indata->Data == NULL || indata->Length == 0 ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys insig == NULL|| insig->Data == NULL || insig->Length == 0 ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys cert == NULL || cert->Data == NULL || cert->Length == 0)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys p = cert->Data;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys xcert = d2i_X509(NULL, (const uchar_t **)&p, cert->Length);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (xcert == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_CERT_FORMAT;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys }
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pkey = X509_get_pubkey(xcert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (pkey == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_CERT_FORMAT;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (algid != KMF_ALGID_NONE) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys switch (algid) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_ALGID_MD5WithRSA:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys md = EVP_md5();
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys break;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_ALGID_MD2WithRSA:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys md = EVP_md2();
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys break;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_ALGID_SHA1WithRSA:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys md = EVP_sha1();
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys break;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_ALGID_RSA:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys md = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys break;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys default:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_PARAMETER;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Get the hash type from the cert signature */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys md = EVP_get_digestbyobj(xcert->sig_alg->algorithm);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (md == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_PARAMETER;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (md != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys switch (EVP_MD_type(md)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case NID_md2:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case NID_md2WithRSAEncryption:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pfxlen = ASN1_MD2_OID_PREFIX_LEN;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pfx = MD2_DER_PREFIX;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys break;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case NID_md5:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case NID_md5WithRSAEncryption:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pfxlen = ASN1_MD5_OID_PREFIX_LEN;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pfx = MD5_DER_PREFIX;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys break;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case NID_sha1:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case NID_sha1WithRSAEncryption:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pfxlen = ASN1_SHA1_OID_PREFIX_LEN;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pfx = SHA1_DER_PREFIX;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys break;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys default: /* Unsupported */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pfxlen = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pfx = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys break;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* RSA with no hash is a special case */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rsaout = malloc(RSA_size(pkey->pkey.rsa));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rsaout == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_MEMORY);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Decrypt the input signature */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys len = RSA_public_decrypt(insig->Length,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys insig->Data, rsaout, pkey->pkey.rsa, RSA_PKCS1_PADDING);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (len < 1) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_PARAMETER;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys size_t hashlen = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys uint32_t dlen;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *digest = NULL;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * If the AlgId requires it, hash the input data before
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * comparing it to the decrypted signature.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (md) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys EVP_MD_CTX ctx;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys hashlen = md->md_size;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys digest = malloc(hashlen + pfxlen);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (digest == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_MEMORY);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Add the prefix to the comparison buffer. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (pfx && pfxlen > 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) memcpy(digest, pfx, pfxlen);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) EVP_DigestInit(&ctx, md);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) EVP_DigestUpdate(&ctx, indata->Data,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys indata->Length);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Add the digest AFTER the ASN1 prefix */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) EVP_DigestFinal(&ctx,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (uchar_t *)digest + pfxlen, &dlen);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys dlen += pfxlen;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys digest = (char *)indata->Data;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys dlen = indata->Length;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * The result of the RSA decryption should be ASN1(OID | Hash).
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Compare the output hash to the input data for the final
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * result.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (memcmp(rsaout, digest, dlen))
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_INTERNAL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys else
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* If we had to allocate space for the digest, free it now */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (hashlen)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(digest);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyscleanup:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (pkey)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys EVP_PKEY_free(pkey);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (xcert)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509_free(xcert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rsaout)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(rsaout);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys/*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * substitute for the unsafe access(2) function.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * If the file in question already exists, return 1.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * else 0. If an error occurs during testing (other
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * than EEXIST), return -1.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic int
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllystest_for_file(char *filename, mode_t mode)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int fd;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Try to create the file with the EXCL flag.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * The call should fail if the file exists.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, mode);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (fd == -1 && errno == EEXIST)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (1);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys else if (fd == -1) /* some other error */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (-1);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* The file did NOT exist. Delete the testcase. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) close(fd);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) unlink(filename);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (0);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_StoreKey(KMF_HANDLE_T handle, int numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN rv = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_HANDLE *pubkey = NULL, *prikey = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RAW_KEY_DATA *rawkey;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys EVP_PKEY *pkey = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ENCODE_FORMAT format = KMF_FORMAT_PEM;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_CREDENTIAL cred = {NULL, 0};
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys BIO *out = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int keys = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *fullpath = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *keyfile = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *dirpath = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (pubkey != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keys++;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys prikey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (prikey != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keys++;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rawkey != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keys++;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Exactly 1 type of key must be passed to this function.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (keys != 1)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys keyfile = (char *)kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (keyfile == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys fullpath = get_fullpath(dirpath, keyfile);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Once we have the full path, we don't need the pieces */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (fullpath == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* If the requested file exists, return an error */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (test_for_file(fullpath, 0400) == 1) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(fullpath);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_DUPLICATE_KEYFILE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &format, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* format is optional. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* CRED is not required for OpenSSL files */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &cred, NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Store the private key to the keyfile */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys out = BIO_new_file(fullpath, "wb");
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (out == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_OPEN_FILE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
9b37d29632d2cb262ba42f1d804f85fcb0aa3709wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (prikey != NULL && prikey->keyp != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (prikey->keyalg == KMF_RSA ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys prikey->keyalg == KMF_DSA) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pkey = (EVP_PKEY *)prikey->keyp;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = ssl_write_key(kmfh, format,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys out, &cred, pkey, TRUE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv == KMF_OK && prikey->keylabel == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys prikey->keylabel = strdup(fullpath);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (prikey->keylabel == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_MEMORY;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (pubkey != NULL && pubkey->keyp != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (pubkey->keyalg == KMF_RSA ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pubkey->keyalg == KMF_DSA) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pkey = (EVP_PKEY *)pubkey->keyp;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = ssl_write_key(kmfh, format,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys out, &cred, pkey, FALSE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv == KMF_OK && pubkey->keylabel == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pubkey->keylabel = strdup(fullpath);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (pubkey->keylabel == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_MEMORY;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (rawkey != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* RAW keys are always private */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rawkey->keytype == KMF_RSA) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pkey = ImportRawRSAKey(&rawkey->rawdata.rsa);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (rawkey->keytype == KMF_DSA) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pkey = ImportRawDSAKey(&rawkey->rawdata.dsa);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = KMF_ERR_BAD_PARAMETER;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = ssl_write_key(kmfh, format, out, &cred, pkey, TRUE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysend:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (out)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) BIO_free(out);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (rv == KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) chmod(fullpath, 0400);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(fullpath);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (rv);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_ImportCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509_CRL *xcrl = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509 *xcert = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys EVP_PKEY *pkey;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ENCODE_FORMAT format;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys BIO *in = NULL, *out = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int openssl_ret = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ENCODE_FORMAT outformat;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys boolean_t crlcheck = FALSE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *certfile, *dirpath, *crlfile, *incrl, *outcrl, *outcrlfile;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (numattr == 0 || attrlist == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* CRL check is optional */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) kmf_get_attr(KMF_CRL_CHECK_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &crlcheck, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (crlcheck == B_TRUE && certfile == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_CERTFILE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys incrl = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys outcrl = kmf_get_attr_ptr(KMF_CRL_OUTFILE_ATTR, attrlist, numattr);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys crlfile = get_fullpath(dirpath, incrl);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (crlfile == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_CRLFILE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys outcrlfile = get_fullpath(dirpath, outcrl);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (outcrlfile == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_CRLFILE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (isdir(outcrlfile)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(outcrlfile);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_CRLFILE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_is_crl_file(handle, crlfile, &format);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(outcrlfile);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys in = BIO_new_file(crlfile, "rb");
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (in == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, ERR_get_error());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_OPEN_FILE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (format == KMF_FORMAT_ASN1) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys xcrl = d2i_X509_CRL_bio(in, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (format == KMF_FORMAT_PEM) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (xcrl == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, ERR_get_error());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_BAD_CRLFILE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* If bypasscheck is specified, no need to verify. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (crlcheck == B_FALSE)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto output;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_is_cert_file(handle, certfile, &format);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Read in the CA cert file and convert to X509 */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (BIO_read_filename(in, certfile) <= 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_OPEN_FILE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (format == KMF_FORMAT_ASN1) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys xcert = d2i_X509_bio(in, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (format == KMF_FORMAT_PEM) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys xcert = PEM_read_bio_X509(in, NULL, NULL, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_CERT_FORMAT;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (xcert == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, ERR_get_error());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_BAD_CERT_FORMAT;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Now get the public key from the CA cert */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pkey = X509_get_pubkey(xcert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (pkey == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_CERTFILE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Verify the CRL with the CA's public key */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys openssl_ret = X509_CRL_verify(xcrl, pkey);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys EVP_PKEY_free(pkey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (openssl_ret > 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_OK; /* verify succeed */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, openssl_ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_BAD_CRLFILE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysoutput:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &outformat, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys outformat = KMF_FORMAT_PEM;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys out = BIO_new_file(outcrlfile, "wb");
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (out == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_OPEN_FILE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (outformat == KMF_FORMAT_ASN1) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys openssl_ret = (int)i2d_X509_CRL_bio(out, xcrl);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (outformat == KMF_FORMAT_PEM) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys openssl_ret = PEM_write_bio_X509_CRL(out, xcrl);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_PARAMETER;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (openssl_ret <= 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_WRITE_FILE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysend:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (xcrl != NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys X509_CRL_free(xcrl);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (xcert != NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys X509_free(xcert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (in != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) BIO_free(in);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (out != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) BIO_free(out);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (outcrlfile != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(outcrlfile);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_ListCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509_CRL *x = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ENCODE_FORMAT format;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *crlfile = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys BIO *in = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys BIO *mem = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys long len;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *memptr;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *data = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char **crldata;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *crlfilename, *dirpath;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (numattr == 0 || attrlist == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (crlfilename == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_CRLFILE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys crldata = (char **)kmf_get_attr_ptr(KMF_CRL_DATA_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys attrlist, numattr);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (crldata == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys crlfile = get_fullpath(dirpath, crlfilename);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (crlfile == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_CRLFILE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (isdir(crlfile)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(crlfile);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_CRLFILE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_is_crl_file(handle, crlfile, &format);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(crlfile);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (bio_err == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys in = BIO_new_file(crlfile, "rb");
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (in == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, ERR_get_error());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_OPEN_FILE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (format == KMF_FORMAT_ASN1) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys x = d2i_X509_CRL_bio(in, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (format == KMF_FORMAT_PEM) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (x == NULL) { /* should not happen */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_OPEN_FILE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys mem = BIO_new(BIO_s_mem());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (mem == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_MEMORY;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) X509_CRL_print(mem, x);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys len = BIO_get_mem_data(mem, &memptr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (len <= 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_MEMORY;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys data = malloc(len + 1);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (data == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_MEMORY;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) memcpy(data, memptr, len);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys data[len] = '\0';
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *crldata = data;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysend:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (x != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509_CRL_free(x);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (crlfile != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(crlfile);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (in != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) BIO_free(in);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (mem != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) BIO_free(mem);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_DeleteCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ENCODE_FORMAT format;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *crlfile = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys BIO *in = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *crlfilename, *dirpath;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (numattr == 0 || attrlist == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys attrlist, numattr);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (crlfilename == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_CRLFILE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys crlfile = get_fullpath(dirpath, crlfilename);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (crlfile == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_CRLFILE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (isdir(crlfile)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_BAD_CRLFILE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_is_crl_file(handle, crlfile, &format);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (unlink(crlfile) != 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_SYS_ERROR(kmfh, errno);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_INTERNAL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysend:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (in != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) BIO_free(in);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (crlfile != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(crlfile);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_FindCertInCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ENCODE_FORMAT format;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys BIO *in = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509 *xcert = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509_CRL *xcrl = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys STACK_OF(X509_REVOKED) *revoke_stack = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509_REVOKED *revoke;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int i;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *crlfilename, *crlfile, *dirpath, *certfile;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (numattr == 0 || attrlist == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (crlfilename == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_CRLFILE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (certfile == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_CRLFILE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys crlfile = get_fullpath(dirpath, crlfilename);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (crlfile == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_CRLFILE);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (isdir(crlfile)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_CRLFILE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_is_crl_file(handle, crlfile, &format);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Read the CRL file and load it into a X509_CRL structure */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys in = BIO_new_file(crlfilename, "rb");
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (in == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SET_ERROR(kmfh, ERR_get_error());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_OPEN_FILE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (format == KMF_FORMAT_ASN1) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys xcrl = d2i_X509_CRL_bio(in, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (format == KMF_FORMAT_PEM) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (xcrl == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_CRLFILE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) BIO_free(in);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Read the Certificate file and load it into a X509 structure */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_is_cert_file(handle, certfile, &format);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys in = BIO_new_file(certfile, "rb");
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (in == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_OPEN_FILE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (format == KMF_FORMAT_ASN1) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys xcert = d2i_X509_bio(in, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (format == KMF_FORMAT_PEM) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys xcert = PEM_read_bio_X509(in, NULL, NULL, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (xcert == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_CERTFILE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Check if the certificate and the CRL have same issuer */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (X509_NAME_cmp(xcert->cert_info->issuer, xcrl->crl->issuer) != 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_ISSUER;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
02744e811b15322c5f109827a116c33bfe3438b5wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Check to see if the certificate serial number is revoked */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys revoke_stack = X509_CRL_get_REVOKED(xcrl);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (sk_X509_REVOKED_num(revoke_stack) <= 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* No revoked certificates in the CRL file */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_EMPTY_CRL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto end;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
02744e811b15322c5f109827a116c33bfe3438b5wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys for (i = 0; i < sk_X509_REVOKED_num(revoke_stack); i++) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*LINTED*/
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys revoke = sk_X509_REVOKED_value(revoke_stack, i);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ASN1_INTEGER_cmp(xcert->cert_info->serialNumber,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys revoke->serialNumber) == 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys break;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
02744e811b15322c5f109827a116c33bfe3438b5wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (i < sk_X509_REVOKED_num(revoke_stack)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_NOT_REVOKED;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysend:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (in != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) BIO_free(in);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (xcrl != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509_CRL_free(xcrl);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (xcert != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509_free(xcert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys}
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_VerifyCRLFile(KMF_HANDLE_T handle, char *crlname, KMF_DATA *tacert)
02744e811b15322c5f109827a116c33bfe3438b5wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN ret = KMF_OK;
02744e811b15322c5f109827a116c33bfe3438b5wyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys BIO *bcrl = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509_CRL *xcrl = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509 *xcert = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys EVP_PKEY *pkey;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int sslret;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ENCODE_FORMAT crl_format;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys unsigned char *p;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys long len;
02744e811b15322c5f109827a116c33bfe3438b5wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL || crlname == NULL || tacert == NULL) {
02744e811b15322c5f109827a116c33bfe3438b5wyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_file_format(crlname, &crl_format);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys bcrl = BIO_new_file(crlname, "rb");
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (bcrl == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_OPEN_FILE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (crl_format == KMF_FORMAT_ASN1) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys xcrl = d2i_X509_CRL_bio(bcrl, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (crl_format == KMF_FORMAT_PEM) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_PARAMETER;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (xcrl == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_CRLFILE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys p = tacert->Data;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys len = tacert->Length;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys xcert = d2i_X509(NULL, (const uchar_t **)&p, len);
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys if (xcert == NULL) {
02744e811b15322c5f109827a116c33bfe3438b5wyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_CERTFILE;
02744e811b15322c5f109827a116c33bfe3438b5wyllys goto cleanup;
02744e811b15322c5f109827a116c33bfe3438b5wyllys }
02744e811b15322c5f109827a116c33bfe3438b5wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Get issuer certificate public key */
02744e811b15322c5f109827a116c33bfe3438b5wyllys pkey = X509_get_pubkey(xcert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (pkey == NULL) {
02744e811b15322c5f109827a116c33bfe3438b5wyllys SET_ERROR(kmfh, ERR_get_error());
02744e811b15322c5f109827a116c33bfe3438b5wyllys ret = KMF_ERR_BAD_CERT_FORMAT;
02744e811b15322c5f109827a116c33bfe3438b5wyllys goto cleanup;
02744e811b15322c5f109827a116c33bfe3438b5wyllys }
02744e811b15322c5f109827a116c33bfe3438b5wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Verify CRL signature */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sslret = X509_CRL_verify(xcrl, pkey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys EVP_PKEY_free(pkey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (sslret > 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_OK;
02744e811b15322c5f109827a116c33bfe3438b5wyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, sslret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_CRLFILE;
02744e811b15322c5f109827a116c33bfe3438b5wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyscleanup:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (bcrl != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) BIO_free(bcrl);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (xcrl != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509_CRL_free(xcrl);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (xcert != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509_free(xcert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys}
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysOpenSSL_CheckCRLDate(KMF_HANDLE_T handle, char *crlname)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ENCODE_FORMAT crl_format;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys BIO *bcrl = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509_CRL *xcrl = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int i;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL || crlname == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
02744e811b15322c5f109827a116c33bfe3438b5wyllys }
02744e811b15322c5f109827a116c33bfe3438b5wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_is_crl_file(handle, crlname, &crl_format);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
02744e811b15322c5f109827a116c33bfe3438b5wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys bcrl = BIO_new_file(crlname, "rb");
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (bcrl == NULL) {
02744e811b15322c5f109827a116c33bfe3438b5wyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_OPEN_FILE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
02744e811b15322c5f109827a116c33bfe3438b5wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (crl_format == KMF_FORMAT_ASN1) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys xcrl = d2i_X509_CRL_bio(bcrl, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else if (crl_format == KMF_FORMAT_PEM) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
02744e811b15322c5f109827a116c33bfe3438b5wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (xcrl == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SET_ERROR(kmfh, ERR_get_error());
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_CRLFILE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
02744e811b15322c5f109827a116c33bfe3438b5wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys i = X509_cmp_time(X509_CRL_get_lastUpdate(xcrl), NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (i >= 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_VALIDITY_PERIOD;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
02744e811b15322c5f109827a116c33bfe3438b5wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (X509_CRL_get_nextUpdate(xcrl)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys i = X509_cmp_time(X509_CRL_get_nextUpdate(xcrl), NULL);
02744e811b15322c5f109827a116c33bfe3438b5wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (i <= 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_VALIDITY_PERIOD;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
02744e811b15322c5f109827a116c33bfe3438b5wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
02744e811b15322c5f109827a116c33bfe3438b5wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_OK;
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllyscleanup:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (bcrl != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) BIO_free(bcrl);
02744e811b15322c5f109827a116c33bfe3438b5wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (xcrl != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys X509_CRL_free(xcrl);
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys return (ret);
02744e811b15322c5f109827a116c33bfe3438b5wyllys}