elfcertlib.c revision 2225707c7e7edf7c636ed349df2592ef85329cdd
df8bdeb362277e8d95a74d6c097341fe97409948johnz * CDDL HEADER START
df8bdeb362277e8d95a74d6c097341fe97409948johnz * The contents of this file are subject to the terms of the
df8bdeb362277e8d95a74d6c097341fe97409948johnz * Common Development and Distribution License (the "License").
df8bdeb362277e8d95a74d6c097341fe97409948johnz * You may not use this file except in compliance with the License.
df8bdeb362277e8d95a74d6c097341fe97409948johnz * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
df8bdeb362277e8d95a74d6c097341fe97409948johnz * See the License for the specific language governing permissions
df8bdeb362277e8d95a74d6c097341fe97409948johnz * and limitations under the License.
df8bdeb362277e8d95a74d6c097341fe97409948johnz * When distributing Covered Code, include this CDDL HEADER in each
df8bdeb362277e8d95a74d6c097341fe97409948johnz * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
df8bdeb362277e8d95a74d6c097341fe97409948johnz * If applicable, add the following below this CDDL HEADER, with the
df8bdeb362277e8d95a74d6c097341fe97409948johnz * fields enclosed by brackets "[]" replaced with your own identifying
df8bdeb362277e8d95a74d6c097341fe97409948johnz * information: Portions Copyright [yyyy] [name of copyright owner]
df8bdeb362277e8d95a74d6c097341fe97409948johnz * CDDL HEADER END
2225707c7e7edf7c636ed349df2592ef85329cddValerie Bubb Fenwick * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
df8bdeb362277e8d95a74d6c097341fe97409948johnz * Use is subject to license terms.
df8bdeb362277e8d95a74d6c097341fe97409948johnzconst char _PATH_ELFSIGN_CRYPTO_CERTS[] = CRYPTO_CERTS_DIR;
df8bdeb362277e8d95a74d6c097341fe97409948johnz * The CACERT and OBJCACERT are the Cryptographic Trust Anchors
df8bdeb362277e8d95a74d6c097341fe97409948johnz * for the Solaris Cryptographic Framework.
df8bdeb362277e8d95a74d6c097341fe97409948johnzstatic const char _PATH_CRYPTO_CACERT[] = CRYPTO_CERTS_DIR "/CA";
df8bdeb362277e8d95a74d6c097341fe97409948johnzstatic const char _PATH_CRYPTO_OBJCACERT[] = CRYPTO_CERTS_DIR "/SUNWObjectCA";
df8bdeb362277e8d95a74d6c097341fe97409948johnzstatic pthread_mutex_t ca_mutex = PTHREAD_MUTEX_INITIALIZER;
df8bdeb362277e8d95a74d6c097341fe97409948johnz * elfcertlib_verifycert - Verify the Cert with a Trust Anchor
df8bdeb362277e8d95a74d6c097341fe97409948johnz * IN ess - elfsign context structure
df8bdeb362277e8d95a74d6c097341fe97409948johnz * We first setup the Trust Anchor (CA and SUNWObjectCA) certs
df8bdeb362277e8d95a74d6c097341fe97409948johnz * if it hasn't been done already. We verify that the files on disk
df8bdeb362277e8d95a74d6c097341fe97409948johnz * are those we expected.
df8bdeb362277e8d95a74d6c097341fe97409948johnz * We then verify the given cert using the publickey of a TA.
df8bdeb362277e8d95a74d6c097341fe97409948johnz * If the passed in cert is a TA or it has been verified already we
df8bdeb362277e8d95a74d6c097341fe97409948johnz * short cut and return TRUE without futher validation.
df8bdeb362277e8d95a74d6c097341fe97409948johnz/*ARGSUSED*/
df8bdeb362277e8d95a74d6c097341fe97409948johnz if ((cert->c_verified == E_OK) || (cert->c_verified == E_IS_TA)) {
df8bdeb362277e8d95a74d6c097341fe97409948johnz (void) elfcertlib_getcert(ess, (char *)_PATH_CRYPTO_CACERT,
df8bdeb362277e8d95a74d6c097341fe97409948johnz (void) elfcertlib_getcert(ess, (char *)_PATH_CRYPTO_OBJCACERT,
df8bdeb362277e8d95a74d6c097341fe97409948johnz * elfcertlib_getcert - Get the certificate for signer_DN
df8bdeb362277e8d95a74d6c097341fe97409948johnz * IN ess - elfsign context structure
df8bdeb362277e8d95a74d6c097341fe97409948johnz * cert_pathname - path to cert (May be NULL)
df8bdeb362277e8d95a74d6c097341fe97409948johnz * signer_DN - The DN we are looking for (May be NULL)
df8bdeb362277e8d95a74d6c097341fe97409948johnz * action - indicates crypto verification call
df8bdeb362277e8d95a74d6c097341fe97409948johnz * OUT certp - allocated/loaded ELFCert_t
df8bdeb362277e8d95a74d6c097341fe97409948johnz * If the cert_pathname is passed use it and don't search.
df8bdeb362277e8d95a74d6c097341fe97409948johnz * Otherwise, go looking in certificate directories
df8bdeb362277e8d95a74d6c097341fe97409948johnz char *signer_DN, ELFCert_t *certp, enum ES_ACTION action)
df8bdeb362277e8d95a74d6c097341fe97409948johnz cryptodebug("elfcertlib_getcert: lack of specificity");
df8bdeb362277e8d95a74d6c097341fe97409948johnz /* look in the specified object */
df8bdeb362277e8d95a74d6c097341fe97409948johnz /* look in the certificate directories */
df8bdeb362277e8d95a74d6c097341fe97409948johnz * crypto verifications don't search beyond
df8bdeb362277e8d95a74d6c097341fe97409948johnz * _PATH_ELFSIGN_CRYPTO_CERTS
df8bdeb362277e8d95a74d6c097341fe97409948johnz rv = KMF_FindCert(ess->es_kmfhandle, &fcparams, certbuf,
df8bdeb362277e8d95a74d6c097341fe97409948johnz /* There can be only one */
df8bdeb362277e8d95a74d6c097341fe97409948johnz "too many certificates found in %s",
df8bdeb362277e8d95a74d6c097341fe97409948johnz /* found it, cache subject and issuer */
df8bdeb362277e8d95a74d6c097341fe97409948johnz cryptodebug("elfcertlib_getcert: no certificate found");
2225707c7e7edf7c636ed349df2592ef85329cddValerie Bubb Fenwick * If the cert we are loading is the trust anchor (ie the CA) then
df8bdeb362277e8d95a74d6c097341fe97409948johnz * we mark it as such in cert. This is so that we don't attempt
df8bdeb362277e8d95a74d6c097341fe97409948johnz * to verify it later. The CA is always implicitly verified.
df8bdeb362277e8d95a74d6c097341fe97409948johnz strcmp(cert_pathname, _PATH_CRYPTO_OBJCACERT) == 0)) {
df8bdeb362277e8d95a74d6c097341fe97409948johnz * elfcertlib_loadprivatekey - Load the private key from path
df8bdeb362277e8d95a74d6c097341fe97409948johnz * IN ess - elfsign context structure
df8bdeb362277e8d95a74d6c097341fe97409948johnzelfcertlib_loadprivatekey(ELFsign_t ess, ELFCert_t cert, const char *pathname)
df8bdeb362277e8d95a74d6c097341fe97409948johnz rv = KMF_FindKey(ess->es_kmfhandle, &fkparams, keybuf, &nkeys);
df8bdeb362277e8d95a74d6c097341fe97409948johnz /* lack of specificity */
df8bdeb362277e8d95a74d6c097341fe97409948johnz * elfcertlib_loadtokenkey - Load the private key from token
df8bdeb362277e8d95a74d6c097341fe97409948johnz * IN ess - elfsign context structure
df8bdeb362277e8d95a74d6c097341fe97409948johnz * token_label
df8bdeb362277e8d95a74d6c097341fe97409948johnz rv = KMF_ConfigureKeystore(ess->es_kmfhandle, &cfgparams);
df8bdeb362277e8d95a74d6c097341fe97409948johnz fkparams.cred.credlen = (pin != NULL ? strlen(pin) : 0);
df8bdeb362277e8d95a74d6c097341fe97409948johnz * We will search for the key based on the ID attribute
df8bdeb362277e8d95a74d6c097341fe97409948johnz * which was added when the key was created. ID is
df8bdeb362277e8d95a74d6c097341fe97409948johnz * a SHA-1 hash of the public modulus shared by the
df8bdeb362277e8d95a74d6c097341fe97409948johnz * key and the certificate.
df8bdeb362277e8d95a74d6c097341fe97409948johnz rv = KMF_GetCertIDString(&cert->c_cert.certificate, &idstr);
df8bdeb362277e8d95a74d6c097341fe97409948johnzstatic const CK_BYTE MD5_DER_PREFIX[] = {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08,
df8bdeb362277e8d95a74d6c097341fe97409948johnz 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10};
df8bdeb362277e8d95a74d6c097341fe97409948johnz * elfcertlib_sign - sign the given DATA using the privatekey in cert
df8bdeb362277e8d95a74d6c097341fe97409948johnz * IN ess - elfsign context structure
df8bdeb362277e8d95a74d6c097341fe97409948johnz * OUT sig - must be big enough to hold the signature of data
df8bdeb362277e8d95a74d6c097341fe97409948johnz * Caller must allocate
df8bdeb362277e8d95a74d6c097341fe97409948johnz * sig_len - actual length used; 0 on failure.
df8bdeb362277e8d95a74d6c097341fe97409948johnz/*ARGSUSED*/
df8bdeb362277e8d95a74d6c097341fe97409948johnz uchar_t der_data[sizeof (MD5_DER_PREFIX) + MD5_DIGEST_LENGTH];
df8bdeb362277e8d95a74d6c097341fe97409948johnz /* compatibility: take MD5 hash of SHA1 hash */
df8bdeb362277e8d95a74d6c097341fe97409948johnz * first: digest using software-based methods, don't
df8bdeb362277e8d95a74d6c097341fe97409948johnz * rely on the token for hashing.
df8bdeb362277e8d95a74d6c097341fe97409948johnz * second: insert prefix
df8bdeb362277e8d95a74d6c097341fe97409948johnz * prepare to sign the local buffer
df8bdeb362277e8d95a74d6c097341fe97409948johnz * elfcertlib_verifysig - verify the given DATA using the public key in cert
df8bdeb362277e8d95a74d6c097341fe97409948johnz * IN ess - elfsign context structure
df8bdeb362277e8d95a74d6c097341fe97409948johnz * signature
2225707c7e7edf7c636ed349df2592ef85329cddValerie Bubb Fenwick * We tell KMF to use the PKCS11 verification APIs
2225707c7e7edf7c636ed349df2592ef85329cddValerie Bubb Fenwick * here to prevent the use of OpenSSL and to keep
2225707c7e7edf7c636ed349df2592ef85329cddValerie Bubb Fenwick * all validation within the FIPS-140 boundary for
2225707c7e7edf7c636ed349df2592ef85329cddValerie Bubb Fenwick * the Cryptographic Framework.
df8bdeb362277e8d95a74d6c097341fe97409948johnz * elfcertlib_getdn
df8bdeb362277e8d95a74d6c097341fe97409948johnz * RETURN dn or NULL
df8bdeb362277e8d95a74d6c097341fe97409948johnz * elfcertlib_getissuer
df8bdeb362277e8d95a74d6c097341fe97409948johnz * RETURN dn or NULL
df8bdeb362277e8d95a74d6c097341fe97409948johnz "unable to initialize KMF library");
df8bdeb362277e8d95a74d6c097341fe97409948johnz * set the token device
df8bdeb362277e8d95a74d6c097341fe97409948johnz rv = KMF_ConfigureKeystore(ess->es_kmfhandle, &cfgparams);
df8bdeb362277e8d95a74d6c097341fe97409948johnz * set the certificate CA identification callback
df8bdeb362277e8d95a74d6c097341fe97409948johnz * set the certificate verification callback
df8bdeb362277e8d95a74d6c097341fe97409948johnz * elfcertlib_releasecert - release a cert
df8bdeb362277e8d95a74d6c097341fe97409948johnz * RETURN N/A
df8bdeb362277e8d95a74d6c097341fe97409948johnz * elfcertlib_allocatecert - create a new ELFCert_t
df8bdeb362277e8d95a74d6c097341fe97409948johnz * RETURN ELFCert_t, NULL on failure.
df8bdeb362277e8d95a74d6c097341fe97409948johnz "elfcertlib_allocatecert: malloc failed %s",
df8bdeb362277e8d95a74d6c097341fe97409948johnz * elfcertlib_freecert - freeup the memory of a cert
df8bdeb362277e8d95a74d6c097341fe97409948johnz * RETURN N/A