1df8bdeb3Sjohnz /* 2df8bdeb3Sjohnz * CDDL HEADER START 3df8bdeb3Sjohnz * 4df8bdeb3Sjohnz * The contents of this file are subject to the terms of the 5df8bdeb3Sjohnz * Common Development and Distribution License (the "License"). 6df8bdeb3Sjohnz * You may not use this file except in compliance with the License. 7df8bdeb3Sjohnz * 8df8bdeb3Sjohnz * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9df8bdeb3Sjohnz * or http://www.opensolaris.org/os/licensing. 10df8bdeb3Sjohnz * See the License for the specific language governing permissions 11df8bdeb3Sjohnz * and limitations under the License. 12df8bdeb3Sjohnz * 13df8bdeb3Sjohnz * When distributing Covered Code, include this CDDL HEADER in each 14df8bdeb3Sjohnz * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15df8bdeb3Sjohnz * If applicable, add the following below this CDDL HEADER, with the 16df8bdeb3Sjohnz * fields enclosed by brackets "[]" replaced with your own identifying 17df8bdeb3Sjohnz * information: Portions Copyright [yyyy] [name of copyright owner] 18df8bdeb3Sjohnz * 19df8bdeb3Sjohnz * CDDL HEADER END 20df8bdeb3Sjohnz */ 21df8bdeb3Sjohnz 22df8bdeb3Sjohnz /* 232225707cSValerie Bubb Fenwick * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24df8bdeb3Sjohnz * Use is subject to license terms. 25df8bdeb3Sjohnz */ 26df8bdeb3Sjohnz 27df8bdeb3Sjohnz #include <limits.h> 28df8bdeb3Sjohnz #include <sys/types.h> 29df8bdeb3Sjohnz #include <sys/stat.h> 30df8bdeb3Sjohnz #include <fcntl.h> 31df8bdeb3Sjohnz #include <unistd.h> 32df8bdeb3Sjohnz #include <dirent.h> 33df8bdeb3Sjohnz #include <strings.h> 34df8bdeb3Sjohnz #include <stdio.h> 35df8bdeb3Sjohnz #include <stdlib.h> 36df8bdeb3Sjohnz #include <errno.h> 37df8bdeb3Sjohnz #include <sys/mman.h> 38df8bdeb3Sjohnz #include <md5.h> 39df8bdeb3Sjohnz #include <pthread.h> 40df8bdeb3Sjohnz 41df8bdeb3Sjohnz #include <cryptoutil.h> 42df8bdeb3Sjohnz 43df8bdeb3Sjohnz #include <kmfapi.h> 44df8bdeb3Sjohnz #include <sys/crypto/elfsign.h> 45df8bdeb3Sjohnz #include <libelfsign.h> 46df8bdeb3Sjohnz 47df8bdeb3Sjohnz #include <synch.h> 48df8bdeb3Sjohnz 49df8bdeb3Sjohnz const char _PATH_ELFSIGN_CRYPTO_CERTS[] = CRYPTO_CERTS_DIR; 50df8bdeb3Sjohnz const char _PATH_ELFSIGN_ETC_CERTS[] = ETC_CERTS_DIR; 51df8bdeb3Sjohnz 52df8bdeb3Sjohnz /* 53df8bdeb3Sjohnz * The CACERT and OBJCACERT are the Cryptographic Trust Anchors 54df8bdeb3Sjohnz * for the Solaris Cryptographic Framework. 55*73556491SAnthony Scarpino * 56*73556491SAnthony Scarpino * The SECACERT is the Signed Execution Trust Anchor that the 57*73556491SAnthony Scarpino * Cryptographic Framework uses for FIPS-140 validation of non-crypto 58*73556491SAnthony Scarpino * binaries 59df8bdeb3Sjohnz */ 60df8bdeb3Sjohnz static const char _PATH_CRYPTO_CACERT[] = CRYPTO_CERTS_DIR "/CA"; 61df8bdeb3Sjohnz static const char _PATH_CRYPTO_OBJCACERT[] = CRYPTO_CERTS_DIR "/SUNWObjectCA"; 62*73556491SAnthony Scarpino static const char _PATH_CRYPTO_SECACERT[] = ETC_CERTS_DIR "/SUNWSolarisCA"; 63df8bdeb3Sjohnz static ELFCert_t CACERT = NULL; 64df8bdeb3Sjohnz static ELFCert_t OBJCACERT = NULL; 65*73556491SAnthony Scarpino static ELFCert_t SECACERT = NULL; 66df8bdeb3Sjohnz static pthread_mutex_t ca_mutex = PTHREAD_MUTEX_INITIALIZER; 67df8bdeb3Sjohnz 68df8bdeb3Sjohnz static void elfcertlib_freecert(ELFsign_t, ELFCert_t); 69df8bdeb3Sjohnz static ELFCert_t elfcertlib_allocatecert(void); 70df8bdeb3Sjohnz 71df8bdeb3Sjohnz /* 72df8bdeb3Sjohnz * elfcertlib_verifycert - Verify the Cert with a Trust Anchor 73df8bdeb3Sjohnz * 74df8bdeb3Sjohnz * IN ess - elfsign context structure 75df8bdeb3Sjohnz * cert 76df8bdeb3Sjohnz * OUT NONE 77df8bdeb3Sjohnz * RETURN TRUE/FALSE 78df8bdeb3Sjohnz * 79df8bdeb3Sjohnz * We first setup the Trust Anchor (CA and SUNWObjectCA) certs 80df8bdeb3Sjohnz * if it hasn't been done already. We verify that the files on disk 81df8bdeb3Sjohnz * are those we expected. 82df8bdeb3Sjohnz * 83df8bdeb3Sjohnz * We then verify the given cert using the publickey of a TA. 84df8bdeb3Sjohnz * If the passed in cert is a TA or it has been verified already we 85df8bdeb3Sjohnz * short cut and return TRUE without futher validation. 86df8bdeb3Sjohnz */ 87df8bdeb3Sjohnz /*ARGSUSED*/ 88df8bdeb3Sjohnz boolean_t 89df8bdeb3Sjohnz elfcertlib_verifycert(ELFsign_t ess, ELFCert_t cert) 90df8bdeb3Sjohnz { 918bab47abSJohn.Zolnowsky@Sun.COM KMF_ATTRIBUTE attrlist[8]; 928bab47abSJohn.Zolnowsky@Sun.COM int numattr; 938bab47abSJohn.Zolnowsky@Sun.COM 94df8bdeb3Sjohnz KMF_RETURN rv; 95df8bdeb3Sjohnz if ((cert->c_verified == E_OK) || (cert->c_verified == E_IS_TA)) { 96df8bdeb3Sjohnz return (B_TRUE); 97df8bdeb3Sjohnz } 98df8bdeb3Sjohnz 99df8bdeb3Sjohnz (void) pthread_mutex_lock(&ca_mutex); 100df8bdeb3Sjohnz if (CACERT == NULL) { 101df8bdeb3Sjohnz (void) elfcertlib_getcert(ess, (char *)_PATH_CRYPTO_CACERT, 102df8bdeb3Sjohnz NULL, &CACERT, ES_GET); 103df8bdeb3Sjohnz } 104*73556491SAnthony Scarpino 105df8bdeb3Sjohnz if (OBJCACERT == NULL) { 106df8bdeb3Sjohnz (void) elfcertlib_getcert(ess, (char *)_PATH_CRYPTO_OBJCACERT, 107df8bdeb3Sjohnz NULL, &OBJCACERT, ES_GET); 108df8bdeb3Sjohnz } 109*73556491SAnthony Scarpino 110*73556491SAnthony Scarpino if (SECACERT == NULL) { 111*73556491SAnthony Scarpino (void) elfcertlib_getcert(ess, 112*73556491SAnthony Scarpino (char *)_PATH_CRYPTO_SECACERT, NULL, &SECACERT, 113*73556491SAnthony Scarpino ES_GET_FIPS140); 114*73556491SAnthony Scarpino } 115*73556491SAnthony Scarpino 116df8bdeb3Sjohnz (void) pthread_mutex_unlock(&ca_mutex); 117df8bdeb3Sjohnz 118df8bdeb3Sjohnz if (CACERT != NULL) { 1198bab47abSJohn.Zolnowsky@Sun.COM numattr = 0; 1208bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, 1218bab47abSJohn.Zolnowsky@Sun.COM KMF_CERT_DATA_ATTR, &cert->c_cert.certificate, 1228bab47abSJohn.Zolnowsky@Sun.COM sizeof (KMF_DATA)); 1238bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, 1248bab47abSJohn.Zolnowsky@Sun.COM KMF_SIGNER_CERT_DATA_ATTR, &CACERT->c_cert.certificate, 1258bab47abSJohn.Zolnowsky@Sun.COM sizeof (KMF_DATA)); 1268bab47abSJohn.Zolnowsky@Sun.COM 1278bab47abSJohn.Zolnowsky@Sun.COM rv = kmf_verify_cert(ess->es_kmfhandle, numattr, attrlist); 128df8bdeb3Sjohnz if (rv == KMF_OK) { 129df8bdeb3Sjohnz if (ess->es_certCAcallback != NULL) 130df8bdeb3Sjohnz (ess->es_certvercallback)(ess->es_callbackctx, 131df8bdeb3Sjohnz cert, CACERT); 132df8bdeb3Sjohnz cert->c_verified = E_OK; 133df8bdeb3Sjohnz return (B_TRUE); 134df8bdeb3Sjohnz } 135df8bdeb3Sjohnz } 136df8bdeb3Sjohnz 137df8bdeb3Sjohnz if (OBJCACERT != NULL) { 1388bab47abSJohn.Zolnowsky@Sun.COM numattr = 0; 1398bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, 1408bab47abSJohn.Zolnowsky@Sun.COM KMF_CERT_DATA_ATTR, &cert->c_cert.certificate, 1418bab47abSJohn.Zolnowsky@Sun.COM sizeof (KMF_DATA)); 1428bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, 1438bab47abSJohn.Zolnowsky@Sun.COM KMF_SIGNER_CERT_DATA_ATTR, &OBJCACERT->c_cert.certificate, 1448bab47abSJohn.Zolnowsky@Sun.COM sizeof (KMF_DATA)); 1458bab47abSJohn.Zolnowsky@Sun.COM 1468bab47abSJohn.Zolnowsky@Sun.COM rv = kmf_verify_cert(ess->es_kmfhandle, numattr, attrlist); 147df8bdeb3Sjohnz if (rv == KMF_OK) { 148df8bdeb3Sjohnz if (ess->es_certCAcallback != NULL) 149df8bdeb3Sjohnz (ess->es_certvercallback)(ess->es_callbackctx, 150df8bdeb3Sjohnz cert, OBJCACERT); 151df8bdeb3Sjohnz cert->c_verified = E_OK; 152df8bdeb3Sjohnz return (B_TRUE); 153df8bdeb3Sjohnz } 154df8bdeb3Sjohnz } 155df8bdeb3Sjohnz 156*73556491SAnthony Scarpino if (SECACERT != NULL) { 157*73556491SAnthony Scarpino rv = KMF_VerifyCertWithCert(ess->es_kmfhandle, 158*73556491SAnthony Scarpino (const KMF_DATA *)&cert->c_cert, 159*73556491SAnthony Scarpino (const KMF_DATA *)&SECACERT->c_cert.certificate); 160*73556491SAnthony Scarpino if (rv == KMF_OK) { 161*73556491SAnthony Scarpino if (ess->es_certCAcallback != NULL) 162*73556491SAnthony Scarpino (ess->es_certvercallback)(ess->es_callbackctx, 163*73556491SAnthony Scarpino cert, SECACERT); 164*73556491SAnthony Scarpino cert->c_verified = E_OK; 165*73556491SAnthony Scarpino return (B_TRUE); 166*73556491SAnthony Scarpino } 167*73556491SAnthony Scarpino } 168*73556491SAnthony Scarpino 169df8bdeb3Sjohnz return (B_FALSE); 170df8bdeb3Sjohnz } 171df8bdeb3Sjohnz 172df8bdeb3Sjohnz /* 173df8bdeb3Sjohnz * elfcertlib_getcert - Get the certificate for signer_DN 174df8bdeb3Sjohnz * 175df8bdeb3Sjohnz * IN ess - elfsign context structure 176df8bdeb3Sjohnz * cert_pathname - path to cert (May be NULL) 177df8bdeb3Sjohnz * signer_DN - The DN we are looking for (May be NULL) 178df8bdeb3Sjohnz * action - indicates crypto verification call 179df8bdeb3Sjohnz * OUT certp - allocated/loaded ELFCert_t 180df8bdeb3Sjohnz * 181df8bdeb3Sjohnz * If the cert_pathname is passed use it and don't search. 182df8bdeb3Sjohnz * Otherwise, go looking in certificate directories 183df8bdeb3Sjohnz */ 184df8bdeb3Sjohnz boolean_t 185df8bdeb3Sjohnz elfcertlib_getcert(ELFsign_t ess, char *cert_pathname, 186df8bdeb3Sjohnz char *signer_DN, ELFCert_t *certp, enum ES_ACTION action) 187df8bdeb3Sjohnz { 188df8bdeb3Sjohnz KMF_RETURN rv; 189df8bdeb3Sjohnz ELFCert_t cert = NULL; 190df8bdeb3Sjohnz KMF_X509_DER_CERT certbuf[2]; 191df8bdeb3Sjohnz uint32_t ncerts; 192df8bdeb3Sjohnz boolean_t ret = B_FALSE; 193df8bdeb3Sjohnz char *pathlist[3], **plp; 194df8bdeb3Sjohnz 195df8bdeb3Sjohnz cryptodebug("elfcertlib_getcert: path=%s, DN=%s", 196df8bdeb3Sjohnz cert_pathname ? cert_pathname : "-none-", 197df8bdeb3Sjohnz signer_DN ? signer_DN : "-none-"); 198df8bdeb3Sjohnz *certp = NULL; 199df8bdeb3Sjohnz if (cert_pathname == NULL && signer_DN == NULL) { 200df8bdeb3Sjohnz cryptodebug("elfcertlib_getcert: lack of specificity"); 201df8bdeb3Sjohnz return (ret); 202df8bdeb3Sjohnz } 203df8bdeb3Sjohnz 204df8bdeb3Sjohnz plp = pathlist; 205df8bdeb3Sjohnz if (cert_pathname != NULL) { 206df8bdeb3Sjohnz /* look in the specified object */ 207df8bdeb3Sjohnz *plp++ = cert_pathname; 208df8bdeb3Sjohnz } else { 209df8bdeb3Sjohnz /* look in the certificate directories */ 210df8bdeb3Sjohnz *plp++ = (char *)_PATH_ELFSIGN_CRYPTO_CERTS; 211df8bdeb3Sjohnz /* 212df8bdeb3Sjohnz * crypto verifications don't search beyond 213df8bdeb3Sjohnz * _PATH_ELFSIGN_CRYPTO_CERTS 214df8bdeb3Sjohnz */ 215df8bdeb3Sjohnz if (action != ES_GET_CRYPTO) 216df8bdeb3Sjohnz *plp++ = (char *)_PATH_ELFSIGN_ETC_CERTS; 217df8bdeb3Sjohnz } 218df8bdeb3Sjohnz *plp = NULL; 219df8bdeb3Sjohnz 220df8bdeb3Sjohnz if ((cert = elfcertlib_allocatecert()) == NULL) { 221df8bdeb3Sjohnz return (ret); 222df8bdeb3Sjohnz } 223df8bdeb3Sjohnz 224df8bdeb3Sjohnz for (plp = pathlist; *plp; plp++) { 2258bab47abSJohn.Zolnowsky@Sun.COM KMF_ATTRIBUTE attrlist[8]; 2268bab47abSJohn.Zolnowsky@Sun.COM KMF_KEYSTORE_TYPE kstype; 2278bab47abSJohn.Zolnowsky@Sun.COM KMF_CERT_VALIDITY certvalidity; 2288bab47abSJohn.Zolnowsky@Sun.COM int numattr; 2298bab47abSJohn.Zolnowsky@Sun.COM 2308bab47abSJohn.Zolnowsky@Sun.COM kstype = KMF_KEYSTORE_OPENSSL; 2318bab47abSJohn.Zolnowsky@Sun.COM certvalidity = KMF_ALL_CERTS; 232df8bdeb3Sjohnz ncerts = 2; 233df8bdeb3Sjohnz 2348bab47abSJohn.Zolnowsky@Sun.COM numattr = 0; 2358bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, 2368bab47abSJohn.Zolnowsky@Sun.COM KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 2378bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, 2388bab47abSJohn.Zolnowsky@Sun.COM KMF_X509_DER_CERT_ATTR, certbuf, 2398bab47abSJohn.Zolnowsky@Sun.COM sizeof (KMF_X509_DER_CERT)); 2408bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, 2418bab47abSJohn.Zolnowsky@Sun.COM KMF_COUNT_ATTR, &ncerts, sizeof (uint32_t)); 2428bab47abSJohn.Zolnowsky@Sun.COM if (signer_DN != NULL) { 2438bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, 2448bab47abSJohn.Zolnowsky@Sun.COM KMF_SUBJECT_NAME_ATTR, signer_DN, 2458bab47abSJohn.Zolnowsky@Sun.COM strlen(signer_DN)); 2468bab47abSJohn.Zolnowsky@Sun.COM } 2478bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, 2488bab47abSJohn.Zolnowsky@Sun.COM KMF_CERT_VALIDITY_ATTR, &certvalidity, 2498bab47abSJohn.Zolnowsky@Sun.COM sizeof (KMF_CERT_VALIDITY)); 2508bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, 2518bab47abSJohn.Zolnowsky@Sun.COM KMF_CERT_FILENAME_ATTR, *plp, strlen (*plp)); 2528bab47abSJohn.Zolnowsky@Sun.COM 2538bab47abSJohn.Zolnowsky@Sun.COM rv = kmf_find_cert(ess->es_kmfhandle, numattr, attrlist); 2548bab47abSJohn.Zolnowsky@Sun.COM 255df8bdeb3Sjohnz if (rv != KMF_OK) 256df8bdeb3Sjohnz continue; 2578bab47abSJohn.Zolnowsky@Sun.COM /* found one */ 2588bab47abSJohn.Zolnowsky@Sun.COM cert->c_cert = certbuf[0]; 2598bab47abSJohn.Zolnowsky@Sun.COM if (ncerts > 1) { 2608bab47abSJohn.Zolnowsky@Sun.COM /* release any extras */ 2618bab47abSJohn.Zolnowsky@Sun.COM kmf_free_kmf_cert(ess->es_kmfhandle, &certbuf[1]); 2628bab47abSJohn.Zolnowsky@Sun.COM if (signer_DN == NULL) { 263df8bdeb3Sjohnz /* There can be only one */ 264df8bdeb3Sjohnz cryptodebug("elfcertlib_getcert: " 265df8bdeb3Sjohnz "too many certificates found in %s", 266df8bdeb3Sjohnz cert_pathname); 267df8bdeb3Sjohnz goto cleanup; 268df8bdeb3Sjohnz } 2698bab47abSJohn.Zolnowsky@Sun.COM } 2708bab47abSJohn.Zolnowsky@Sun.COM /* cache subject and issuer */ 2718bab47abSJohn.Zolnowsky@Sun.COM rv = kmf_get_cert_subject_str(ess->es_kmfhandle, 272df8bdeb3Sjohnz &cert->c_cert.certificate, &cert->c_subject); 273df8bdeb3Sjohnz if (rv != KMF_OK) 274df8bdeb3Sjohnz goto cleanup; 275df8bdeb3Sjohnz 2768bab47abSJohn.Zolnowsky@Sun.COM rv = kmf_get_cert_issuer_str(ess->es_kmfhandle, 277df8bdeb3Sjohnz &cert->c_cert.certificate, &cert->c_issuer); 278df8bdeb3Sjohnz if (rv != KMF_OK) 279df8bdeb3Sjohnz goto cleanup; 280df8bdeb3Sjohnz break; 281df8bdeb3Sjohnz } 282df8bdeb3Sjohnz if (*plp == NULL) { 283df8bdeb3Sjohnz cryptodebug("elfcertlib_getcert: no certificate found"); 284df8bdeb3Sjohnz goto cleanup; 285df8bdeb3Sjohnz } 286df8bdeb3Sjohnz 287df8bdeb3Sjohnz cert->c_verified = E_UNCHECKED; 288df8bdeb3Sjohnz 289df8bdeb3Sjohnz /* 2902225707cSValerie Bubb Fenwick * If the cert we are loading is the trust anchor (ie the CA) then 291df8bdeb3Sjohnz * we mark it as such in cert. This is so that we don't attempt 292df8bdeb3Sjohnz * to verify it later. The CA is always implicitly verified. 293df8bdeb3Sjohnz */ 294df8bdeb3Sjohnz if (cert_pathname != NULL && ( 295df8bdeb3Sjohnz strcmp(cert_pathname, _PATH_CRYPTO_CACERT) == 0 || 296*73556491SAnthony Scarpino strcmp(cert_pathname, _PATH_CRYPTO_OBJCACERT) == 0 || 297*73556491SAnthony Scarpino strcmp(cert_pathname, _PATH_CRYPTO_SECACERT) == 0)) { 298df8bdeb3Sjohnz if (ess->es_certCAcallback != NULL) 299df8bdeb3Sjohnz (ess->es_certCAcallback)(ess->es_callbackctx, cert, 300df8bdeb3Sjohnz cert_pathname); 301df8bdeb3Sjohnz cert->c_verified = E_IS_TA; 302df8bdeb3Sjohnz } 303df8bdeb3Sjohnz 304df8bdeb3Sjohnz ret = B_TRUE; 305df8bdeb3Sjohnz 306df8bdeb3Sjohnz cleanup: 307df8bdeb3Sjohnz if (ret) { 308df8bdeb3Sjohnz *certp = cert; 309df8bdeb3Sjohnz } else { 310df8bdeb3Sjohnz if (cert != NULL) 311df8bdeb3Sjohnz elfcertlib_freecert(ess, cert); 312df8bdeb3Sjohnz if (signer_DN != NULL) 313df8bdeb3Sjohnz cryptoerror(LOG_ERR, "unable to find a certificate " 314df8bdeb3Sjohnz "for DN: %s", signer_DN); 315df8bdeb3Sjohnz else 316df8bdeb3Sjohnz cryptoerror(LOG_ERR, "unable to load certificate " 317df8bdeb3Sjohnz "from %s", cert_pathname); 318df8bdeb3Sjohnz } 319df8bdeb3Sjohnz return (ret); 320df8bdeb3Sjohnz } 321df8bdeb3Sjohnz 322df8bdeb3Sjohnz /* 323df8bdeb3Sjohnz * elfcertlib_loadprivatekey - Load the private key from path 324df8bdeb3Sjohnz * 325df8bdeb3Sjohnz * IN ess - elfsign context structure 326df8bdeb3Sjohnz * cert 327df8bdeb3Sjohnz * pathname 328df8bdeb3Sjohnz * OUT cert 329df8bdeb3Sjohnz * RETURNS TRUE/FALSE 330df8bdeb3Sjohnz */ 331df8bdeb3Sjohnz boolean_t 332df8bdeb3Sjohnz elfcertlib_loadprivatekey(ELFsign_t ess, ELFCert_t cert, const char *pathname) 333df8bdeb3Sjohnz { 334df8bdeb3Sjohnz KMF_RETURN rv = KMF_OK; 335df8bdeb3Sjohnz KMF_KEY_HANDLE keybuf[2]; 3368bab47abSJohn.Zolnowsky@Sun.COM KMF_ATTRIBUTE attrlist[16]; 3378bab47abSJohn.Zolnowsky@Sun.COM uint32_t nkeys; 3388bab47abSJohn.Zolnowsky@Sun.COM KMF_KEYSTORE_TYPE kstype; 3398bab47abSJohn.Zolnowsky@Sun.COM KMF_KEY_ALG keytype; 3408bab47abSJohn.Zolnowsky@Sun.COM KMF_KEY_CLASS keyclass; 3418bab47abSJohn.Zolnowsky@Sun.COM KMF_ENCODE_FORMAT format; 3428bab47abSJohn.Zolnowsky@Sun.COM int numattr; 343df8bdeb3Sjohnz 3448bab47abSJohn.Zolnowsky@Sun.COM kstype = KMF_KEYSTORE_OPENSSL; 3458bab47abSJohn.Zolnowsky@Sun.COM nkeys = 2; 3468bab47abSJohn.Zolnowsky@Sun.COM keytype = KMF_KEYALG_NONE; 3478bab47abSJohn.Zolnowsky@Sun.COM keyclass = KMF_ASYM_PRI; 3488bab47abSJohn.Zolnowsky@Sun.COM format = KMF_FORMAT_UNDEF; 349df8bdeb3Sjohnz 3508bab47abSJohn.Zolnowsky@Sun.COM numattr = 0; 3518bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_KEYSTORE_TYPE_ATTR, 3528bab47abSJohn.Zolnowsky@Sun.COM &kstype, sizeof (kstype)); 3538bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_KEY_HANDLE_ATTR, 3548bab47abSJohn.Zolnowsky@Sun.COM keybuf, sizeof (KMF_KEY_HANDLE)); 3558bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_COUNT_ATTR, 3568bab47abSJohn.Zolnowsky@Sun.COM &nkeys, sizeof (uint32_t)); 3578bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_KEYALG_ATTR, 3588bab47abSJohn.Zolnowsky@Sun.COM &keytype, sizeof (keytype)); 3598bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_KEYCLASS_ATTR, 3608bab47abSJohn.Zolnowsky@Sun.COM &keyclass, sizeof (keyclass)); 3618bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_ENCODE_FORMAT_ATTR, 3628bab47abSJohn.Zolnowsky@Sun.COM &format, sizeof (format)); 3638bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_KEY_FILENAME_ATTR, 3648bab47abSJohn.Zolnowsky@Sun.COM (char *)pathname, strlen(pathname)); 3658bab47abSJohn.Zolnowsky@Sun.COM 3668bab47abSJohn.Zolnowsky@Sun.COM rv = kmf_find_key(ess->es_kmfhandle, numattr, attrlist); 367df8bdeb3Sjohnz if (rv != KMF_OK) 368df8bdeb3Sjohnz return (B_FALSE); 369df8bdeb3Sjohnz if (nkeys != 1) { 370df8bdeb3Sjohnz /* lack of specificity */ 371df8bdeb3Sjohnz cryptodebug("found %d keys at %s", nkeys, pathname); 372df8bdeb3Sjohnz return (B_FALSE); 373df8bdeb3Sjohnz } 374df8bdeb3Sjohnz cert->c_privatekey = keybuf[0]; 375df8bdeb3Sjohnz cryptodebug("key %s loaded", pathname); 376df8bdeb3Sjohnz return (B_TRUE); 377df8bdeb3Sjohnz } 378df8bdeb3Sjohnz 379df8bdeb3Sjohnz /* 380df8bdeb3Sjohnz * elfcertlib_loadtokenkey - Load the private key from token 381df8bdeb3Sjohnz * 382df8bdeb3Sjohnz * IN ess - elfsign context structure 383df8bdeb3Sjohnz * cert 384df8bdeb3Sjohnz * token_label 385df8bdeb3Sjohnz * pin 386df8bdeb3Sjohnz * OUT cert 387df8bdeb3Sjohnz * RETURNS TRUE/FALSE 388df8bdeb3Sjohnz */ 389df8bdeb3Sjohnz boolean_t 390df8bdeb3Sjohnz elfcertlib_loadtokenkey(ELFsign_t ess, ELFCert_t cert, 391df8bdeb3Sjohnz const char *token_label, const char *pin) 392df8bdeb3Sjohnz { 3938bab47abSJohn.Zolnowsky@Sun.COM KMF_RETURN rv; 394df8bdeb3Sjohnz char *idstr = NULL; 3958bab47abSJohn.Zolnowsky@Sun.COM char *kmferr; 3968bab47abSJohn.Zolnowsky@Sun.COM KMF_ATTRIBUTE attrlist[16]; 3978bab47abSJohn.Zolnowsky@Sun.COM uint32_t nkeys; 3988bab47abSJohn.Zolnowsky@Sun.COM KMF_KEYSTORE_TYPE kstype; 3998bab47abSJohn.Zolnowsky@Sun.COM KMF_KEY_ALG keytype; 4008bab47abSJohn.Zolnowsky@Sun.COM KMF_KEY_CLASS keyclass; 4018bab47abSJohn.Zolnowsky@Sun.COM KMF_ENCODE_FORMAT format; 4028bab47abSJohn.Zolnowsky@Sun.COM KMF_CREDENTIAL pincred; 4038bab47abSJohn.Zolnowsky@Sun.COM boolean_t tokenbool, privatebool; 4048bab47abSJohn.Zolnowsky@Sun.COM int numattr; 405df8bdeb3Sjohnz 406df8bdeb3Sjohnz /* 407df8bdeb3Sjohnz * We will search for the key based on the ID attribute 408df8bdeb3Sjohnz * which was added when the key was created. ID is 409df8bdeb3Sjohnz * a SHA-1 hash of the public modulus shared by the 410df8bdeb3Sjohnz * key and the certificate. 411df8bdeb3Sjohnz */ 4128bab47abSJohn.Zolnowsky@Sun.COM rv = kmf_get_cert_id_str(&cert->c_cert.certificate, &idstr); 413df8bdeb3Sjohnz if (rv != KMF_OK) { 4148bab47abSJohn.Zolnowsky@Sun.COM (void) kmf_get_kmf_error_str(rv, &kmferr); 4158bab47abSJohn.Zolnowsky@Sun.COM cryptodebug("Error getting ID from cert: %s\n", 4168bab47abSJohn.Zolnowsky@Sun.COM (kmferr ? kmferr : "Unrecognized KMF error")); 4178bab47abSJohn.Zolnowsky@Sun.COM free(kmferr); 418df8bdeb3Sjohnz return (B_FALSE); 419df8bdeb3Sjohnz } 420df8bdeb3Sjohnz 4218bab47abSJohn.Zolnowsky@Sun.COM kstype = KMF_KEYSTORE_PK11TOKEN; 4228bab47abSJohn.Zolnowsky@Sun.COM nkeys = 1; 4238bab47abSJohn.Zolnowsky@Sun.COM keytype = KMF_KEYALG_NONE; 4248bab47abSJohn.Zolnowsky@Sun.COM keyclass = KMF_ASYM_PRI; 4258bab47abSJohn.Zolnowsky@Sun.COM format = KMF_FORMAT_UNDEF; 4268bab47abSJohn.Zolnowsky@Sun.COM pincred.cred = (char *)pin; 4278bab47abSJohn.Zolnowsky@Sun.COM pincred.credlen = strlen(pin); 4288bab47abSJohn.Zolnowsky@Sun.COM tokenbool = B_FALSE; 4298bab47abSJohn.Zolnowsky@Sun.COM privatebool = B_TRUE; 4308bab47abSJohn.Zolnowsky@Sun.COM 4318bab47abSJohn.Zolnowsky@Sun.COM numattr = 0; 4328bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_KEYSTORE_TYPE_ATTR, 4338bab47abSJohn.Zolnowsky@Sun.COM &kstype, sizeof (kstype)); 4348bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_KEY_HANDLE_ATTR, 4358bab47abSJohn.Zolnowsky@Sun.COM &cert->c_privatekey, sizeof (KMF_KEY_HANDLE)); 4368bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_COUNT_ATTR, 4378bab47abSJohn.Zolnowsky@Sun.COM &nkeys, sizeof (uint32_t)); 4388bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_KEYALG_ATTR, 4398bab47abSJohn.Zolnowsky@Sun.COM &keytype, sizeof (keytype)); 4408bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_KEYCLASS_ATTR, 4418bab47abSJohn.Zolnowsky@Sun.COM &keyclass, sizeof (keyclass)); 4428bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_ENCODE_FORMAT_ATTR, 4438bab47abSJohn.Zolnowsky@Sun.COM &format, sizeof (format)); 4448bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_IDSTR_ATTR, 4458bab47abSJohn.Zolnowsky@Sun.COM idstr, strlen(idstr)); 4468bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_CREDENTIAL_ATTR, 4478bab47abSJohn.Zolnowsky@Sun.COM &pincred, sizeof (KMF_CREDENTIAL)); 4488bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_TOKEN_BOOL_ATTR, 4498bab47abSJohn.Zolnowsky@Sun.COM &tokenbool, sizeof (tokenbool)); 4508bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_PRIVATE_BOOL_ATTR, 4518bab47abSJohn.Zolnowsky@Sun.COM &privatebool, sizeof (privatebool)); 4528bab47abSJohn.Zolnowsky@Sun.COM 4538bab47abSJohn.Zolnowsky@Sun.COM rv = kmf_find_key(ess->es_kmfhandle, numattr, attrlist); 454df8bdeb3Sjohnz free(idstr); 4558bab47abSJohn.Zolnowsky@Sun.COM if (rv != KMF_OK) { 4568bab47abSJohn.Zolnowsky@Sun.COM (void) kmf_get_kmf_error_str(rv, &kmferr); 4578bab47abSJohn.Zolnowsky@Sun.COM cryptodebug("Error finding private key: %s\n", 4588bab47abSJohn.Zolnowsky@Sun.COM (kmferr ? kmferr : "Unrecognized KMF error")); 4598bab47abSJohn.Zolnowsky@Sun.COM free(kmferr); 4608bab47abSJohn.Zolnowsky@Sun.COM return (B_FALSE); 4618bab47abSJohn.Zolnowsky@Sun.COM } 4628bab47abSJohn.Zolnowsky@Sun.COM if (nkeys != 1) { 4638bab47abSJohn.Zolnowsky@Sun.COM cryptodebug("Error finding private key: No key found\n"); 464df8bdeb3Sjohnz return (B_FALSE); 465df8bdeb3Sjohnz } 466df8bdeb3Sjohnz cryptodebug("key found in %s", token_label); 467df8bdeb3Sjohnz cryptodebug("elfcertlib_loadprivatekey = 0x%.8X", 468df8bdeb3Sjohnz &cert->c_privatekey); 469df8bdeb3Sjohnz 470df8bdeb3Sjohnz return (B_TRUE); 471df8bdeb3Sjohnz } 472df8bdeb3Sjohnz 473df8bdeb3Sjohnz static const CK_BYTE MD5_DER_PREFIX[] = {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 474df8bdeb3Sjohnz 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10}; 475df8bdeb3Sjohnz 476df8bdeb3Sjohnz /* 477df8bdeb3Sjohnz * elfcertlib_sign - sign the given DATA using the privatekey in cert 478df8bdeb3Sjohnz * 479df8bdeb3Sjohnz * IN ess - elfsign context structure 480df8bdeb3Sjohnz * cert 481df8bdeb3Sjohnz * data 482df8bdeb3Sjohnz * data_len 483df8bdeb3Sjohnz * OUT sig - must be big enough to hold the signature of data 484df8bdeb3Sjohnz * Caller must allocate 485df8bdeb3Sjohnz * sig_len - actual length used; 0 on failure. 486df8bdeb3Sjohnz * RETURNS TRUE/FALSE 487df8bdeb3Sjohnz */ 488df8bdeb3Sjohnz /*ARGSUSED*/ 489df8bdeb3Sjohnz boolean_t 490df8bdeb3Sjohnz elfcertlib_sign(ELFsign_t ess, ELFCert_t cert, 491df8bdeb3Sjohnz const uchar_t *data, size_t data_len, 492df8bdeb3Sjohnz uchar_t *sig, size_t *sig_len) 493df8bdeb3Sjohnz { 4948bab47abSJohn.Zolnowsky@Sun.COM KMF_RETURN ret; 495df8bdeb3Sjohnz KMF_DATA tobesigned; 496df8bdeb3Sjohnz KMF_DATA signature; 497df8bdeb3Sjohnz uchar_t der_data[sizeof (MD5_DER_PREFIX) + MD5_DIGEST_LENGTH]; 4988bab47abSJohn.Zolnowsky@Sun.COM KMF_ATTRIBUTE attrlist[8]; 4998bab47abSJohn.Zolnowsky@Sun.COM int numattr; 500df8bdeb3Sjohnz 501df8bdeb3Sjohnz if (ess->es_version <= FILESIG_VERSION2) { 502df8bdeb3Sjohnz /* compatibility: take MD5 hash of SHA1 hash */ 503df8bdeb3Sjohnz size_t derlen = MD5_DIGEST_LENGTH; 504df8bdeb3Sjohnz MD5_CTX ctx; 505df8bdeb3Sjohnz 506df8bdeb3Sjohnz /* 507df8bdeb3Sjohnz * first: digest using software-based methods, don't 508df8bdeb3Sjohnz * rely on the token for hashing. 509df8bdeb3Sjohnz */ 510df8bdeb3Sjohnz MD5Init(&ctx); 511df8bdeb3Sjohnz MD5Update(&ctx, data, data_len); 512df8bdeb3Sjohnz MD5Final(&der_data[sizeof (MD5_DER_PREFIX)], &ctx); 513df8bdeb3Sjohnz 514df8bdeb3Sjohnz /* 515df8bdeb3Sjohnz * second: insert prefix 516df8bdeb3Sjohnz */ 517df8bdeb3Sjohnz (void) memcpy(der_data, MD5_DER_PREFIX, 518df8bdeb3Sjohnz sizeof (MD5_DER_PREFIX)); 519df8bdeb3Sjohnz /* 520df8bdeb3Sjohnz * prepare to sign the local buffer 521df8bdeb3Sjohnz */ 522df8bdeb3Sjohnz tobesigned.Data = (uchar_t *)der_data; 523df8bdeb3Sjohnz tobesigned.Length = sizeof (MD5_DER_PREFIX) + derlen; 524df8bdeb3Sjohnz } else { 525df8bdeb3Sjohnz tobesigned.Data = (uchar_t *)data; 526df8bdeb3Sjohnz tobesigned.Length = data_len; 527df8bdeb3Sjohnz } 528df8bdeb3Sjohnz 529df8bdeb3Sjohnz signature.Data = (uchar_t *)sig; 530df8bdeb3Sjohnz signature.Length = *sig_len; 531df8bdeb3Sjohnz 5328bab47abSJohn.Zolnowsky@Sun.COM numattr = 0; 5338bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, 5348bab47abSJohn.Zolnowsky@Sun.COM KMF_KEYSTORE_TYPE_ATTR, &(cert->c_privatekey.kstype), 5358bab47abSJohn.Zolnowsky@Sun.COM sizeof (KMF_KEYSTORE_TYPE)); 5368bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, 5378bab47abSJohn.Zolnowsky@Sun.COM KMF_KEY_HANDLE_ATTR, &cert->c_privatekey, sizeof (KMF_KEY_HANDLE)); 5388bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, 5398bab47abSJohn.Zolnowsky@Sun.COM KMF_OID_ATTR, (KMF_OID *)&KMFOID_RSA, sizeof (KMF_OID)); 5408bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, 5418bab47abSJohn.Zolnowsky@Sun.COM KMF_DATA_ATTR, &tobesigned, sizeof (KMF_DATA)); 5428bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, 5438bab47abSJohn.Zolnowsky@Sun.COM KMF_OUT_DATA_ATTR, &signature, sizeof (KMF_DATA)); 5448bab47abSJohn.Zolnowsky@Sun.COM 5458bab47abSJohn.Zolnowsky@Sun.COM ret = kmf_sign_data(ess->es_kmfhandle, numattr, attrlist); 546df8bdeb3Sjohnz 547df8bdeb3Sjohnz if (ret != KMF_OK) { 5488bab47abSJohn.Zolnowsky@Sun.COM char *kmferr; 5498bab47abSJohn.Zolnowsky@Sun.COM 5508bab47abSJohn.Zolnowsky@Sun.COM (void) kmf_get_kmf_error_str(ret, &kmferr); 5518bab47abSJohn.Zolnowsky@Sun.COM cryptodebug("Error signing data: %s\n", 5528bab47abSJohn.Zolnowsky@Sun.COM (kmferr ? kmferr : "Unrecognized KMF error")); 5538bab47abSJohn.Zolnowsky@Sun.COM free(kmferr); 554df8bdeb3Sjohnz *sig_len = 0; 555df8bdeb3Sjohnz return (B_FALSE); 556df8bdeb3Sjohnz } 557df8bdeb3Sjohnz *sig_len = signature.Length; 558df8bdeb3Sjohnz return (B_TRUE); 559df8bdeb3Sjohnz } 560df8bdeb3Sjohnz 561df8bdeb3Sjohnz /* 562df8bdeb3Sjohnz * elfcertlib_verifysig - verify the given DATA using the public key in cert 563df8bdeb3Sjohnz * 564df8bdeb3Sjohnz * IN ess - elfsign context structure 565df8bdeb3Sjohnz * cert 566df8bdeb3Sjohnz * signature 567df8bdeb3Sjohnz * sig_len 568df8bdeb3Sjohnz * data 569df8bdeb3Sjohnz * data_len 570df8bdeb3Sjohnz * OUT N/A 571df8bdeb3Sjohnz * RETURNS TRUE/FALSE 572df8bdeb3Sjohnz */ 573df8bdeb3Sjohnz boolean_t 574df8bdeb3Sjohnz elfcertlib_verifysig(ELFsign_t ess, ELFCert_t cert, 575df8bdeb3Sjohnz const uchar_t *signature, size_t sig_len, 576df8bdeb3Sjohnz const uchar_t *data, size_t data_len) 577df8bdeb3Sjohnz { 578df8bdeb3Sjohnz KMF_RETURN rv; 579df8bdeb3Sjohnz KMF_DATA indata; 580df8bdeb3Sjohnz KMF_DATA insig; 581df8bdeb3Sjohnz KMF_ALGORITHM_INDEX algid; 5828bab47abSJohn.Zolnowsky@Sun.COM KMF_ATTRIBUTE attrlist[8]; 5838bab47abSJohn.Zolnowsky@Sun.COM KMF_KEYSTORE_TYPE kstype; 5848bab47abSJohn.Zolnowsky@Sun.COM int numattr; 585df8bdeb3Sjohnz 586df8bdeb3Sjohnz indata.Data = (uchar_t *)data; 587df8bdeb3Sjohnz indata.Length = data_len; 588df8bdeb3Sjohnz insig.Data = (uchar_t *)signature; 589df8bdeb3Sjohnz insig.Length = sig_len; 590df8bdeb3Sjohnz 591df8bdeb3Sjohnz if (ess->es_version <= FILESIG_VERSION2) 592df8bdeb3Sjohnz algid = KMF_ALGID_MD5WithRSA; 593df8bdeb3Sjohnz else 594df8bdeb3Sjohnz algid = KMF_ALGID_RSA; 595df8bdeb3Sjohnz 596df8bdeb3Sjohnz /* 5972225707cSValerie Bubb Fenwick * We tell KMF to use the PKCS11 verification APIs 5982225707cSValerie Bubb Fenwick * here to prevent the use of OpenSSL and to keep 5992225707cSValerie Bubb Fenwick * all validation within the FIPS-140 boundary for 6002225707cSValerie Bubb Fenwick * the Cryptographic Framework. 601df8bdeb3Sjohnz */ 6028bab47abSJohn.Zolnowsky@Sun.COM kstype = KMF_KEYSTORE_PK11TOKEN; 6038bab47abSJohn.Zolnowsky@Sun.COM 6048bab47abSJohn.Zolnowsky@Sun.COM numattr = 0; 6058bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_KEYSTORE_TYPE_ATTR, 6068bab47abSJohn.Zolnowsky@Sun.COM &kstype, sizeof (kstype)); 6078bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_DATA_ATTR, 6088bab47abSJohn.Zolnowsky@Sun.COM &indata, sizeof (KMF_DATA)); 6098bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_IN_SIGN_ATTR, 6108bab47abSJohn.Zolnowsky@Sun.COM &insig, sizeof (KMF_DATA)); 6118bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_SIGNER_CERT_DATA_ATTR, 6128bab47abSJohn.Zolnowsky@Sun.COM (KMF_DATA *)(&cert->c_cert.certificate), sizeof (KMF_DATA)); 6138bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, KMF_ALGORITHM_INDEX_ATTR, 6148bab47abSJohn.Zolnowsky@Sun.COM &algid, sizeof (algid)); 6158bab47abSJohn.Zolnowsky@Sun.COM 6168bab47abSJohn.Zolnowsky@Sun.COM rv = kmf_verify_data(ess->es_kmfhandle, numattr, attrlist); 617df8bdeb3Sjohnz 618df8bdeb3Sjohnz return ((rv == KMF_OK)); 619df8bdeb3Sjohnz } 620df8bdeb3Sjohnz 621df8bdeb3Sjohnz /* 622df8bdeb3Sjohnz * elfcertlib_getdn 623df8bdeb3Sjohnz * 624df8bdeb3Sjohnz * IN cert 625df8bdeb3Sjohnz * OUT NONE 626df8bdeb3Sjohnz * RETURN dn or NULL 627df8bdeb3Sjohnz */ 628df8bdeb3Sjohnz char * 629df8bdeb3Sjohnz elfcertlib_getdn(ELFCert_t cert) 630df8bdeb3Sjohnz { 631df8bdeb3Sjohnz cryptodebug("elfcertlib_getdn"); 632df8bdeb3Sjohnz 633df8bdeb3Sjohnz return (cert->c_subject); 634df8bdeb3Sjohnz } 635df8bdeb3Sjohnz 636df8bdeb3Sjohnz /* 637df8bdeb3Sjohnz * elfcertlib_getissuer 638df8bdeb3Sjohnz * 639df8bdeb3Sjohnz * IN cert 640df8bdeb3Sjohnz * OUT NONE 641df8bdeb3Sjohnz * RETURN dn or NULL 642df8bdeb3Sjohnz */ 643df8bdeb3Sjohnz char * 644df8bdeb3Sjohnz elfcertlib_getissuer(ELFCert_t cert) 645df8bdeb3Sjohnz { 646df8bdeb3Sjohnz cryptodebug("elfcertlib_issuer"); 647df8bdeb3Sjohnz 648df8bdeb3Sjohnz return (cert->c_issuer); 649df8bdeb3Sjohnz } 650df8bdeb3Sjohnz 651df8bdeb3Sjohnz boolean_t 652df8bdeb3Sjohnz elfcertlib_init(ELFsign_t ess) 653df8bdeb3Sjohnz { 654df8bdeb3Sjohnz boolean_t rc = B_TRUE; 655df8bdeb3Sjohnz KMF_RETURN rv; 656df8bdeb3Sjohnz if (ess->es_kmfhandle == NULL) { 6578bab47abSJohn.Zolnowsky@Sun.COM rv = kmf_initialize(&ess->es_kmfhandle, NULL, NULL); 658df8bdeb3Sjohnz if (rv != KMF_OK) { 659df8bdeb3Sjohnz cryptoerror(LOG_ERR, 660df8bdeb3Sjohnz "unable to initialize KMF library"); 661df8bdeb3Sjohnz rc = B_FALSE; 662df8bdeb3Sjohnz } 663df8bdeb3Sjohnz } 664df8bdeb3Sjohnz return (rc); 665df8bdeb3Sjohnz } 666df8bdeb3Sjohnz 667df8bdeb3Sjohnz void 668df8bdeb3Sjohnz elfcertlib_fini(ELFsign_t ess) 669df8bdeb3Sjohnz { 6708bab47abSJohn.Zolnowsky@Sun.COM (void) kmf_finalize(ess->es_kmfhandle); 671df8bdeb3Sjohnz } 672df8bdeb3Sjohnz 673df8bdeb3Sjohnz /* 674df8bdeb3Sjohnz * set the token device 675df8bdeb3Sjohnz */ 676df8bdeb3Sjohnz boolean_t 677df8bdeb3Sjohnz elfcertlib_settoken(ELFsign_t ess, char *token) 678df8bdeb3Sjohnz { 679df8bdeb3Sjohnz boolean_t rc = B_TRUE; 680df8bdeb3Sjohnz KMF_RETURN rv; 6818bab47abSJohn.Zolnowsky@Sun.COM KMF_ATTRIBUTE attrlist[8]; 6828bab47abSJohn.Zolnowsky@Sun.COM KMF_KEYSTORE_TYPE kstype; 6838bab47abSJohn.Zolnowsky@Sun.COM boolean_t readonly; 6848bab47abSJohn.Zolnowsky@Sun.COM int numattr; 685df8bdeb3Sjohnz 6868bab47abSJohn.Zolnowsky@Sun.COM kstype = KMF_KEYSTORE_PK11TOKEN; 6878bab47abSJohn.Zolnowsky@Sun.COM readonly = B_TRUE; 6888bab47abSJohn.Zolnowsky@Sun.COM 6898bab47abSJohn.Zolnowsky@Sun.COM numattr = 0; 6908bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, 6918bab47abSJohn.Zolnowsky@Sun.COM KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 6928bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, 6938bab47abSJohn.Zolnowsky@Sun.COM KMF_TOKEN_LABEL_ATTR, token, strlen(token)); 6948bab47abSJohn.Zolnowsky@Sun.COM kmf_set_attr_at_index(attrlist, numattr++, 6958bab47abSJohn.Zolnowsky@Sun.COM KMF_READONLY_ATTR, &readonly, sizeof (readonly)); 6968bab47abSJohn.Zolnowsky@Sun.COM 6978bab47abSJohn.Zolnowsky@Sun.COM rv = kmf_configure_keystore(ess->es_kmfhandle, numattr, attrlist); 698df8bdeb3Sjohnz if (rv != KMF_OK) { 699df8bdeb3Sjohnz cryptoerror(LOG_ERR, "unable to select token\n"); 700df8bdeb3Sjohnz rc = B_FALSE; 701df8bdeb3Sjohnz } 702df8bdeb3Sjohnz 703df8bdeb3Sjohnz return (rc); 704df8bdeb3Sjohnz } 705df8bdeb3Sjohnz 706df8bdeb3Sjohnz /* 707df8bdeb3Sjohnz * set the certificate CA identification callback 708df8bdeb3Sjohnz */ 709df8bdeb3Sjohnz void 710df8bdeb3Sjohnz elfcertlib_setcertCAcallback(ELFsign_t ess, 711df8bdeb3Sjohnz void (*cb)(void *, ELFCert_t, char *)) 712df8bdeb3Sjohnz { 713df8bdeb3Sjohnz ess->es_certCAcallback = cb; 714df8bdeb3Sjohnz } 715df8bdeb3Sjohnz 716df8bdeb3Sjohnz /* 717df8bdeb3Sjohnz * set the certificate verification callback 718df8bdeb3Sjohnz */ 719df8bdeb3Sjohnz void 720df8bdeb3Sjohnz elfcertlib_setcertvercallback(ELFsign_t ess, 721df8bdeb3Sjohnz void (*cb)(void *, ELFCert_t, ELFCert_t)) 722df8bdeb3Sjohnz { 723df8bdeb3Sjohnz ess->es_certvercallback = cb; 724df8bdeb3Sjohnz } 725df8bdeb3Sjohnz 726df8bdeb3Sjohnz 727df8bdeb3Sjohnz /* 728df8bdeb3Sjohnz * elfcertlib_releasecert - release a cert 729df8bdeb3Sjohnz * 730df8bdeb3Sjohnz * IN cert 731df8bdeb3Sjohnz * OUT cert 732df8bdeb3Sjohnz * RETURN N/A 733df8bdeb3Sjohnz * 734df8bdeb3Sjohnz */ 735df8bdeb3Sjohnz void 736df8bdeb3Sjohnz elfcertlib_releasecert(ELFsign_t ess, ELFCert_t cert) 737df8bdeb3Sjohnz { 738df8bdeb3Sjohnz elfcertlib_freecert(ess, cert); 739df8bdeb3Sjohnz } 740df8bdeb3Sjohnz 741df8bdeb3Sjohnz /* 742df8bdeb3Sjohnz * elfcertlib_allocatecert - create a new ELFCert_t 743df8bdeb3Sjohnz * 744df8bdeb3Sjohnz * IN N/A 745df8bdeb3Sjohnz * OUT N/A 746df8bdeb3Sjohnz * RETURN ELFCert_t, NULL on failure. 747df8bdeb3Sjohnz */ 748df8bdeb3Sjohnz static ELFCert_t 749df8bdeb3Sjohnz elfcertlib_allocatecert(void) 750df8bdeb3Sjohnz { 751df8bdeb3Sjohnz ELFCert_t cert = NULL; 752df8bdeb3Sjohnz 753df8bdeb3Sjohnz cert = malloc(sizeof (struct ELFCert_s)); 754df8bdeb3Sjohnz if (cert == NULL) { 755df8bdeb3Sjohnz cryptoerror(LOG_ERR, 756df8bdeb3Sjohnz "elfcertlib_allocatecert: malloc failed %s", 757df8bdeb3Sjohnz strerror(errno)); 758df8bdeb3Sjohnz return (NULL); 759df8bdeb3Sjohnz } 760df8bdeb3Sjohnz (void) memset(cert, 0, sizeof (struct ELFCert_s)); 761df8bdeb3Sjohnz cert->c_verified = E_UNCHECKED; 762df8bdeb3Sjohnz cert->c_subject = NULL; 763df8bdeb3Sjohnz cert->c_issuer = NULL; 764df8bdeb3Sjohnz return (cert); 765df8bdeb3Sjohnz } 766df8bdeb3Sjohnz 767df8bdeb3Sjohnz /* 768df8bdeb3Sjohnz * elfcertlib_freecert - freeup the memory of a cert 769df8bdeb3Sjohnz * 770df8bdeb3Sjohnz * IN cert 771df8bdeb3Sjohnz * OUT cert 772df8bdeb3Sjohnz * RETURN N/A 773df8bdeb3Sjohnz * 774df8bdeb3Sjohnz */ 775df8bdeb3Sjohnz static void 776df8bdeb3Sjohnz elfcertlib_freecert(ELFsign_t ess, ELFCert_t cert) 777df8bdeb3Sjohnz { 778df8bdeb3Sjohnz if (cert == NULL) 779df8bdeb3Sjohnz return; 780df8bdeb3Sjohnz 781df8bdeb3Sjohnz free(cert->c_subject); 782df8bdeb3Sjohnz free(cert->c_issuer); 783df8bdeb3Sjohnz 7848bab47abSJohn.Zolnowsky@Sun.COM kmf_free_kmf_cert(ess->es_kmfhandle, &cert->c_cert); 7858bab47abSJohn.Zolnowsky@Sun.COM kmf_free_kmf_key(ess->es_kmfhandle, &cert->c_privatekey); 786df8bdeb3Sjohnz 787df8bdeb3Sjohnz free(cert); 788df8bdeb3Sjohnz } 789