15194Sjohnz /*
25194Sjohnz * CDDL HEADER START
35194Sjohnz *
45194Sjohnz * The contents of this file are subject to the terms of the
55194Sjohnz * Common Development and Distribution License (the "License").
65194Sjohnz * You may not use this file except in compliance with the License.
75194Sjohnz *
85194Sjohnz * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95194Sjohnz * or http://www.opensolaris.org/os/licensing.
105194Sjohnz * See the License for the specific language governing permissions
115194Sjohnz * and limitations under the License.
125194Sjohnz *
135194Sjohnz * When distributing Covered Code, include this CDDL HEADER in each
145194Sjohnz * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155194Sjohnz * If applicable, add the following below this CDDL HEADER, with the
165194Sjohnz * fields enclosed by brackets "[]" replaced with your own identifying
175194Sjohnz * information: Portions Copyright [yyyy] [name of copyright owner]
185194Sjohnz *
195194Sjohnz * CDDL HEADER END
205194Sjohnz */
215194Sjohnz
225194Sjohnz /*
23*11462Swyllys.ingersoll@sun.com * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
245194Sjohnz * Use is subject to license terms.
255194Sjohnz */
265194Sjohnz
275194Sjohnz #include <limits.h>
285194Sjohnz #include <sys/types.h>
295194Sjohnz #include <sys/stat.h>
305194Sjohnz #include <fcntl.h>
315194Sjohnz #include <unistd.h>
325194Sjohnz #include <dirent.h>
335194Sjohnz #include <strings.h>
345194Sjohnz #include <stdio.h>
355194Sjohnz #include <stdlib.h>
365194Sjohnz #include <errno.h>
375194Sjohnz #include <sys/mman.h>
385194Sjohnz #include <md5.h>
395194Sjohnz #include <pthread.h>
405194Sjohnz
415194Sjohnz #include <cryptoutil.h>
425194Sjohnz
435194Sjohnz #include <kmfapi.h>
445194Sjohnz #include <sys/crypto/elfsign.h>
455194Sjohnz #include <libelfsign.h>
465194Sjohnz
475194Sjohnz #include <synch.h>
485194Sjohnz
495194Sjohnz const char _PATH_ELFSIGN_CRYPTO_CERTS[] = CRYPTO_CERTS_DIR;
505194Sjohnz const char _PATH_ELFSIGN_ETC_CERTS[] = ETC_CERTS_DIR;
515194Sjohnz
525194Sjohnz /*
535194Sjohnz * The CACERT and OBJCACERT are the Cryptographic Trust Anchors
545194Sjohnz * for the Solaris Cryptographic Framework.
5510732SAnthony.Scarpino@Sun.COM *
5610732SAnthony.Scarpino@Sun.COM * The SECACERT is the Signed Execution Trust Anchor that the
5710732SAnthony.Scarpino@Sun.COM * Cryptographic Framework uses for FIPS-140 validation of non-crypto
5810732SAnthony.Scarpino@Sun.COM * binaries
595194Sjohnz */
605194Sjohnz static const char _PATH_CRYPTO_CACERT[] = CRYPTO_CERTS_DIR "/CA";
615194Sjohnz static const char _PATH_CRYPTO_OBJCACERT[] = CRYPTO_CERTS_DIR "/SUNWObjectCA";
6210732SAnthony.Scarpino@Sun.COM static const char _PATH_CRYPTO_SECACERT[] = ETC_CERTS_DIR "/SUNWSolarisCA";
635194Sjohnz static ELFCert_t CACERT = NULL;
645194Sjohnz static ELFCert_t OBJCACERT = NULL;
6510732SAnthony.Scarpino@Sun.COM static ELFCert_t SECACERT = NULL;
665194Sjohnz static pthread_mutex_t ca_mutex = PTHREAD_MUTEX_INITIALIZER;
675194Sjohnz
685194Sjohnz static void elfcertlib_freecert(ELFsign_t, ELFCert_t);
695194Sjohnz static ELFCert_t elfcertlib_allocatecert(void);
705194Sjohnz
715194Sjohnz /*
725194Sjohnz * elfcertlib_verifycert - Verify the Cert with a Trust Anchor
735194Sjohnz *
745194Sjohnz * IN ess - elfsign context structure
755194Sjohnz * cert
765194Sjohnz * OUT NONE
775194Sjohnz * RETURN TRUE/FALSE
785194Sjohnz *
795194Sjohnz * We first setup the Trust Anchor (CA and SUNWObjectCA) certs
805194Sjohnz * if it hasn't been done already. We verify that the files on disk
815194Sjohnz * are those we expected.
825194Sjohnz *
835194Sjohnz * We then verify the given cert using the publickey of a TA.
845194Sjohnz * If the passed in cert is a TA or it has been verified already we
855194Sjohnz * short cut and return TRUE without futher validation.
865194Sjohnz */
875194Sjohnz /*ARGSUSED*/
885194Sjohnz boolean_t
elfcertlib_verifycert(ELFsign_t ess,ELFCert_t cert)895194Sjohnz elfcertlib_verifycert(ELFsign_t ess, ELFCert_t cert)
905194Sjohnz {
9110671SJohn.Zolnowsky@Sun.COM KMF_ATTRIBUTE attrlist[8];
9210671SJohn.Zolnowsky@Sun.COM int numattr;
9310671SJohn.Zolnowsky@Sun.COM
945194Sjohnz KMF_RETURN rv;
955194Sjohnz if ((cert->c_verified == E_OK) || (cert->c_verified == E_IS_TA)) {
965194Sjohnz return (B_TRUE);
975194Sjohnz }
985194Sjohnz
995194Sjohnz (void) pthread_mutex_lock(&ca_mutex);
1005194Sjohnz if (CACERT == NULL) {
1015194Sjohnz (void) elfcertlib_getcert(ess, (char *)_PATH_CRYPTO_CACERT,
1025194Sjohnz NULL, &CACERT, ES_GET);
1035194Sjohnz }
10410732SAnthony.Scarpino@Sun.COM
1055194Sjohnz if (OBJCACERT == NULL) {
1065194Sjohnz (void) elfcertlib_getcert(ess, (char *)_PATH_CRYPTO_OBJCACERT,
1075194Sjohnz NULL, &OBJCACERT, ES_GET);
1085194Sjohnz }
10910732SAnthony.Scarpino@Sun.COM
11010732SAnthony.Scarpino@Sun.COM if (SECACERT == NULL) {
11110732SAnthony.Scarpino@Sun.COM (void) elfcertlib_getcert(ess,
11210732SAnthony.Scarpino@Sun.COM (char *)_PATH_CRYPTO_SECACERT, NULL, &SECACERT,
11310732SAnthony.Scarpino@Sun.COM ES_GET_FIPS140);
11410732SAnthony.Scarpino@Sun.COM }
11510732SAnthony.Scarpino@Sun.COM
1165194Sjohnz (void) pthread_mutex_unlock(&ca_mutex);
1175194Sjohnz
1185194Sjohnz if (CACERT != NULL) {
11910671SJohn.Zolnowsky@Sun.COM numattr = 0;
12010671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++,
12110671SJohn.Zolnowsky@Sun.COM KMF_CERT_DATA_ATTR, &cert->c_cert.certificate,
12210671SJohn.Zolnowsky@Sun.COM sizeof (KMF_DATA));
12310671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++,
12410671SJohn.Zolnowsky@Sun.COM KMF_SIGNER_CERT_DATA_ATTR, &CACERT->c_cert.certificate,
12510671SJohn.Zolnowsky@Sun.COM sizeof (KMF_DATA));
12610671SJohn.Zolnowsky@Sun.COM
12710671SJohn.Zolnowsky@Sun.COM rv = kmf_verify_cert(ess->es_kmfhandle, numattr, attrlist);
1285194Sjohnz if (rv == KMF_OK) {
1295194Sjohnz if (ess->es_certCAcallback != NULL)
1305194Sjohnz (ess->es_certvercallback)(ess->es_callbackctx,
1315194Sjohnz cert, CACERT);
1325194Sjohnz cert->c_verified = E_OK;
1335194Sjohnz return (B_TRUE);
1345194Sjohnz }
1355194Sjohnz }
1365194Sjohnz
1375194Sjohnz if (OBJCACERT != NULL) {
13810671SJohn.Zolnowsky@Sun.COM numattr = 0;
13910671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++,
14010671SJohn.Zolnowsky@Sun.COM KMF_CERT_DATA_ATTR, &cert->c_cert.certificate,
14110671SJohn.Zolnowsky@Sun.COM sizeof (KMF_DATA));
14210671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++,
14310671SJohn.Zolnowsky@Sun.COM KMF_SIGNER_CERT_DATA_ATTR, &OBJCACERT->c_cert.certificate,
14410671SJohn.Zolnowsky@Sun.COM sizeof (KMF_DATA));
14510671SJohn.Zolnowsky@Sun.COM
14610671SJohn.Zolnowsky@Sun.COM rv = kmf_verify_cert(ess->es_kmfhandle, numattr, attrlist);
1475194Sjohnz if (rv == KMF_OK) {
1485194Sjohnz if (ess->es_certCAcallback != NULL)
1495194Sjohnz (ess->es_certvercallback)(ess->es_callbackctx,
1505194Sjohnz cert, OBJCACERT);
1515194Sjohnz cert->c_verified = E_OK;
1525194Sjohnz return (B_TRUE);
1535194Sjohnz }
1545194Sjohnz }
1555194Sjohnz
15610732SAnthony.Scarpino@Sun.COM if (SECACERT != NULL) {
157*11462Swyllys.ingersoll@sun.com numattr = 0;
158*11462Swyllys.ingersoll@sun.com kmf_set_attr_at_index(attrlist, numattr++,
159*11462Swyllys.ingersoll@sun.com KMF_CERT_DATA_ATTR, &cert->c_cert.certificate,
160*11462Swyllys.ingersoll@sun.com sizeof (KMF_DATA));
161*11462Swyllys.ingersoll@sun.com kmf_set_attr_at_index(attrlist, numattr++,
162*11462Swyllys.ingersoll@sun.com KMF_SIGNER_CERT_DATA_ATTR, &SECACERT->c_cert.certificate,
163*11462Swyllys.ingersoll@sun.com sizeof (KMF_DATA));
164*11462Swyllys.ingersoll@sun.com
165*11462Swyllys.ingersoll@sun.com rv = kmf_verify_cert(ess->es_kmfhandle, numattr, attrlist);
16610732SAnthony.Scarpino@Sun.COM if (rv == KMF_OK) {
16710732SAnthony.Scarpino@Sun.COM if (ess->es_certCAcallback != NULL)
16810732SAnthony.Scarpino@Sun.COM (ess->es_certvercallback)(ess->es_callbackctx,
16910732SAnthony.Scarpino@Sun.COM cert, SECACERT);
17010732SAnthony.Scarpino@Sun.COM cert->c_verified = E_OK;
17110732SAnthony.Scarpino@Sun.COM return (B_TRUE);
17210732SAnthony.Scarpino@Sun.COM }
17310732SAnthony.Scarpino@Sun.COM }
17410732SAnthony.Scarpino@Sun.COM
1755194Sjohnz return (B_FALSE);
1765194Sjohnz }
1775194Sjohnz
1785194Sjohnz /*
1795194Sjohnz * elfcertlib_getcert - Get the certificate for signer_DN
1805194Sjohnz *
1815194Sjohnz * IN ess - elfsign context structure
1825194Sjohnz * cert_pathname - path to cert (May be NULL)
1835194Sjohnz * signer_DN - The DN we are looking for (May be NULL)
1845194Sjohnz * action - indicates crypto verification call
1855194Sjohnz * OUT certp - allocated/loaded ELFCert_t
1865194Sjohnz *
1875194Sjohnz * If the cert_pathname is passed use it and don't search.
1885194Sjohnz * Otherwise, go looking in certificate directories
1895194Sjohnz */
1905194Sjohnz boolean_t
elfcertlib_getcert(ELFsign_t ess,char * cert_pathname,char * signer_DN,ELFCert_t * certp,enum ES_ACTION action)1915194Sjohnz elfcertlib_getcert(ELFsign_t ess, char *cert_pathname,
1925194Sjohnz char *signer_DN, ELFCert_t *certp, enum ES_ACTION action)
1935194Sjohnz {
1945194Sjohnz KMF_RETURN rv;
1955194Sjohnz ELFCert_t cert = NULL;
1965194Sjohnz KMF_X509_DER_CERT certbuf[2];
1975194Sjohnz uint32_t ncerts;
1985194Sjohnz boolean_t ret = B_FALSE;
1995194Sjohnz char *pathlist[3], **plp;
2005194Sjohnz
2015194Sjohnz cryptodebug("elfcertlib_getcert: path=%s, DN=%s",
2025194Sjohnz cert_pathname ? cert_pathname : "-none-",
2035194Sjohnz signer_DN ? signer_DN : "-none-");
2045194Sjohnz *certp = NULL;
2055194Sjohnz if (cert_pathname == NULL && signer_DN == NULL) {
2065194Sjohnz cryptodebug("elfcertlib_getcert: lack of specificity");
2075194Sjohnz return (ret);
2085194Sjohnz }
2095194Sjohnz
2105194Sjohnz plp = pathlist;
2115194Sjohnz if (cert_pathname != NULL) {
2125194Sjohnz /* look in the specified object */
2135194Sjohnz *plp++ = cert_pathname;
2145194Sjohnz } else {
2155194Sjohnz /* look in the certificate directories */
2165194Sjohnz *plp++ = (char *)_PATH_ELFSIGN_CRYPTO_CERTS;
2175194Sjohnz /*
2185194Sjohnz * crypto verifications don't search beyond
2195194Sjohnz * _PATH_ELFSIGN_CRYPTO_CERTS
2205194Sjohnz */
2215194Sjohnz if (action != ES_GET_CRYPTO)
2225194Sjohnz *plp++ = (char *)_PATH_ELFSIGN_ETC_CERTS;
2235194Sjohnz }
2245194Sjohnz *plp = NULL;
2255194Sjohnz
2265194Sjohnz if ((cert = elfcertlib_allocatecert()) == NULL) {
2275194Sjohnz return (ret);
2285194Sjohnz }
2295194Sjohnz
2305194Sjohnz for (plp = pathlist; *plp; plp++) {
23110671SJohn.Zolnowsky@Sun.COM KMF_ATTRIBUTE attrlist[8];
23210671SJohn.Zolnowsky@Sun.COM KMF_KEYSTORE_TYPE kstype;
23310671SJohn.Zolnowsky@Sun.COM KMF_CERT_VALIDITY certvalidity;
23410671SJohn.Zolnowsky@Sun.COM int numattr;
23510671SJohn.Zolnowsky@Sun.COM
23610671SJohn.Zolnowsky@Sun.COM kstype = KMF_KEYSTORE_OPENSSL;
23710671SJohn.Zolnowsky@Sun.COM certvalidity = KMF_ALL_CERTS;
2385194Sjohnz ncerts = 2;
2395194Sjohnz
24010671SJohn.Zolnowsky@Sun.COM numattr = 0;
24110671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++,
24210671SJohn.Zolnowsky@Sun.COM KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
24310671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++,
24410671SJohn.Zolnowsky@Sun.COM KMF_X509_DER_CERT_ATTR, certbuf,
24510671SJohn.Zolnowsky@Sun.COM sizeof (KMF_X509_DER_CERT));
24610671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++,
24710671SJohn.Zolnowsky@Sun.COM KMF_COUNT_ATTR, &ncerts, sizeof (uint32_t));
24810671SJohn.Zolnowsky@Sun.COM if (signer_DN != NULL) {
24910671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++,
25010671SJohn.Zolnowsky@Sun.COM KMF_SUBJECT_NAME_ATTR, signer_DN,
25110671SJohn.Zolnowsky@Sun.COM strlen(signer_DN));
25210671SJohn.Zolnowsky@Sun.COM }
25310671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++,
25410671SJohn.Zolnowsky@Sun.COM KMF_CERT_VALIDITY_ATTR, &certvalidity,
25510671SJohn.Zolnowsky@Sun.COM sizeof (KMF_CERT_VALIDITY));
25610671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++,
25710671SJohn.Zolnowsky@Sun.COM KMF_CERT_FILENAME_ATTR, *plp, strlen (*plp));
25810671SJohn.Zolnowsky@Sun.COM
25910671SJohn.Zolnowsky@Sun.COM rv = kmf_find_cert(ess->es_kmfhandle, numattr, attrlist);
26010671SJohn.Zolnowsky@Sun.COM
2615194Sjohnz if (rv != KMF_OK)
2625194Sjohnz continue;
26310671SJohn.Zolnowsky@Sun.COM /* found one */
26410671SJohn.Zolnowsky@Sun.COM cert->c_cert = certbuf[0];
26510671SJohn.Zolnowsky@Sun.COM if (ncerts > 1) {
26610671SJohn.Zolnowsky@Sun.COM /* release any extras */
26710671SJohn.Zolnowsky@Sun.COM kmf_free_kmf_cert(ess->es_kmfhandle, &certbuf[1]);
26810671SJohn.Zolnowsky@Sun.COM if (signer_DN == NULL) {
26910671SJohn.Zolnowsky@Sun.COM /* There can be only one */
27010671SJohn.Zolnowsky@Sun.COM cryptodebug("elfcertlib_getcert: "
27110671SJohn.Zolnowsky@Sun.COM "too many certificates found in %s",
27210671SJohn.Zolnowsky@Sun.COM cert_pathname);
27310671SJohn.Zolnowsky@Sun.COM goto cleanup;
27410671SJohn.Zolnowsky@Sun.COM }
2755194Sjohnz }
27610671SJohn.Zolnowsky@Sun.COM /* cache subject and issuer */
27710671SJohn.Zolnowsky@Sun.COM rv = kmf_get_cert_subject_str(ess->es_kmfhandle,
2785194Sjohnz &cert->c_cert.certificate, &cert->c_subject);
2795194Sjohnz if (rv != KMF_OK)
2805194Sjohnz goto cleanup;
2815194Sjohnz
28210671SJohn.Zolnowsky@Sun.COM rv = kmf_get_cert_issuer_str(ess->es_kmfhandle,
2835194Sjohnz &cert->c_cert.certificate, &cert->c_issuer);
2845194Sjohnz if (rv != KMF_OK)
2855194Sjohnz goto cleanup;
2865194Sjohnz break;
2875194Sjohnz }
2885194Sjohnz if (*plp == NULL) {
2895194Sjohnz cryptodebug("elfcertlib_getcert: no certificate found");
2905194Sjohnz goto cleanup;
2915194Sjohnz }
2925194Sjohnz
2935194Sjohnz cert->c_verified = E_UNCHECKED;
2945194Sjohnz
2955194Sjohnz /*
29610123SValerie.Fenwick@Sun.COM * If the cert we are loading is the trust anchor (ie the CA) then
2975194Sjohnz * we mark it as such in cert. This is so that we don't attempt
2985194Sjohnz * to verify it later. The CA is always implicitly verified.
2995194Sjohnz */
3005194Sjohnz if (cert_pathname != NULL && (
3015194Sjohnz strcmp(cert_pathname, _PATH_CRYPTO_CACERT) == 0 ||
30210732SAnthony.Scarpino@Sun.COM strcmp(cert_pathname, _PATH_CRYPTO_OBJCACERT) == 0 ||
30310732SAnthony.Scarpino@Sun.COM strcmp(cert_pathname, _PATH_CRYPTO_SECACERT) == 0)) {
3045194Sjohnz if (ess->es_certCAcallback != NULL)
3055194Sjohnz (ess->es_certCAcallback)(ess->es_callbackctx, cert,
3065194Sjohnz cert_pathname);
3075194Sjohnz cert->c_verified = E_IS_TA;
3085194Sjohnz }
3095194Sjohnz
3105194Sjohnz ret = B_TRUE;
3115194Sjohnz
3125194Sjohnz cleanup:
3135194Sjohnz if (ret) {
3145194Sjohnz *certp = cert;
3155194Sjohnz } else {
3165194Sjohnz if (cert != NULL)
3175194Sjohnz elfcertlib_freecert(ess, cert);
3185194Sjohnz if (signer_DN != NULL)
3195194Sjohnz cryptoerror(LOG_ERR, "unable to find a certificate "
3205194Sjohnz "for DN: %s", signer_DN);
3215194Sjohnz else
3225194Sjohnz cryptoerror(LOG_ERR, "unable to load certificate "
3235194Sjohnz "from %s", cert_pathname);
3245194Sjohnz }
3255194Sjohnz return (ret);
3265194Sjohnz }
3275194Sjohnz
3285194Sjohnz /*
3295194Sjohnz * elfcertlib_loadprivatekey - Load the private key from path
3305194Sjohnz *
3315194Sjohnz * IN ess - elfsign context structure
3325194Sjohnz * cert
3335194Sjohnz * pathname
3345194Sjohnz * OUT cert
3355194Sjohnz * RETURNS TRUE/FALSE
3365194Sjohnz */
3375194Sjohnz boolean_t
elfcertlib_loadprivatekey(ELFsign_t ess,ELFCert_t cert,const char * pathname)3385194Sjohnz elfcertlib_loadprivatekey(ELFsign_t ess, ELFCert_t cert, const char *pathname)
3395194Sjohnz {
34010671SJohn.Zolnowsky@Sun.COM KMF_RETURN rv = KMF_OK;
3415194Sjohnz KMF_KEY_HANDLE keybuf[2];
34210671SJohn.Zolnowsky@Sun.COM KMF_ATTRIBUTE attrlist[16];
34310671SJohn.Zolnowsky@Sun.COM uint32_t nkeys;
34410671SJohn.Zolnowsky@Sun.COM KMF_KEYSTORE_TYPE kstype;
34510671SJohn.Zolnowsky@Sun.COM KMF_KEY_ALG keytype;
34610671SJohn.Zolnowsky@Sun.COM KMF_KEY_CLASS keyclass;
34710671SJohn.Zolnowsky@Sun.COM KMF_ENCODE_FORMAT format;
34810671SJohn.Zolnowsky@Sun.COM int numattr;
34910671SJohn.Zolnowsky@Sun.COM
35010671SJohn.Zolnowsky@Sun.COM kstype = KMF_KEYSTORE_OPENSSL;
35110671SJohn.Zolnowsky@Sun.COM nkeys = 2;
35210671SJohn.Zolnowsky@Sun.COM keytype = KMF_KEYALG_NONE;
35310671SJohn.Zolnowsky@Sun.COM keyclass = KMF_ASYM_PRI;
35410671SJohn.Zolnowsky@Sun.COM format = KMF_FORMAT_UNDEF;
3555194Sjohnz
35610671SJohn.Zolnowsky@Sun.COM numattr = 0;
35710671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_KEYSTORE_TYPE_ATTR,
35810671SJohn.Zolnowsky@Sun.COM &kstype, sizeof (kstype));
35910671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_KEY_HANDLE_ATTR,
36010671SJohn.Zolnowsky@Sun.COM keybuf, sizeof (KMF_KEY_HANDLE));
36110671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_COUNT_ATTR,
36210671SJohn.Zolnowsky@Sun.COM &nkeys, sizeof (uint32_t));
36310671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_KEYALG_ATTR,
36410671SJohn.Zolnowsky@Sun.COM &keytype, sizeof (keytype));
36510671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_KEYCLASS_ATTR,
36610671SJohn.Zolnowsky@Sun.COM &keyclass, sizeof (keyclass));
36710671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_ENCODE_FORMAT_ATTR,
36810671SJohn.Zolnowsky@Sun.COM &format, sizeof (format));
36910671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_KEY_FILENAME_ATTR,
37010671SJohn.Zolnowsky@Sun.COM (char *)pathname, strlen(pathname));
3715194Sjohnz
37210671SJohn.Zolnowsky@Sun.COM rv = kmf_find_key(ess->es_kmfhandle, numattr, attrlist);
3735194Sjohnz if (rv != KMF_OK)
3745194Sjohnz return (B_FALSE);
3755194Sjohnz if (nkeys != 1) {
3765194Sjohnz /* lack of specificity */
3775194Sjohnz cryptodebug("found %d keys at %s", nkeys, pathname);
3785194Sjohnz return (B_FALSE);
3795194Sjohnz }
3805194Sjohnz cert->c_privatekey = keybuf[0];
3815194Sjohnz cryptodebug("key %s loaded", pathname);
3825194Sjohnz return (B_TRUE);
3835194Sjohnz }
3845194Sjohnz
3855194Sjohnz /*
3865194Sjohnz * elfcertlib_loadtokenkey - Load the private key from token
3875194Sjohnz *
3885194Sjohnz * IN ess - elfsign context structure
3895194Sjohnz * cert
3905194Sjohnz * token_label
3915194Sjohnz * pin
3925194Sjohnz * OUT cert
3935194Sjohnz * RETURNS TRUE/FALSE
3945194Sjohnz */
3955194Sjohnz boolean_t
elfcertlib_loadtokenkey(ELFsign_t ess,ELFCert_t cert,const char * token_label,const char * pin)3965194Sjohnz elfcertlib_loadtokenkey(ELFsign_t ess, ELFCert_t cert,
3975194Sjohnz const char *token_label, const char *pin)
3985194Sjohnz {
39910671SJohn.Zolnowsky@Sun.COM KMF_RETURN rv;
40010671SJohn.Zolnowsky@Sun.COM char *idstr = NULL;
40110671SJohn.Zolnowsky@Sun.COM char *kmferr;
40210671SJohn.Zolnowsky@Sun.COM KMF_ATTRIBUTE attrlist[16];
40310671SJohn.Zolnowsky@Sun.COM uint32_t nkeys;
40410671SJohn.Zolnowsky@Sun.COM KMF_KEYSTORE_TYPE kstype;
40510671SJohn.Zolnowsky@Sun.COM KMF_KEY_ALG keytype;
40610671SJohn.Zolnowsky@Sun.COM KMF_KEY_CLASS keyclass;
40710671SJohn.Zolnowsky@Sun.COM KMF_ENCODE_FORMAT format;
40810671SJohn.Zolnowsky@Sun.COM KMF_CREDENTIAL pincred;
40910671SJohn.Zolnowsky@Sun.COM boolean_t tokenbool, privatebool;
41010671SJohn.Zolnowsky@Sun.COM int numattr;
4115194Sjohnz
4125194Sjohnz /*
4135194Sjohnz * We will search for the key based on the ID attribute
4145194Sjohnz * which was added when the key was created. ID is
4155194Sjohnz * a SHA-1 hash of the public modulus shared by the
4165194Sjohnz * key and the certificate.
4175194Sjohnz */
41810671SJohn.Zolnowsky@Sun.COM rv = kmf_get_cert_id_str(&cert->c_cert.certificate, &idstr);
4195194Sjohnz if (rv != KMF_OK) {
42010671SJohn.Zolnowsky@Sun.COM (void) kmf_get_kmf_error_str(rv, &kmferr);
42110671SJohn.Zolnowsky@Sun.COM cryptodebug("Error getting ID from cert: %s\n",
42210671SJohn.Zolnowsky@Sun.COM (kmferr ? kmferr : "Unrecognized KMF error"));
42310671SJohn.Zolnowsky@Sun.COM free(kmferr);
4245194Sjohnz return (B_FALSE);
4255194Sjohnz }
42610671SJohn.Zolnowsky@Sun.COM
42710671SJohn.Zolnowsky@Sun.COM kstype = KMF_KEYSTORE_PK11TOKEN;
42810671SJohn.Zolnowsky@Sun.COM nkeys = 1;
42910671SJohn.Zolnowsky@Sun.COM keytype = KMF_KEYALG_NONE;
43010671SJohn.Zolnowsky@Sun.COM keyclass = KMF_ASYM_PRI;
43110671SJohn.Zolnowsky@Sun.COM format = KMF_FORMAT_UNDEF;
43210671SJohn.Zolnowsky@Sun.COM pincred.cred = (char *)pin;
43310671SJohn.Zolnowsky@Sun.COM pincred.credlen = strlen(pin);
43410671SJohn.Zolnowsky@Sun.COM tokenbool = B_FALSE;
43510671SJohn.Zolnowsky@Sun.COM privatebool = B_TRUE;
4365194Sjohnz
43710671SJohn.Zolnowsky@Sun.COM numattr = 0;
43810671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_KEYSTORE_TYPE_ATTR,
43910671SJohn.Zolnowsky@Sun.COM &kstype, sizeof (kstype));
44010671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_KEY_HANDLE_ATTR,
44110671SJohn.Zolnowsky@Sun.COM &cert->c_privatekey, sizeof (KMF_KEY_HANDLE));
44210671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_COUNT_ATTR,
44310671SJohn.Zolnowsky@Sun.COM &nkeys, sizeof (uint32_t));
44410671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_KEYALG_ATTR,
44510671SJohn.Zolnowsky@Sun.COM &keytype, sizeof (keytype));
44610671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_KEYCLASS_ATTR,
44710671SJohn.Zolnowsky@Sun.COM &keyclass, sizeof (keyclass));
44810671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_ENCODE_FORMAT_ATTR,
44910671SJohn.Zolnowsky@Sun.COM &format, sizeof (format));
45010671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_IDSTR_ATTR,
45110671SJohn.Zolnowsky@Sun.COM idstr, strlen(idstr));
45210671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_CREDENTIAL_ATTR,
45310671SJohn.Zolnowsky@Sun.COM &pincred, sizeof (KMF_CREDENTIAL));
45410671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_TOKEN_BOOL_ATTR,
45510671SJohn.Zolnowsky@Sun.COM &tokenbool, sizeof (tokenbool));
45610671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_PRIVATE_BOOL_ATTR,
45710671SJohn.Zolnowsky@Sun.COM &privatebool, sizeof (privatebool));
45810671SJohn.Zolnowsky@Sun.COM
45910671SJohn.Zolnowsky@Sun.COM rv = kmf_find_key(ess->es_kmfhandle, numattr, attrlist);
46010671SJohn.Zolnowsky@Sun.COM free(idstr);
46110671SJohn.Zolnowsky@Sun.COM if (rv != KMF_OK) {
46210671SJohn.Zolnowsky@Sun.COM (void) kmf_get_kmf_error_str(rv, &kmferr);
46310671SJohn.Zolnowsky@Sun.COM cryptodebug("Error finding private key: %s\n",
46410671SJohn.Zolnowsky@Sun.COM (kmferr ? kmferr : "Unrecognized KMF error"));
46510671SJohn.Zolnowsky@Sun.COM free(kmferr);
46610671SJohn.Zolnowsky@Sun.COM return (B_FALSE);
46710671SJohn.Zolnowsky@Sun.COM }
46810671SJohn.Zolnowsky@Sun.COM if (nkeys != 1) {
46910671SJohn.Zolnowsky@Sun.COM cryptodebug("Error finding private key: No key found\n");
4705194Sjohnz return (B_FALSE);
4715194Sjohnz }
4725194Sjohnz cryptodebug("key found in %s", token_label);
4735194Sjohnz cryptodebug("elfcertlib_loadprivatekey = 0x%.8X",
4745194Sjohnz &cert->c_privatekey);
4755194Sjohnz
4765194Sjohnz return (B_TRUE);
4775194Sjohnz }
4785194Sjohnz
4795194Sjohnz static const CK_BYTE MD5_DER_PREFIX[] = {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08,
4805194Sjohnz 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10};
4815194Sjohnz
4825194Sjohnz /*
4835194Sjohnz * elfcertlib_sign - sign the given DATA using the privatekey in cert
4845194Sjohnz *
4855194Sjohnz * IN ess - elfsign context structure
4865194Sjohnz * cert
4875194Sjohnz * data
4885194Sjohnz * data_len
4895194Sjohnz * OUT sig - must be big enough to hold the signature of data
4905194Sjohnz * Caller must allocate
4915194Sjohnz * sig_len - actual length used; 0 on failure.
4925194Sjohnz * RETURNS TRUE/FALSE
4935194Sjohnz */
4945194Sjohnz /*ARGSUSED*/
4955194Sjohnz boolean_t
elfcertlib_sign(ELFsign_t ess,ELFCert_t cert,const uchar_t * data,size_t data_len,uchar_t * sig,size_t * sig_len)4965194Sjohnz elfcertlib_sign(ELFsign_t ess, ELFCert_t cert,
4975194Sjohnz const uchar_t *data, size_t data_len,
4985194Sjohnz uchar_t *sig, size_t *sig_len)
4995194Sjohnz {
50010671SJohn.Zolnowsky@Sun.COM KMF_RETURN ret;
50110671SJohn.Zolnowsky@Sun.COM KMF_DATA tobesigned;
50210671SJohn.Zolnowsky@Sun.COM KMF_DATA signature;
50310671SJohn.Zolnowsky@Sun.COM uchar_t der_data[sizeof (MD5_DER_PREFIX) + MD5_DIGEST_LENGTH];
50410671SJohn.Zolnowsky@Sun.COM KMF_ATTRIBUTE attrlist[8];
50510671SJohn.Zolnowsky@Sun.COM int numattr;
5065194Sjohnz
5075194Sjohnz if (ess->es_version <= FILESIG_VERSION2) {
5085194Sjohnz /* compatibility: take MD5 hash of SHA1 hash */
5095194Sjohnz size_t derlen = MD5_DIGEST_LENGTH;
5105194Sjohnz MD5_CTX ctx;
5115194Sjohnz
5125194Sjohnz /*
5135194Sjohnz * first: digest using software-based methods, don't
5145194Sjohnz * rely on the token for hashing.
5155194Sjohnz */
5165194Sjohnz MD5Init(&ctx);
5175194Sjohnz MD5Update(&ctx, data, data_len);
5185194Sjohnz MD5Final(&der_data[sizeof (MD5_DER_PREFIX)], &ctx);
5195194Sjohnz
5205194Sjohnz /*
5215194Sjohnz * second: insert prefix
5225194Sjohnz */
5235194Sjohnz (void) memcpy(der_data, MD5_DER_PREFIX,
5245194Sjohnz sizeof (MD5_DER_PREFIX));
5255194Sjohnz /*
5265194Sjohnz * prepare to sign the local buffer
5275194Sjohnz */
5285194Sjohnz tobesigned.Data = (uchar_t *)der_data;
5295194Sjohnz tobesigned.Length = sizeof (MD5_DER_PREFIX) + derlen;
5305194Sjohnz } else {
5315194Sjohnz tobesigned.Data = (uchar_t *)data;
5325194Sjohnz tobesigned.Length = data_len;
5335194Sjohnz }
5345194Sjohnz
5355194Sjohnz signature.Data = (uchar_t *)sig;
5365194Sjohnz signature.Length = *sig_len;
5375194Sjohnz
53810671SJohn.Zolnowsky@Sun.COM numattr = 0;
53910671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++,
54010671SJohn.Zolnowsky@Sun.COM KMF_KEYSTORE_TYPE_ATTR, &(cert->c_privatekey.kstype),
54110671SJohn.Zolnowsky@Sun.COM sizeof (KMF_KEYSTORE_TYPE));
54210671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++,
54310671SJohn.Zolnowsky@Sun.COM KMF_KEY_HANDLE_ATTR, &cert->c_privatekey, sizeof (KMF_KEY_HANDLE));
54410671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++,
54510671SJohn.Zolnowsky@Sun.COM KMF_OID_ATTR, (KMF_OID *)&KMFOID_RSA, sizeof (KMF_OID));
54610671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++,
54710671SJohn.Zolnowsky@Sun.COM KMF_DATA_ATTR, &tobesigned, sizeof (KMF_DATA));
54810671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++,
54910671SJohn.Zolnowsky@Sun.COM KMF_OUT_DATA_ATTR, &signature, sizeof (KMF_DATA));
55010671SJohn.Zolnowsky@Sun.COM
55110671SJohn.Zolnowsky@Sun.COM ret = kmf_sign_data(ess->es_kmfhandle, numattr, attrlist);
5525194Sjohnz
5535194Sjohnz if (ret != KMF_OK) {
55410671SJohn.Zolnowsky@Sun.COM char *kmferr;
55510671SJohn.Zolnowsky@Sun.COM
55610671SJohn.Zolnowsky@Sun.COM (void) kmf_get_kmf_error_str(ret, &kmferr);
55710671SJohn.Zolnowsky@Sun.COM cryptodebug("Error signing data: %s\n",
55810671SJohn.Zolnowsky@Sun.COM (kmferr ? kmferr : "Unrecognized KMF error"));
55910671SJohn.Zolnowsky@Sun.COM free(kmferr);
5605194Sjohnz *sig_len = 0;
5615194Sjohnz return (B_FALSE);
5625194Sjohnz }
5635194Sjohnz *sig_len = signature.Length;
5645194Sjohnz return (B_TRUE);
5655194Sjohnz }
5665194Sjohnz
5675194Sjohnz /*
5685194Sjohnz * elfcertlib_verifysig - verify the given DATA using the public key in cert
5695194Sjohnz *
5705194Sjohnz * IN ess - elfsign context structure
5715194Sjohnz * cert
5725194Sjohnz * signature
5735194Sjohnz * sig_len
5745194Sjohnz * data
5755194Sjohnz * data_len
5765194Sjohnz * OUT N/A
5775194Sjohnz * RETURNS TRUE/FALSE
5785194Sjohnz */
5795194Sjohnz boolean_t
elfcertlib_verifysig(ELFsign_t ess,ELFCert_t cert,const uchar_t * signature,size_t sig_len,const uchar_t * data,size_t data_len)5805194Sjohnz elfcertlib_verifysig(ELFsign_t ess, ELFCert_t cert,
5815194Sjohnz const uchar_t *signature, size_t sig_len,
5825194Sjohnz const uchar_t *data, size_t data_len)
5835194Sjohnz {
5845194Sjohnz KMF_RETURN rv;
5855194Sjohnz KMF_DATA indata;
5865194Sjohnz KMF_DATA insig;
5875194Sjohnz KMF_ALGORITHM_INDEX algid;
58810671SJohn.Zolnowsky@Sun.COM KMF_ATTRIBUTE attrlist[8];
58910671SJohn.Zolnowsky@Sun.COM KMF_KEYSTORE_TYPE kstype;
59010671SJohn.Zolnowsky@Sun.COM int numattr;
5915194Sjohnz
5925194Sjohnz indata.Data = (uchar_t *)data;
5935194Sjohnz indata.Length = data_len;
5945194Sjohnz insig.Data = (uchar_t *)signature;
5955194Sjohnz insig.Length = sig_len;
5965194Sjohnz
5975194Sjohnz if (ess->es_version <= FILESIG_VERSION2)
5985194Sjohnz algid = KMF_ALGID_MD5WithRSA;
5995194Sjohnz else
6005194Sjohnz algid = KMF_ALGID_RSA;
6015194Sjohnz
6025194Sjohnz /*
60310123SValerie.Fenwick@Sun.COM * We tell KMF to use the PKCS11 verification APIs
60410123SValerie.Fenwick@Sun.COM * here to prevent the use of OpenSSL and to keep
60510123SValerie.Fenwick@Sun.COM * all validation within the FIPS-140 boundary for
60610123SValerie.Fenwick@Sun.COM * the Cryptographic Framework.
6075194Sjohnz */
60810671SJohn.Zolnowsky@Sun.COM kstype = KMF_KEYSTORE_PK11TOKEN;
60910671SJohn.Zolnowsky@Sun.COM
61010671SJohn.Zolnowsky@Sun.COM numattr = 0;
61110671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_KEYSTORE_TYPE_ATTR,
61210671SJohn.Zolnowsky@Sun.COM &kstype, sizeof (kstype));
61310671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_DATA_ATTR,
61410671SJohn.Zolnowsky@Sun.COM &indata, sizeof (KMF_DATA));
61510671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_IN_SIGN_ATTR,
61610671SJohn.Zolnowsky@Sun.COM &insig, sizeof (KMF_DATA));
61710671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_SIGNER_CERT_DATA_ATTR,
61810671SJohn.Zolnowsky@Sun.COM (KMF_DATA *)(&cert->c_cert.certificate), sizeof (KMF_DATA));
61910671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_ALGORITHM_INDEX_ATTR,
62010671SJohn.Zolnowsky@Sun.COM &algid, sizeof (algid));
62110671SJohn.Zolnowsky@Sun.COM
62210671SJohn.Zolnowsky@Sun.COM rv = kmf_verify_data(ess->es_kmfhandle, numattr, attrlist);
6235194Sjohnz
6245194Sjohnz return ((rv == KMF_OK));
6255194Sjohnz }
6265194Sjohnz
6275194Sjohnz /*
6285194Sjohnz * elfcertlib_getdn
6295194Sjohnz *
6305194Sjohnz * IN cert
6315194Sjohnz * OUT NONE
6325194Sjohnz * RETURN dn or NULL
6335194Sjohnz */
6345194Sjohnz char *
elfcertlib_getdn(ELFCert_t cert)6355194Sjohnz elfcertlib_getdn(ELFCert_t cert)
6365194Sjohnz {
6375194Sjohnz cryptodebug("elfcertlib_getdn");
6385194Sjohnz
6395194Sjohnz return (cert->c_subject);
6405194Sjohnz }
6415194Sjohnz
6425194Sjohnz /*
6435194Sjohnz * elfcertlib_getissuer
6445194Sjohnz *
6455194Sjohnz * IN cert
6465194Sjohnz * OUT NONE
6475194Sjohnz * RETURN dn or NULL
6485194Sjohnz */
6495194Sjohnz char *
elfcertlib_getissuer(ELFCert_t cert)6505194Sjohnz elfcertlib_getissuer(ELFCert_t cert)
6515194Sjohnz {
6525194Sjohnz cryptodebug("elfcertlib_issuer");
6535194Sjohnz
6545194Sjohnz return (cert->c_issuer);
6555194Sjohnz }
6565194Sjohnz
6575194Sjohnz boolean_t
elfcertlib_init(ELFsign_t ess)6585194Sjohnz elfcertlib_init(ELFsign_t ess)
6595194Sjohnz {
6605194Sjohnz boolean_t rc = B_TRUE;
6615194Sjohnz KMF_RETURN rv;
6625194Sjohnz if (ess->es_kmfhandle == NULL) {
66310671SJohn.Zolnowsky@Sun.COM rv = kmf_initialize(&ess->es_kmfhandle, NULL, NULL);
6645194Sjohnz if (rv != KMF_OK) {
6655194Sjohnz cryptoerror(LOG_ERR,
6665194Sjohnz "unable to initialize KMF library");
6675194Sjohnz rc = B_FALSE;
6685194Sjohnz }
6695194Sjohnz }
6705194Sjohnz return (rc);
6715194Sjohnz }
6725194Sjohnz
6735194Sjohnz void
elfcertlib_fini(ELFsign_t ess)6745194Sjohnz elfcertlib_fini(ELFsign_t ess)
6755194Sjohnz {
67610671SJohn.Zolnowsky@Sun.COM (void) kmf_finalize(ess->es_kmfhandle);
6775194Sjohnz }
6785194Sjohnz
6795194Sjohnz /*
6805194Sjohnz * set the token device
6815194Sjohnz */
6825194Sjohnz boolean_t
elfcertlib_settoken(ELFsign_t ess,char * token)6835194Sjohnz elfcertlib_settoken(ELFsign_t ess, char *token)
6845194Sjohnz {
68510671SJohn.Zolnowsky@Sun.COM boolean_t rc = B_TRUE;
68610671SJohn.Zolnowsky@Sun.COM KMF_RETURN rv;
68710671SJohn.Zolnowsky@Sun.COM KMF_ATTRIBUTE attrlist[8];
68810671SJohn.Zolnowsky@Sun.COM KMF_KEYSTORE_TYPE kstype;
68910671SJohn.Zolnowsky@Sun.COM boolean_t readonly;
69010671SJohn.Zolnowsky@Sun.COM int numattr;
69110671SJohn.Zolnowsky@Sun.COM
69210671SJohn.Zolnowsky@Sun.COM kstype = KMF_KEYSTORE_PK11TOKEN;
69310671SJohn.Zolnowsky@Sun.COM readonly = B_TRUE;
6945194Sjohnz
69510671SJohn.Zolnowsky@Sun.COM numattr = 0;
69610671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++,
69710671SJohn.Zolnowsky@Sun.COM KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
69810671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++,
69910671SJohn.Zolnowsky@Sun.COM KMF_TOKEN_LABEL_ATTR, token, strlen(token));
70010671SJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++,
70110671SJohn.Zolnowsky@Sun.COM KMF_READONLY_ATTR, &readonly, sizeof (readonly));
70210671SJohn.Zolnowsky@Sun.COM
70310671SJohn.Zolnowsky@Sun.COM rv = kmf_configure_keystore(ess->es_kmfhandle, numattr, attrlist);
7045194Sjohnz if (rv != KMF_OK) {
7055194Sjohnz cryptoerror(LOG_ERR, "unable to select token\n");
7065194Sjohnz rc = B_FALSE;
7075194Sjohnz }
7085194Sjohnz
7095194Sjohnz return (rc);
7105194Sjohnz }
7115194Sjohnz
7125194Sjohnz /*
7135194Sjohnz * set the certificate CA identification callback
7145194Sjohnz */
7155194Sjohnz void
elfcertlib_setcertCAcallback(ELFsign_t ess,void (* cb)(void *,ELFCert_t,char *))7165194Sjohnz elfcertlib_setcertCAcallback(ELFsign_t ess,
7175194Sjohnz void (*cb)(void *, ELFCert_t, char *))
7185194Sjohnz {
7195194Sjohnz ess->es_certCAcallback = cb;
7205194Sjohnz }
7215194Sjohnz
7225194Sjohnz /*
7235194Sjohnz * set the certificate verification callback
7245194Sjohnz */
7255194Sjohnz void
elfcertlib_setcertvercallback(ELFsign_t ess,void (* cb)(void *,ELFCert_t,ELFCert_t))7265194Sjohnz elfcertlib_setcertvercallback(ELFsign_t ess,
7275194Sjohnz void (*cb)(void *, ELFCert_t, ELFCert_t))
7285194Sjohnz {
7295194Sjohnz ess->es_certvercallback = cb;
7305194Sjohnz }
7315194Sjohnz
7325194Sjohnz
7335194Sjohnz /*
7345194Sjohnz * elfcertlib_releasecert - release a cert
7355194Sjohnz *
7365194Sjohnz * IN cert
7375194Sjohnz * OUT cert
7385194Sjohnz * RETURN N/A
7395194Sjohnz *
7405194Sjohnz */
7415194Sjohnz void
elfcertlib_releasecert(ELFsign_t ess,ELFCert_t cert)7425194Sjohnz elfcertlib_releasecert(ELFsign_t ess, ELFCert_t cert)
7435194Sjohnz {
7445194Sjohnz elfcertlib_freecert(ess, cert);
7455194Sjohnz }
7465194Sjohnz
7475194Sjohnz /*
7485194Sjohnz * elfcertlib_allocatecert - create a new ELFCert_t
7495194Sjohnz *
7505194Sjohnz * IN N/A
7515194Sjohnz * OUT N/A
7525194Sjohnz * RETURN ELFCert_t, NULL on failure.
7535194Sjohnz */
7545194Sjohnz static ELFCert_t
elfcertlib_allocatecert(void)7555194Sjohnz elfcertlib_allocatecert(void)
7565194Sjohnz {
7575194Sjohnz ELFCert_t cert = NULL;
7585194Sjohnz
7595194Sjohnz cert = malloc(sizeof (struct ELFCert_s));
7605194Sjohnz if (cert == NULL) {
7615194Sjohnz cryptoerror(LOG_ERR,
7625194Sjohnz "elfcertlib_allocatecert: malloc failed %s",
7635194Sjohnz strerror(errno));
7645194Sjohnz return (NULL);
7655194Sjohnz }
7665194Sjohnz (void) memset(cert, 0, sizeof (struct ELFCert_s));
7675194Sjohnz cert->c_verified = E_UNCHECKED;
7685194Sjohnz cert->c_subject = NULL;
7695194Sjohnz cert->c_issuer = NULL;
7705194Sjohnz return (cert);
7715194Sjohnz }
7725194Sjohnz
7735194Sjohnz /*
7745194Sjohnz * elfcertlib_freecert - freeup the memory of a cert
7755194Sjohnz *
7765194Sjohnz * IN cert
7775194Sjohnz * OUT cert
7785194Sjohnz * RETURN N/A
7795194Sjohnz *
7805194Sjohnz */
7815194Sjohnz static void
elfcertlib_freecert(ELFsign_t ess,ELFCert_t cert)7825194Sjohnz elfcertlib_freecert(ELFsign_t ess, ELFCert_t cert)
7835194Sjohnz {
7845194Sjohnz if (cert == NULL)
7855194Sjohnz return;
7865194Sjohnz
7875194Sjohnz free(cert->c_subject);
7885194Sjohnz free(cert->c_issuer);
7895194Sjohnz
79010671SJohn.Zolnowsky@Sun.COM kmf_free_kmf_cert(ess->es_kmfhandle, &cert->c_cert);
79110671SJohn.Zolnowsky@Sun.COM kmf_free_kmf_key(ess->es_kmfhandle, &cert->c_privatekey);
7925194Sjohnz
7935194Sjohnz free(cert);
7945194Sjohnz }
795