99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * CDDL HEADER START
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
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 *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * or http://www.opensolaris.org/os/licensing.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * See the License for the specific language governing permissions
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * and limitations under the License.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
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 *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * CDDL HEADER END
9f0bc604621fbb9b9b038e6de7da8f9c46e28608Wyllys Ingersoll *
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <stdio.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <link.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <fcntl.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <ctype.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <sys/param.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <sys/types.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <sys/stat.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <sys/socket.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <ber_der.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <kmfapiP.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <pem_encode.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <libgen.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <cryptoutil.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#define CERTFILE_TEMPNAME "/tmp/user.certXXXXXX"
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#define CRLFILE_TEMPNAME "/tmp/crlXXXXXX"
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#define X509_FORMAT_VERSION 2
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllysstatic KMF_RETURN
448b8615fe9e8af757530284920a235430ead7e8wyllyssign_cert(KMF_HANDLE_T, const KMF_DATA *, KMF_KEY_HANDLE *,
448b8615fe9e8af757530284920a235430ead7e8wyllys KMF_OID *, KMF_DATA *);
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysverify_cert_with_key(KMF_HANDLE_T, KMF_DATA *, const KMF_DATA *);
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysverify_cert_with_cert(KMF_HANDLE_T, const KMF_DATA *, const KMF_DATA *);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic KMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysget_keyalg_from_cert(KMF_DATA *cert, KMF_KEY_ALG *keyalg)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN rv;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509_CERTIFICATE *SignerCert = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_ALGORITHM_INDEX AlgorithmId;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = DerDecodeSignedCertificate(cert, &SignerCert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Get the algorithm info from the signer certificate */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys AlgorithmId = x509_algoid_to_algid(
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys &SignerCert->signature.algorithmIdentifier.algorithm);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys switch (AlgorithmId) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case KMF_ALGID_MD5WithRSA:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case KMF_ALGID_SHA1WithRSA:
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll case KMF_ALGID_SHA256WithRSA:
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll case KMF_ALGID_SHA384WithRSA:
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll case KMF_ALGID_SHA512WithRSA:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *keyalg = KMF_RSA;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case KMF_ALGID_SHA1WithDSA:
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll case KMF_ALGID_SHA256WithDSA:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *keyalg = KMF_DSA;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll case KMF_ALGID_SHA1WithECDSA:
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll case KMF_ALGID_SHA256WithECDSA:
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll case KMF_ALGID_SHA384WithECDSA:
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll case KMF_ALGID_SHA512WithECDSA:
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll case KMF_ALGID_ECDSA:
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll *keyalg = KMF_ECDSA;
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys default:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_BAD_ALGORITHM;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_signed_cert(SignerCert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(SignerCert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Name: kmf_find_prikey_by_cert
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Description:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * This function finds the corresponding private key in keystore
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * for a certificate
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_find_prikey_by_cert(KMF_HANDLE_T handle, int numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_PLUGIN *plugin;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEYSTORE_TYPE kstype;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_ALG keyalg;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_HANDLE *key = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *cert = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE_TESTER required_attrs[] = {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_KEY_HANDLE_ATTR, TRUE, sizeof (KMF_KEY_HANDLE),
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sizeof (KMF_KEY_HANDLE)}
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys };
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int num_req_attrs = sizeof (required_attrs) /
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sizeof (KMF_ATTRIBUTE_TESTER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CLEAR_ERROR(handle, ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = test_attributes(num_req_attrs, required_attrs,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys 0, NULL, numattr, attrlist);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * First, get the key algorithm info from the certificate and saves it
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * in the returned key handle.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (cert == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = get_keyalg_from_cert(cert, &keyalg);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (key == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key->keyalg = keyalg;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Call the plugin to do the work. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &kstype, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys plugin = FindPlugin(handle, kstype);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (plugin == NULL || plugin->funclist->FindPrikeyByCert == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_PLUGIN_NOTFOUND);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (plugin->funclist->FindPrikeyByCert(handle, numattr, attrlist));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysKMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyscheck_key_usage(void *handle,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys const KMF_DATA *cert,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys const KMF_KU_PURPOSE purpose)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509EXT_BASICCONSTRAINTS constraint;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_BOOL critical = B_FALSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509EXT_KEY_USAGE keyusage;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (handle == NULL || cert == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memset(&constraint, 0, sizeof (KMF_X509EXT_BASICCONSTRAINTS));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memset(&keyusage, 0, sizeof (KMF_X509EXT_KEY_USAGE));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_cert_ku(cert, &keyusage);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * If absent or error, the cert is assumed to be invalid
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * for all key usage checking.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys switch (purpose) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case KMF_KU_SIGN_CERT:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * RFC 3280:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * The keyCertSign bit is asserted when the subject
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * public key is used for verifying a signature on
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * public key certificates. If the keyCertSign bit
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * is asserted, then the cA bit in the basic constraints
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * extension (section 4.2.1.10) MUST also be asserted.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * The basic constraints extension MUST appear as a
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * critical extension in all CA certificates that
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * contain public keys used to validate digital
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * signatures on certificates.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll if (keyusage.KeyUsageBits & KMF_keyCertSign) {
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll ret = kmf_get_cert_basic_constraint(cert,
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll &critical, &constraint);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll if (ret != KMF_OK)
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll if ((!critical) || (!constraint.cA))
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll return (KMF_ERR_KEYUSAGE);
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_KEYUSAGE);
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case KMF_KU_SIGN_DATA:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * RFC 3280:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * The digitalSignature bit is asserted when the subject
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * public key is used with a digital signature mechanism
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * to support security services other than certificate
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * signing(bit 5), or CRL signing(bit 6).
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (!(keyusage.KeyUsageBits & KMF_digitalSignature))
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_KEYUSAGE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case KMF_KU_ENCRYPT_DATA:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * RFC 3280:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * The dataEncipherment bit is asserted when the subject
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * public key is used for enciphering user data, other than
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * cryptographic keys.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (!(keyusage.KeyUsageBits & KMF_dataEncipherment))
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_KEYUSAGE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys default:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_OK);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_find_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_PLUGIN *plugin;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEYSTORE_TYPE kstype;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE_TESTER required_attrs[] = {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_COUNT_ATTR, FALSE, sizeof (uint32_t), sizeof (uint32_t)}
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys };
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int num_req_attrs = sizeof (required_attrs) /
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sizeof (KMF_ATTRIBUTE_TESTER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CLEAR_ERROR(handle, ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = test_attributes(num_req_attrs, required_attrs,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys 0, NULL, numattr, attrlist);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &kstype, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys plugin = FindPlugin(handle, kstype);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (plugin == NULL || plugin->funclist->FindCert == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_PLUGIN_NOTFOUND);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (plugin->funclist->FindCert(handle, numattr, attrlist));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#define NODATA(d) (d.Data == NULL || d.Length == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_encode_cert_record(KMF_X509_CERTIFICATE *CertData, KMF_DATA *encodedCert)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_X509_TBS_CERT *tbs_cert;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (CertData == NULL || encodedCert == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Validate that all required fields are present.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys tbs_cert = &(CertData->certificate);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (NODATA(tbs_cert->version) ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys NODATA(tbs_cert->signature.algorithm) ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys NODATA(tbs_cert->subjectPublicKeyInfo.subjectPublicKey) ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys tbs_cert->serialNumber.val == NULL ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys tbs_cert->serialNumber.len == 0 ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys tbs_cert->subject.numberOfRDNs == 0 ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys tbs_cert->issuer.numberOfRDNs == 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_INCOMPLETE_TBS_CERT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys encodedCert->Length = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys encodedCert->Data = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Pack the new certificate */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = DerEncodeSignedCertificate(CertData, encodedCert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * This function is used to setup the attribute list before calling
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * kmf_find_prikey_by_cert(). This function is used by
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * kmf_decrypt_with_cert
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * kmf_sign_cert
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * kmf_sign_data
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * The attribute list in these callers contain all the attributes
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * needed by kmf_find_prikey_by_cert(), except the
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * KMF_KEY_HANDLE attribute and the KMF_CERT_DATA_ATTR attribute.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * These 2 attributes need to be added or reset.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * The caller should free the new_attrlist after use it.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyssetup_findprikey_attrlist(KMF_ATTRIBUTE *src_attrlist, int src_num,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE **new_attrlist, int *new_num, KMF_KEY_HANDLE *key,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *cert)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE *attrlist = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int cur_num = src_num;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int index;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int i;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (src_attrlist == NULL || new_num == NULL || key == NULL ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys cert == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Create a new attribute list with 2 more elements */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys attrlist = (KMF_ATTRIBUTE *) malloc(
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (src_num + 2) * sizeof (KMF_ATTRIBUTE));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (attrlist == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_MEMORY);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Copy the src_attrlist to the new list */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys for (i = 0; i < src_num; i++) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys attrlist[i].type = src_attrlist[i].type;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys attrlist[i].pValue = src_attrlist[i].pValue;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys attrlist[i].valueLen = src_attrlist[i].valueLen;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Add or reset the key handle attribute */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys index = kmf_find_attr(KMF_KEY_HANDLE_ATTR, attrlist, cur_num);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (index == -1) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* not found; add it */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, cur_num,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_HANDLE_ATTR, key, sizeof (KMF_KEY_HANDLE));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys cur_num++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* found; just reset it */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, index,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_HANDLE_ATTR, key, sizeof (KMF_KEY_HANDLE));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* add or reset the cert data attribute */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys index = kmf_find_attr(KMF_CERT_DATA_ATTR, attrlist, cur_num);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (index == -1) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* not found; add it */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, cur_num,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_CERT_DATA_ATTR, cert, sizeof (KMF_DATA));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys cur_num++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* found; just reset it */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, index,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_CERT_DATA_ATTR, cert, sizeof (KMF_DATA));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *new_attrlist = attrlist;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys *new_num = cur_num;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_OK);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll/*
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * Determine a default signature type to use based on
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * the key algorithm.
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll */
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersollstatic KMF_OID *
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersollget_default_signoid(KMF_KEY_HANDLE *key)
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll{
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll KMF_OID *oid;
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll switch (key->keyalg) {
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll case KMF_RSA:
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll oid = (KMF_OID *)&KMFOID_SHA256WithRSA;
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll break;
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll case KMF_DSA:
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll /* NSS doesnt support DSA-SHA2 hashes yet */
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll if (key->kstype == KMF_KEYSTORE_NSS)
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll oid = (KMF_OID *)&KMFOID_X9CM_DSAWithSHA1;
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll else
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll oid = (KMF_OID *)&KMFOID_SHA256WithDSA;
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll break;
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll case KMF_ECDSA:
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll oid = (KMF_OID *)&KMFOID_SHA256WithECDSA;
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll break;
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll default:
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll oid = NULL;
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll break;
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll }
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll return (oid);
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll}
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll/*
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * This is to check to see if a certificate being signed has
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * the keyCertSign KeyUsage bit set, and if so, make sure the
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * "BasicConstraints" extension is also set accordingly.
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll */
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersollstatic KMF_RETURN
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersollcheck_for_basic_constraint(KMF_DATA *cert)
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll{
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll KMF_RETURN rv = KMF_OK;
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll KMF_X509EXT_KEY_USAGE keyUsage;
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll KMF_X509_CERTIFICATE *x509cert = NULL;
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll rv = kmf_get_cert_ku((const KMF_DATA *)cert, &keyUsage);
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll if (rv == KMF_OK) {
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll KMF_X509EXT_BASICCONSTRAINTS basicConstraint;
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll KMF_BOOL critical;
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll /* If keyCertSign is set, look for basicConstraints */
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll if (keyUsage.KeyUsageBits & KMF_keyCertSign)
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll rv = kmf_get_cert_basic_constraint(
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll (const KMF_DATA *)cert,
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll &critical, &basicConstraint);
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll /*
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * If we got KMF_OK (or an error), then return
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * because the extension is already present. We
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * only want to continue with this function if
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * the extension is NOT found.
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll */
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll if (rv != KMF_ERR_EXTENSION_NOT_FOUND)
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll return (rv);
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll /*
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * Don't limit the pathLen (for now).
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * This should probably be a policy setting in the
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * future.
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll */
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll basicConstraint.cA = TRUE;
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll basicConstraint.pathLenConstraintPresent = FALSE;
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll /*
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * Decode the DER cert data into the internal
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * X.509 structure we need to set extensions.
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll */
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll rv = DerDecodeSignedCertificate(cert, &x509cert);
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll if (rv != KMF_OK)
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll return (rv);
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll /*
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * Add the missing basic constraint.
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll */
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll rv = kmf_set_cert_basic_constraint(x509cert,
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll TRUE, &basicConstraint);
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll if (rv != KMF_OK) {
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll kmf_free_signed_cert(x509cert);
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll free(x509cert);
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll return (rv);
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll }
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll /* Free the old cert data record */
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll kmf_free_data(cert);
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll /* Re-encode the cert with the extension */
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll rv = kmf_encode_cert_record(x509cert, cert);
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll /* cleanup */
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll kmf_free_signed_cert(x509cert);
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll free(x509cert);
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll }
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll if (rv == KMF_ERR_EXTENSION_NOT_FOUND)
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll rv = KMF_OK;
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll return (rv);
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll}
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Name: kmf_sign_cert
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Description:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * This function signs a certificate using the signer cert and
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * returns a signed and DER-encoded certificate.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * The following types of certificate data can be submitted to be signed:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * KMF_TBS_CERT_DATA_ATTR - a KMF_DATA ptr is provided in the attrlist
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * and is signed directly.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * KMF_X509_CERTIFICATE_ATTR - a KMF_X509_CERTIFICATE record is provided
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * in the attribute list. This is converted to raw KMF_DATA
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * prior to signing.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * The key for the signing operation can be provided as a KMF_KEY_HANDLE_ATTR
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * or the caller may choose to provide a KMF_SIGNER_CERT_ATTR (KMF_DATA *).
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * If the latter, this function will then attempt to find the private key
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * associated with the certificate. The private key must be stored in
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * the same keystore as the signer certificate.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_sign_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int new_numattr = numattr + 1;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE *new_attrlist = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *signer_cert = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *tbs_cert = NULL; /* to be signed cert */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *signed_cert = NULL;
6b35cb3cf158584a9408d44b9b6796564e8e1882Richard PALO KMF_DATA unsignedCert = { 0, NULL };
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_HANDLE sign_key, *sign_key_ptr;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int freethekey = 0;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_POLICY_RECORD *policy;
448b8615fe9e8af757530284920a235430ead7e8wyllys KMF_OID *oid = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_X509_CERTIFICATE *x509cert;
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll KMF_X509_TBS_CERT *decodedTbsCert = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE_TESTER required_attrs[] = {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)}
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys };
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int num_req_attrs = sizeof (required_attrs) /
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sizeof (KMF_ATTRIBUTE_TESTER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CLEAR_ERROR(handle, ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = test_attributes(num_req_attrs, required_attrs,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys 0, NULL, numattr, attrlist);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Get the signer cert and check its keyUsage */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys signer_cert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sign_key_ptr = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr);
448b8615fe9e8af757530284920a235430ead7e8wyllys /*
448b8615fe9e8af757530284920a235430ead7e8wyllys * Only accept 1 or the other, not both.
448b8615fe9e8af757530284920a235430ead7e8wyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (signer_cert == NULL && sign_key_ptr == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
448b8615fe9e8af757530284920a235430ead7e8wyllys if (signer_cert != NULL && sign_key_ptr != NULL)
448b8615fe9e8af757530284920a235430ead7e8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll oid = kmf_get_attr_ptr(KMF_OID_ATTR, attrlist, numattr);
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll if (oid == NULL) {
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll /*
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * If the signature OID was not given, check
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * for an algorithm index identifier instead.
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll */
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll KMF_ALGORITHM_INDEX AlgId;
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll ret = kmf_get_attr(KMF_ALGORITHM_INDEX_ATTR, attrlist, numattr,
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll &AlgId, NULL);
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll if (ret == KMF_OK)
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll oid = x509_algid_to_algoid(AlgId);
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll }
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (signer_cert != NULL) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys policy = handle->policy;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = check_key_usage(handle, signer_cert, KMF_KU_SIGN_CERT);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Find the private key from the signer certificate by calling
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * kmf_find_prikey_by_cert().
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = setup_findprikey_attrlist(attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &new_attrlist, &new_numattr, &sign_key, signer_cert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_find_prikey_by_cert(handle, new_numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys new_attrlist);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sign_key_ptr = &sign_key;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys freethekey = 1;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys tbs_cert = kmf_get_attr_ptr(KMF_TBS_CERT_DATA_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (tbs_cert == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys x509cert = kmf_get_attr_ptr(KMF_X509_CERTIFICATE_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (x509cert == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_PARAMETER;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_encode_cert_record(x509cert, &unsignedCert);
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll tbs_cert = &unsignedCert;
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll }
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll /*
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * Check for the keyCertSign bit in the KeyUsage extn. If it is set,
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * then the basicConstraints must also be present and be
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * marked critical.
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll */
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll ret = check_for_basic_constraint(tbs_cert);
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll if (ret)
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll goto out;
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll if (oid == NULL) {
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll /*
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * If OID is not known yet, use a default value
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * based on the signers key type.
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll */
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll oid = get_default_signoid(sign_key_ptr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys signed_cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (signed_cert == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_PARAMETER;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto out;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
448b8615fe9e8af757530284920a235430ead7e8wyllys ret = sign_cert(handle, tbs_cert, sign_key_ptr, oid, signed_cert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysout:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (new_attrlist)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) free(new_attrlist);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* If we had to find the key, free it here. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (freethekey)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_kmf_key(handle, &sign_key);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_data(&unsignedCert);
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll if (decodedTbsCert != NULL) {
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll kmf_free_tbs_cert(decodedTbsCert);
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll free(decodedTbsCert);
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Name: kmf_sign_data
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Description:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * This function signs a block of data using the signer cert and
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * returns the the signature in output
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_sign_data(KMF_HANDLE_T handle, int numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_PLUGIN *plugin;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE *new_attrlist = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int new_numattr = numattr;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *signer_cert = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *tbs_data = NULL; /* to be signed data */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *output = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_HANDLE sign_key, *sign_key_ptr;
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll KMF_ALGORITHM_INDEX AlgId = KMF_ALGID_NONE;
6b35cb3cf158584a9408d44b9b6796564e8e1882Richard PALO KMF_DATA signature = { 0, NULL };
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_OID *oid;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_POLICY_RECORD *policy;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE_TESTER required_attrs[] = {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_OUT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)}
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys };
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int num_req_attrs = sizeof (required_attrs) /
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sizeof (KMF_ATTRIBUTE_TESTER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CLEAR_ERROR(handle, ret);
6adaf03e130142c9de7b6c050f0d0b1df4e73044wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = test_attributes(num_req_attrs, required_attrs,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys 0, NULL, numattr, attrlist);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Get the signer cert and check its keyUsage. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys signer_cert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sign_key_ptr = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (signer_cert == NULL && sign_key_ptr == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * If a signer cert was given, use it to find the private key
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * to use for signing the data.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (signer_cert != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = check_key_usage(handle, signer_cert, KMF_KU_SIGN_DATA);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Signing generic data does not require the
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * KeyUsage extension.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys policy = handle->policy;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Find the private key from the signer certificate.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = setup_findprikey_attrlist(attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &new_attrlist, &new_numattr, &sign_key, signer_cert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_find_prikey_by_cert(handle, new_numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys new_attrlist);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sign_key_ptr = &sign_key;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Get the tbs_data and signed_data attributes now */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys tbs_data = kmf_get_attr_ptr(KMF_DATA_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (tbs_data == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_PARAMETER;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys output = kmf_get_attr_ptr(KMF_OUT_DATA_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (output == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_PARAMETER;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
02744e811b15322c5f109827a116c33bfe3438b5wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Get the algorithm index attribute and its oid. If this attribute
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * is not provided, then we use a default value.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys oid = kmf_get_attr_ptr(KMF_OID_ATTR, attrlist, numattr);
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll if (oid == NULL) {
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll ret = kmf_get_attr(KMF_ALGORITHM_INDEX_ATTR, attrlist,
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll numattr, &AlgId, NULL);
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll /* If there was no Algorithm ID, use default based on key */
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll if (ret != KMF_OK)
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll oid = get_default_signoid(sign_key_ptr);
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll else
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll oid = x509_algid_to_algoid(AlgId);
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll }
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll if (sign_key_ptr->keyp == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = KMF_ERR_BAD_PARAMETER;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Now call the plugin function to sign it */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys plugin = FindPlugin(handle, sign_key_ptr->kstype);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (plugin == NULL || plugin->funclist->SignData == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_PLUGIN_NOTFOUND;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = plugin->funclist->SignData(handle, sign_key_ptr, oid, tbs_data,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys output);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * For DSA, NSS returns an encoded signature. Decode the
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll * signature and expect a 40-byte DSA signature.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (plugin->type == KMF_KEYSTORE_NSS &&
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll (IsEqualOid(oid, (KMF_OID *)&KMFOID_X9CM_DSAWithSHA1) ||
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll IsEqualOid(oid, (KMF_OID *)&KMFOID_SHA256WithDSA))) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = DerDecodeDSASignature(output, &signature);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys output->Length = signature.Length;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) memcpy(output->Data, signature.Data, signature.Length);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyscleanup:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (new_attrlist != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(new_attrlist);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (signature.Data)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(signature.Data);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (signer_cert != NULL && sign_key_ptr != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_kmf_key(handle, sign_key_ptr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * kmf_verify_data
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * This routine will try to verify a block of data using
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * either a public key or a certificate as the source
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * of the verification (the key).
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * The caller may provider either a KMF_KEY_HANDLE_ATTR or
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * a KMF_SIGNER_CERT_DATA_ATTR (with a KMF_DATA record) to
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * use for the key to the verification step. If a certificate
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * is used and that certificate has the KeyUsage extension,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * the SIGN-DATA bit must be set. Also, if a certificate
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * is used, the verification will be done in a specific
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * keystore mechanism.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * If a KMF_KEY_HANDLE is given in the attribute list, the
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * verification will occur in the framework itself using
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * PKCS#11 C_Verify functions.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_verify_data(KMF_HANDLE_T handle,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int num_args,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_PLUGIN *plugin;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEYSTORE_TYPE kstype;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys uint32_t len;
6b35cb3cf158584a9408d44b9b6796564e8e1882Richard PALO KMF_DATA derkey = { 0, NULL };
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_HANDLE *KMFKey;
448b8615fe9e8af757530284920a235430ead7e8wyllys KMF_ALGORITHM_INDEX sigAlg = KMF_ALGID_NONE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *indata;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *insig;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *signer_cert;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_X509_SPKI spki;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_POLICY_RECORD *policy;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE_TESTER required_attrs[] = {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_DATA_ATTR, FALSE, sizeof (KMF_DATA),
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sizeof (KMF_DATA)},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_IN_SIGN_ATTR, FALSE, sizeof (KMF_DATA),
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sizeof (KMF_DATA)}
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys };
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int num_req_attrs = sizeof (required_attrs) /
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sizeof (KMF_ATTRIBUTE_TESTER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CLEAR_ERROR(handle, ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = test_attributes(num_req_attrs, required_attrs,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys 0, NULL, num_args, attrlist);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys len = sizeof (kstype);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, num_args,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &kstype, &len);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMFKey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, num_args);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys signer_cert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys num_args);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (KMFKey == NULL && signer_cert == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys len = sizeof (sigAlg);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_attr(KMF_ALGORITHM_INDEX_ATTR, attrlist, num_args,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &sigAlg, &len);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys /* We only need the algorithm index if we don't have a signer cert. */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (ret != KMF_OK && signer_cert == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys indata = kmf_get_attr_ptr(KMF_DATA_ATTR, attrlist, num_args);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (indata == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys insig = kmf_get_attr_ptr(KMF_IN_SIGN_ATTR, attrlist, num_args);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (insig == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* If the caller passed a signer cert instead of a key use it. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (signer_cert != NULL) {
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll KMF_X509_CERTIFICATE *SignerCert = NULL;
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll
d00756ccb34596a328f8a15d1965da5412d366d0wyllys policy = handle->policy;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = check_key_usage(handle, signer_cert, KMF_KU_SIGN_DATA);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll /* Decode the signer cert so we can get the SPKI data */
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll ret = DerDecodeSignedCertificate(signer_cert, &SignerCert);
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll if (ret != KMF_OK)
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll return (ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll /* If no algorithm specified, use the certs signature alg */
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll if (sigAlg == KMF_ALGID_NONE)
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll sigAlg = x509_algoid_to_algid(CERT_ALG_OID(SignerCert));
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll if (sigAlg == KMF_ALGID_NONE) {
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll kmf_free_signed_cert(SignerCert);
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll free(SignerCert);
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll return (KMF_ERR_BAD_ALGORITHM);
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll }
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll /*
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll * Verify the data locally (i.e. using PKCS#11).
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll * The verify operation uses a public key and does not
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll * require access to a specific keystore. Save time
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll * (and code) by just using the frameworks implementation
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll * of the verify operation using crypto framework
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll * APIs.
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll */
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll ret = PKCS_VerifyData(handle, sigAlg,
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll &SignerCert->certificate.subjectPublicKeyInfo,
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll indata, insig);
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll kmf_free_signed_cert(SignerCert);
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll free(SignerCert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Retrieve public key data from keystore */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys plugin = FindPlugin(handle, kstype);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (plugin != NULL &&
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys plugin->funclist->EncodePubkeyData != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = plugin->funclist->EncodePubkeyData(handle,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMFKey, &derkey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_PLUGIN_NOTFOUND);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = DerDecodeSPKI(&derkey, &spki);
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll if (ret == KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = PKCS_VerifyData(handle, sigAlg, &spki,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys indata, insig);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (derkey.Data != NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(derkey.Data);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_algoid(&spki.algorithm);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_data(&spki.subjectPublicKey);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Name: kmf_verify_cert
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Description:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * This function verifies that the a certificate was signed
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * using a specific private key and that the certificate has not
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * been altered since it was signed using that private key
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * The public key used for verification may be given in the
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * attribute list as a KMF_KEY_HANDLE or the caller may give
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * just the signing certificate (as KMF_SIGNER_CERT_DATA_ATTR)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * from which the public key needed for verification can be
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * derived.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Parameters:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * handle(input) - opaque handle for KMF session
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * numattr - number of attributes in the list
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * attrlist - KMF_ATTRIBUTES
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Returns:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * A KMF_RETURN value indicating success or specifying a particular
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * error condition. The value KMF_OK indicates success. All other
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * values represent an error condition.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_verify_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN ret;
6b35cb3cf158584a9408d44b9b6796564e8e1882Richard PALO KMF_DATA derkey = { 0, NULL };
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_PLUGIN *plugin;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_HANDLE *KMFKey;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *CertToBeVerified;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *SignerCert;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE_TESTER required_attrs[] = {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)}
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys };
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int num_req_attrs = sizeof (required_attrs) /
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sizeof (KMF_ATTRIBUTE_TESTER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CLEAR_ERROR(handle, ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = test_attributes(num_req_attrs, required_attrs,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys 0, NULL, numattr, attrlist);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMFKey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SignerCert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Caller must provide at least a key handle or a cert to use
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * as the "key" for verification.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (KMFKey == NULL && SignerCert == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CertToBeVerified = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (CertToBeVerified == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (SignerCert != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = verify_cert_with_cert(handle, CertToBeVerified,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys SignerCert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * The keystore must extract the pubkey data because
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * the framework doesn't have access to the raw key bytes
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * that are needed to construct the DER encoded public
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * key information needed for the verify operation.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys plugin = FindPlugin(handle, KMFKey->kstype);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (plugin != NULL && plugin->funclist->EncodePubkeyData !=
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = plugin->funclist->EncodePubkeyData(handle,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMFKey, &derkey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_PLUGIN_NOTFOUND);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret == KMF_OK && derkey.Length > 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = verify_cert_with_key(handle, &derkey,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CertToBeVerified);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (derkey.Data != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(derkey.Data);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Name: kmf_encrypt
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Description:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Uses the public key from the cert to encrypt the plaintext
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * into the ciphertext.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Parameters:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * handle(input) - opaque handle for KMF session
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * cert(input) - pointer to a DER encoded certificate for encryption
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * by using its public key
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * plaintext(input) - pointer to the plaintext to be encrypted
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * ciphertext(output) - pointer to the ciphertext contains
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * encrypted data
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Returns:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * A KMF_RETURN value indicating success or specifying a particular
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * error condition.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * The value KMF_OK indicates success. All other values represent
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * an error condition.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_encrypt(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret;
02744e811b15322c5f109827a116c33bfe3438b5wyllys KMF_X509_CERTIFICATE *x509cert = NULL;
02744e811b15322c5f109827a116c33bfe3438b5wyllys KMF_X509_SPKI *pubkey;
02744e811b15322c5f109827a116c33bfe3438b5wyllys KMF_OID *alg;
02744e811b15322c5f109827a116c33bfe3438b5wyllys KMF_ALGORITHM_INDEX algid;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *cert;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *plaintext;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *ciphertext;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_POLICY_RECORD *policy;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE_TESTER required_attrs[] = {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA),
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sizeof (KMF_DATA)},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_PLAINTEXT_DATA_ATTR, FALSE, sizeof (KMF_DATA),
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sizeof (KMF_DATA)},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_CIPHERTEXT_DATA_ATTR, FALSE, sizeof (KMF_DATA),
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sizeof (KMF_DATA)}
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys };
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int num_req_attrs = sizeof (required_attrs) /
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sizeof (KMF_ATTRIBUTE_TESTER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CLEAR_ERROR(handle, ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = test_attributes(num_req_attrs, required_attrs,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys 0, NULL, numattr, attrlist);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys plaintext = kmf_get_attr_ptr(KMF_PLAINTEXT_DATA_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ciphertext = kmf_get_attr_ptr(KMF_CIPHERTEXT_DATA_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (cert == NULL || plaintext == NULL || ciphertext == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* check the keyUsage of the certificate */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys policy = handle->policy;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = check_key_usage(handle, cert, KMF_KU_ENCRYPT_DATA);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0)
6adaf03e130142c9de7b6c050f0d0b1df4e73044wyllys ret = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys /* Decode the cert so we can get the SPKI data */
02744e811b15322c5f109827a116c33bfe3438b5wyllys if ((ret = DerDecodeSignedCertificate(cert, &x509cert)) != KMF_OK)
02744e811b15322c5f109827a116c33bfe3438b5wyllys return (ret);
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys /* Get the public key info from the certificate */
02744e811b15322c5f109827a116c33bfe3438b5wyllys pubkey = &x509cert->certificate.subjectPublicKeyInfo;
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys /* Use the algorithm in SPKI to encrypt data */
02744e811b15322c5f109827a116c33bfe3438b5wyllys alg = &pubkey->algorithm.algorithm;
02744e811b15322c5f109827a116c33bfe3438b5wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys algid = x509_algoid_to_algid(alg);
02744e811b15322c5f109827a116c33bfe3438b5wyllys
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll /* [EC]DSA does not support encrypt */
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll if (algid == KMF_ALGID_DSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll algid == KMF_ALGID_SHA1WithDSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll algid == KMF_ALGID_SHA256WithDSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll algid == KMF_ALGID_SHA1WithECDSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll algid == KMF_ALGID_SHA256WithECDSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll algid == KMF_ALGID_SHA384WithECDSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll algid == KMF_ALGID_SHA512WithECDSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll algid == KMF_ALGID_NONE) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_signed_cert(x509cert);
02744e811b15322c5f109827a116c33bfe3438b5wyllys free(x509cert);
02744e811b15322c5f109827a116c33bfe3438b5wyllys return (KMF_ERR_BAD_ALGORITHM);
02744e811b15322c5f109827a116c33bfe3438b5wyllys }
02744e811b15322c5f109827a116c33bfe3438b5wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Encrypt using the crypto framework (not the KMF plugin mechanism).
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys */
02744e811b15322c5f109827a116c33bfe3438b5wyllys ret = PKCS_EncryptData(handle, algid, pubkey, plaintext, ciphertext);
02744e811b15322c5f109827a116c33bfe3438b5wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_signed_cert(x509cert);
02744e811b15322c5f109827a116c33bfe3438b5wyllys free(x509cert);
02744e811b15322c5f109827a116c33bfe3438b5wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Name: kmf_decrypt
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Description:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Uses the private key associated with the cert to decrypt
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * the ciphertext into the plaintext.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_decrypt(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509_CERTIFICATE *x509cert = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509_SPKI *spki_ptr;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_PLUGIN *plugin;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_ALGORITHM_INDEX AlgorithmId;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE *new_attrlist = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int new_numattr;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *cert = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *ciphertext = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *plaintext = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEY_HANDLE prikey;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_POLICY_RECORD *policy;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE_TESTER required_attrs[] = {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_PLAINTEXT_DATA_ATTR, FALSE, sizeof (KMF_DATA),
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sizeof (KMF_DATA)},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_CIPHERTEXT_DATA_ATTR, FALSE, sizeof (KMF_DATA),
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sizeof (KMF_DATA)},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys };
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int num_req_attrs = sizeof (required_attrs) /
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sizeof (KMF_ATTRIBUTE_TESTER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CLEAR_ERROR(handle, ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = test_attributes(num_req_attrs, required_attrs,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys 0, NULL, numattr, attrlist);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Get the cert and check its keyUsage */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (cert == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* check the keyUsage of the certificate */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys policy = handle->policy;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = check_key_usage(handle, cert, KMF_KU_ENCRYPT_DATA);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0)
6adaf03e130142c9de7b6c050f0d0b1df4e73044wyllys ret = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Get the ciphertext and plaintext attributes */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ciphertext = kmf_get_attr_ptr(KMF_CIPHERTEXT_DATA_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ciphertext == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys plaintext = kmf_get_attr_ptr(KMF_PLAINTEXT_DATA_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (plaintext == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Retrieve the private key from the keystore based on
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * the certificate.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = setup_findprikey_attrlist(attrlist, numattr, &new_attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &new_numattr, &prikey, cert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_find_prikey_by_cert(handle, new_numattr, new_attrlist);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Decode the cert so we can get the alogorithm */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = DerDecodeSignedCertificate(cert, &x509cert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys spki_ptr = &x509cert->certificate.subjectPublicKeyInfo;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys AlgorithmId = x509_algoid_to_algid((KMF_OID *)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys &spki_ptr->algorithm.algorithm);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll /* [EC]DSA does not support decrypt */
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll if (AlgorithmId == KMF_ALGID_DSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll AlgorithmId == KMF_ALGID_ECDSA) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_BAD_ALGORITHM;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys plugin = FindPlugin(handle, prikey.kstype);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (plugin != NULL && plugin->funclist->DecryptData != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = plugin->funclist->DecryptData(handle,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &prikey, &spki_ptr->algorithm.algorithm,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ciphertext, plaintext);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_PLUGIN_NOTFOUND;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyscleanup:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (new_attrlist != NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys free(new_attrlist);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_kmf_key(handle, &prikey);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_signed_cert(x509cert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(x509cert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_store_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_PLUGIN *plugin;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEYSTORE_TYPE kstype;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE_TESTER required_attrs[] = {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys };
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int num_req_attrs = sizeof (required_attrs) /
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sizeof (KMF_ATTRIBUTE_TESTER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CLEAR_ERROR(handle, ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = test_attributes(num_req_attrs, required_attrs,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys 0, NULL, numattr, attrlist);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &kstype, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys plugin = FindPlugin(handle, kstype);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (plugin == NULL || plugin->funclist->StoreCert == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_PLUGIN_NOTFOUND);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (plugin->funclist->StoreCert(handle, numattr, attrlist));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_import_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_PLUGIN *plugin;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEYSTORE_TYPE kstype;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE_TESTER required_attrs[] = {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_CERT_FILENAME_ATTR, TRUE, 1, 0},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys };
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int num_req_attrs = sizeof (required_attrs) /
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sizeof (KMF_ATTRIBUTE_TESTER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CLEAR_ERROR(handle, ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = test_attributes(num_req_attrs, required_attrs, 0, NULL,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr, attrlist);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &kstype, NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys plugin = FindPlugin(handle, kstype);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (plugin == NULL || plugin->funclist->ImportCert == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_PLUGIN_NOTFOUND);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (plugin->funclist->ImportCert(handle, numattr, attrlist));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_delete_cert_from_keystore(KMF_HANDLE_T handle, int numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_PLUGIN *plugin;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEYSTORE_TYPE kstype;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE_TESTER required_attrs[] = {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys };
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int num_req_attrs = sizeof (required_attrs) /
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sizeof (KMF_ATTRIBUTE_TESTER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CLEAR_ERROR(handle, ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = test_attributes(num_req_attrs, required_attrs,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys 0, NULL, numattr, attrlist);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &kstype, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys plugin = FindPlugin(handle, kstype);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (plugin == NULL || plugin->funclist->DeleteCert == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_PLUGIN_NOTFOUND);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (plugin->funclist->DeleteCert(handle, numattr, attrlist));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * This function gets the CRL URI entries from the certificate's Distribution
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * points extension, and downloads the CRL file. The function also returns
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * the URI string and the format of the CRL file. The caller should free
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * the space allocated for the returned URI string.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic KMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyscert_get_crl(KMF_HANDLE_T handle, const KMF_DATA *cert, char *proxy,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *filename, char **retn_uri, KMF_ENCODE_FORMAT *format)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509EXT_CRLDISTPOINTS crl_dps;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys boolean_t done = B_FALSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char uri[1024];
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *proxyname = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *proxy_port_s = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int proxy_port = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int i, j;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *path = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (handle == NULL || cert == NULL || filename == NULL ||
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys retn_uri == NULL || format == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Get the proxy info */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (proxy != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys proxyname = strtok(proxy, ":");
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys proxy_port_s = strtok(NULL, "\0");
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (proxy_port_s != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys proxy_port = strtol(proxy_port_s, NULL, 0);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys proxy_port = 8080; /* default */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Get the CRL URI from the certificate's CRL Distribution
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Points extension and download the CRL file. There maybe more than
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * one CRL URI entries in the DP extension, so we will continue
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * the process until a CRL file is sucessfully downloaded or we
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * are running out the CRL URI's.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_cert_crl_dist_pts((const KMF_DATA *)cert,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys &crl_dps);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys for (i = 0; i < crl_dps.number; i++) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_CRL_DIST_POINT *dp = &(crl_dps.dplist[i]);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_GENERALNAMES *fullname = &(dp->name.full_name);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_DATA *data;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (done)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys for (j = 0; j < fullname->number; j++) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys data = &(fullname->namelist[j].name);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memcpy(uri, data->Data, data->Length);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys uri[data->Length] = '\0';
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_download_crl(handle, uri, proxyname,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys proxy_port, 30, filename, format);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret == KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys done = B_TRUE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys path = malloc(data->Length + 1);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (path == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_MEMORY;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) strncpy(path, uri, data->Length);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *retn_uri = path;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysout:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_crl_dist_pts(&crl_dps);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllysstatic KMF_RETURN
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllyscheck_crl_validity(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE kstype,
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys char *crlfilename, KMF_DATA *issuer_cert)
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys{
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys KMF_RETURN ret = KMF_OK;
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys KMF_POLICY_RECORD *policy;
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys if (handle == NULL)
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys return (KMF_ERR_BAD_PARAMETER);
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys policy = handle->policy;
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys /*
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys * NSS CRL is not file based, and its signature
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys * has been verified during CRL import.
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys * We only check CRL validity for file-based CRLs,
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys * NSS handles these checks internally.
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys */
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys if (kstype == KMF_KEYSTORE_NSS)
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys return (KMF_OK);
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys /*
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys * Check the CRL signature if needed.
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys */
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys if (!policy->validation_info.crl_info.ignore_crl_sign) {
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys ret = kmf_verify_crl_file(handle, crlfilename,
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys issuer_cert);
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys if (ret != KMF_OK)
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys return (ret);
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys }
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys /*
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys * Check the CRL validity if needed.
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys */
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys if (!policy->validation_info.crl_info.ignore_crl_date) {
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys ret = kmf_check_crl_date(handle, crlfilename);
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys if (ret != KMF_OK)
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys return (ret);
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys }
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys return (ret);
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys}
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyscert_crl_check(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE *kstype,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *user_cert, KMF_DATA *issuer_cert)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_POLICY_RECORD *policy;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE attrlist[16];
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int numattr = 0;
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys int fd;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys boolean_t crlchk;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char user_certfile[MAXPATHLEN];
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char crlfile_tmp[MAXPATHLEN];
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *basefilename = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *dir = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *crlfilename = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *proxy = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *uri = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_ENCODE_FORMAT format;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL || kstype == NULL || user_cert == NULL ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys issuer_cert == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
431deaa01ac039d796fdfaf86b909a75e7d9ac48hylee if (!is_valid_keystore_type(*kstype))
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys policy = handle->policy;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * If the get-crl-uri policy is TRUE, then download the CRL
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * file first. The newly downloaded file will be stored in the
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * NSS internal database for NSS keystore, and stored in a file for
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * the File-based CRL plugins (OpenSSL and PKCS11).
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * For file-based plugins, if the get-crl-uri policy is FALSE,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * then the caller should provide a CRL file in the policy.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Also, after this step is done, the "crlfilename" variable should
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * contain the proper CRL file to be used for the rest of CRL
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * validation process.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys basefilename = policy->validation_info.crl_info.basefilename;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys dir = policy->validation_info.crl_info.directory;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (policy->validation_info.crl_info.get_crl_uri) {
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys /*
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys * Check to see if we already have this CRL.
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys */
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys if (basefilename == NULL)
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys basefilename = basename(uri);
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys crlfilename = get_fullpath(dir == NULL ? "./" : dir,
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys basefilename);
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys if (crlfilename == NULL) {
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys ret = KMF_ERR_BAD_CRLFILE;
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys goto cleanup;
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys }
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys /*
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys * If this file already exists and is valid, we don't need to
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys * download a new one.
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys */
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys if ((fd = open(crlfilename, O_RDONLY)) != -1) {
85b5e720b6ec2a46e28202e7e7be913a889bca0ewyllys (void) close(fd);
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys if ((ret = check_crl_validity(handle, *kstype,
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys crlfilename, issuer_cert)) == KMF_OK) {
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys goto checkcrl;
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys }
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys }
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Create a temporary file to hold the new CRL file initially.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) strlcpy(crlfile_tmp, CRLFILE_TEMPNAME,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys sizeof (crlfile_tmp));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (mkstemp(crlfile_tmp) == -1) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_INTERNAL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Get the URI entry from the certificate's CRL distribution
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * points extension and download the CRL file.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys proxy = policy->validation_info.crl_info.proxy;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = cert_get_crl(handle, user_cert, proxy, crlfile_tmp,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys &uri, &format);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) unlink(crlfile_tmp);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys /*
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys * If we just downloaded one, make sure it is OK.
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys */
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys if ((ret = check_crl_validity(handle, *kstype, crlfile_tmp,
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys issuer_cert)) != KMF_OK)
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Cache the CRL file. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (*kstype == KMF_KEYSTORE_NSS) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * For NSS keystore, import this CRL file into th
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * internal database.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEYSTORE_TYPE_ATTR, kstype, sizeof (kstype));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_CRL_FILENAME_ATTR, crlfile_tmp,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys strlen(crlfile_tmp));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys crlchk = B_FALSE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_CRL_CHECK_ATTR, &crlchk, sizeof (boolean_t));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_import_crl(handle, numattr, attrlist);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) unlink(crlfile_tmp);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rename(crlfile_tmp, crlfilename) == -1) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) unlink(crlfile_tmp);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_WRITE_FILE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * If the get_crl_uri policy is FALSE, for File-based CRL
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * plugins, get the input CRL file from the policy.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (*kstype != KMF_KEYSTORE_NSS) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (basefilename == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_BAD_PARAMETER;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys crlfilename = get_fullpath(dir == NULL ? "./" : dir,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys basefilename);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (crlfilename == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_BAD_CRLFILE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys /*
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys * Make sure this CRL is still valid.
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys */
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys if ((ret = check_crl_validity(handle, *kstype,
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys crlfilename, issuer_cert)) != KMF_OK)
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllyscheckcrl:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Check the CRL revocation for the certificate.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kstype, sizeof (kstype));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys switch (*kstype) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case KMF_KEYSTORE_NSS:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_CERT_DATA_ATTR, user_cert, sizeof (KMF_DATA));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr++;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case KMF_KEYSTORE_PK11TOKEN:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys case KMF_KEYSTORE_OPENSSL:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Create temporary file to hold the user certificate.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) strlcpy(user_certfile, CERTFILE_TEMPNAME,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys sizeof (user_certfile));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (mkstemp(user_certfile) == -1) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_INTERNAL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_create_cert_file(user_cert, KMF_FORMAT_ASN1,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys user_certfile);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_CERT_FILENAME_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys user_certfile, strlen(user_certfile));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_CRL_FILENAME_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys crlfilename, strlen(crlfilename));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr++;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys default:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_PLUGIN_NOTFOUND;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_find_cert_in_crl(handle, numattr, attrlist);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret == KMF_ERR_NOT_REVOKED) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyscleanup:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) unlink(user_certfile);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (crlfilename != NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(crlfilename);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (uri != NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(uri);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyscert_ocsp_check(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE *kstype,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *user_cert, KMF_DATA *issuer_cert, KMF_DATA *response,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *slotlabel, char *dirpath)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_POLICY_RECORD *policy;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_DATA *new_response = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys boolean_t ignore_response_sign = B_FALSE;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys uint32_t ltime = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_DATA *signer_cert = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_BIGINT sernum = { NULL, 0 };
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int response_status;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int reason;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int cert_status;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE attrlist[32];
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int numattr;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL || kstype == NULL || user_cert == NULL ||
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys issuer_cert == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys policy = handle->policy;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Get the response lifetime from policy.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (policy->VAL_OCSP_BASIC.response_lifetime != NULL &&
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (str2lifetime(policy->VAL_OCSP_BASIC.response_lifetime, &ltime)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys < 0))
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_OCSP_RESPONSE_LIFETIME);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Get the ignore_response_sign policy.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * If ignore_response_sign is FALSE, we need to verify the response.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Find the OCSP Responder certificate if it is specified in the OCSP
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * policy.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ignore_response_sign = policy->VAL_OCSP_BASIC.ignore_response_sign;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ignore_response_sign == B_FALSE &&
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys policy->VAL_OCSP.has_resp_cert == B_TRUE) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *signer_name;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509_DER_CERT signer_retrcert;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys uchar_t *bytes = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys size_t bytelen;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys uint32_t num = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE fc_attrlist[16];
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int fc_numattr = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *dir = "./";
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (policy->VAL_OCSP_RESP_CERT.name == NULL ||
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys policy->VAL_OCSP_RESP_CERT.serial == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_POLICY_NOT_FOUND);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys signer_cert = malloc(sizeof (KMF_DATA));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (signer_cert == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_MEMORY;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memset(signer_cert, 0, sizeof (KMF_DATA));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys signer_name = policy->VAL_OCSP_RESP_CERT.name;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_hexstr_to_bytes(
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (uchar_t *)policy->VAL_OCSP_RESP_CERT.serial,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys &bytes, &bytelen);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK || bytes == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_OCSP_POLICY;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys sernum.val = bytes;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys sernum.len = bytelen;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(fc_attrlist, fc_numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEYSTORE_TYPE_ATTR, kstype,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sizeof (KMF_KEYSTORE_TYPE));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys fc_numattr++;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(fc_attrlist, fc_numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_SUBJECT_NAME_ATTR, signer_name, strlen(signer_name));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys fc_numattr++;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_BIGINT_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &sernum, sizeof (KMF_BIGINT));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys fc_numattr++;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (*kstype == KMF_KEYSTORE_NSS && slotlabel != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(fc_attrlist, fc_numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_TOKEN_LABEL_ATTR, slotlabel,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys strlen(slotlabel));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys fc_numattr++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (*kstype == KMF_KEYSTORE_OPENSSL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (dirpath == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(fc_attrlist, fc_numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DIRPATH_ATTR, dir, strlen(dir));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys fc_numattr++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(fc_attrlist, fc_numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DIRPATH_ATTR, dirpath,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys strlen(dirpath));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys fc_numattr++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys num = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(fc_attrlist, fc_numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_COUNT_ATTR, &num, sizeof (uint32_t));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys fc_numattr++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_find_cert(handle, fc_numattr, fc_attrlist);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK || num != 1) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (num == 0)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_CERT_NOT_FOUND;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (num > 0)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_CERT_MULTIPLE_FOUND;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memset(&signer_retrcert, 0, sizeof (KMF_X509_DER_CERT));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(fc_attrlist, fc_numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_X509_DER_CERT_ATTR, &signer_retrcert,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sizeof (KMF_X509_DER_CERT));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys fc_numattr++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_find_cert(handle, fc_numattr, fc_attrlist);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret == KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys signer_cert->Length =
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys signer_retrcert.certificate.Length;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys signer_cert->Data = signer_retrcert.certificate.Data;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * If the caller provides an OCSP response, we will use it directly.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Otherwise, we will try to fetch an OCSP response for the given
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * certificate now.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (response == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys new_response = (KMF_DATA *) malloc(sizeof (KMF_DATA));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (new_response == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_MEMORY;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys new_response->Data = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys new_response->Length = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_ocsp_for_cert(handle, user_cert, issuer_cert,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys new_response);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Process the OCSP response and retrieve the certificate status.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, numattr, KMF_ISSUER_CERT_DATA_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys issuer_cert, sizeof (KMF_DATA));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, numattr, KMF_USER_CERT_DATA_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys user_cert, sizeof (KMF_DATA));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (signer_cert != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_SIGNER_CERT_DATA_ATTR, user_cert, sizeof (KMF_DATA));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, numattr, KMF_OCSP_RESPONSE_DATA_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys response == NULL ? new_response : response, sizeof (KMF_DATA));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, numattr, KMF_RESPONSE_LIFETIME_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &ltime, sizeof (uint32_t));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_IGNORE_RESPONSE_SIGN_ATTR, &ignore_response_sign,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sizeof (boolean_t));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_OCSP_RESPONSE_STATUS_ATTR, &response_status, sizeof (int));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_OCSP_RESPONSE_REASON_ATTR, &reason, sizeof (int));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_OCSP_RESPONSE_CERT_STATUS_ATTR, &cert_status, sizeof (int));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_ocsp_status_for_cert(handle, numattr, attrlist);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret == KMF_OK) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys switch (cert_status) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case OCSP_GOOD:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case OCSP_UNKNOWN:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_OCSP_UNKNOWN_CERT;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case OCSP_REVOKED:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_OCSP_REVOKED;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysout:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (new_response) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_data(new_response);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(new_response);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (signer_cert) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_data(signer_cert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(signer_cert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (sernum.val != NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(sernum.val);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic KMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyscert_ku_check(KMF_HANDLE_T handle, KMF_DATA *cert)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_POLICY_RECORD *policy;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509EXT_KEY_USAGE keyusage;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret = KMF_OK;
31558a356540225e286233d63c122a35e4a4bd22wyllys KMF_X509EXT_BASICCONSTRAINTS constraint;
31558a356540225e286233d63c122a35e4a4bd22wyllys KMF_BOOL critical = B_FALSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (handle == NULL || cert == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys policy = handle->policy;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memset(&keyusage, 0, sizeof (keyusage));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_cert_ku(cert, &keyusage);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret == KMF_ERR_EXTENSION_NOT_FOUND) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (policy->ku_bits) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* keyusage is not set in cert but is set in policy */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_KEYUSAGE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* no keyusage set in both cert and policy */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_OK);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* real error */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
31558a356540225e286233d63c122a35e4a4bd22wyllys /*
31558a356540225e286233d63c122a35e4a4bd22wyllys * If KeyCertSign is set, then constraints.cA must be TRUE and
31558a356540225e286233d63c122a35e4a4bd22wyllys * marked critical.
31558a356540225e286233d63c122a35e4a4bd22wyllys */
31558a356540225e286233d63c122a35e4a4bd22wyllys if ((keyusage.KeyUsageBits & KMF_keyCertSign)) {
31558a356540225e286233d63c122a35e4a4bd22wyllys (void) memset(&constraint, 0, sizeof (constraint));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_cert_basic_constraint(cert,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &critical, &constraint);
31558a356540225e286233d63c122a35e4a4bd22wyllys
31558a356540225e286233d63c122a35e4a4bd22wyllys if (ret != KMF_OK) {
31558a356540225e286233d63c122a35e4a4bd22wyllys /* real error */
31558a356540225e286233d63c122a35e4a4bd22wyllys return (ret);
31558a356540225e286233d63c122a35e4a4bd22wyllys }
31558a356540225e286233d63c122a35e4a4bd22wyllys if (!constraint.cA || !critical)
31558a356540225e286233d63c122a35e4a4bd22wyllys return (KMF_ERR_KEYUSAGE);
31558a356540225e286233d63c122a35e4a4bd22wyllys }
31558a356540225e286233d63c122a35e4a4bd22wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Rule: if the KU bit is set in policy, the corresponding KU bit
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * must be set in the certificate (but not vice versa).
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((policy->ku_bits & keyusage.KeyUsageBits) == policy->ku_bits) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_OK);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_KEYUSAGE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic KMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyscert_eku_check(KMF_HANDLE_T handle, KMF_DATA *cert)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_POLICY_RECORD *policy;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509EXT_EKU eku;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys uint16_t cert_eku = 0, policy_eku = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int i;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (handle == NULL || cert == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys policy = handle->policy;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
31558a356540225e286233d63c122a35e4a4bd22wyllys /*
31558a356540225e286233d63c122a35e4a4bd22wyllys * If the policy does not have any EKU, then there is
31558a356540225e286233d63c122a35e4a4bd22wyllys * nothing further to check.
31558a356540225e286233d63c122a35e4a4bd22wyllys */
31558a356540225e286233d63c122a35e4a4bd22wyllys if (policy->eku_set.eku_count == 0)
31558a356540225e286233d63c122a35e4a4bd22wyllys return (KMF_OK);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_cert_eku(cert, &eku);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((ret != KMF_ERR_EXTENSION_NOT_FOUND) && (ret != KMF_OK)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* real error */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret == KMF_ERR_EXTENSION_NOT_FOUND) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys cert_eku = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Build the EKU bitmap based on the certificate
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys for (i = 0; i < eku.nEKUs; i++) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (IsEqualOid(&eku.keyPurposeIdList[i],
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (KMF_OID *)&KMFOID_PKIX_KP_ServerAuth)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys cert_eku |= KMF_EKU_SERVERAUTH;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (IsEqualOid(&eku.keyPurposeIdList[i],
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (KMF_OID *)&KMFOID_PKIX_KP_ClientAuth)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys cert_eku |= KMF_EKU_CLIENTAUTH;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (IsEqualOid(&eku.keyPurposeIdList[i],
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (KMF_OID *)&KMFOID_PKIX_KP_CodeSigning)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys cert_eku |= KMF_EKU_CODESIGNING;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (IsEqualOid(&eku.keyPurposeIdList[i],
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (KMF_OID *)&KMFOID_PKIX_KP_EmailProtection)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys cert_eku |= KMF_EKU_EMAIL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (IsEqualOid(&eku.keyPurposeIdList[i],
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (KMF_OID *)&KMFOID_PKIX_KP_TimeStamping)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys cert_eku |= KMF_EKU_TIMESTAMP;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (IsEqualOid(&eku.keyPurposeIdList[i],
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (KMF_OID *)&KMFOID_PKIX_KP_OCSPSigning)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys cert_eku |= KMF_EKU_OCSPSIGNING;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (!policy->ignore_unknown_ekus) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_KEYUSAGE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } /* for */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
31558a356540225e286233d63c122a35e4a4bd22wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Build the EKU bitmap based on the policy
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys for (i = 0; i < policy->eku_set.eku_count; i++) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (IsEqualOid(&policy->eku_set.ekulist[i],
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (KMF_OID *)&KMFOID_PKIX_KP_ServerAuth)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys policy_eku |= KMF_EKU_SERVERAUTH;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (IsEqualOid(&policy->eku_set.ekulist[i],
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (KMF_OID *)&KMFOID_PKIX_KP_ClientAuth)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys policy_eku |= KMF_EKU_CLIENTAUTH;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (IsEqualOid(&policy->eku_set.ekulist[i],
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (KMF_OID *)&KMFOID_PKIX_KP_CodeSigning)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys policy_eku |= KMF_EKU_CODESIGNING;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (IsEqualOid(&policy->eku_set.ekulist[i],
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (KMF_OID *)&KMFOID_PKIX_KP_EmailProtection)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys policy_eku |= KMF_EKU_EMAIL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (IsEqualOid(&policy->eku_set.ekulist[i],
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (KMF_OID *)&KMFOID_PKIX_KP_TimeStamping)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys policy_eku |= KMF_EKU_TIMESTAMP;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (IsEqualOid(&policy->eku_set.ekulist[i],
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (KMF_OID *)&KMFOID_PKIX_KP_OCSPSigning)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys policy_eku |= KMF_EKU_OCSPSIGNING;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (!policy->ignore_unknown_ekus) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_KEYUSAGE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } /* for */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Rule: if the EKU OID is set in policy, the corresponding EKU OID
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * must be set in the certificate (but not vice versa).
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((policy_eku & cert_eku) == policy_eku) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_OK);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_KEYUSAGE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysfind_issuer_cert(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE *kstype,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *user_issuer, KMF_DATA *issuer_cert,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *slotlabel, char *dirpath)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509_DER_CERT *certlist = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys uint32_t i, num = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys time_t t_notbefore;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys time_t t_notafter;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys time_t latest;
6b35cb3cf158584a9408d44b9b6796564e8e1882Richard PALO KMF_DATA tmp_cert = { 0, NULL };
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE fc_attrlist[16];
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int fc_numattr = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *dir = "./";
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL || kstype == NULL || user_issuer == NULL ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys issuer_cert == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
431deaa01ac039d796fdfaf86b909a75e7d9ac48hylee if (!is_valid_keystore_type(*kstype))
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_KEYSTORE_TYPE_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kstype, sizeof (KMF_KEYSTORE_TYPE));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys fc_numattr++;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_SUBJECT_NAME_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys user_issuer, strlen(user_issuer));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys fc_numattr++;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (*kstype == KMF_KEYSTORE_NSS && slotlabel != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(fc_attrlist, fc_numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_TOKEN_LABEL_ATTR, slotlabel, strlen(slotlabel));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys fc_numattr++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (*kstype == KMF_KEYSTORE_OPENSSL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (dirpath == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(fc_attrlist, fc_numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DIRPATH_ATTR, dir, strlen(dir));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys fc_numattr++;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(fc_attrlist, fc_numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DIRPATH_ATTR, dirpath, strlen(dirpath));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys fc_numattr++;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys num = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(fc_attrlist, fc_numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_COUNT_ATTR, &num, sizeof (uint32_t));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys fc_numattr++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_find_cert(handle, fc_numattr, fc_attrlist);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret == KMF_OK && num > 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys certlist = (KMF_X509_DER_CERT *)malloc(num *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys sizeof (KMF_X509_DER_CERT));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (certlist == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_MEMORY;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(fc_attrlist, fc_numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_X509_DER_CERT_ATTR, certlist,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys sizeof (KMF_X509_DER_CERT));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys fc_numattr++;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_find_cert(handle, fc_numattr, fc_attrlist);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(certlist);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys certlist = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (num == 1) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* only one issuer cert is found */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys tmp_cert.Length = certlist[0].certificate.Length;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys tmp_cert.Data = certlist[0].certificate.Data;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * More than one issuer certs are found. We will
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * pick the latest one.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys latest = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys for (i = 0; i < num; i++) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_cert_validity(&certlist[i].certificate,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys &t_notbefore, &t_notafter);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_VALIDITY_PERIOD;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (t_notbefore > latest) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys tmp_cert.Length =
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys certlist[i].certificate.Length;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys tmp_cert.Data =
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys certlist[i].certificate.Data;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys latest = t_notbefore;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys issuer_cert->Length = tmp_cert.Length;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys issuer_cert->Data = malloc(tmp_cert.Length);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (issuer_cert->Data == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_MEMORY;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memcpy(issuer_cert->Data, tmp_cert.Data,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys tmp_cert.Length);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysout:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (certlist != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys for (i = 0; i < num; i++)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_kmf_cert(handle, &certlist[i]);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(certlist);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysfind_ta_cert(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE *kstype,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *ta_cert, KMF_X509_NAME *user_issuerDN,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *slotlabel, char *dirpath)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_POLICY_RECORD *policy;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys uint32_t num = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *ta_name;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_BIGINT serial = { NULL, 0 };
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys uchar_t *bytes = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys size_t bytelen;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509_DER_CERT ta_retrCert;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *ta_subject = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509_NAME ta_subjectDN;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE fc_attrlist[16];
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int fc_numattr = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *dir = "./";
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL || kstype == NULL || ta_cert == NULL ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys user_issuerDN == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
431deaa01ac039d796fdfaf86b909a75e7d9ac48hylee if (!is_valid_keystore_type(*kstype))
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Get the TA name and serial number from the policy */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys policy = handle->policy;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ta_name = policy->ta_name;
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll /*
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll * Use name and serial from policy.
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_hexstr_to_bytes((uchar_t *)policy->ta_serial,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys &bytes, &bytelen);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK || bytes == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_TA_POLICY;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys serial.val = bytes;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys serial.len = bytelen;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* set up fc_attrlist for kmf_find_cert */
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll kmf_set_attr_at_index(fc_attrlist,
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll fc_numattr++, KMF_BIGINT_ATTR,
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll &serial, sizeof (KMF_BIGINT));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll kmf_set_attr_at_index(fc_attrlist,
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll fc_numattr++, KMF_SUBJECT_NAME_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ta_name, strlen(ta_name));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll kmf_set_attr_at_index(fc_attrlist, fc_numattr++, KMF_KEYSTORE_TYPE_ATTR,
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll kstype, sizeof (KMF_KEYSTORE_TYPE));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (*kstype == KMF_KEYSTORE_NSS && slotlabel != NULL) {
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll kmf_set_attr_at_index(fc_attrlist, fc_numattr++,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_TOKEN_LABEL_ATTR, slotlabel, strlen(slotlabel));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (*kstype == KMF_KEYSTORE_OPENSSL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (dirpath == NULL) {
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll kmf_set_attr_at_index(fc_attrlist, fc_numattr++,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DIRPATH_ATTR, dir, strlen(dir));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll kmf_set_attr_at_index(fc_attrlist, fc_numattr++,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DIRPATH_ATTR, dirpath, strlen(dirpath));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys num = 0;
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll kmf_set_attr_at_index(fc_attrlist, fc_numattr++,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_COUNT_ATTR, &num, sizeof (uint32_t));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_find_cert(handle, fc_numattr, fc_attrlist);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK || num != 1) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (num == 0)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_CERT_NOT_FOUND;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (num > 1)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_CERT_MULTIPLE_FOUND;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(fc_attrlist, fc_numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_X509_DER_CERT_ATTR, &ta_retrCert, sizeof (KMF_X509_DER_CERT));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys fc_numattr++;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_find_cert(handle, fc_numattr, fc_attrlist);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret == KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ta_cert->Length = ta_retrCert.certificate.Length;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ta_cert->Data = malloc(ta_retrCert.certificate.Length);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ta_cert->Data == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_MEMORY;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memcpy(ta_cert->Data, ta_retrCert.certificate.Data,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ta_retrCert.certificate.Length);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * The found TA's name must be matching with issuer name in
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * subscriber's certificate.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memset(&ta_subjectDN, 0, sizeof (ta_subjectDN));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_cert_subject_str(handle, ta_cert, &ta_subject);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_dn_parser(ta_subject, &ta_subjectDN);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (kmf_compare_rdns(user_issuerDN, &ta_subjectDN) != 0)
31558a356540225e286233d63c122a35e4a4bd22wyllys ret = KMF_ERR_CERT_NOT_FOUND;
31558a356540225e286233d63c122a35e4a4bd22wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_dn(&ta_subjectDN);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
31558a356540225e286233d63c122a35e4a4bd22wyllys /* Make sure the TA cert has the correct extensions */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (ret == KMF_OK) {
31558a356540225e286233d63c122a35e4a4bd22wyllys ret = check_key_usage(handle, ta_cert, KMF_KU_SIGN_CERT);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys ret = KMF_OK;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysout:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ta_retrCert.certificate.Data)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_kmf_cert(handle, &ta_retrCert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll if ((ret != KMF_OK))
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll kmf_free_data(ta_cert);
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll if (ta_subject != NULL)
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll free(ta_subject);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (serial.val != NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(serial.val);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_validate_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_KEYSTORE_TYPE *kstype = NULL;
5363b1129db4ee42d2c9736898eab4670580bec7hylee KMF_DATA *pcert = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int *result = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *slotlabel = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *dirpath = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *ocsp_response = NULL;
6b35cb3cf158584a9408d44b9b6796564e8e1882Richard PALO KMF_DATA ta_cert = { 0, NULL };
6b35cb3cf158584a9408d44b9b6796564e8e1882Richard PALO KMF_DATA issuer_cert = { 0, NULL };
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *user_issuer = NULL, *user_subject = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509_NAME user_issuerDN, user_subjectDN;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys boolean_t self_signed = B_FALSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_POLICY_RECORD *policy;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE_TESTER required_attrs[] = {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_VALIDATE_RESULT_ATTR, FALSE, 1, sizeof (int)}
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys };
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int num_req_attrs = sizeof (required_attrs) /
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sizeof (KMF_ATTRIBUTE_TESTER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CLEAR_ERROR(handle, ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = test_attributes(num_req_attrs, required_attrs,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys 0, NULL, numattr, attrlist);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys policy = handle->policy;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Get the attribute values */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kstype = kmf_get_attr_ptr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pcert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys result = kmf_get_attr_ptr(KMF_VALIDATE_RESULT_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (kstype == NULL || pcert == NULL || result == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys slotlabel = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ocsp_response = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_DATA_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Initialize the returned result */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *result = KMF_CERT_VALIDATE_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
5363b1129db4ee42d2c9736898eab4670580bec7hylee * Get the issuer information from the input certficate first.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((ret = kmf_get_cert_issuer_str(handle, pcert,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys &user_issuer)) != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *result |= KMF_CERT_VALIDATE_ERR_USER;
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll } else if ((ret = kmf_dn_parser(user_issuer, &user_issuerDN)) !=
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *result |= KMF_CERT_VALIDATE_ERR_USER;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
5363b1129db4ee42d2c9736898eab4670580bec7hylee /*
5363b1129db4ee42d2c9736898eab4670580bec7hylee * Check if the certificate is a self-signed cert.
5363b1129db4ee42d2c9736898eab4670580bec7hylee */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((ret = kmf_get_cert_subject_str(handle, pcert,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys &user_subject)) != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *result |= KMF_CERT_VALIDATE_ERR_USER;
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll } else if ((ret = kmf_dn_parser(user_subject, &user_subjectDN)) !=
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *result |= KMF_CERT_VALIDATE_ERR_USER;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll if ((*result & KMF_CERT_VALIDATE_ERR_USER) == 0 &&
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll (kmf_compare_rdns(&user_issuerDN, &user_subjectDN)) == 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * this is a self-signed cert
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys self_signed = B_TRUE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_dn(&user_subjectDN);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
02744e811b15322c5f109827a116c33bfe3438b5wyllys * Check KeyUsage extension of the subscriber's certificate
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
5363b1129db4ee42d2c9736898eab4670580bec7hylee ret = cert_ku_check(handle, pcert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *result |= KMF_CERT_VALIDATE_ERR_KEYUSAGE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
02744e811b15322c5f109827a116c33bfe3438b5wyllys * Validate Extended KeyUsage extension
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
5363b1129db4ee42d2c9736898eab4670580bec7hylee ret = cert_eku_check(handle, pcert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *result |= KMF_CERT_VALIDATE_ERR_EXT_KEYUSAGE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
02744e811b15322c5f109827a116c33bfe3438b5wyllys * Check the certificate's validity period
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * This step is needed when "ignore_date" in policy is set
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * to false.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (!policy->ignore_date) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Validate expiration date
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_check_cert_date(handle, pcert);
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *result |= KMF_CERT_VALIDATE_ERR_TIME;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * When "ignore_trust_anchor" in policy is set to FALSE,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * we will try to find the TA cert based on the TA policy
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * attributes.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * TA's subject name (ta_name) and serial number (ta_serial)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * are defined as optional attributes in policy dtd, but they
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * should exist in policy when "ignore_trust_anchor" is set
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * to FALSE. The policy verification code has enforced that.
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll *
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll * The serial number may be NULL if the ta_name == "search"
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll * which indicates that KMF should try to locate the issuer
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll * of the subject cert instead of using a specific TA name.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (policy->ignore_trust_anchor) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto check_revocation;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Verify the signature of subscriber's certificate using
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * TA certificate.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (self_signed) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = verify_cert_with_cert(handle, pcert, pcert);
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll if (ret != KMF_OK)
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll *result |= KMF_CERT_VALIDATE_ERR_SIGNATURE;
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll } else if (user_issuer != NULL) {
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll if (policy->ta_name != NULL &&
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll strcasecmp(policy->ta_name, "search") == 0) {
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll ret = find_issuer_cert(handle, kstype, user_issuer,
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll &issuer_cert, slotlabel, dirpath);
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll if (ret != KMF_OK) {
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll *result |= KMF_CERT_VALIDATE_ERR_TA;
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll } else {
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll ta_cert = issuer_cert; /* used later */
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll }
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll } else {
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll /*
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll * If we didnt find the user_issuer string, we
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll * won't have a "user_issuerDN" either.
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll */
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll ret = find_ta_cert(handle, kstype, &ta_cert,
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll &user_issuerDN, slotlabel, dirpath);
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll }
5363b1129db4ee42d2c9736898eab4670580bec7hylee if (ret != KMF_OK) {
5363b1129db4ee42d2c9736898eab4670580bec7hylee *result |= KMF_CERT_VALIDATE_ERR_TA;
5363b1129db4ee42d2c9736898eab4670580bec7hylee }
5363b1129db4ee42d2c9736898eab4670580bec7hylee
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll /* Only verify if we got the TA without an error. */
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll if ((*result & KMF_CERT_VALIDATE_ERR_TA) == 0) {
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll ret = verify_cert_with_cert(handle, pcert,
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll &ta_cert);
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll if (ret != KMF_OK)
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll *result |= KMF_CERT_VALIDATE_ERR_SIGNATURE;
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll }
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll } else {
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll /* No issuer was found, so we cannot find a trust anchor */
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll *result |= KMF_CERT_VALIDATE_ERR_TA;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyscheck_revocation:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Check certificate revocation
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (self_signed) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* skip revocation checking */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * When CRL or OCSP revocation method is set in the policy,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * we will try to find the issuer of the subscriber certificate
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * using the issuer name of the subscriber certificate. The
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * issuer certificate will be used to do the CRL checking
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * and OCSP checking.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (!(policy->revocation & KMF_REVOCATION_METHOD_CRL) &&
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys !(policy->revocation & KMF_REVOCATION_METHOD_OCSP)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll /*
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll * If we did not find the issuer cert earlier
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll * (when policy->ta_name == "search"), get it here.
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll * We need the issuer cert if the revocation method is
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll * CRL or OCSP.
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll */
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll if (issuer_cert.Length == 0 &&
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll policy->revocation & KMF_REVOCATION_METHOD_CRL ||
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll policy->revocation & KMF_REVOCATION_METHOD_OCSP) {
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll ret = find_issuer_cert(handle, kstype, user_issuer,
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll &issuer_cert, slotlabel, dirpath);
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll if (ret != KMF_OK) {
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll *result |= KMF_CERT_VALIDATE_ERR_ISSUER;
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll if (policy->revocation & KMF_REVOCATION_METHOD_CRL &&
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll (*result & KMF_CERT_VALIDATE_ERR_ISSUER) == 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = cert_crl_check(handle, kstype, pcert, &issuer_cert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *result |= KMF_CERT_VALIDATE_ERR_CRL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll if (policy->revocation & KMF_REVOCATION_METHOD_OCSP &&
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll (*result & KMF_CERT_VALIDATE_ERR_ISSUER) == 0) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = cert_ocsp_check(handle, kstype, pcert, &issuer_cert,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ocsp_response, slotlabel, dirpath);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *result |= KMF_CERT_VALIDATE_ERR_OCSP;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysout:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (user_issuer) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_dn(&user_issuerDN);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(user_issuer);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (user_subject)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(user_subject);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll /*
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll * If we did not copy ta_cert to issuer_cert, free it.
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll */
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll if (issuer_cert.Data &&
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll issuer_cert.Data != ta_cert.Data)
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll kmf_free_data(&issuer_cert);
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll kmf_free_data(&ta_cert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll /*
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll * If we got an error flag from any of the checks,
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll * remap the return code to a generic "CERT_VALIDATION"
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll * error so the caller knows to check the individual flags.
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll */
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll if (*result != 0)
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll ret = KMF_ERR_CERT_VALIDATION;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_create_cert_file(const KMF_DATA *certdata, KMF_ENCODE_FORMAT format,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *certfile)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int fd = -1;
6b35cb3cf158584a9408d44b9b6796564e8e1882Richard PALO KMF_DATA pemdata = { 0, NULL };
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (certdata == NULL || certfile == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (format != KMF_FORMAT_PEM && format != KMF_FORMAT_ASN1)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (format == KMF_FORMAT_PEM) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int len;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_der_to_pem(KMF_CERT,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys certdata->Data, certdata->Length,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &pemdata.Data, &len);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys pemdata.Length = (size_t)len;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((fd = open(certfile, O_CREAT | O_RDWR | O_TRUNC, 0644)) == -1) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_OPEN_FILE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (format == KMF_FORMAT_PEM) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (write(fd, pemdata.Data, pemdata.Length) !=
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys pemdata.Length) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_WRITE_FILE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (write(fd, certdata->Data, certdata->Length) !=
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys certdata->Length) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_WRITE_FILE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyscleanup:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (fd != -1)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) close(fd);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_data(&pemdata);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys/*
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * kmf_is_cert_data
d00756ccb34596a328f8a15d1965da5412d366d0wyllys *
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * Determine if a KMF_DATA buffer contains an encoded X.509 certificate.
d00756ccb34596a328f8a15d1965da5412d366d0wyllys *
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * Return:
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * KMF_OK if it is a certificate
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * KMF_ERR_ENCODING (or other error) if not.
d00756ccb34596a328f8a15d1965da5412d366d0wyllys */
d00756ccb34596a328f8a15d1965da5412d366d0wyllysKMF_RETURN
d00756ccb34596a328f8a15d1965da5412d366d0wyllyskmf_is_cert_data(KMF_DATA *data, KMF_ENCODE_FORMAT *fmt)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys{
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_RETURN rv = KMF_OK;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_X509_CERTIFICATE *x509 = NULL;
6b35cb3cf158584a9408d44b9b6796564e8e1882Richard PALO KMF_DATA oldpem = { 0, NULL };
d00756ccb34596a328f8a15d1965da5412d366d0wyllys uchar_t *d = NULL;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys int len = 0;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (data == NULL || fmt == NULL)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (KMF_ERR_BAD_PARAMETER);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = kmf_get_data_format(data, fmt);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (rv != KMF_OK)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (rv);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys switch (*fmt) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case KMF_FORMAT_ASN1:
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = DerDecodeSignedCertificate(data, &x509);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case KMF_FORMAT_PEM:
d00756ccb34596a328f8a15d1965da5412d366d0wyllys /* Convert to ASN.1 DER first */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = kmf_pem_to_der(data->Data, data->Length,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys &d, &len);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (rv != KMF_OK)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (rv);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys oldpem.Data = d;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys oldpem.Length = len;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = DerDecodeSignedCertificate(&oldpem, &x509);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_free_data(&oldpem);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case KMF_FORMAT_PKCS12:
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case KMF_FORMAT_UNDEF:
d00756ccb34596a328f8a15d1965da5412d366d0wyllys default:
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (KMF_ERR_ENCODING);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (x509 != NULL) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_free_signed_cert(x509);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys free(x509);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (rv);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys}
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_is_cert_file(KMF_HANDLE_T handle, char *filename,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ENCODE_FORMAT *pformat)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_DATA filedata;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CLEAR_ERROR(handle, ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (filename == NULL || pformat == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys ret = kmf_read_input_file(handle, filename, &filedata);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (ret != KMF_OK)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys ret = kmf_is_cert_data(&filedata, pformat);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (ret == KMF_ERR_BAD_CERT_FORMAT)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys ret = KMF_ERR_BAD_CERTFILE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_free_data(&filedata);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * This function checks the validity period of a der-encoded certificate.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_check_cert_date(KMF_HANDLE_T handle, const KMF_DATA *cert)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN rv;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys struct tm *gmt;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys time_t t_now;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys time_t t_notbefore;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys time_t t_notafter;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_POLICY_RECORD *policy;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys uint32_t adj;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CLEAR_ERROR(handle, rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (cert == NULL || cert->Data == NULL || cert->Length == 0)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys policy = handle->policy;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_get_cert_validity(cert, &t_notbefore, &t_notafter);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Get the current time. The time returned from time() is local which
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * cannot be used directly. It must be converted to UTC/GMT first.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys t_now = time(NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys gmt = gmtime(&t_now);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys t_now = mktime(gmt);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Adjust the validity time
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (policy->validity_adjusttime != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (str2lifetime(policy->validity_adjusttime, &adj) < 0)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_VALIDITY_PERIOD);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys adj = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys t_notafter += adj;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys t_notbefore -= adj;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (t_now <= t_notafter && t_now >= t_notbefore) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rv = KMF_ERR_VALIDITY_PERIOD;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_export_pk12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_PLUGIN *plugin;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN ret = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_KEYSTORE_TYPE kstype;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE_TESTER required_attrs[] = {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_OUTPUT_FILENAME_ATTR, TRUE, 1, 0},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys };
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int num_req_attrs = sizeof (required_attrs) /
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sizeof (KMF_ATTRIBUTE_TESTER);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CLEAR_ERROR(handle, ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = test_attributes(num_req_attrs, required_attrs, 0, NULL,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr, attrlist);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &kstype, NULL);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys plugin = FindPlugin(handle, kstype);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (plugin == NULL || plugin->funclist->ExportPK12 == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_PLUGIN_NOTFOUND);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (plugin->funclist->ExportPK12(handle, numattr, attrlist));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_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)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN rv;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_PLUGIN *plugin;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN (*buildpk12)(KMF_HANDLE *, int, KMF_X509_DER_CERT *,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int, KMF_KEY_HANDLE *, KMF_CREDENTIAL *, char *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CLEAR_ERROR(handle, rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rv != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (filename == NULL || p12cred == NULL ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (certlist == NULL && keylist == NULL))
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (plugin == NULL || plugin->dldesc == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_PLUGIN_NOTFOUND);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys buildpk12 = (KMF_RETURN(*)())dlsym(plugin->dldesc,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys "openssl_build_pk12");
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (buildpk12 == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_FUNCTION_NOT_FOUND);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = buildpk12(handle, numcerts, certlist, numkeys, keylist, p12cred,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys filename);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
71593db26bb6ef7b739cffe06d53bf990cac112cwyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_import_objects(KMF_HANDLE_T handle, char *filename,
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys KMF_CREDENTIAL *cred,
5b3e1433c6213363bcb6387e66fc84ee9ff21a5dwyllys KMF_X509_DER_CERT **certs, int *ncerts,
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys KMF_RAW_KEY_DATA **rawkeys, int *nkeys)
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys{
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys KMF_RETURN rv;
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys KMF_PLUGIN *plugin;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN (*import_objects)(KMF_HANDLE *, char *, KMF_CREDENTIAL *,
5b3e1433c6213363bcb6387e66fc84ee9ff21a5dwyllys KMF_X509_DER_CERT **, int *, KMF_RAW_KEY_DATA **, int *);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys CLEAR_ERROR(handle, rv);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys if (rv != KMF_OK)
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys return (rv);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (filename == NULL || cred == NULL || certs == NULL ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ncerts == NULL ||rawkeys == NULL || nkeys == NULL)
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys return (KMF_ERR_BAD_PARAMETER);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys /*
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys * Use the Keypair reader from the OpenSSL plugin.
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys */
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys if (plugin == NULL || plugin->dldesc == NULL) {
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys return (KMF_ERR_PLUGIN_NOTFOUND);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys }
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys import_objects = (KMF_RETURN(*)())dlsym(plugin->dldesc,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys "openssl_import_objects");
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (import_objects == NULL) {
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys return (KMF_ERR_FUNCTION_NOT_FOUND);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys }
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys /* Use OpenSSL interfaces to get raw key and cert data */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = import_objects(handle, filename, cred, certs, ncerts,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rawkeys, nkeys);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys return (rv);
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_BOOL
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysIsEqualOid(KMF_OID *Oid1, KMF_OID *Oid2)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return ((Oid1->Length == Oid2->Length) &&
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys !memcmp(Oid1->Data, Oid2->Data, Oid1->Length));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
448b8615fe9e8af757530284920a235430ead7e8wyllysstatic KMF_RETURN
448b8615fe9e8af757530284920a235430ead7e8wyllysset_algoid(KMF_X509_ALGORITHM_IDENTIFIER *destid,
448b8615fe9e8af757530284920a235430ead7e8wyllys KMF_OID *newoid)
448b8615fe9e8af757530284920a235430ead7e8wyllys{
448b8615fe9e8af757530284920a235430ead7e8wyllys if (destid == NULL || newoid == NULL)
448b8615fe9e8af757530284920a235430ead7e8wyllys return (KMF_ERR_BAD_PARAMETER);
448b8615fe9e8af757530284920a235430ead7e8wyllys
448b8615fe9e8af757530284920a235430ead7e8wyllys destid->algorithm.Length = newoid->Length;
448b8615fe9e8af757530284920a235430ead7e8wyllys destid->algorithm.Data = malloc(destid->algorithm.Length);
448b8615fe9e8af757530284920a235430ead7e8wyllys if (destid->algorithm.Data == NULL)
448b8615fe9e8af757530284920a235430ead7e8wyllys return (KMF_ERR_MEMORY);
448b8615fe9e8af757530284920a235430ead7e8wyllys
448b8615fe9e8af757530284920a235430ead7e8wyllys (void) memcpy(destid->algorithm.Data, newoid->Data,
448b8615fe9e8af757530284920a235430ead7e8wyllys destid->algorithm.Length);
448b8615fe9e8af757530284920a235430ead7e8wyllys
448b8615fe9e8af757530284920a235430ead7e8wyllys return (KMF_OK);
448b8615fe9e8af757530284920a235430ead7e8wyllys}
448b8615fe9e8af757530284920a235430ead7e8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysKMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyscopy_algoid(KMF_X509_ALGORITHM_IDENTIFIER *destid,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509_ALGORITHM_IDENTIFIER *srcid)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (!destid || !srcid)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys destid->algorithm.Length = srcid->algorithm.Length;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys destid->algorithm.Data = malloc(destid->algorithm.Length);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (destid->algorithm.Data == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_MEMORY);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memcpy(destid->algorithm.Data, srcid->algorithm.Data,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys destid->algorithm.Length);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys destid->parameters.Length = srcid->parameters.Length;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (destid->parameters.Length > 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys destid->parameters.Data = malloc(destid->parameters.Length);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (destid->parameters.Data == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_MEMORY);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memcpy(destid->parameters.Data, srcid->parameters.Data,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys destid->parameters.Length);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys destid->parameters.Data = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyssign_cert(KMF_HANDLE_T handle,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys const KMF_DATA *SubjectCert,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_KEY_HANDLE *Signkey,
448b8615fe9e8af757530284920a235430ead7e8wyllys KMF_OID *signature_oid,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_DATA *SignedCert)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509_CERTIFICATE *subj_cert = NULL;
6b35cb3cf158584a9408d44b9b6796564e8e1882Richard PALO KMF_DATA data_to_sign = { 0, NULL };
6b35cb3cf158584a9408d44b9b6796564e8e1882Richard PALO KMF_DATA signed_data = { 0, NULL };
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_ALGORITHM_INDEX algid;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int i = 0;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE attrlist[8];
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (!SignedCert)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SignedCert->Length = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys SignedCert->Data = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (!SubjectCert)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (!SubjectCert->Data || !SubjectCert->Length)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Shortcut - just extract the already encoded TBS cert data from
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * the original data buffer. Since we haven't changed anything,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * there is no need to re-encode it.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = ExtractX509CertParts((KMF_DATA *)SubjectCert,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &data_to_sign, NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Estimate the signed data length generously */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys signed_data.Length = data_to_sign.Length*2;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys signed_data.Data = calloc(1, signed_data.Length);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (!signed_data.Data) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_MEMORY;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * If we got here OK, decode into a structure and then re-encode
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * the complete certificate.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = DerDecodeSignedCertificate(SubjectCert, &subj_cert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* We are re-signing this cert, so clear out old signature data */
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll if (!IsEqualOid(&subj_cert->signature.algorithmIdentifier.algorithm,
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll signature_oid)) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_algoid(&subj_cert->signature.algorithmIdentifier);
448b8615fe9e8af757530284920a235430ead7e8wyllys ret = set_algoid(&subj_cert->signature.algorithmIdentifier,
448b8615fe9e8af757530284920a235430ead7e8wyllys signature_oid);
448b8615fe9e8af757530284920a235430ead7e8wyllys if (ret != KMF_OK)
448b8615fe9e8af757530284920a235430ead7e8wyllys goto cleanup;
448b8615fe9e8af757530284920a235430ead7e8wyllys ret = set_algoid(&subj_cert->certificate.signature,
448b8615fe9e8af757530284920a235430ead7e8wyllys signature_oid);
4165f46543b20d435f7ef0aced6239f7e97b12ffWyllys Ingersoll if (ret)
4165f46543b20d435f7ef0aced6239f7e97b12ffWyllys Ingersoll goto cleanup;
f5880f733dae6fbca929002abbce77c9c77dbf6aWyllys Ingersoll
f5880f733dae6fbca929002abbce77c9c77dbf6aWyllys Ingersoll /* Free the previous "data to be signed" block */
f5880f733dae6fbca929002abbce77c9c77dbf6aWyllys Ingersoll kmf_free_data(&data_to_sign);
f5880f733dae6fbca929002abbce77c9c77dbf6aWyllys Ingersoll
f5880f733dae6fbca929002abbce77c9c77dbf6aWyllys Ingersoll /*
f5880f733dae6fbca929002abbce77c9c77dbf6aWyllys Ingersoll * We changed the cert (updated the signature OID), so we
f5880f733dae6fbca929002abbce77c9c77dbf6aWyllys Ingersoll * need to re-encode it so the correct data gets signed.
f5880f733dae6fbca929002abbce77c9c77dbf6aWyllys Ingersoll */
f5880f733dae6fbca929002abbce77c9c77dbf6aWyllys Ingersoll ret = DerEncodeTbsCertificate(&subj_cert->certificate,
f5880f733dae6fbca929002abbce77c9c77dbf6aWyllys Ingersoll &data_to_sign);
f5880f733dae6fbca929002abbce77c9c77dbf6aWyllys Ingersoll if (ret != KMF_OK)
f5880f733dae6fbca929002abbce77c9c77dbf6aWyllys Ingersoll goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, i, KMF_KEYSTORE_TYPE_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &Signkey->kstype, sizeof (KMF_KEYSTORE_TYPE));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys i++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, i, KMF_KEY_HANDLE_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys Signkey, sizeof (KMF_KEY_HANDLE));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys i++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, i, KMF_DATA_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &data_to_sign, sizeof (KMF_DATA));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys i++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, i, KMF_OUT_DATA_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &signed_data, sizeof (KMF_DATA));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys i++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, i, KMF_OID_ATTR,
448b8615fe9e8af757530284920a235430ead7e8wyllys signature_oid, sizeof (KMF_OID));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys i++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Sign the data */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_sign_data(handle, i, attrlist);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
448b8615fe9e8af757530284920a235430ead7e8wyllys algid = x509_algoid_to_algid(signature_oid);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll if (algid == KMF_ALGID_SHA1WithECDSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll algid == KMF_ALGID_SHA256WithECDSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll algid == KMF_ALGID_SHA384WithECDSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll algid == KMF_ALGID_SHA512WithECDSA) {
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll /* ASN.1 encode ECDSA signature */
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll KMF_DATA signature;
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll ret = DerEncodeECDSASignature(&signed_data, &signature);
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll kmf_free_data(&signed_data);
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll if (ret != KMF_OK)
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll subj_cert->signature.encrypted = signature;
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll } else if (algid == KMF_ALGID_SHA1WithDSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll algid == KMF_ALGID_SHA256WithDSA) {
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll /*
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll * For DSA, kmf_sign_data() returns a 40-byte
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll * signature. We must encode the signature correctly.
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_DATA signature;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = DerEncodeDSASignature(&signed_data, &signature);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_data(&signed_data);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys subj_cert->signature.encrypted = signature;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
f5880f733dae6fbca929002abbce77c9c77dbf6aWyllys Ingersoll ret = copy_data(&subj_cert->signature.encrypted, &signed_data);
f5880f733dae6fbca929002abbce77c9c77dbf6aWyllys Ingersoll kmf_free_data(&signed_data);
f5880f733dae6fbca929002abbce77c9c77dbf6aWyllys Ingersoll
f5880f733dae6fbca929002abbce77c9c77dbf6aWyllys Ingersoll if (ret != KMF_OK)
f5880f733dae6fbca929002abbce77c9c77dbf6aWyllys Ingersoll goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Now, re-encode the cert with the new signature */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = DerEncodeSignedCertificate(subj_cert, SignedCert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyscleanup:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Cleanup & return */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_data(SignedCert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_data(&data_to_sign);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (subj_cert != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_signed_cert(subj_cert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(subj_cert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysverify_cert_with_key(KMF_HANDLE_T handle,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_DATA *derkey,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys const KMF_DATA *CertToBeVerified)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509_CERTIFICATE *signed_cert = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509_SPKI spki;
6b35cb3cf158584a9408d44b9b6796564e8e1882Richard PALO KMF_DATA data_to_verify = { 0, NULL };
6b35cb3cf158584a9408d44b9b6796564e8e1882Richard PALO KMF_DATA signed_data = { 0, NULL };
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_DATA signature = { 0, NULL };
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_ALGORITHM_INDEX algid;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* check the caller and do other setup for this SPI call */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (handle == NULL || CertToBeVerified == NULL ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys derkey == NULL || derkey->Data == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memset(&spki, 0, sizeof (KMF_X509_SPKI));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = ExtractX509CertParts((KMF_DATA *)CertToBeVerified,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &data_to_verify, &signed_data);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = DerDecodeSPKI(derkey, &spki);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Decode the signer cert so we can get the Algorithm data */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = DerDecodeSignedCertificate(CertToBeVerified, &signed_cert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys algid = x509_algoid_to_algid(CERT_SIG_OID(signed_cert));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (algid == KMF_ALGID_NONE)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_ALGORITHM);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll if (algid == KMF_ALGID_SHA1WithDSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll algid == KMF_ALGID_SHA256WithDSA) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = DerDecodeDSASignature(&signed_data, &signature);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll } else if (algid == KMF_ALGID_SHA1WithECDSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll algid == KMF_ALGID_SHA256WithECDSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll algid == KMF_ALGID_SHA384WithECDSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll algid == KMF_ALGID_SHA512WithECDSA) {
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll ret = DerDecodeECDSASignature(&signed_data, &signature);
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll if (ret != KMF_OK)
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys signature.Data = signed_data.Data;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys signature.Length = signed_data.Length;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = PKCS_VerifyData(handle, algid, &spki,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &data_to_verify, &signature);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyscleanup:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (data_to_verify.Data != NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(data_to_verify.Data);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (signed_data.Data != NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(signed_data.Data);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (signed_cert) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_signed_cert(signed_cert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(signed_cert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll if (algid == KMF_ALGID_SHA1WithDSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll algid == KMF_ALGID_SHA256WithDSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll algid == KMF_ALGID_SHA1WithECDSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll algid == KMF_ALGID_SHA256WithECDSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll algid == KMF_ALGID_SHA384WithECDSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll algid == KMF_ALGID_SHA512WithECDSA) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(signature.Data);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_algoid(&spki.algorithm);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_data(&spki.subjectPublicKey);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
02744e811b15322c5f109827a116c33bfe3438b5wyllys/*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Use a signer cert to verify another certificate's signature.
2225707c7e7edf7c636ed349df2592ef85329cddValerie Bubb Fenwick * This code forces the use of the PKCS11 mechanism for the verify
2225707c7e7edf7c636ed349df2592ef85329cddValerie Bubb Fenwick * operation for the Cryptographic Framework's FIPS-140 boundary.
02744e811b15322c5f109827a116c33bfe3438b5wyllys */
02744e811b15322c5f109827a116c33bfe3438b5wyllysstatic KMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysverify_cert_with_cert(KMF_HANDLE_T handle,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys const KMF_DATA *CertToBeVerifiedData,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys const KMF_DATA *SignerCertData)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509_CERTIFICATE *SignerCert = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509_CERTIFICATE *ToBeVerifiedCert = NULL;
6b35cb3cf158584a9408d44b9b6796564e8e1882Richard PALO KMF_DATA data_to_verify = { 0, NULL };
6b35cb3cf158584a9408d44b9b6796564e8e1882Richard PALO KMF_DATA signed_data = { 0, NULL };
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_DATA signature;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_ALGORITHM_INDEX algid;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_POLICY_RECORD *policy;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (handle == NULL ||
d00756ccb34596a328f8a15d1965da5412d366d0wyllys !CertToBeVerifiedData ||
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys !CertToBeVerifiedData->Data ||
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys !CertToBeVerifiedData->Length)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (!SignerCertData ||
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys !SignerCertData->Data ||
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys !SignerCertData->Length)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys policy = handle->policy;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Make sure the signer has proper key usage bits */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = check_key_usage(handle, SignerCertData, KMF_KU_SIGN_CERT);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys ret = KMF_OK;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (ret != KMF_OK)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (ret);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Decode the cert into parts for verification */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = ExtractX509CertParts((KMF_DATA *)CertToBeVerifiedData,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &data_to_verify, &signed_data);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Decode the to-be-verified cert so we know what algorithm to use */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = DerDecodeSignedCertificate(CertToBeVerifiedData,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys &ToBeVerifiedCert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys algid = x509_algoid_to_algid(CERT_SIG_OID(ToBeVerifiedCert));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll if (algid == KMF_ALGID_SHA1WithDSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll algid == KMF_ALGID_SHA256WithDSA) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = DerDecodeDSASignature(&signed_data, &signature);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto cleanup;
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll } else if (algid == KMF_ALGID_SHA1WithECDSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll algid == KMF_ALGID_SHA256WithECDSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll algid == KMF_ALGID_SHA384WithECDSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll algid == KMF_ALGID_SHA512WithECDSA) {
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll ret = DerDecodeECDSASignature(&signed_data, &signature);
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll if (ret != KMF_OK)
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll goto cleanup;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys signature.Data = signed_data.Data;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys signature.Length = signed_data.Length;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll ret = DerDecodeSignedCertificate(SignerCertData, &SignerCert);
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll if (ret != KMF_OK)
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll goto cleanup;
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll
9b37d29632d2cb262ba42f1d804f85fcb0aa3709wyllys /*
2225707c7e7edf7c636ed349df2592ef85329cddValerie Bubb Fenwick * Force use of PKCS11 API for kcfd/libelfsign. This is
2225707c7e7edf7c636ed349df2592ef85329cddValerie Bubb Fenwick * required for the Cryptographic Framework's FIPS-140 boundary.
9b37d29632d2cb262ba42f1d804f85fcb0aa3709wyllys */
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll ret = PKCS_VerifyData(handle, algid,
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll &SignerCert->certificate.subjectPublicKeyInfo,
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll &data_to_verify, &signature);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyscleanup:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_data(&data_to_verify);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_data(&signed_data);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (SignerCert) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_signed_cert(SignerCert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(SignerCert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ToBeVerifiedCert) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_signed_cert(ToBeVerifiedCert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(ToBeVerifiedCert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll if (algid == KMF_ALGID_SHA1WithDSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll algid == KMF_ALGID_SHA256WithDSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll algid == KMF_ALGID_SHA1WithECDSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll algid == KMF_ALGID_SHA256WithECDSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll algid == KMF_ALGID_SHA384WithECDSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll algid == KMF_ALGID_SHA512WithECDSA) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(signature.Data);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}