openssl_spi.c revision 71593db26bb6ef7b739cffe06d53bf990cac112c
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * CDDL HEADER START
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * The contents of this file are subject to the terms of the
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Common Development and Distribution License (the "License").
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * You may not use this file except in compliance with the License.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * See the License for the specific language governing permissions
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * and limitations under the License.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * When distributing Covered Code, include this CDDL HEADER in each
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * If applicable, add the following below this CDDL HEADER, with the
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * fields enclosed by brackets "[]" replaced with your own identifying
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * information: Portions Copyright [yyyy] [name of copyright owner]
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * CDDL HEADER END
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * OpenSSL keystore wrapper
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Use is subject to license terms.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#pragma ident "%Z%%M% %I% %E% SMI"
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/* OPENSSL related headers */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic uchar_t P[] = { 0x00, 0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic uchar_t Q[] = { 0x00, 0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic uchar_t G[] = { 0x00, 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#define SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_OPENSSL; \
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#define SET_SYS_ERROR(h, c) h->lasterr.kstype = -1; h->lasterr.errcode = c;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic int ssl_initialized = 0;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllysextract_objects(KMF_HANDLE *, char *, CK_UTF8CHAR *, CK_ULONG,
71593db26bb6ef7b739cffe06d53bf990cac112cwyllyskmf_load_cert(KMF_HANDLE *, KMF_FINDCERT_PARAMS *, char *, KMF_DATA *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_FreeKMFCert(KMF_HANDLE_T, KMF_X509_DER_CERT *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_StoreCert(KMF_HANDLE_T handle, KMF_STORECERT_PARAMS *, KMF_DATA *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_CreateKeypair(KMF_HANDLE_T, KMF_CREATEKEYPAIR_PARAMS *,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_DeleteKey(KMF_HANDLE_T, KMF_DELETEKEY_PARAMS *,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_ImportCRL(KMF_HANDLE_T, KMF_IMPORTCRL_PARAMS *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_DeleteCRL(KMF_HANDLE_T, KMF_DELETECRL_PARAMS *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_ListCRL(KMF_HANDLE_T, KMF_LISTCRL_PARAMS *, char **);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_FindCertInCRL(KMF_HANDLE_T, KMF_FINDCERTINCRL_PARAMS *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_CertGetPrintable(KMF_HANDLE_T, const KMF_DATA *,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_GetPrikeyByCert(KMF_HANDLE_T, KMF_CRYPTOWITHCERT_PARAMS *, KMF_DATA *,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_CreateOCSPRequest(KMF_HANDLE_T, KMF_OCSPREQUEST_PARAMS *,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T, KMF_OCSPRESPONSE_PARAMS_INPUT *,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_StorePrivateKey(KMF_HANDLE_T, KMF_STOREKEY_PARAMS *,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_CreateSymKey(KMF_HANDLE_T, KMF_CREATESYMKEY_PARAMS *,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_VerifyCRLFile(KMF_HANDLE_T, KMF_VERIFYCRL_PARAMS *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_CheckCRLDate(KMF_HANDLE_T, KMF_CHECKCRLDATE_PARAMS *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic long *lock_count;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*ARGSUSED*/
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic unsigned long
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return ((unsigned long)thr_self());
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Enable error strings for reporting */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Add support for extension OIDs that are not yet in the
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * openssl default set.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys "X509v3 Name Constraints");
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys "X509v3 Policy Mappings");
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys "X509v3 Policy Constraints");
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys "X509v3 Freshest CRL");
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys "X509v3 Inhibit Any-Policy");
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Set up for thread-safe operation.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (mutex_t));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (long));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys for (i = 0; i < CRYPTO_num_locks(); i++) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CRYPTO_set_id_callback((unsigned long (*)())thread_id);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Convert an SSL DN to a KMF DN.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Convert to raw DER format */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((tmp = derdata.Data = (uchar_t *)OPENSSL_malloc(derdata.Length))
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Decode to KMF format */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (0);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysssl_cert2KMFDATA(KMF_HANDLE *kmfh, X509 *x509cert, KMF_DATA *cert)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Convert the X509 internal struct to DER encoded data
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * i2d_X509 will increment the buf pointer so that we need to
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* caller's responsibility to free it */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyscheck_cert(X509 *xcert, KMF_FINDCERT_PARAMS *params, boolean_t *match)
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 if (params->issuer != NULL && strlen(params->issuer)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = get_x509_dn(xcert->cert_info->issuer, &certIssuerDN);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (params->subject != NULL && strlen(params->subject)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = get_x509_dn(xcert->cert_info->subject, &certSubjectDN);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (params->serial != NULL && params->serial->val != NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Comparing BIGNUMs is a pain! */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys bn = ASN1_INTEGER_to_BN(xcert->cert_info->serialNumber, NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (a == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *match = !KMF_CompareRDNs(&subjectDN, &certSubjectDN);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * auto-detect the file format, regardless of what
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * the 'format' parameters in the params say.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Not ASN1(DER) format */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((bcert = BIO_new_file(pathname, "rb")) == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys xcert = PEM_read_bio_X509_AUX(bcert, NULL, NULL, NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (check_cert(xcert, params, &match) != KMF_OK || match == FALSE) {
71593db26bb6ef7b739cffe06d53bf990cac112cwyllysdatacmp(const void *a, const void *b)
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys return (-1);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys return (1);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys return (0);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllysload_certs(KMF_HANDLE *kmfh, KMF_FINDCERT_PARAMS *params, char *pathname,
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys /* load a single certificate */
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys /* We need a credential to access a PKCS#12 file */
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys /* This function only works on PEM files */
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys for (i = 0; i < nc; i++) {
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys if (params->find_cert_validity == KMF_NONEXPIRED_CERTS) {
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys } else if (params->find_cert_validity == KMF_EXPIRED_CERTS) {
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys /* Remove this cert from the list by clearing it. */
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 qsort((void *)certs, nc, sizeof (KMF_DATA), datacmp);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys /* since we sorted the list, just return the number of hits */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = load_X509cert(kmfh, params, pathname, &x509cert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv == KMF_OK && x509cert != NULL && cert != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (params->find_cert_validity == KMF_NONEXPIRED_CERTS) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (params->find_cert_validity == KMF_EXPIRED_CERTS) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * This is a valid cert so skip it.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * We want to return success when we
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * find an invalid cert.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysopenssl_load_key(KMF_HANDLE_T handle, const char *file)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (KMF_GetFileFormat((char *)file, &format) != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys pkey = PEM_read_bio_PrivateKey(keyfile, NULL, NULL, NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* open all files in the directory and attempt to read them */
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys for (i = 0; i < numcerts; i++)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* If load succeeds, add certdata to the list */
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys for (i = 0; i < numcerts; i++) {
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys for (i = 0; i < numcerts; i++)
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys rv = load_certs(kmfh, params, fullpath, &certlist, &numcerts);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys for (i = 0; i < numcerts; i++) {
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys for (i = 0; i < numcerts; i++)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*ARGSUSED*/
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_StoreCert(KMF_HANDLE_T handle, KMF_STORECERT_PARAMS *params,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys unsigned char *outbuf;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys unsigned char *outbuf_p;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (params == NULL || params->ks_opt_u.openssl_opts.certfile == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * check if the cert output format is supported by OPENSSL.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * however, since the keystore for OPENSSL is just a file, we have
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * no way to store the format along with the file.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (format != KMF_FORMAT_ASN1 && format != KMF_FORMAT_PEM)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * When storing a certificate, you must specify a filename.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* copy cert data to outbuf */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * The output format is not KMF_FORMAT_ASN1, so we will
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Convert the cert data to OpenSSL internal X509 first.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys outbuf_p = outbuf; /* use a temp pointer; required by openssl */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, outbuflen);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Convert to the PEM format and write it out */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *params)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* open all files in the directory and attempt to read them */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Just try to load a single certificate */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = kmf_load_cert(kmfh, params, fullpath, &certdata);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysssl_write_private_key(KMF_HANDLE *kmfh, KMF_ENCODE_FORMAT format, BIO *out,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (params == NULL || params->sslparms.keyfile == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* If the requested file exists, return an error */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys sslPrivKey = RSA_generate_key(params->keylength, eValue,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* OpenSSL derives the public key from the private */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((sslDSAKey->p = BN_bin2bn(P, sizeof (P), sslDSAKey->p)) ==
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((sslDSAKey->q = BN_bin2bn(Q, sizeof (Q), sslDSAKey->q)) ==
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((sslDSAKey->g = BN_bin2bn(G, sizeof (G), sslDSAKey->g)) ==
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Make a copy for the public key */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Store the private key to the keyfile */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = ssl_write_private_key(kmfh, format, out, ¶ms->cred, eprikey);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Protect the file by making it read-only */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_OID *AlgOID, KMF_DATA *tobesigned, KMF_DATA *output)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Map the OID to an OpenSSL algorithm */
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 output->Length = i = BN_bn2bin(dsasig->r, output->Data);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*ARGSUSED*/
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_DeleteKey(KMF_HANDLE_T handle, KMF_DELETEKEY_PARAMS *params,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* If the file exists, make sure it is a proper key. */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_ImportCRL(KMF_HANDLE_T handle, KMF_IMPORTCRL_PARAMS *params)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (params == NULL || params->sslparms.crlfile == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_IsCRLFile(handle, params->sslparms.crlfile, &format);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* If bypasscheck is specified, no need to verify. */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_IsCertFile(handle, params->sslparms.certfile, &format);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Read in the CA cert file and convert to X509 */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (BIO_read_filename(in, params->sslparms.certfile) <= 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Now get the public key from the CA cert */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Verify the CRL with the CA's public key */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_ListCRL(KMF_HANDLE_T handle, KMF_LISTCRL_PARAMS *params,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (params == NULL || params->sslparms.crlfile == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (len <= 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_DeleteCRL(KMF_HANDLE_T handle, KMF_DELETECRL_PARAMS *params)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (params == NULL || params->sslparms.crlfile == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_FindCertInCRL(KMF_HANDLE_T handle, KMF_FINDCERTINCRL_PARAMS *params)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (params == NULL || params->sslparms.crlfile == NULL ||
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_IsCRLFile(handle, params->sslparms.crlfile, &format);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Read the CRL file and load it into a X509_CRL structure */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Read the Certificate file and load it into a X509 structure */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_IsCertFile(handle, params->sslparms.certfile, &format);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Check if the certificate and the CRL have same issuer */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (X509_NAME_cmp(xcert->cert_info->issuer, xcrl->crl->issuer) != 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Check to see if the certificate serial number is revoked */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* No revoked certificates in the CRL file */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys for (i = 0; i < sk_X509_REVOKED_num(revoke_stack); i++) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_GetErrorString(KMF_HANDLE_T handle, char **msgstr)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char str[256]; /* OpenSSL needs at least 120 byte buffer */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ERR_error_string_n(kmfh->lasterr.errcode, str, sizeof (str));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *pcert,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys unsigned char *outbuf_p;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* copy cert data to outbuf */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys outbuf_p = outbuf; /* use a temp pointer; required by openssl */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, pcert->Length);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) X509_NAME_print_ex(mem, X509_get_issuer_name(xcert), 0,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) X509_NAME_print_ex(mem, X509_get_subject_name(xcert), 0,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys tmpstr = i2s_ASN1_INTEGER(NULL, xcert->cert_info->version);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) strncpy(resultStr, tmpstr, KMF_CERT_PRINTABLE_LEN);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (i2a_ASN1_INTEGER(mem, X509_get_serialNumber(xcert)) > 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) ASN1_TIME_print(mem, X509_get_notBefore(xcert));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) ASN1_TIME_print(mem, X509_get_notAfter(xcert));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys "RSA Public Key: (%d bit)\n",
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ext_index = X509v3_get_ext_by_NID(ci->extensions, nid, -1);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) i2a_ASN1_OBJECT(mem, X509_EXTENSION_get_object(ex));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys X509_EXTENSION_get_critical(ex) ? "critical" : "") <=
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (!X509V3_EXT_print(mem, ex, X509V3_EXT_DUMP_UNKNOWN, 4)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (len <= 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*ARGSUSED*/
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (params == NULL && params->sslparms.keyfile == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * This is really just a FindKey operation, reuse the
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * FindKey function.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = OpenSSL_FindKey(handle, &fkparms, key, &numkeys);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*ARGSUSED*/
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys for (i = 0; i < blocks; i++) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * This function will create a certid from issuer_cert and user_cert.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * The caller should use OCSP_CERTID_free(OCSP_CERTID *) to deallocate
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * certid memory after use.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyscreate_certid(KMF_HANDLE_T handle, const KMF_DATA *issuer_cert,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys unsigned char *ptmp;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* convert the DER-encoded issuer cert to an internal X509 */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* convert the DER-encoded user cert to an internal X509 */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* create a CERTID */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle, KMF_OCSPREQUEST_PARAMS *params,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (params->user_cert == NULL || params->issuer_cert == NULL ||
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = create_certid(handle, params->issuer_cert, params->user_cert,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Create an OCSP request */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Write the request to the output file with DER encoding */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * We don't need to free "id" explicitely, because OCSP_REQUEST_free()
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * will deallocate certid's space also.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/* ocsp_find_signer_sk() is copied from openssl source */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Easy if lookup by name */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (X509_find_by_subject(certs, id->value.byName));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Lookup by key hash */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* If key hash isn't SHA1 length then forget it */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Calculate hash of each key and compare */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (x);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/* ocsp_find_signer() is copied from openssl source */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*ARGSUSED*/
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (2);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (1);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Maybe lookup from store if by subject name */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (0);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * This function will verify the signature of a basic response, using
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * the public key from the OCSP responder certificate.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyscheck_response_signature(KMF_HANDLE_T handle, OCSP_BASICRESP *bs,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys unsigned char *ptmp;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Find the certificate that signed the basic response.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * If signer_cert is not NULL, we will use that as the signer cert.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Otherwise, we will check if the issuer cert is actually the signer.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * If we still do not find a signer, we will look for it from the
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * certificate list came with the response file.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Convert the issuer cert into X509 and push it into a
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * stack to be used by ocsp_find_signer().
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = ocsp_find_signer(&signer, bs, cert_stack, NULL, 0);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* can not find the signer */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Verify the signature of the response */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret == 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (params_in == NULL || params_in->issuer_cert == NULL ||
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys params_in->user_cert == NULL || params_in->response == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Read in the response */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Check the response status */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys printf("Successfully checked the response file status.\n");
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#endif /* DEBUG */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Extract basic response */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys printf("Successfully retrieved the basic response.\n");
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#endif /* DEBUG */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Check the basic response signature if required */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys printf("Successfully verified the response signature.\n");
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#endif /* DEBUG */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Create a certid for the certificate in question */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys printf("successfully created a certid for the cert.\n");
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#endif /* DEBUG */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Find the index of the single response for the certid */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* cound not find this certificate in the response */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys printf("Successfully found the single response index for the cert.\n");
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#endif /* DEBUG */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Retrieve the single response and get the cert status */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys status = OCSP_single_get0_status(single, &reason, &rev, &thisupd,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else { /* revoked */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Verify the time */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#endif /* DEBUG */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Make sure the requested file actually exists. */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * If the file is a recognized format,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * then it is NOT a symmetric key.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * If we don't know the encoding,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * it is probably a symmetric key.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *params,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (handle == NULL || params == NULL || numkeys == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* open all files in the directory and attempt to read them */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = fetch_key(handle, fullpath, params->keyclass, key);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((*numkeys) == 0)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys unsigned int keyidlen = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Must have at least a cert OR a key */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Section 1:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * The first PKCS#12 container (safebag) will hold the certificates
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * associated with this key. The result of this section is a
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * PIN-encrypted PKCS#7 container (authsafe). If there are no
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * certificates, there is no point in creating the "safebag" or the
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * "authsafe" so we go to the next section.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* The key doesn't match the cert */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Convert cert from X509 struct to PKCS#12 bag */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Add the key id to the certificate bag. */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Pile it on the bag_stack. */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* No support for CA certs yet */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys for (i = 0; i < ncacerts; i++) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Convert CA cert to PKCS#12 bag. */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Pile it onto the bag_stack. */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Turn bag_stack of certs into encrypted authsafe. */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Clear away this bag_stack, we're done with it. */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Section 2:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * The second PKCS#12 container (safebag) will hold the private key
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * that goes with the certificates above. The results of this section
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * is an unencrypted PKCS#7 container (authsafe). If there is no
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * private key, there is no point in creating the "safebag" or the
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * "authsafe" so we go to the next section.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Put the shrouded key into a PKCS#12 bag. */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Clean up the PKCS#8 shrouded key, don't need it now. */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Start a PKCS#12 safebag container for the private key. */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Pile on the private key on the bag_stack. */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Clear away this bag_stack, we're done with it. */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Section 3:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * This is where the two PKCS#7 containers, one for the certificates
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * and one for the private key, are put together into a PKCS#12
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * element. This final PKCS#12 element is written to the export file.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Start a PKCS#7 stack. */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Put the PKCS#7 stack into the PKCS#12 element. */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (!PKCS12_pack_authsafes(p12_elem, authsafe_stack)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Clear away the PKCS#7 stack, we're done with it. */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Set the integrity MAC on the PKCS#12 element. */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (!PKCS12_set_mac(p12_elem, cred->cred, cred->credlen,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Write the PKCS#12 element to the export file. */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Clear away this bag_stack, we're done with it. */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((rsa->n = BN_bin2bn(key->mod.val, key->mod.len, rsa->n)) == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((rsa->e = BN_bin2bn(key->pubexp.val, key->pubexp.len, rsa->e)) ==
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((rsa->d = BN_bin2bn(key->priexp.val, key->priexp.len,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((rsa->p = BN_bin2bn(key->prime1.val, key->prime1.len,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((rsa->q = BN_bin2bn(key->prime2.val, key->prime2.len,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((rsa->dmp1 = BN_bin2bn(key->exp1.val, key->exp1.len,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((rsa->dmq1 = BN_bin2bn(key->exp2.val, key->exp2.len,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((rsa->iqmp = BN_bin2bn(key->coef.val, key->coef.len,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* The original key must be freed once here or it leaks memory */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((dsa->p = BN_bin2bn(key->prime.val, key->prime.len,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((dsa->q = BN_bin2bn(key->subprime.val, key->subprime.len,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((dsa->g = BN_bin2bn(key->base.val, key->base.len,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((dsa->priv_key = BN_bin2bn(key->value.val, key->value.len,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* The original key must be freed once here or it leaks memory */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Open the output file.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Stick the key and the cert into a PKCS#12 file */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * First, find the certificate.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * If the caller already sent the raw keys and certs,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * shortcut the search and just export that
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * One *may* export a key OR a cert by itself.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Now find the private key.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Open the output file.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Stick the key and the cert into a PKCS#12 file */
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys * Helper function to extract keys and certificates from
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys * a single PEM file. Typically the file should contain a
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys * private key and an associated public key wrapped in an x509 cert.
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys * However, the file may be just a list of X509 certs with no keys.
71593db26bb6ef7b739cffe06d53bf990cac112cwyllysextract_objects(KMF_HANDLE *kmfh, char *filename, CK_UTF8CHAR *pin,
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys CK_ULONG pinlen, EVP_PKEY **priv_key, KMF_DATA **certs,
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys/* ARGSUSED */
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys int i, ncerts = 0;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys x509_info_stack = PEM_X509_INFO_read(fp, NULL, NULL, pin);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys while ((info = sk_X509_INFO_pop(x509_info_stack)) != NULL &&
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys if (ncerts == 0) {
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys * Make sure the private key matchs the last cert in the file.
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys if (pkey != NULL && !X509_check_private_key(x, pkey)) {
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys certlist = (KMF_DATA *)malloc(ncerts * sizeof (KMF_DATA));
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys * Convert all of the certs to DER format.
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys for (i = 0; rv == KMF_OK && certs != NULL && i < ncerts; i++) {
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys rv = ssl_cert2KMFDATA(kmfh, info->x509, &certlist[i]);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Helper function to decrypt and parse PKCS#12 import file.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysextract_pkcs12(BIO *fbio, CK_UTF8CHAR *pin, CK_ULONG pinlen,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys EVP_PKEY **priv_key, X509 **cert, STACK_OF(X509) **ca)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/* ARGSUSED */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((pk12_tmp = d2i_PKCS12_bio(fbio, &pk12)) == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* This is ok; it seems to mean there is no more to read. */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ERR_GET_REASON(ERR_peek_error()) == ASN1_R_HEADER_TOO_LONG)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (PKCS12_parse(pk12, (char *)pin, &temp_pkey, &temp_cert,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((rv = sslBN2KMFBN(rsa->n, &kmfkey->mod)) != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((rv = sslBN2KMFBN(rsa->e, &kmfkey->pubexp)) != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((rv = sslBN2KMFBN(rsa->d, &kmfkey->priexp)) != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((rv = sslBN2KMFBN(rsa->p, &kmfkey->prime1)) != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((rv = sslBN2KMFBN(rsa->q, &kmfkey->prime2)) != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((rv = sslBN2KMFBN(rsa->dmp1, &kmfkey->exp1)) != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((rv = sslBN2KMFBN(rsa->dmq1, &kmfkey->exp2)) != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((rv = sslBN2KMFBN(rsa->iqmp, &kmfkey->coef)) != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Free the reference to this key, SSL will not actually free
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * the memory until the refcount == 0, so this is safe.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((rv = sslBN2KMFBN(dsa->p, &kmfkey->prime)) != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((rv = sslBN2KMFBN(dsa->q, &kmfkey->subprime)) != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((rv = sslBN2KMFBN(dsa->g, &kmfkey->base)) != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((rv = sslBN2KMFBN(dsa->priv_key, &kmfkey->value)) != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Free the reference to this key, SSL will not actually free
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * the memory until the refcount == 0, so this is safe.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int n = (*ncerts);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys list = (KMF_DATA *)realloc(list, sizeof (KMF_DATA) * (n + 1));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int n = (*nkeys);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys list = (KMF_RAW_KEY_DATA *)malloc(sizeof (KMF_RAW_KEY_DATA));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys EVP_PKEY *sslkey, X509 *sslcert, STACK_OF(X509) *sslcacerts,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Convert SSL key to raw key */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Now add the certificate to the certlist */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = add_cert_to_list(kmfh, sslcert, certlist, ncerts);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Also add any included CA certs to the list */
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys for (i = 0; sslcacerts != NULL && i < sk_X509_num(sslcacerts); i++) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * sk_X509_value() is macro that embeds a cast to (X509 *).
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Here it translates into ((X509 *)sk_value((ca), (i))).
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Lint is complaining about the embedded casting, and
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * to fix it, you need to fix openssl header files.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* LINTED E_BAD_PTR_CAST_ALIGN */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Now add the ca cert to the certlist */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Reached end of import file? */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Convert keys and certs to exportable format */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = convertPK12Objects(kmfh, privkey, cert, cacerts,
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys * auto-detect the file format, regardless of what
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys * the 'format' parameters in the params say.
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys /* This function only works on PEM files */
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys /* Reached end of import file? */
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys /* Convert keys and certs to exportable format */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_StorePrivateKey(KMF_HANDLE_T handle, KMF_STOREKEY_PARAMS *params,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* If the requested file exists, return an error */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Protect the file by making it read-only */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* create the 1st DES key */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Create the 2nd DES key and make sure its value is different
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * from the 1st DES key.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (memcmp((const void *) deskey1, (const void *) deskey2, 8)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Create the 3rd DES key and make sure its value is different
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * from the 2nd DES key.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (memcmp((const void *)deskey2, (const void *)deskey3, 8)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Concatenate 3 DES keys into a DES3 key */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memcpy((void *)newkey, (const void *)deskey1, 8);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memcpy((void *)(newkey + 8), (const void *)deskey2, 8);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memcpy((void *)(newkey + 16), (const void *)deskey3, 8);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (params == NULL || params->sslparms.keyfile == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* If the requested file exists, return an error */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (params->keytype == KMF_AES || params->keytype == KMF_RC4) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) write(fd, (const void *) rkey->keydata.val, rkey->keydata.len);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_VerifyCRLFile(KMF_HANDLE_T handle, KMF_VERIFYCRL_PARAMS *params)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys unsigned char *p;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (params->crl_name == NULL || params->tacert == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_GetFileFormat(params->crl_name, &crl_format);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Get issuer certificate public key */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Verify CRL signature */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_IsCRLFile(handle, params->crl_name, &crl_format);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys i = X509_cmp_time(X509_CRL_get_lastUpdate(xcrl), NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (i >= 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys i = X509_cmp_time(X509_CRL_get_nextUpdate(xcrl), NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (i <= 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Check a file to see if it is a CRL file with PEM or DER format.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * If success, return its format in the "pformat" argument.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_IsCRLFile(KMF_HANDLE_T handle, char *filename, int *pformat)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((xcrl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)) != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Now try to read it as raw DER data.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Check a file to see if it is a certficate file with PEM or DER format.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * If success, return its format in the pformat argument.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_IsCertFile(KMF_HANDLE_T handle, char *filename,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysOpenSSL_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RAW_SYM_KEY *rawkey = (KMF_RAW_SYM_KEY *)symkey->keyp;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memcpy(rkey->keydata.val, rawkey->keydata.val,