signcsr.c revision d00756ccb34596a328f8a15d1965da5412d366d0
d00756ccb34596a328f8a15d1965da5412d366d0wyllys/*
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * CDDL HEADER START
d00756ccb34596a328f8a15d1965da5412d366d0wyllys *
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * The contents of this file are subject to the terms of the
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * Common Development and Distribution License (the "License").
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * You may not use this file except in compliance with the License.
d00756ccb34596a328f8a15d1965da5412d366d0wyllys *
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * or http://www.opensolaris.org/os/licensing.
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * See the License for the specific language governing permissions
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * and limitations under the License.
d00756ccb34596a328f8a15d1965da5412d366d0wyllys *
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * When distributing Covered Code, include this CDDL HEADER in each
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * If applicable, add the following below this CDDL HEADER, with the
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * fields enclosed by brackets "[]" replaced with your own identifying
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * information: Portions Copyright [yyyy] [name of copyright owner]
d00756ccb34596a328f8a15d1965da5412d366d0wyllys *
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * CDDL HEADER END
d00756ccb34596a328f8a15d1965da5412d366d0wyllys */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys/*
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * Use is subject to license terms.
d00756ccb34596a328f8a15d1965da5412d366d0wyllys */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys#pragma ident "%Z%%M% %I% %E% SMI"
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys/*
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * This file implements the sign CSR operation for this tool.
d00756ccb34596a328f8a15d1965da5412d366d0wyllys */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys#include <stdio.h>
d00756ccb34596a328f8a15d1965da5412d366d0wyllys#include <errno.h>
d00756ccb34596a328f8a15d1965da5412d366d0wyllys#include <string.h>
d00756ccb34596a328f8a15d1965da5412d366d0wyllys#include <cryptoutil.h>
d00756ccb34596a328f8a15d1965da5412d366d0wyllys#include <security/cryptoki.h>
d00756ccb34596a328f8a15d1965da5412d366d0wyllys#include "common.h"
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys#include <kmfapi.h>
d00756ccb34596a328f8a15d1965da5412d366d0wyllys#define SET_VALUE(f, s) \
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = f; \
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (rv != KMF_OK) { \
d00756ccb34596a328f8a15d1965da5412d366d0wyllys cryptoerror(LOG_STDERR, \
d00756ccb34596a328f8a15d1965da5412d366d0wyllys gettext("Failed to set %s: 0x%02x\n"), s, rv); \
d00756ccb34596a328f8a15d1965da5412d366d0wyllys goto cleanup; \
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllysstatic int
d00756ccb34596a328f8a15d1965da5412d366d0wyllysread_csrdata(KMF_HANDLE_T handle, char *csrfile, KMF_CSR_DATA *csrdata)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys{
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_RETURN rv = KMF_OK;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_ENCODE_FORMAT csrfmt;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_DATA csrfiledata = {NULL, 0};
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_DATA rawcsr = {NULL, 0};
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = kmf_get_file_format(csrfile, &csrfmt);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (rv != KMF_OK)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (rv);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = kmf_read_input_file(handle, csrfile, &csrfiledata);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (rv != KMF_OK)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (rv);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (csrfmt == KMF_FORMAT_PEM) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = kmf_pem_to_der(csrfiledata.Data, csrfiledata.Length,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys &rawcsr.Data, (int *)&rawcsr.Length);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (rv != KMF_OK)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (rv);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_free_data(&csrfiledata);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys } else {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rawcsr.Data = csrfiledata.Data;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rawcsr.Length = csrfiledata.Length;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = kmf_decode_csr(handle, &rawcsr, csrdata);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_free_data(&rawcsr);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (rv);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys}
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllysstatic int
d00756ccb34596a328f8a15d1965da5412d366d0wyllysbuild_cert_from_csr(KMF_CSR_DATA *csrdata,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_X509_CERTIFICATE *signedCert,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_BIGINT *serial,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys uint32_t ltime,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys char *issuer, char *subject,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys char *altname,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_GENERALNAMECHOICES alttype,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys int altcrit,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys uint16_t kubits,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys int kucrit,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys EKU_LIST *ekulist)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys{
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_RETURN rv = KMF_OK;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_X509_NAME issuerDN, subjectDN;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys /*
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * If the CSR is ok, now we can generate the final certificate.
d00756ccb34596a328f8a15d1965da5412d366d0wyllys */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys (void) memset(signedCert, 0, sizeof (KMF_X509_CERTIFICATE));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys (void) memset(&issuerDN, 0, sizeof (issuerDN));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys (void) memset(&subjectDN, 0, sizeof (subjectDN));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys SET_VALUE(kmf_set_cert_version(signedCert, 2), "version number");
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys SET_VALUE(kmf_set_cert_serial(signedCert, serial), "serial number");
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys SET_VALUE(kmf_set_cert_validity(signedCert, NULL, ltime),
d00756ccb34596a328f8a15d1965da5412d366d0wyllys "validity time");
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (issuer) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (kmf_dn_parser(issuer, &issuerDN) != KMF_OK) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys cryptoerror(LOG_STDERR,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys gettext("Issuer name cannot be parsed\n"));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (PK_ERR_USAGE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys SET_VALUE(kmf_set_cert_issuer(signedCert, &issuerDN),
d00756ccb34596a328f8a15d1965da5412d366d0wyllys "Issuer Name");
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (subject) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (kmf_dn_parser(subject, &subjectDN) != KMF_OK) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys cryptoerror(LOG_STDERR,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys gettext("Subject name cannot be parsed\n"));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (PK_ERR_USAGE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys SET_VALUE(kmf_set_cert_subject(signedCert, &subjectDN),
d00756ccb34596a328f8a15d1965da5412d366d0wyllys "Subject Name");
d00756ccb34596a328f8a15d1965da5412d366d0wyllys } else {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys signedCert->certificate.subject = csrdata->csr.subject;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys signedCert->certificate.subjectPublicKeyInfo =
d00756ccb34596a328f8a15d1965da5412d366d0wyllys csrdata->csr.subjectPublicKeyInfo;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys signedCert->certificate.extensions = csrdata->csr.extensions;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys signedCert->certificate.signature =
d00756ccb34596a328f8a15d1965da5412d366d0wyllys csrdata->signature.algorithmIdentifier;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (kubits != 0) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys SET_VALUE(kmf_set_cert_ku(signedCert, kucrit, kubits),
d00756ccb34596a328f8a15d1965da5412d366d0wyllys "KeyUsage");
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (altname != NULL) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys SET_VALUE(kmf_set_cert_subject_altname(signedCert,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys altcrit, alttype, altname), "subjectAltName");
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (ekulist != NULL) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys int i;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys for (i = 0; rv == KMF_OK && i < ekulist->eku_count; i++) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys SET_VALUE(kmf_add_cert_eku(signedCert,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys &ekulist->ekulist[i],
d00756ccb34596a328f8a15d1965da5412d366d0wyllys ekulist->critlist[i]), "Extended Key Usage");
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllyscleanup:
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (issuer != NULL)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_free_dn(&issuerDN);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (subject != NULL)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_free_dn(&subjectDN);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (rv);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys}
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllysstatic int
d00756ccb34596a328f8a15d1965da5412d366d0wyllyspk_sign_cert(KMF_HANDLE_T handle, KMF_X509_CERTIFICATE *cert,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_KEY_HANDLE *key, KMF_DATA *outdata)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys{
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_RETURN rv;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys int numattr;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_ATTRIBUTE attrlist[4];
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys numattr = 0;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys &key->kstype, sizeof (KMF_KEYSTORE_TYPE));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys numattr++;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys key, sizeof (KMF_KEY_HANDLE_ATTR));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys numattr++;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys /* cert data that is to be signed */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys cert, sizeof (KMF_X509_CERTIFICATE));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys numattr++;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys /* output buffer for the signed cert */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys outdata, sizeof (KMF_DATA));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys numattr++;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if ((rv = kmf_sign_cert(handle, numattr, attrlist)) != KMF_OK) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys cryptoerror(LOG_STDERR,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys gettext("Failed to sign certificate.\n"));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (rv);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (rv);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys}
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllysstatic int
d00756ccb34596a328f8a15d1965da5412d366d0wyllyspk_signcsr_files(KMF_HANDLE_T handle,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys char *signkey,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys char *csrfile,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_BIGINT *serial,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys char *certfile,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys char *issuer,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys char *subject,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys char *altname,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_GENERALNAMECHOICES alttype,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys int altcrit,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys uint16_t kubits,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys int kucrit,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys EKU_LIST *ekulist,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys uint32_t ltime,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_ENCODE_FORMAT fmt)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys{
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_RETURN rv = KMF_OK;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_CSR_DATA csrdata;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_ATTRIBUTE attrlist[16];
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_X509_CERTIFICATE signedCert;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_KEY_CLASS keyclass = KMF_ASYM_PRI;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_KEY_HANDLE cakey;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_DATA certdata = {NULL, 0};
d00756ccb34596a328f8a15d1965da5412d366d0wyllys int numattr, count;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = read_csrdata(handle, csrfile, &csrdata);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (rv != KMF_OK) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys cryptoerror(LOG_STDERR,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys gettext("Error reading CSR data\n"));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (rv);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys /* verify the signature first */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys numattr = 0;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CSR_DATA_ATTR,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys &csrdata, sizeof (csrdata));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys numattr++;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = kmf_verify_csr(handle, numattr, attrlist);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (rv != KMF_OK) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys cryptoerror(LOG_STDERR, gettext("CSR signature "
d00756ccb34596a328f8a15d1965da5412d366d0wyllys "verification failed.\n"));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys goto cleanup;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = build_cert_from_csr(&csrdata, &signedCert, serial, ltime,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys issuer, subject, altname, alttype, altcrit, kubits,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kucrit, ekulist);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (rv != KMF_OK)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys goto cleanup;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys /*
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * Find the signing key.
d00756ccb34596a328f8a15d1965da5412d366d0wyllys */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys (void) memset(&cakey, 0, sizeof (cakey));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys numattr = 0;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys &kstype, sizeof (kstype));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys numattr++;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys signkey, strlen(signkey));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys numattr++;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys &keyclass, sizeof (keyclass));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys numattr++;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys &cakey, sizeof (cakey));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys numattr++;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys count = 1;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys &count, sizeof (count));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys numattr++;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = kmf_find_key(handle, numattr, attrlist);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (rv != KMF_OK) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys cryptoerror(LOG_STDERR, gettext(
d00756ccb34596a328f8a15d1965da5412d366d0wyllys "Error finding CA signing key\n"));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys goto cleanup;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = pk_sign_cert(handle, &signedCert, &cakey, &certdata);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (rv != KMF_OK) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys cryptoerror(LOG_STDERR, gettext(
d00756ccb34596a328f8a15d1965da5412d366d0wyllys "Error signing certificate.\n"));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys goto cleanup;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = kmf_create_cert_file(&certdata, fmt, certfile);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllyscleanup:
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_free_signed_csr(&csrdata);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_free_data(&certdata);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_free_kmf_key(handle, &cakey);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (rv);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys}
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllysstatic int
d00756ccb34596a328f8a15d1965da5412d366d0wyllyspk_signcsr_pk11_nss(KMF_HANDLE_T handle,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_KEYSTORE_TYPE kstype,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys char *dir, char *prefix,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys char *token, KMF_CREDENTIAL *cred,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys char *signkey, char *csrfile,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_BIGINT *serial, char *certfile, char *issuer, char *subject,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys char *altname, KMF_GENERALNAMECHOICES alttype, int altcrit,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys uint16_t kubits, int kucrit,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys EKU_LIST *ekulist, uint32_t ltime,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_ENCODE_FORMAT fmt, int store, char *outlabel)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys{
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_RETURN rv = KMF_OK;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_DATA outcert = {NULL, 0};
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_CSR_DATA csrdata;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_KEY_HANDLE casignkey;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_KEY_CLASS keyclass = KMF_ASYM_PRI;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys int numattr = 0;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys int keys = 1;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_ATTRIBUTE attrlist[16];
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_X509_CERTIFICATE signedCert;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys boolean_t token_bool = B_TRUE;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys boolean_t private_bool = B_TRUE;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = read_csrdata(handle, csrfile, &csrdata);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (rv != KMF_OK) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys cryptoerror(LOG_STDERR,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys gettext("Error reading CSR data\n"));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (rv);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (kstype == KMF_KEYSTORE_PK11TOKEN) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = select_token(handle, token, FALSE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys } else if (kstype == KMF_KEYSTORE_NSS) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = configure_nss(handle, dir, prefix);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys /* verify the signature first */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CSR_DATA_ATTR,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys &csrdata, sizeof (csrdata));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys numattr++;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = kmf_verify_csr(handle, numattr, attrlist);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (rv != KMF_OK) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys cryptoerror(LOG_STDERR, gettext("CSR signature "
d00756ccb34596a328f8a15d1965da5412d366d0wyllys "verification failed.\n"));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys goto cleanup;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = build_cert_from_csr(&csrdata,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys &signedCert, serial, ltime,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys issuer, subject, altname,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys alttype, altcrit, kubits,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kucrit, ekulist);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (rv != KMF_OK)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys goto cleanup;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys /*
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * Find the signing key.
d00756ccb34596a328f8a15d1965da5412d366d0wyllys */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys numattr = 0;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys &kstype, sizeof (kstype));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys numattr++;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (kstype == KMF_KEYSTORE_NSS) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys token, strlen(token));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys numattr++;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR, signkey,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys strlen(signkey));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys numattr++;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_set_attr_at_index(attrlist, numattr, KMF_PRIVATE_BOOL_ATTR,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys &private_bool, sizeof (private_bool));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys numattr++;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_BOOL_ATTR,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys &token_bool, sizeof (token_bool));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys numattr++;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys &keyclass, sizeof (keyclass));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys numattr++;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys cred, sizeof (KMF_CREDENTIAL_ATTR));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys numattr++;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys &keys, sizeof (keys));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys numattr++;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys &casignkey, sizeof (casignkey));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys numattr++;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = kmf_find_key(handle, numattr, attrlist);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (rv != KMF_OK) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys cryptoerror(LOG_STDERR,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys gettext("Failed to find signing key\n"));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys goto cleanup;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys /*
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * If we found the key, now we can sign the cert.
d00756ccb34596a328f8a15d1965da5412d366d0wyllys */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = pk_sign_cert(handle, &signedCert, &casignkey, &outcert);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (rv != KMF_OK) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys cryptoerror(LOG_STDERR, gettext(
d00756ccb34596a328f8a15d1965da5412d366d0wyllys "Error signing certificate.\n"));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys goto cleanup;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys /*
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * Store it on the token if the user asked for it.
d00756ccb34596a328f8a15d1965da5412d366d0wyllys */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (store) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys numattr = 0;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys &kstype, sizeof (kstype));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys numattr++;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys &outcert, sizeof (KMF_DATA));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys numattr++;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (outlabel != NULL) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_set_attr_at_index(attrlist, numattr,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_CERT_LABEL_ATTR,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys outlabel, strlen(outlabel));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys numattr++;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (kstype == KMF_KEYSTORE_NSS) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (token != NULL)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_set_attr_at_index(attrlist, numattr,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_TOKEN_LABEL_ATTR,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys token, strlen(token));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys numattr++;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = kmf_store_cert(handle, numattr, attrlist);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (rv != KMF_OK) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys display_error(handle, rv,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys gettext("Failed to store cert "
d00756ccb34596a328f8a15d1965da5412d366d0wyllys "on PKCS#11 token.\n"));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = KMF_OK;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys /* Not fatal, we can still write it to a file. */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = kmf_create_cert_file(&outcert, fmt, certfile);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllyscleanup:
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_free_signed_csr(&csrdata);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_free_data(&outcert);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmf_free_kmf_key(handle, &casignkey);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (rv);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys}
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys/*
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * sign a CSR and generate an x509v3 certificate file.
d00756ccb34596a328f8a15d1965da5412d366d0wyllys */
d00756ccb34596a328f8a15d1965da5412d366d0wyllysint
d00756ccb34596a328f8a15d1965da5412d366d0wyllyspk_signcsr(int argc, char *argv[])
d00756ccb34596a328f8a15d1965da5412d366d0wyllys{
d00756ccb34596a328f8a15d1965da5412d366d0wyllys int opt;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys extern int optind_av;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys extern char *optarg_av;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys char *token_spec = NULL;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys char *subject = NULL;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys char *issuer = NULL;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys char *dir = NULL;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys char *prefix = NULL;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys char *csrfile = NULL;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys char *serstr = NULL;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys char *ekustr = NULL;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys char *kustr = NULL;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys char *format = NULL;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys char *storestr = NULL;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys char *altname = NULL;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys char *certfile = NULL;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys char *lifetime = NULL;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys char *signkey = NULL;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys char *outlabel = NULL;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys uint32_t ltime = 365 * 24 * 60 * 60; /* 1 Year */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys int store = 0;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys uint16_t kubits = 0;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys int altcrit = 0, kucrit = 0;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_BIGINT serial = { NULL, 0 };
d00756ccb34596a328f8a15d1965da5412d366d0wyllys EKU_LIST *ekulist = NULL;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_KEYSTORE_TYPE kstype = 0;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_RETURN rv = KMF_OK;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_HANDLE_T kmfhandle = NULL;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_CREDENTIAL tokencred = {NULL, 0};
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_GENERALNAMECHOICES alttype = 0;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys KMF_ENCODE_FORMAT fmt = KMF_FORMAT_PEM;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys /* Parse command line options. Do NOT i18n/l10n. */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys while ((opt = getopt_av(argc, argv,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys "k:(keystore)c:(csr)T:(token)d:(dir)"
d00756ccb34596a328f8a15d1965da5412d366d0wyllys "p:(prefix)S:(serial)s:(subject)a:(altname)"
d00756ccb34596a328f8a15d1965da5412d366d0wyllys "t:(store)F:(format)K:(keyusage)l:(signkey)"
d00756ccb34596a328f8a15d1965da5412d366d0wyllys "L:(lifetime)e:(eku)i:(issuer)"
d00756ccb34596a328f8a15d1965da5412d366d0wyllys "n:(outlabel)o:(outcert)")) != EOF) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (EMPTYSTRING(optarg_av))
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (PK_ERR_USAGE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys switch (opt) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 'k':
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (kstype != 0)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (PK_ERR_USAGE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kstype = KS2Int(optarg_av);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (kstype == 0)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (PK_ERR_USAGE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 't':
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (storestr != NULL)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (PK_ERR_USAGE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys storestr = optarg_av;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys store = yn_to_int(optarg_av);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (store == -1)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (PK_ERR_USAGE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 'a':
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (altname)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (PK_ERR_USAGE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys altname = optarg_av;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 's':
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (subject)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (PK_ERR_USAGE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys subject = optarg_av;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 'i':
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (issuer)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (PK_ERR_USAGE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys issuer = optarg_av;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 'd':
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (dir)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (PK_ERR_USAGE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys dir = optarg_av;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 'p':
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (prefix)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (PK_ERR_USAGE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys prefix = optarg_av;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 'S':
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (serstr != NULL)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (PK_ERR_USAGE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys serstr = optarg_av;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 'c':
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (csrfile)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (PK_ERR_USAGE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys csrfile = optarg_av;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 'T': /* token specifier */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (token_spec)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (PK_ERR_USAGE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys token_spec = optarg_av;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 'l': /* object with specific label */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (signkey)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (PK_ERR_USAGE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys signkey = optarg_av;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 'e':
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (ekustr != NULL)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (PK_ERR_USAGE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys ekustr = optarg_av;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 'K':
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (kustr != NULL)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (PK_ERR_USAGE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kustr = optarg_av;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 'F':
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (format != NULL)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (PK_ERR_USAGE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys format = optarg_av;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 'o':
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (certfile != NULL)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (PK_ERR_USAGE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys certfile = optarg_av;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 'L':
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (lifetime != NULL)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (PK_ERR_USAGE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys lifetime = optarg_av;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 'n':
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (outlabel != NULL)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (PK_ERR_USAGE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys outlabel = optarg_av;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys default:
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (PK_ERR_USAGE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys /* No additional args allowed. */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys argc -= optind_av;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys argv += optind_av;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (argc)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (PK_ERR_USAGE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (rv);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys /* Assume keystore = PKCS#11 if not specified. */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (kstype == 0)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kstype = KMF_KEYSTORE_PK11TOKEN;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (signkey == NULL) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys (void) fprintf(stderr, gettext("The signing key label "
d00756ccb34596a328f8a15d1965da5412d366d0wyllys "or filename was not specified\n"));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (PK_ERR_USAGE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (csrfile == NULL) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys (void) fprintf(stderr, gettext("The CSR filename was not"
d00756ccb34596a328f8a15d1965da5412d366d0wyllys " specified\n"));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (PK_ERR_USAGE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (certfile == NULL) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys (void) fprintf(stderr, gettext("The output certificate file "
d00756ccb34596a328f8a15d1965da5412d366d0wyllys "was not specified\n"));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (PK_ERR_USAGE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (issuer == NULL) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys (void) fprintf(stderr, gettext("The issuer DN "
d00756ccb34596a328f8a15d1965da5412d366d0wyllys "was not specified\n"));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (PK_ERR_USAGE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (lifetime != NULL) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (Str2Lifetime(lifetime, &ltime) != 0) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys cryptoerror(LOG_STDERR,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys gettext("Error parsing lifetime string\n"));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (PK_ERR_USAGE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec)) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys token_spec = PK_DEFAULT_PK11TOKEN;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys } else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec)) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys token_spec = DEFAULT_NSS_TOKEN;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (serstr != NULL) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys uchar_t *bytes = NULL;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys size_t bytelen;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (rv != KMF_OK || bytes == NULL) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys (void) fprintf(stderr, gettext("Serial number "
d00756ccb34596a328f8a15d1965da5412d366d0wyllys "must be specified as a hex number "
d00756ccb34596a328f8a15d1965da5412d366d0wyllys "(ex: 0x0102030405ffeeddee)\n"));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (PK_ERR_USAGE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys serial.val = bytes;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys serial.len = bytelen;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys } else {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys (void) fprintf(stderr, gettext("The serial number was not"
d00756ccb34596a328f8a15d1965da5412d366d0wyllys " specified\n"));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (PK_ERR_USAGE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if ((kstype == KMF_KEYSTORE_PK11TOKEN ||
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kstype == KMF_KEYSTORE_NSS)) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys /* Need to get password for private key access */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys (void) get_token_password(kstype, token_spec,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys &tokencred);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (ekustr != NULL) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = verify_ekunames(ekustr, &ekulist);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (rv != KMF_OK) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys (void) fprintf(stderr, gettext("EKUs must "
d00756ccb34596a328f8a15d1965da5412d366d0wyllys "be specified as a comma-separated list. "
d00756ccb34596a328f8a15d1965da5412d366d0wyllys "See the man page for details.\n"));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = PK_ERR_USAGE;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys goto end;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (altname != NULL) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys char *p;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = verify_altname(altname, &alttype, &altcrit);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (rv != KMF_OK) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys (void) fprintf(stderr, gettext("Subject AltName "
d00756ccb34596a328f8a15d1965da5412d366d0wyllys "must be specified as a name=value pair. "
d00756ccb34596a328f8a15d1965da5412d366d0wyllys "See the man page for details.\n"));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = PK_ERR_USAGE;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys goto end;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys /* advance the altname past the '=' sign */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys p = strchr(altname, '=');
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (p != NULL)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys altname = p + 1;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (format && (fmt = Str2Format(format)) == KMF_FORMAT_UNDEF) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys cryptoerror(LOG_STDERR,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys gettext("Error parsing format string (%s).\n"),
d00756ccb34596a328f8a15d1965da5412d366d0wyllys format);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (PK_ERR_USAGE);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (kstype == KMF_KEYSTORE_PK11TOKEN) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = pk_signcsr_pk11_nss(kmfhandle,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kstype, dir, prefix, token_spec, &tokencred,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys signkey, csrfile, &serial, certfile, issuer, subject,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys altname, alttype, altcrit, kubits, kucrit,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys ekulist, ltime, fmt, store, outlabel);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys } else if (kstype == KMF_KEYSTORE_NSS) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (dir == NULL)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys dir = PK_DEFAULT_DIRECTORY;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = pk_signcsr_pk11_nss(kmfhandle,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kstype, dir, prefix, token_spec, &tokencred,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys signkey, csrfile, &serial, certfile, issuer, subject,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys altname, alttype, altcrit, kubits, kucrit,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys ekulist, ltime, fmt, store, outlabel);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys } else if (kstype == KMF_KEYSTORE_OPENSSL) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rv = pk_signcsr_files(kmfhandle,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys signkey, csrfile, &serial, certfile, issuer, subject,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys altname, alttype, altcrit, kubits, kucrit,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys ekulist, ltime, fmt);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllysend:
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (rv != KMF_OK) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys display_error(kmfhandle, rv,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys gettext("Error listing objects"));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (serial.val != NULL)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys free(serial.val);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (tokencred.cred != NULL)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys free(tokencred.cred);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys free_eku_list(ekulist);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys (void) kmf_finalize(kmfhandle);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (rv);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys}