99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * CDDL HEADER START
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * The contents of this file are subject to the terms of the
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Common Development and Distribution License (the "License").
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * You may not use this file except in compliance with the License.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * See the License for the specific language governing permissions
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * and limitations under the License.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * When distributing Covered Code, include this CDDL HEADER in each
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * If applicable, add the following below this CDDL HEADER, with the
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * fields enclosed by brackets "[]" replaced with your own identifying
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * information: Portions Copyright [yyyy] [name of copyright owner]
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * CDDL HEADER END
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
448b8615fe9e8af757530284920a235430ead7e8wyllyssign_cert(KMF_HANDLE_T, const KMF_DATA *, KMF_KEY_HANDLE *,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysverify_cert_with_key(KMF_HANDLE_T, KMF_DATA *, const KMF_DATA *);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysverify_cert_with_cert(KMF_HANDLE_T, const KMF_DATA *, const KMF_DATA *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysget_keyalg_from_cert(KMF_DATA *cert, KMF_KEY_ALG *keyalg)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Get the algorithm info from the signer certificate */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys &SignerCert->signature.algorithmIdentifier.algorithm);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Name: kmf_find_prikey_by_cert
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Description:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * This function finds the corresponding private key in keystore
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * for a certificate
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_find_prikey_by_cert(KMF_HANDLE_T handle, int numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * First, get the key algorithm info from the certificate and saves it
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * in the returned key handle.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Call the plugin to do the work. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (plugin == NULL || plugin->funclist->FindPrikeyByCert == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (plugin->funclist->FindPrikeyByCert(handle, numattr, attrlist));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memset(&constraint, 0, sizeof (KMF_X509EXT_BASICCONSTRAINTS));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memset(&keyusage, 0, sizeof (KMF_X509EXT_KEY_USAGE));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * If absent or error, the cert is assumed to be invalid
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * for all key usage checking.
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.
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll if (keyusage.KeyUsageBits & KMF_keyCertSign) {
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 * 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.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_find_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_COUNT_ATTR, FALSE, sizeof (uint32_t), sizeof (uint32_t)}
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (plugin == NULL || plugin->funclist->FindCert == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (plugin->funclist->FindCert(handle, numattr, attrlist));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#define NODATA(d) (d.Data == NULL || d.Length == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_encode_cert_record(KMF_X509_CERTIFICATE *CertData, KMF_DATA *encodedCert)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Validate that all required fields are present.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys NODATA(tbs_cert->subjectPublicKeyInfo.subjectPublicKey) ||
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Pack the new certificate */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = DerEncodeSignedCertificate(CertData, encodedCert);
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
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.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * The caller should free the new_attrlist after use it.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyssetup_findprikey_attrlist(KMF_ATTRIBUTE *src_attrlist, int src_num,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE **new_attrlist, int *new_num, KMF_KEY_HANDLE *key,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (src_attrlist == NULL || new_num == NULL || key == NULL ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Create a new attribute list with 2 more elements */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Copy the src_attrlist to the new list */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys for (i = 0; i < src_num; i++) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Add or reset the key handle attribute */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys index = kmf_find_attr(KMF_KEY_HANDLE_ATTR, attrlist, cur_num);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* not found; add it */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* found; just reset it */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* add or reset the cert data attribute */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys index = kmf_find_attr(KMF_CERT_DATA_ATTR, attrlist, cur_num);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* not found; add it */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* found; just reset it */
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * Determine a default signature type to use based on
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * the key algorithm.
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll /* NSS doesnt support DSA-SHA2 hashes yet */
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 rv = kmf_get_cert_ku((const KMF_DATA *)cert, &keyUsage);
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll KMF_X509EXT_BASICCONSTRAINTS basicConstraint;
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll /* If keyCertSign is set, look for basicConstraints */
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll if (keyUsage.KeyUsageBits & KMF_keyCertSign)
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 * Don't limit the pathLen (for now).
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * This should probably be a policy setting in the
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll basicConstraint.pathLenConstraintPresent = FALSE;
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * Decode the DER cert data into the internal
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * X.509 structure we need to set extensions.
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll rv = DerDecodeSignedCertificate(cert, &x509cert);
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * Add the missing basic constraint.
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll rv = kmf_set_cert_basic_constraint(x509cert,
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll /* Free the old cert data record */
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll /* Re-encode the cert with the extension */
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll rv = kmf_encode_cert_record(x509cert, cert);
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll /* cleanup */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Name: kmf_sign_cert
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Description:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * This function signs a certificate using the signer cert and
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * returns a signed and DER-encoded certificate.
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.
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.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_sign_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)}
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Get the signer cert and check its keyUsage */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys signer_cert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sign_key_ptr = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist,
448b8615fe9e8af757530284920a235430ead7e8wyllys * Only accept 1 or the other, not both.
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll oid = kmf_get_attr_ptr(KMF_OID_ATTR, attrlist, numattr);
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * If the signature OID was not given, check
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * for an algorithm index identifier instead.
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll ret = kmf_get_attr(KMF_ALGORITHM_INDEX_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = check_key_usage(handle, signer_cert, KMF_KU_SIGN_CERT);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Find the private key from the signer certificate by calling
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * kmf_find_prikey_by_cert().
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &new_attrlist, &new_numattr, &sign_key, signer_cert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys tbs_cert = kmf_get_attr_ptr(KMF_TBS_CERT_DATA_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys x509cert = kmf_get_attr_ptr(KMF_X509_CERTIFICATE_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_encode_cert_record(x509cert, &unsignedCert);
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 ret = check_for_basic_constraint(tbs_cert);
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * If OID is not known yet, use a default value
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * based on the signers key type.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys signed_cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist,
448b8615fe9e8af757530284920a235430ead7e8wyllys ret = sign_cert(handle, tbs_cert, sign_key_ptr, oid, signed_cert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* If we had to find the key, free it here. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Name: kmf_sign_data
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Description:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * This function signs a block of data using the signer cert and
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * returns the the signature in output
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll KMF_ALGORITHM_INDEX AlgId = KMF_ALGID_NONE;
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 /* Get the signer cert and check its keyUsage. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys signer_cert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sign_key_ptr = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * If a signer cert was given, use it to find the private key
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * to use for signing the data.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = check_key_usage(handle, signer_cert, KMF_KU_SIGN_DATA);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Signing generic data does not require the
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * KeyUsage extension.
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Find the private key from the signer certificate.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys &new_attrlist, &new_numattr, &sign_key, signer_cert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Get the tbs_data and signed_data attributes now */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys tbs_data = kmf_get_attr_ptr(KMF_DATA_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys output = kmf_get_attr_ptr(KMF_OUT_DATA_ATTR, attrlist, numattr);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Get the algorithm index attribute and its oid. If this attribute
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll * is not provided, then we use a default value.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys oid = kmf_get_attr_ptr(KMF_OID_ATTR, attrlist, numattr);
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll ret = kmf_get_attr(KMF_ALGORITHM_INDEX_ATTR, attrlist,
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll /* If there was no Algorithm ID, use default based on key */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Now call the plugin function to sign it */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (plugin == NULL || plugin->funclist->SignData == NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = plugin->funclist->SignData(handle, sign_key_ptr, oid, tbs_data,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * For DSA, NSS returns an encoded signature. Decode the
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll * signature and expect a 40-byte DSA signature.
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll (IsEqualOid(oid, (KMF_OID *)&KMFOID_X9CM_DSAWithSHA1) ||
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll IsEqualOid(oid, (KMF_OID *)&KMFOID_SHA256WithDSA))) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys (void) memcpy(output->Data, signature.Data, signature.Length);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * kmf_verify_data
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).
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.
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.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, num_args,
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 ret = kmf_get_attr(KMF_ALGORITHM_INDEX_ATTR, attrlist, num_args,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys /* We only need the algorithm index if we don't have a signer cert. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys indata = kmf_get_attr_ptr(KMF_DATA_ATTR, attrlist, num_args);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys insig = kmf_get_attr_ptr(KMF_IN_SIGN_ATTR, attrlist, num_args);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* If the caller passed a signer cert instead of a key use it. */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = check_key_usage(handle, signer_cert, KMF_KU_SIGN_DATA);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0)
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll /* Decode the signer cert so we can get the SPKI data */
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll ret = DerDecodeSignedCertificate(signer_cert, &SignerCert);
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll /* If no algorithm specified, use the certs signature alg */
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll sigAlg = x509_algoid_to_algid(CERT_ALG_OID(SignerCert));
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 &SignerCert->certificate.subjectPublicKeyInfo,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Retrieve public key data from keystore */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Name: kmf_verify_cert
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
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Parameters:
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * handle(input) - opaque handle for KMF session
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * numattr - number of attributes in the list
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * attrlist - KMF_ATTRIBUTES
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.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_verify_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)}
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 * Caller must provide at least a key handle or a cert to use
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * as the "key" for verification.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CertToBeVerified = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = verify_cert_with_cert(handle, CertToBeVerified,
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 if (plugin != NULL && plugin->funclist->EncodePubkeyData !=
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Name: kmf_encrypt
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Description:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Uses the public key from the cert to encrypt the plaintext
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * into the ciphertext.
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 * 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.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_encrypt(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys plaintext = kmf_get_attr_ptr(KMF_PLAINTEXT_DATA_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ciphertext = kmf_get_attr_ptr(KMF_CIPHERTEXT_DATA_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (cert == NULL || plaintext == NULL || ciphertext == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* check the keyUsage of the certificate */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = check_key_usage(handle, cert, KMF_KU_ENCRYPT_DATA);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0)
02744e811b15322c5f109827a116c33bfe3438b5wyllys /* Decode the cert so we can get the SPKI data */
02744e811b15322c5f109827a116c33bfe3438b5wyllys if ((ret = DerDecodeSignedCertificate(cert, &x509cert)) != KMF_OK)
02744e811b15322c5f109827a116c33bfe3438b5wyllys /* Get the public key info from the certificate */
02744e811b15322c5f109827a116c33bfe3438b5wyllys pubkey = &x509cert->certificate.subjectPublicKeyInfo;
02744e811b15322c5f109827a116c33bfe3438b5wyllys /* Use the algorithm in SPKI to encrypt data */
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll /* [EC]DSA does not support encrypt */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Encrypt using the crypto framework (not the KMF plugin mechanism).
02744e811b15322c5f109827a116c33bfe3438b5wyllys ret = PKCS_EncryptData(handle, algid, pubkey, plaintext, ciphertext);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Name: kmf_decrypt
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Description:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Uses the private key associated with the cert to decrypt
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * the ciphertext into the plaintext.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_decrypt(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Get the cert and check its keyUsage */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* check the keyUsage of the certificate */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = check_key_usage(handle, cert, KMF_KU_ENCRYPT_DATA);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Get the ciphertext and plaintext attributes */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ciphertext = kmf_get_attr_ptr(KMF_CIPHERTEXT_DATA_ATTR, attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys plaintext = kmf_get_attr_ptr(KMF_PLAINTEXT_DATA_ATTR, attrlist,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Retrieve the private key from the keystore based on
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * the certificate.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = setup_findprikey_attrlist(attrlist, numattr, &new_attrlist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_find_prikey_by_cert(handle, new_numattr, new_attrlist);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Decode the cert so we can get the alogorithm */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys spki_ptr = &x509cert->certificate.subjectPublicKeyInfo;
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll /* [EC]DSA does not support decrypt */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (plugin != NULL && plugin->funclist->DecryptData != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_store_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (plugin == NULL || plugin->funclist->StoreCert == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (plugin->funclist->StoreCert(handle, numattr, attrlist));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_import_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = test_attributes(num_req_attrs, required_attrs, 0, NULL,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (plugin == NULL || plugin->funclist->ImportCert == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (plugin->funclist->ImportCert(handle, numattr, attrlist));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_delete_cert_from_keystore(KMF_HANDLE_T handle, int numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (plugin == NULL || plugin->funclist->DeleteCert == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (plugin->funclist->DeleteCert(handle, numattr, attrlist));
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.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyscert_get_crl(KMF_HANDLE_T handle, const KMF_DATA *cert, char *proxy,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *filename, char **retn_uri, KMF_ENCODE_FORMAT *format)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (handle == NULL || cert == NULL || filename == NULL ||
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Get the proxy info */
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.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_cert_crl_dist_pts((const KMF_DATA *)cert,
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllyscheck_crl_validity(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE kstype,
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 * Check the CRL signature if needed.
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys if (!policy->validation_info.crl_info.ignore_crl_sign) {
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys * Check the CRL validity if needed.
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys if (!policy->validation_info.crl_info.ignore_crl_date) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyscert_crl_check(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE *kstype,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL || kstype == NULL || user_cert == NULL ||
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 * 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 basefilename = policy->validation_info.crl_info.basefilename;
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys * Check to see if we already have this CRL.
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys * If this file already exists and is valid, we don't need to
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys * download a new one.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Create a temporary file to hold the new CRL file initially.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Get the URI entry from the certificate's CRL distribution
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * points extension and download the CRL file.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = cert_get_crl(handle, user_cert, proxy, crlfile_tmp,
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys * If we just downloaded one, make sure it is OK.
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys if ((ret = check_crl_validity(handle, *kstype, crlfile_tmp,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Cache the CRL file. */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * For NSS keystore, import this CRL file into th
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * internal database.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * If the get_crl_uri policy is FALSE, for File-based CRL
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * plugins, get the input CRL file from the policy.
646cf3c6c5f9a3403fe9d15809bbbb2441deb1e2wyllys * Make sure this CRL is still valid.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Check the CRL revocation for the certificate.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys switch (*kstype) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Create temporary file to hold the user certificate.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_create_cert_file(user_cert, KMF_FORMAT_ASN1,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_find_cert_in_crl(handle, numattr, attrlist);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyscert_ocsp_check(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE *kstype,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_DATA *user_cert, KMF_DATA *issuer_cert, KMF_DATA *response,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL || kstype == NULL || user_cert == NULL ||
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Get the response lifetime from policy.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (policy->VAL_OCSP_BASIC.response_lifetime != NULL &&
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (str2lifetime(policy->VAL_OCSP_BASIC.response_lifetime, <ime)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Get the ignore_response_sign policy.
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 ignore_response_sign = policy->VAL_OCSP_BASIC.ignore_response_sign;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_SUBJECT_NAME_ATTR, signer_name, strlen(signer_name));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_BIGINT_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (*kstype == KMF_KEYSTORE_NSS && slotlabel != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_find_cert(handle, fc_numattr, fc_attrlist);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memset(&signer_retrcert, 0, sizeof (KMF_X509_DER_CERT));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_find_cert(handle, fc_numattr, fc_attrlist);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys signer_cert->Data = signer_retrcert.certificate.Data;
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 new_response = (KMF_DATA *) malloc(sizeof (KMF_DATA));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_ocsp_for_cert(handle, user_cert, issuer_cert,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Process the OCSP response and retrieve the certificate status.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, numattr, KMF_ISSUER_CERT_DATA_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, numattr, KMF_USER_CERT_DATA_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_SIGNER_CERT_DATA_ATTR, user_cert, sizeof (KMF_DATA));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, numattr, KMF_OCSP_RESPONSE_DATA_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys response == NULL ? new_response : response, sizeof (KMF_DATA));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, numattr, KMF_RESPONSE_LIFETIME_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_IGNORE_RESPONSE_SIGN_ATTR, &ignore_response_sign,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_OCSP_RESPONSE_STATUS_ATTR, &response_status, sizeof (int));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_OCSP_RESPONSE_REASON_ATTR, &reason, sizeof (int));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_OCSP_RESPONSE_CERT_STATUS_ATTR, &cert_status, sizeof (int));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_ocsp_status_for_cert(handle, numattr, attrlist);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* keyusage is not set in cert but is set in policy */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* no keyusage set in both cert and policy */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* real error */
31558a356540225e286233d63c122a35e4a4bd22wyllys * If KeyCertSign is set, then constraints.cA must be TRUE and
31558a356540225e286233d63c122a35e4a4bd22wyllys * marked critical.
31558a356540225e286233d63c122a35e4a4bd22wyllys /* real error */
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 if ((policy->ku_bits & keyusage.KeyUsageBits) == policy->ku_bits) {
31558a356540225e286233d63c122a35e4a4bd22wyllys * If the policy does not have any EKU, then there is
31558a356540225e286233d63c122a35e4a4bd22wyllys * nothing further to check.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((ret != KMF_ERR_EXTENSION_NOT_FOUND) && (ret != KMF_OK)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* real error */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Build the EKU bitmap based on the certificate
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } /* for */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Build the EKU bitmap based on the policy
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } /* for */
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).
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysfind_issuer_cert(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE *kstype,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL || kstype == NULL || user_issuer == NULL ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_KEYSTORE_TYPE_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(fc_attrlist, fc_numattr, KMF_SUBJECT_NAME_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (*kstype == KMF_KEYSTORE_NSS && slotlabel != NULL) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_find_cert(handle, fc_numattr, fc_attrlist);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_find_cert(handle, fc_numattr, fc_attrlist);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* only one issuer cert is found */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * More than one issuer certs are found. We will
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * pick the latest one.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys for (i = 0; i < num; i++) {
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_cert_validity(&certlist[i].certificate,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys for (i = 0; i < num; i++)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysfind_ta_cert(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE *kstype,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (handle == NULL || kstype == NULL || ta_cert == NULL ||
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* Get the TA name and serial number from the policy */
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll * Use name and serial from policy.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_hexstr_to_bytes((uchar_t *)policy->ta_serial,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys /* set up fc_attrlist for kmf_find_cert */
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll kmf_set_attr_at_index(fc_attrlist, fc_numattr++, KMF_KEYSTORE_TYPE_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (*kstype == KMF_KEYSTORE_NSS && slotlabel != NULL) {
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll kmf_set_attr_at_index(fc_attrlist, fc_numattr++,
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll kmf_set_attr_at_index(fc_attrlist, fc_numattr++,
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll kmf_set_attr_at_index(fc_attrlist, fc_numattr++,
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll kmf_set_attr_at_index(fc_attrlist, fc_numattr++,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_find_cert(handle, fc_numattr, fc_attrlist);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_X509_DER_CERT_ATTR, &ta_retrCert, sizeof (KMF_X509_DER_CERT));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_find_cert(handle, fc_numattr, fc_attrlist);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ta_cert->Data = malloc(ta_retrCert.certificate.Length);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memcpy(ta_cert->Data, ta_retrCert.certificate.Data,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * The found TA's name must be matching with issuer name in
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * subscriber's certificate.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memset(&ta_subjectDN, 0, sizeof (ta_subjectDN));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_cert_subject_str(handle, ta_cert, &ta_subject);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (kmf_compare_rdns(user_issuerDN, &ta_subjectDN) != 0)
31558a356540225e286233d63c122a35e4a4bd22wyllys /* Make sure the TA cert has the correct extensions */
31558a356540225e286233d63c122a35e4a4bd22wyllys ret = check_key_usage(handle, ta_cert, KMF_KU_SIGN_CERT);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (ret == KMF_ERR_EXTENSION_NOT_FOUND && policy->ku_bits == 0)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_validate_cert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), sizeof (KMF_DATA)},
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)
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 /* Initialize the returned result */
5363b1129db4ee42d2c9736898eab4670580bec7hylee * Get the issuer information from the input certficate first.
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll } else if ((ret = kmf_dn_parser(user_issuer, &user_issuerDN)) !=
5363b1129db4ee42d2c9736898eab4670580bec7hylee * Check if the certificate is a self-signed cert.
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll } else if ((ret = kmf_dn_parser(user_subject, &user_subjectDN)) !=
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll if ((*result & KMF_CERT_VALIDATE_ERR_USER) == 0 &&
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll (kmf_compare_rdns(&user_issuerDN, &user_subjectDN)) == 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * this is a self-signed cert
02744e811b15322c5f109827a116c33bfe3438b5wyllys * Check KeyUsage extension of the subscriber's certificate
02744e811b15322c5f109827a116c33bfe3438b5wyllys * Validate Extended KeyUsage extension
02744e811b15322c5f109827a116c33bfe3438b5wyllys * Check the certificate's validity period
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * This step is needed when "ignore_date" in policy is set
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * to false.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Validate expiration date
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 * 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 * 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 * Verify the signature of subscriber's certificate using
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * TA certificate.
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll *result |= KMF_CERT_VALIDATE_ERR_SIGNATURE;
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll strcasecmp(policy->ta_name, "search") == 0) {
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll ret = find_issuer_cert(handle, kstype, user_issuer,
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll * If we didnt find the user_issuer string, we
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll * won't have a "user_issuerDN" either.
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll ret = find_ta_cert(handle, kstype, &ta_cert,
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll /* Only verify if we got the TA without an error. */
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll if ((*result & KMF_CERT_VALIDATE_ERR_TA) == 0) {
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll *result |= KMF_CERT_VALIDATE_ERR_SIGNATURE;
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll /* No issuer was found, so we cannot find a trust anchor */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Check certificate revocation
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* skip revocation checking */
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 if (!(policy->revocation & KMF_REVOCATION_METHOD_CRL) &&
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys !(policy->revocation & KMF_REVOCATION_METHOD_OCSP)) {
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 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 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);
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,
fc2613b0a10c787c0f90e9b36f170183746c63f8Wyllys Ingersoll * If we did not copy ta_cert to issuer_cert, free it.
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.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_create_cert_file(const KMF_DATA *certdata, KMF_ENCODE_FORMAT format,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (format != KMF_FORMAT_PEM && format != KMF_FORMAT_ASN1)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if ((fd = open(certfile, O_CREAT | O_RDWR | O_TRUNC, 0644)) == -1) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * kmf_is_cert_data
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * Determine if a KMF_DATA buffer contains an encoded X.509 certificate.
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * KMF_OK if it is a certificate
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * KMF_ERR_ENCODING (or other error) if not.
d00756ccb34596a328f8a15d1965da5412d366d0wyllyskmf_is_cert_data(KMF_DATA *data, KMF_ENCODE_FORMAT *fmt)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys switch (*fmt) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys /* Convert to ASN.1 DER first */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys ret = kmf_read_input_file(handle, filename, &filedata);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * This function checks the validity period of a der-encoded certificate.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_check_cert_date(KMF_HANDLE_T handle, const KMF_DATA *cert)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (cert == NULL || cert->Data == NULL || cert->Length == 0)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = kmf_get_cert_validity(cert, &t_notbefore, &t_notafter);
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 * Adjust the validity time
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (str2lifetime(policy->validity_adjusttime, &adj) < 0)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_export_pk12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)},
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = test_attributes(num_req_attrs, required_attrs, 0, NULL,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (plugin == NULL || plugin->funclist->ExportPK12 == NULL)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (plugin->funclist->ExportPK12(handle, numattr, attrlist));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_X509_DER_CERT *certlist, int numkeys, KMF_KEY_HANDLE *keylist,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN (*buildpk12)(KMF_HANDLE *, int, KMF_X509_DER_CERT *,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys "openssl_build_pk12");
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = buildpk12(handle, numcerts, certlist, numkeys, keylist, p12cred,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_import_objects(KMF_HANDLE_T handle, char *filename,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_RETURN (*import_objects)(KMF_HANDLE *, char *, KMF_CREDENTIAL *,
5b3e1433c6213363bcb6387e66fc84ee9ff21a5dwyllys KMF_X509_DER_CERT **, int *, KMF_RAW_KEY_DATA **, int *);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (filename == NULL || cred == NULL || certs == NULL ||
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys * Use the Keypair reader from the OpenSSL plugin.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys import_objects = (KMF_RETURN(*)())dlsym(plugin->dldesc,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys "openssl_import_objects");
71593db26bb6ef7b739cffe06d53bf990cac112cwyllys /* Use OpenSSL interfaces to get raw key and cert data */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys rv = import_objects(handle, filename, cred, certs, ncerts,
448b8615fe9e8af757530284920a235430ead7e8wyllys destid->algorithm.Data = malloc(destid->algorithm.Length);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys destid->algorithm.Data = malloc(destid->algorithm.Length);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memcpy(destid->algorithm.Data, srcid->algorithm.Data,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys destid->parameters.Length = srcid->parameters.Length;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys destid->parameters.Data = malloc(destid->parameters.Length);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memcpy(destid->parameters.Data, srcid->parameters.Data,
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 /* Estimate the signed data length generously */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * If we got here OK, decode into a structure and then re-encode
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * the complete certificate.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = DerDecodeSignedCertificate(SubjectCert, &subj_cert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* We are re-signing this cert, so clear out old signature data */
2c9a247fb01631b3eb3b85a1127e72f0b60ae108Wyllys Ingersoll if (!IsEqualOid(&subj_cert->signature.algorithmIdentifier.algorithm,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_free_algoid(&subj_cert->signature.algorithmIdentifier);
448b8615fe9e8af757530284920a235430ead7e8wyllys ret = set_algoid(&subj_cert->signature.algorithmIdentifier,
f5880f733dae6fbca929002abbce77c9c77dbf6aWyllys Ingersoll /* Free the previous "data to be signed" block */
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 ret = DerEncodeTbsCertificate(&subj_cert->certificate,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, i, KMF_KEYSTORE_TYPE_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, i, KMF_KEY_HANDLE_ATTR,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, i, KMF_OUT_DATA_ATTR,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Sign the data */
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll /* ASN.1 encode ECDSA signature */
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll ret = DerEncodeECDSASignature(&signed_data, &signature);
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll subj_cert->signature.encrypted = signature;
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll } else if (algid == KMF_ALGID_SHA1WithDSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll * For DSA, kmf_sign_data() returns a 40-byte
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll * signature. We must encode the signature correctly.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = DerEncodeDSASignature(&signed_data, &signature);
f5880f733dae6fbca929002abbce77c9c77dbf6aWyllys Ingersoll ret = copy_data(&subj_cert->signature.encrypted, &signed_data);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Now, re-encode the cert with the new signature */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = DerEncodeSignedCertificate(subj_cert, SignedCert);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Cleanup & return */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* check the caller and do other setup for this SPI call */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = ExtractX509CertParts((KMF_DATA *)CertToBeVerified,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Decode the signer cert so we can get the Algorithm data */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = DerDecodeSignedCertificate(CertToBeVerified, &signed_cert);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys algid = x509_algoid_to_algid(CERT_SIG_OID(signed_cert));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = DerDecodeDSASignature(&signed_data, &signature);
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll } else if (algid == KMF_ALGID_SHA1WithECDSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll ret = DerDecodeECDSASignature(&signed_data, &signature);
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.
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)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Decode the cert into parts for verification */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = ExtractX509CertParts((KMF_DATA *)CertToBeVerifiedData,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Decode the to-be-verified cert so we know what algorithm to use */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = DerDecodeSignedCertificate(CertToBeVerifiedData,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys algid = x509_algoid_to_algid(CERT_SIG_OID(ToBeVerifiedCert));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = DerDecodeDSASignature(&signed_data, &signature);
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll } else if (algid == KMF_ALGID_SHA1WithECDSA ||
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll ret = DerDecodeECDSASignature(&signed_data, &signature);
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll ret = DerDecodeSignedCertificate(SignerCertData, &SignerCert);
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.