/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2012 Milan Jurik. All rights reserved. */ /* * This file implements the token object list operation for this tool. * It loads the PKCS#11 modules, finds the object to list, lists it, * and cleans up. User must be logged into the token to list private * objects. */ #include #include #include #include #include #include "common.h" #include static void pk_show_certs(KMF_HANDLE_T kmfhandle, KMF_X509_DER_CERT *certs, int num_certs) { int i; char *subject, *issuer, *serial, *id, *altname; char *start, *end, *keyusage, *extkeyusage; for (i = 0; i < num_certs; i++) { subject = NULL; issuer = NULL; serial = NULL; id = NULL; altname = NULL; start = end = NULL; keyusage = extkeyusage = NULL; (void) fprintf(stdout, gettext("%d. (X.509 certificate)\n"), i + 1); if (certs[i].kmf_private.label != NULL) (void) fprintf(stdout, gettext("\t%s: %s\n"), (certs[i].kmf_private.keystore_type == KMF_KEYSTORE_OPENSSL ? "Filename" : "Label"), certs[i].kmf_private.label); if (kmf_get_cert_id_str(&certs[i].certificate, &id) == KMF_OK) (void) fprintf(stdout, gettext("\tID: %s\n"), id); if (kmf_get_cert_subject_str(kmfhandle, &certs[i].certificate, &subject) == KMF_OK) (void) fprintf(stdout, gettext("\tSubject: %s\n"), subject); if (kmf_get_cert_issuer_str(kmfhandle, &certs[i].certificate, &issuer) == KMF_OK) (void) fprintf(stdout, gettext("\tIssuer: %s\n"), issuer); if (kmf_get_cert_start_date_str(kmfhandle, &certs[i].certificate, &start) == KMF_OK) (void) fprintf(stdout, gettext("\tNot Before: %s\n"), start); if (kmf_get_cert_end_date_str(kmfhandle, &certs[i].certificate, &end) == KMF_OK) (void) fprintf(stdout, gettext("\tNot After: %s\n"), end); if (kmf_get_cert_serial_str(kmfhandle, &certs[i].certificate, &serial) == KMF_OK) (void) fprintf(stdout, gettext("\tSerial: %s\n"), serial); if (kmf_get_cert_extn_str(kmfhandle, &certs[i].certificate, KMF_X509_EXT_SUBJ_ALTNAME, &altname) == KMF_OK) { (void) fprintf(stdout, gettext("\t%s\n"), altname); } if (kmf_get_cert_extn_str(kmfhandle, &certs[i].certificate, KMF_X509_EXT_KEY_USAGE, &keyusage) == KMF_OK) { (void) fprintf(stdout, gettext("\t%s\n"), keyusage); } if (kmf_get_cert_extn_str(kmfhandle, &certs[i].certificate, KMF_X509_EXT_EXT_KEY_USAGE, &extkeyusage) == KMF_OK) { (void) fprintf(stdout, gettext("\t%s\n"), extkeyusage); } kmf_free_str(subject); kmf_free_str(issuer); kmf_free_str(serial); kmf_free_str(id); kmf_free_str(altname); kmf_free_str(keyusage); kmf_free_str(extkeyusage); kmf_free_str(start); kmf_free_str(end); (void) fprintf(stdout, "\n"); } } static char * describeKey(KMF_KEY_HANDLE *key) { if (key->keyclass == KMF_ASYM_PUB) { if (key->keyalg == KMF_RSA) return (gettext("RSA public key")); if (key->keyalg == KMF_DSA) return (gettext("DSA public key")); if (key->keyalg == KMF_ECDSA) return (gettext("ECDSA public key")); } if (key->keyclass == KMF_ASYM_PRI) { if (key->keyalg == KMF_RSA) return (gettext("RSA private key")); if (key->keyalg == KMF_DSA) return (gettext("DSA private key")); if (key->keyalg == KMF_ECDSA) return (gettext("ECDSA private key")); } if (key->keyclass == KMF_SYMMETRIC) { switch (key->keyalg) { case KMF_AES: return (gettext("AES")); case KMF_RC4: return (gettext("ARCFOUR")); case KMF_DES: return (gettext("DES")); case KMF_DES3: return (gettext("Triple-DES")); default: return (gettext("symmetric")); } } return (gettext("unrecognized key object")); } static void pk_show_keys(void *handle, KMF_KEY_HANDLE *keys, int numkeys) { int i; for (i = 0; i < numkeys; i++) { (void) fprintf(stdout, gettext("Key #%d - %s: %s"), i+1, describeKey(&keys[i]), keys[i].keylabel ? keys[i].keylabel : gettext("No label")); if (keys[i].keyclass == KMF_SYMMETRIC) { KMF_RETURN rv; KMF_RAW_SYM_KEY rkey; (void) memset(&rkey, 0, sizeof (rkey)); rv = kmf_get_sym_key_value(handle, &keys[i], &rkey); if (rv == KMF_OK) { (void) fprintf(stdout, " (%d bits)", rkey.keydata.len * 8); kmf_free_bigint(&rkey.keydata); } else if (keys[i].kstype == KMF_KEYSTORE_PK11TOKEN) { if (rv == KMF_ERR_SENSITIVE_KEY) { (void) fprintf(stdout, " (sensitive)"); } else if (rv == KMF_ERR_UNEXTRACTABLE_KEY) { (void) fprintf(stdout, " (non-extractable)"); } else { char *err = NULL; if (kmf_get_kmf_error_str(rv, &err) == KMF_OK) (void) fprintf(stdout, " (error: %s)", err); if (err != NULL) free(err); } } } (void) fprintf(stdout, "\n"); } } /* * Generic routine used by all "list cert" operations to find * all matching certificates. */ static KMF_RETURN pk_find_certs(KMF_HANDLE_T kmfhandle, KMF_ATTRIBUTE *attrlist, int numattr) { KMF_RETURN rv = KMF_OK; KMF_X509_DER_CERT *certlist = NULL; uint32_t numcerts = 0; KMF_KEYSTORE_TYPE kstype; rv = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr, &kstype, NULL); if (rv != KMF_OK) return (rv); kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR, &numcerts, sizeof (uint32_t)); numattr++; rv = kmf_find_cert(kmfhandle, numattr, attrlist); if (rv == KMF_OK && numcerts > 0) { (void) printf(gettext("Found %d certificates.\n"), numcerts); certlist = (KMF_X509_DER_CERT *)malloc(numcerts * sizeof (KMF_X509_DER_CERT)); if (certlist == NULL) return (KMF_ERR_MEMORY); (void) memset(certlist, 0, numcerts * sizeof (KMF_X509_DER_CERT)); kmf_set_attr_at_index(attrlist, numattr, KMF_X509_DER_CERT_ATTR, certlist, sizeof (KMF_X509_DER_CERT)); numattr++; rv = kmf_find_cert(kmfhandle, numattr, attrlist); if (rv == KMF_OK) { int i; (void) pk_show_certs(kmfhandle, certlist, numcerts); for (i = 0; i < numcerts; i++) kmf_free_kmf_cert(kmfhandle, &certlist[i]); } free(certlist); } if (rv == KMF_ERR_CERT_NOT_FOUND && kstype != KMF_KEYSTORE_OPENSSL) rv = KMF_OK; return (rv); } static KMF_RETURN pk_list_keys(void *handle, KMF_ATTRIBUTE *attrlist, int numattr, char *label) { KMF_RETURN rv; KMF_KEY_HANDLE *keys; uint32_t numkeys = 0; KMF_KEYSTORE_TYPE kstype; rv = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr, &kstype, NULL); if (rv != KMF_OK) return (rv); kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR, &numkeys, sizeof (uint32_t)); numattr++; rv = kmf_find_key(handle, numattr, attrlist); if (rv == KMF_OK && numkeys > 0) { int i; (void) printf(gettext("Found %d %s keys.\n"), numkeys, label); keys = (KMF_KEY_HANDLE *)malloc(numkeys * sizeof (KMF_KEY_HANDLE)); if (keys == NULL) return (KMF_ERR_MEMORY); (void) memset(keys, 0, numkeys * sizeof (KMF_KEY_HANDLE)); kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR, keys, sizeof (KMF_KEY_HANDLE)); numattr++; rv = kmf_find_key(handle, numattr, attrlist); if (rv == KMF_OK) pk_show_keys(handle, keys, numkeys); for (i = 0; i < numkeys; i++) kmf_free_kmf_key(handle, &keys[i]); free(keys); } if (rv == KMF_ERR_KEY_NOT_FOUND && kstype != KMF_KEYSTORE_OPENSSL) rv = KMF_OK; return (rv); } static KMF_RETURN list_pk11_objects(KMF_HANDLE_T kmfhandle, char *token, int oclass, char *objlabel, KMF_BIGINT *serial, char *issuer, char *subject, char *dir, char *filename, KMF_CREDENTIAL *tokencred, KMF_CERT_VALIDITY find_criteria_flag) { KMF_RETURN rv; KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; int numattr = 0; KMF_ATTRIBUTE attrlist[18]; boolean_t token_bool = B_TRUE; boolean_t private = B_FALSE; KMF_KEY_CLASS keyclass; KMF_ENCODE_FORMAT format; int auth = 0; KMF_CREDENTIAL cred = { NULL, 0 }; /* * Symmetric keys and RSA/DSA/ECDSA private keys are always * created with the "CKA_PRIVATE" field == TRUE, so * make sure we search for them with it also set. */ if (oclass & (PK_SYMKEY_OBJ | PK_PRIKEY_OBJ)) oclass |= PK_PRIVATE_OBJ; rv = select_token(kmfhandle, token, !(oclass & (PK_PRIVATE_OBJ | PK_PRIKEY_OBJ))); if (rv != KMF_OK) { return (rv); } rv = token_auth_needed(kmfhandle, token, &auth); if (rv != KMF_OK) return (rv); if (tokencred != NULL) cred = *tokencred; if (oclass & (PK_KEY_OBJ | PK_PRIVATE_OBJ)) { kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); numattr++; if (objlabel != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR, objlabel, strlen(objlabel)); numattr++; } private = ((oclass & PK_PRIVATE_OBJ) > 0); kmf_set_attr_at_index(attrlist, numattr, KMF_PRIVATE_BOOL_ATTR, &private, sizeof (private)); numattr++; kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_BOOL_ATTR, &token_bool, sizeof (token_bool)); numattr++; if (oclass & PK_PRIKEY_OBJ) { int num = numattr; keyclass = KMF_ASYM_PRI; kmf_set_attr_at_index(attrlist, num, KMF_KEYCLASS_ATTR, &keyclass, sizeof (keyclass)); num++; if (tokencred != NULL && tokencred->credlen > 0) { kmf_set_attr_at_index(attrlist, num, KMF_CREDENTIAL_ATTR, tokencred, sizeof (KMF_CREDENTIAL)); num++; } /* list asymmetric private keys */ rv = pk_list_keys(kmfhandle, attrlist, num, "asymmetric private"); } if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) { int num = numattr; keyclass = KMF_SYMMETRIC; kmf_set_attr_at_index(attrlist, num, KMF_KEYCLASS_ATTR, &keyclass, sizeof (keyclass)); num++; if (tokencred != NULL && tokencred->credlen > 0) { kmf_set_attr_at_index(attrlist, num, KMF_CREDENTIAL_ATTR, tokencred, sizeof (KMF_CREDENTIAL)); num++; } format = KMF_FORMAT_RAWKEY; kmf_set_attr_at_index(attrlist, num, KMF_ENCODE_FORMAT_ATTR, &format, sizeof (format)); num++; /* list symmetric keys */ rv = pk_list_keys(kmfhandle, attrlist, num, "symmetric"); } if (rv == KMF_OK && (oclass & PK_PUBKEY_OBJ)) { int num = numattr; if (auth > 0 && (tokencred == NULL || tokencred->cred == NULL) && (cred.cred == NULL)) { (void) get_token_password(kstype, token, &cred); kmf_set_attr_at_index(attrlist, num, KMF_CREDENTIAL_ATTR, &cred, sizeof (KMF_CREDENTIAL)); num++; } private = B_FALSE; keyclass = KMF_ASYM_PUB; kmf_set_attr_at_index(attrlist, num, KMF_KEYCLASS_ATTR, &keyclass, sizeof (keyclass)); num++; /* list asymmetric public keys (if any) */ rv = pk_list_keys(kmfhandle, attrlist, num, "asymmetric public"); } if (rv != KMF_OK) return (rv); } numattr = 0; if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) { kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); numattr++; if (auth > 0 && (cred.cred == NULL)) { (void) get_token_password(kstype, token, &cred); } if (cred.cred != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR, &cred, sizeof (KMF_CREDENTIAL)); numattr++; } if (objlabel != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_LABEL_ATTR, objlabel, strlen(objlabel)); numattr++; } if (issuer != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer)); numattr++; } if (subject != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_SUBJECT_NAME_ATTR, subject, strlen(subject)); numattr++; } if (serial != NULL && serial->val != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT)); numattr++; } kmf_set_attr_at_index(attrlist, numattr, KMF_PRIVATE_BOOL_ATTR, &private, sizeof (private)); numattr++; kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_VALIDITY_ATTR, &find_criteria_flag, sizeof (KMF_CERT_VALIDITY)); numattr++; rv = pk_find_certs(kmfhandle, attrlist, numattr); if (rv != KMF_OK) return (rv); } numattr = 0; kstype = KMF_KEYSTORE_OPENSSL; /* CRL is file-based */ if (oclass & PK_CRL_OBJ) { char *crldata = NULL; kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); numattr++; if (dir != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_DIRPATH_ATTR, dir, strlen(dir)); numattr++; } if (filename != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_FILENAME_ATTR, filename, strlen(filename)); numattr++; } kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_DATA_ATTR, &crldata, sizeof (char *)); numattr++; rv = kmf_list_crl(kmfhandle, numattr, attrlist); if (rv == KMF_OK && crldata != NULL) { (void) printf("%s\n", crldata); free(crldata); } } return (rv); } static int list_file_objects(KMF_HANDLE_T kmfhandle, int oclass, char *dir, char *filename, KMF_BIGINT *serial, char *issuer, char *subject, KMF_CERT_VALIDITY find_criteria_flag) { KMF_RETURN rv = KMF_OK; KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; int numattr = 0; KMF_ATTRIBUTE attrlist[16]; KMF_KEY_CLASS keyclass; KMF_ENCODE_FORMAT format; char *defaultdir = "."; if (oclass & PK_KEY_OBJ) { kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); numattr++; if (dir == NULL && filename == NULL) dir = defaultdir; if (dir != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_DIRPATH_ATTR, dir, strlen(dir)); numattr++; } if (filename != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR, filename, strlen(filename)); numattr++; } if (oclass & PK_PRIKEY_OBJ) { int num = numattr; keyclass = KMF_ASYM_PRI; kmf_set_attr_at_index(attrlist, num, KMF_KEYCLASS_ATTR, &keyclass, sizeof (keyclass)); num++; /* list asymmetric private keys */ rv = pk_list_keys(kmfhandle, attrlist, num, "asymmetric private"); } if (rv == KMF_ERR_KEY_NOT_FOUND) rv = KMF_OK; if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) { int num = numattr; keyclass = KMF_SYMMETRIC; kmf_set_attr_at_index(attrlist, num, KMF_KEYCLASS_ATTR, &keyclass, sizeof (keyclass)); num++; format = KMF_FORMAT_RAWKEY; kmf_set_attr_at_index(attrlist, num, KMF_ENCODE_FORMAT_ATTR, &format, sizeof (format)); num++; /* list symmetric keys */ rv = pk_list_keys(kmfhandle, attrlist, num, "symmetric"); } if (rv == KMF_ERR_KEY_NOT_FOUND) rv = KMF_OK; if (rv != KMF_OK) return (rv); } numattr = 0; if (oclass & PK_CERT_OBJ) { kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); numattr++; if (issuer != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer)); numattr++; } if (subject != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_SUBJECT_NAME_ATTR, subject, strlen(subject)); numattr++; } if (serial != NULL && serial->val != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT)); numattr++; } if (filename != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_FILENAME_ATTR, filename, strlen(filename)); numattr++; } if (dir != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_DIRPATH_ATTR, dir, strlen(dir)); numattr++; } kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_VALIDITY_ATTR, &find_criteria_flag, sizeof (KMF_CERT_VALIDITY)); numattr++; rv = pk_find_certs(kmfhandle, attrlist, numattr); if (rv != KMF_OK) return (rv); } numattr = 0; if (oclass & PK_CRL_OBJ) { char *crldata = NULL; kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); numattr++; if (dir != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_DIRPATH_ATTR, dir, strlen(dir)); numattr++; } if (filename != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_FILENAME_ATTR, filename, strlen(filename)); numattr++; } kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_DATA_ATTR, &crldata, sizeof (char *)); numattr++; rv = kmf_list_crl(kmfhandle, numattr, attrlist); if (rv == KMF_OK && crldata != NULL) { (void) printf("%s\n", crldata); free(crldata); } } return (rv); } static int list_nss_objects(KMF_HANDLE_T kmfhandle, int oclass, char *token_spec, char *dir, char *prefix, char *nickname, KMF_BIGINT *serial, char *issuer, char *subject, KMF_CREDENTIAL *tokencred, KMF_CERT_VALIDITY find_criteria_flag) { KMF_RETURN rv = KMF_OK; KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS; int numattr = 0; KMF_ATTRIBUTE attrlist[16]; KMF_KEY_CLASS keyclass; KMF_ENCODE_FORMAT format; rv = configure_nss(kmfhandle, dir, prefix); if (rv != KMF_OK) return (rv); kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); numattr++; if (oclass & PK_KEY_OBJ) { if (tokencred != NULL && tokencred->credlen > 0) { kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR, tokencred, sizeof (KMF_CREDENTIAL)); numattr++; } if (token_spec && strlen(token_spec)) { kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR, token_spec, strlen(token_spec)); numattr++; } if (nickname != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR, nickname, strlen(nickname)); numattr++; } } if (oclass & PK_PRIKEY_OBJ) { int num = numattr; keyclass = KMF_ASYM_PRI; kmf_set_attr_at_index(attrlist, num, KMF_KEYCLASS_ATTR, &keyclass, sizeof (keyclass)); num++; /* list asymmetric private keys */ rv = pk_list_keys(kmfhandle, attrlist, num, "asymmetric private"); } if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) { int num = numattr; keyclass = KMF_SYMMETRIC; kmf_set_attr_at_index(attrlist, num, KMF_KEYCLASS_ATTR, &keyclass, sizeof (keyclass)); num++; format = KMF_FORMAT_RAWKEY; kmf_set_attr_at_index(attrlist, num, KMF_ENCODE_FORMAT_ATTR, &format, sizeof (format)); num++; /* list symmetric keys */ rv = pk_list_keys(kmfhandle, attrlist, num, "symmetric"); } if (rv == KMF_OK && (oclass & PK_PUBKEY_OBJ)) { int num = numattr; keyclass = KMF_ASYM_PUB; kmf_set_attr_at_index(attrlist, num, KMF_KEYCLASS_ATTR, &keyclass, sizeof (keyclass)); num++; /* list asymmetric public keys */ rv = pk_list_keys(kmfhandle, attrlist, num, "asymmetric public"); } /* If searching for public objects or certificates, find certs now */ numattr = 0; if (rv == KMF_OK && (oclass & PK_CERT_OBJ)) { kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); numattr++; if (nickname != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_LABEL_ATTR, nickname, strlen(nickname)); numattr++; } if (issuer != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer)); numattr++; } if (subject != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_SUBJECT_NAME_ATTR, subject, strlen(subject)); numattr++; } if (serial != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT)); numattr++; } if (token_spec != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR, token_spec, strlen(token_spec)); numattr++; } kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_VALIDITY_ATTR, &find_criteria_flag, sizeof (KMF_CERT_VALIDITY)); numattr++; rv = pk_find_certs(kmfhandle, attrlist, numattr); } numattr = 0; if (rv == KMF_OK && (oclass & PK_CRL_OBJ)) { int numcrls; kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); numattr++; if (token_spec != NULL) { kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR, token_spec, strlen(token_spec)); numattr++; } kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_COUNT_ATTR, &numcrls, sizeof (int)); numattr++; rv = kmf_find_crl(kmfhandle, numattr, attrlist); if (rv == KMF_OK) { char **p; if (numcrls == 0) { (void) printf(gettext("No CRLs found in " "NSS keystore.\n")); return (KMF_OK); } p = malloc(numcrls * sizeof (char *)); if (p == NULL) { return (KMF_ERR_MEMORY); } (void) memset(p, 0, numcrls * sizeof (char *)); kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_NAMELIST_ATTR, p, sizeof (char *)); numattr++; rv = kmf_find_crl(kmfhandle, numattr, attrlist); if (rv == KMF_OK) { int i; for (i = 0; i < numcrls; i++) { (void) printf("%d. Name = %s\n", i + 1, p[i]); free(p[i]); } } free(p); } } return (rv); } /* * List token object. */ int pk_list(int argc, char *argv[]) { int opt; extern int optind_av; extern char *optarg_av; char *token_spec = NULL; char *subject = NULL; char *issuer = NULL; char *dir = NULL; char *prefix = NULL; char *filename = NULL; char *serstr = NULL; KMF_BIGINT serial = { NULL, 0 }; char *list_label = NULL; int oclass = 0; KMF_KEYSTORE_TYPE kstype = 0; KMF_RETURN rv = KMF_OK; KMF_HANDLE_T kmfhandle = NULL; char *find_criteria = NULL; KMF_CERT_VALIDITY find_criteria_flag = KMF_ALL_CERTS; KMF_CREDENTIAL tokencred = { NULL, 0 }; /* Parse command line options. Do NOT i18n/l10n. */ while ((opt = getopt_av(argc, argv, "k:(keystore)t:(objtype)T:(token)d:(dir)" "p:(prefix)n:(nickname)S:(serial)s:(subject)" "c:(criteria)" "i:(issuer)l:(label)f:(infile)")) != EOF) { if (EMPTYSTRING(optarg_av)) return (PK_ERR_USAGE); switch (opt) { case 'k': if (kstype != 0) return (PK_ERR_USAGE); kstype = KS2Int(optarg_av); if (kstype == 0) return (PK_ERR_USAGE); break; case 't': if (oclass != 0) return (PK_ERR_USAGE); oclass = OT2Int(optarg_av); if (oclass == -1) return (PK_ERR_USAGE); break; case 's': if (subject) return (PK_ERR_USAGE); subject = optarg_av; break; case 'i': if (issuer) return (PK_ERR_USAGE); issuer = optarg_av; break; case 'd': if (dir) return (PK_ERR_USAGE); dir = optarg_av; break; case 'p': if (prefix) return (PK_ERR_USAGE); prefix = optarg_av; break; case 'S': serstr = optarg_av; break; case 'f': if (filename) return (PK_ERR_USAGE); filename = optarg_av; break; case 'T': /* token specifier */ if (token_spec) return (PK_ERR_USAGE); token_spec = optarg_av; break; case 'n': case 'l': /* object with specific label */ if (list_label) return (PK_ERR_USAGE); list_label = optarg_av; break; case 'c': find_criteria = optarg_av; if (!strcasecmp(find_criteria, "valid")) find_criteria_flag = KMF_NONEXPIRED_CERTS; else if (!strcasecmp(find_criteria, "expired")) find_criteria_flag = KMF_EXPIRED_CERTS; else if (!strcasecmp(find_criteria, "both")) find_criteria_flag = KMF_ALL_CERTS; else return (PK_ERR_USAGE); break; default: return (PK_ERR_USAGE); } } /* No additional args allowed. */ argc -= optind_av; argv += optind_av; if (argc) return (PK_ERR_USAGE); if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) { /* Error message ? */ return (rv); } /* Assume keystore = PKCS#11 if not specified. */ if (kstype == 0) kstype = KMF_KEYSTORE_PK11TOKEN; /* if PUBLIC or PRIVATE obj was given, the old syntax was used. */ if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) && kstype != KMF_KEYSTORE_PK11TOKEN) { (void) fprintf(stderr, gettext("The objtype parameter " "is only relevant if keystore=pkcs11\n")); return (PK_ERR_USAGE); } if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec)) { token_spec = PK_DEFAULT_PK11TOKEN; } else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec)) { token_spec = DEFAULT_NSS_TOKEN; } if (serstr != NULL) { uchar_t *bytes = NULL; size_t bytelen; rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen); if (rv != KMF_OK || bytes == NULL) { (void) fprintf(stderr, gettext("serial number " "must be specified as a hex number " "(ex: 0x0102030405ffeeddee)\n")); return (PK_ERR_USAGE); } serial.val = bytes; serial.len = bytelen; /* if objtype was not given, it must be for certs */ if (oclass == 0) oclass = PK_CERT_OBJ; } if (oclass == 0 && (issuer != NULL || subject != NULL)) oclass = PK_CERT_OBJ; /* If no object class specified, list public objects. */ if (oclass == 0) oclass = PK_CERT_OBJ | PK_PUBKEY_OBJ; if ((kstype == KMF_KEYSTORE_PK11TOKEN || kstype == KMF_KEYSTORE_NSS) && (oclass & (PK_PRIKEY_OBJ | PK_PRIVATE_OBJ))) { (void) get_token_password(kstype, token_spec, &tokencred); } if (kstype == KMF_KEYSTORE_PK11TOKEN) { rv = list_pk11_objects(kmfhandle, token_spec, oclass, list_label, &serial, issuer, subject, dir, filename, &tokencred, find_criteria_flag); } else if (kstype == KMF_KEYSTORE_NSS) { if (dir == NULL) dir = PK_DEFAULT_DIRECTORY; rv = list_nss_objects(kmfhandle, oclass, token_spec, dir, prefix, list_label, &serial, issuer, subject, &tokencred, find_criteria_flag); } else if (kstype == KMF_KEYSTORE_OPENSSL) { rv = list_file_objects(kmfhandle, oclass, dir, filename, &serial, issuer, subject, find_criteria_flag); } if (rv != KMF_OK) { display_error(kmfhandle, rv, gettext("Error listing objects")); } if (serial.val != NULL) free(serial.val); if (tokencred.cred != NULL) free(tokencred.cred); (void) kmf_finalize(kmfhandle); return (rv); }