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 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 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 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 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 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 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 * 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 * 6505194Sjohnz elfcertlib_getissuer(ELFCert_t cert) 6515194Sjohnz { 6525194Sjohnz cryptodebug("elfcertlib_issuer"); 6535194Sjohnz 6545194Sjohnz return (cert->c_issuer); 6555194Sjohnz } 6565194Sjohnz 6575194Sjohnz boolean_t 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 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 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 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 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 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 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 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