/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <limits.h>
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
#include <strings.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <md5.h>
#include <pthread.h>
#include <cryptoutil.h>
#include <kmfapi.h>
#include <libelfsign.h>
#include <synch.h>
/*
* The CACERT and OBJCACERT are the Cryptographic Trust Anchors
* for the Solaris Cryptographic Framework.
*
* The SECACERT is the Signed Execution Trust Anchor that the
* Cryptographic Framework uses for FIPS-140 validation of non-crypto
* binaries
*/
static ELFCert_t elfcertlib_allocatecert(void);
/*
* elfcertlib_verifycert - Verify the Cert with a Trust Anchor
*
* IN ess - elfsign context structure
* cert
* OUT NONE
*
* We first setup the Trust Anchor (CA and SUNWObjectCA) certs
* if it hasn't been done already. We verify that the files on disk
* are those we expected.
*
* We then verify the given cert using the publickey of a TA.
* If the passed in cert is a TA or it has been verified already we
* short cut and return TRUE without futher validation.
*/
/*ARGSUSED*/
{
int numattr;
return (B_TRUE);
}
(void) pthread_mutex_lock(&ca_mutex);
}
}
(void) elfcertlib_getcert(ess,
}
(void) pthread_mutex_unlock(&ca_mutex);
numattr = 0;
sizeof (KMF_DATA));
sizeof (KMF_DATA));
return (B_TRUE);
}
}
numattr = 0;
sizeof (KMF_DATA));
sizeof (KMF_DATA));
return (B_TRUE);
}
}
numattr = 0;
sizeof (KMF_DATA));
sizeof (KMF_DATA));
return (B_TRUE);
}
}
return (B_FALSE);
}
/*
* elfcertlib_getcert - Get the certificate for signer_DN
*
* IN ess - elfsign context structure
* cert_pathname - path to cert (May be NULL)
* signer_DN - The DN we are looking for (May be NULL)
* action - indicates crypto verification call
*
* If the cert_pathname is passed use it and don't search.
* Otherwise, go looking in certificate directories
*/
{
cryptodebug("elfcertlib_getcert: path=%s, DN=%s",
cryptodebug("elfcertlib_getcert: lack of specificity");
return (ret);
}
if (cert_pathname != NULL) {
/* look in the specified object */
*plp++ = cert_pathname;
} else {
/* look in the certificate directories */
*plp++ = (char *)_PATH_ELFSIGN_CRYPTO_CERTS;
/*
* crypto verifications don't search beyond
* _PATH_ELFSIGN_CRYPTO_CERTS
*/
if (action != ES_GET_CRYPTO)
*plp++ = (char *)_PATH_ELFSIGN_ETC_CERTS;
}
return (ret);
}
int numattr;
ncerts = 2;
numattr = 0;
sizeof (KMF_X509_DER_CERT));
}
sizeof (KMF_CERT_VALIDITY));
continue;
/* found one */
if (ncerts > 1) {
/* release any extras */
/* There can be only one */
cryptodebug("elfcertlib_getcert: "
"too many certificates found in %s",
goto cleanup;
}
}
/* cache subject and issuer */
goto cleanup;
goto cleanup;
break;
}
cryptodebug("elfcertlib_getcert: no certificate found");
goto cleanup;
}
/*
* If the cert we are loading is the trust anchor (ie the CA) then
* we mark it as such in cert. This is so that we don't attempt
* to verify it later. The CA is always implicitly verified.
*/
if (cert_pathname != NULL && (
}
if (ret) {
} else {
"for DN: %s", signer_DN);
else
"from %s", cert_pathname);
}
return (ret);
}
/*
* elfcertlib_loadprivatekey - Load the private key from path
*
* IN ess - elfsign context structure
* cert
* pathname
* OUT cert
*/
{
int numattr;
nkeys = 2;
numattr = 0;
keybuf, sizeof (KMF_KEY_HANDLE));
return (B_FALSE);
if (nkeys != 1) {
/* lack of specificity */
return (B_FALSE);
}
return (B_TRUE);
}
/*
* elfcertlib_loadtokenkey - Load the private key from token
*
* IN ess - elfsign context structure
* cert
* token_label
* pin
* OUT cert
*/
const char *token_label, const char *pin)
{
char *kmferr;
int numattr;
/*
* We will search for the key based on the ID attribute
* which was added when the key was created. ID is
* a SHA-1 hash of the public modulus shared by the
* key and the certificate.
*/
cryptodebug("Error getting ID from cert: %s\n",
return (B_FALSE);
}
nkeys = 1;
numattr = 0;
&pincred, sizeof (KMF_CREDENTIAL));
&privatebool, sizeof (privatebool));
cryptodebug("Error finding private key: %s\n",
return (B_FALSE);
}
if (nkeys != 1) {
cryptodebug("Error finding private key: No key found\n");
return (B_FALSE);
}
cryptodebug("elfcertlib_loadprivatekey = 0x%.8X",
&cert->c_privatekey);
return (B_TRUE);
}
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10};
/*
* elfcertlib_sign - sign the given DATA using the privatekey in cert
*
* IN ess - elfsign context structure
* cert
* data
* data_len
* OUT sig - must be big enough to hold the signature of data
* Caller must allocate
* sig_len - actual length used; 0 on failure.
*/
/*ARGSUSED*/
{
int numattr;
/* compatibility: take MD5 hash of SHA1 hash */
/*
* first: digest using software-based methods, don't
* rely on the token for hashing.
*/
/*
* second: insert prefix
*/
sizeof (MD5_DER_PREFIX));
/*
* prepare to sign the local buffer
*/
} else {
}
numattr = 0;
sizeof (KMF_KEYSTORE_TYPE));
char *kmferr;
cryptodebug("Error signing data: %s\n",
*sig_len = 0;
return (B_FALSE);
}
return (B_TRUE);
}
/*
* elfcertlib_verifysig - verify the given DATA using the public key in cert
*
* IN ess - elfsign context structure
* cert
* signature
* sig_len
* data
* data_len
* OUT N/A
*/
{
int numattr;
else
/*
* We tell KMF to use the PKCS11 verification APIs
* here to prevent the use of OpenSSL and to keep
* all validation within the FIPS-140 boundary for
* the Cryptographic Framework.
*/
numattr = 0;
}
/*
* elfcertlib_getdn
*
* IN cert
* OUT NONE
* RETURN dn or NULL
*/
char *
{
cryptodebug("elfcertlib_getdn");
}
/*
* elfcertlib_getissuer
*
* IN cert
* OUT NONE
* RETURN dn or NULL
*/
char *
{
cryptodebug("elfcertlib_issuer");
}
{
"unable to initialize KMF library");
}
}
return (rc);
}
void
{
}
/*
* set the token device
*/
{
int numattr;
numattr = 0;
}
return (rc);
}
/*
* set the certificate CA identification callback
*/
void
{
}
/*
* set the certificate verification callback
*/
void
{
}
/*
* elfcertlib_releasecert - release a cert
*
* IN cert
* OUT cert
* RETURN N/A
*
*/
void
{
}
/*
* elfcertlib_allocatecert - create a new ELFCert_t
*
* IN N/A
* OUT N/A
* RETURN ELFCert_t, NULL on failure.
*/
static ELFCert_t
elfcertlib_allocatecert(void)
{
"elfcertlib_allocatecert: malloc failed %s",
return (NULL);
}
return (cert);
}
/*
* elfcertlib_freecert - freeup the memory of a cert
*
* IN cert
* OUT cert
* RETURN N/A
*
*/
static void
{
return;
}