summaryrefslogtreecommitdiff
path: root/usr/src/lib/libkmf/libkmf/common/csrcrlop.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libkmf/libkmf/common/csrcrlop.c')
-rw-r--r--usr/src/lib/libkmf/libkmf/common/csrcrlop.c563
1 files changed, 563 insertions, 0 deletions
diff --git a/usr/src/lib/libkmf/libkmf/common/csrcrlop.c b/usr/src/lib/libkmf/libkmf/common/csrcrlop.c
new file mode 100644
index 0000000000..4c8a700994
--- /dev/null
+++ b/usr/src/lib/libkmf/libkmf/common/csrcrlop.c
@@ -0,0 +1,563 @@
+/*
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright(c) 1995-2000 Intel Corporation. All rights reserved.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <link.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+
+#include <ber_der.h>
+#include <kmfapiP.h>
+
+#include <pem_encode.h>
+#include <libgen.h>
+#include <cryptoutil.h>
+
+
+/*
+ *
+ * Name: KMF_SetCSRPubKey
+ *
+ * Description:
+ * This function converts the specified plugin public key to SPKI form,
+ * and save it in the KMF_CSR_DATA internal structure
+ *
+ * Parameters:
+ * KMFkey(input) - pointer to the KMF_KEY_HANDLE structure containing the
+ * public key generated by the plug-in CreateKeypair
+ * Csr(input/output) - pointer to a KMF_CSR_DATA structure containing
+ * SPKI
+ *
+ * Returns:
+ * A KMF_RETURN value indicating success or specifying a particular
+ * error condition.
+ * The value KMF_OK indicates success. All other values represent
+ * an error condition.
+ *
+ */
+KMF_RETURN
+KMF_SetCSRPubKey(KMF_HANDLE_T handle,
+ KMF_KEY_HANDLE *KMFKey,
+ KMF_CSR_DATA *Csr)
+{
+ KMF_RETURN ret = KMF_OK;
+ KMF_X509_SPKI *spki_ptr;
+ KMF_PLUGIN *plugin;
+ KMF_DATA KeyData = {NULL, 0};
+
+ CLEAR_ERROR(handle, ret);
+ if (ret != KMF_OK)
+ return (ret);
+
+ if (KMFKey == NULL || Csr == NULL) {
+ return (KMF_ERR_BAD_PARAMETER);
+ }
+
+ /* The keystore must extract the pubkey data */
+ plugin = FindPlugin(handle, KMFKey->kstype);
+ if (plugin != NULL && plugin->funclist->EncodePubkeyData != NULL) {
+ ret = plugin->funclist->EncodePubkeyData(handle,
+ KMFKey, &KeyData);
+ } else {
+ return (KMF_ERR_PLUGIN_NOTFOUND);
+ }
+
+ spki_ptr = &Csr->csr.subjectPublicKeyInfo;
+
+ ret = DerDecodeSPKI(&KeyData, spki_ptr);
+
+ KMF_FreeData(&KeyData);
+
+ return (ret);
+}
+
+KMF_RETURN
+KMF_SetCSRVersion(KMF_CSR_DATA *CsrData, uint32_t version)
+{
+ if (CsrData == NULL)
+ return (KMF_ERR_BAD_PARAMETER);
+
+ /*
+ * From RFC 3280:
+ * Version ::= INTEGER { v1(0), v2(1), v3(2) }
+ */
+ if (version != 0 && version != 1 && version != 2)
+ return (KMF_ERR_BAD_PARAMETER);
+ return (set_integer(&CsrData->csr.version, (void *)&version,
+ sizeof (uint32_t)));
+}
+
+KMF_RETURN
+KMF_SetCSRSubjectName(KMF_CSR_DATA *CsrData,
+ KMF_X509_NAME *subject_name_ptr)
+{
+ if (CsrData != NULL && subject_name_ptr != NULL)
+ CsrData->csr.subject = *subject_name_ptr;
+ else
+ return (KMF_ERR_BAD_PARAMETER);
+
+ return (KMF_OK);
+}
+
+KMF_RETURN
+KMF_CreateCSRFile(KMF_DATA *csrdata, KMF_ENCODE_FORMAT format,
+ char *csrfile)
+{
+ KMF_RETURN rv = KMF_OK;
+ int fd = -1;
+ KMF_DATA pemdata = {NULL, 0};
+
+ if (csrdata == NULL || csrfile == NULL)
+ return (KMF_ERR_BAD_PARAMETER);
+
+ if (format != KMF_FORMAT_PEM && format != KMF_FORMAT_ASN1)
+ return (KMF_ERR_BAD_PARAMETER);
+
+ if (format == KMF_FORMAT_PEM) {
+ int len;
+ rv = KMF_Der2Pem(KMF_CSR,
+ csrdata->Data, csrdata->Length,
+ &pemdata.Data, &len);
+ if (rv != KMF_OK)
+ goto cleanup;
+ pemdata.Length = (size_t)len;
+ }
+
+ if ((fd = open(csrfile, O_CREAT |O_RDWR, 0644)) == -1) {
+ rv = KMF_ERR_OPEN_FILE;
+ goto cleanup;
+ }
+
+ if (format == KMF_FORMAT_PEM) {
+ if (write(fd, pemdata.Data, pemdata.Length) !=
+ pemdata.Length) {
+ rv = KMF_ERR_WRITE_FILE;
+ }
+ } else {
+ if (write(fd, csrdata->Data, csrdata->Length) !=
+ csrdata->Length) {
+ rv = KMF_ERR_WRITE_FILE;
+ }
+ }
+
+cleanup:
+ if (fd != -1)
+ (void) close(fd);
+
+ KMF_FreeData(&pemdata);
+
+ return (rv);
+}
+
+KMF_RETURN
+KMF_SetCSRExtension(KMF_CSR_DATA *Csr,
+ KMF_X509_EXTENSION *extn)
+{
+ KMF_RETURN ret = KMF_OK;
+ KMF_X509_EXTENSIONS *exts;
+
+ if (Csr == NULL || extn == NULL)
+ return (KMF_ERR_BAD_PARAMETER);
+
+ exts = &Csr->csr.extensions;
+
+ ret = add_an_extension(exts, extn);
+
+ return (ret);
+}
+
+KMF_RETURN
+KMF_SetCSRSignatureAlgorithm(KMF_CSR_DATA *CsrData,
+ KMF_ALGORITHM_INDEX sigAlg)
+{
+ KMF_OID *alg;
+
+ if (CsrData == NULL)
+ return (KMF_ERR_BAD_PARAMETER);
+
+ alg = X509_AlgIdToAlgorithmOid(sigAlg);
+
+ if (alg != NULL) {
+ (void) copy_data((KMF_DATA *)
+ &CsrData->signature.algorithmIdentifier.algorithm,
+ (KMF_DATA *)alg);
+ (void) copy_data(
+ &CsrData->signature.algorithmIdentifier.parameters,
+ &CsrData->csr.subjectPublicKeyInfo.algorithm.parameters);
+ } else {
+ return (KMF_ERR_BAD_PARAMETER);
+ }
+ return (KMF_OK);
+}
+
+KMF_RETURN
+KMF_SetCSRSubjectAltName(KMF_CSR_DATA *Csr,
+ char *altname, int critical,
+ KMF_GENERALNAMECHOICES alttype)
+{
+ KMF_RETURN ret = KMF_OK;
+
+ if (Csr == NULL || altname == NULL)
+ return (KMF_ERR_BAD_PARAMETER);
+
+ ret = KMF_SetAltName(&Csr->csr.extensions,
+ (KMF_OID *)&KMFOID_SubjectAltName, critical, alttype,
+ altname);
+
+ return (ret);
+}
+
+KMF_RETURN
+KMF_SetCSRKeyUsage(KMF_CSR_DATA *CSRData,
+ int critical, uint16_t kubits)
+{
+ KMF_RETURN ret = KMF_OK;
+
+ if (CSRData == NULL)
+ return (KMF_ERR_BAD_PARAMETER);
+
+ ret = set_key_usage_extension(
+ &CSRData->csr.extensions,
+ critical, kubits);
+
+ return (ret);
+}
+
+/*
+ *
+ * Name: KMF_SignCSR
+ *
+ * Description:
+ * This function signs a CSR and returns the result as a
+ * signed, encoded CSR in SignedCsr
+ *
+ * Parameters:
+ * tbsCsr(input) - pointer to a KMF_DATA structure containing a
+ * DER encoded TBS CSR data
+ * Signkey(input) - pointer to the KMF_KEY_HANDLE structure containing
+ * the private key generated by the plug-in CreateKeypair
+ * algo(input) - contains algorithm info needed for signing
+ * SignedCsr(output) - pointer to the KMF_DATA structure containing
+ * the signed CSR
+ *
+ * Returns:
+ * A KMF_RETURN value indicating success or specifying a particular
+ * error condition.
+ * The value KMF_OK indicates success. All other values represent
+ * an error condition.
+ *
+ */
+KMF_RETURN
+KMF_SignCSR(KMF_HANDLE_T handle,
+ const KMF_CSR_DATA *tbsCsr,
+ KMF_KEY_HANDLE *Signkey,
+ KMF_DATA *SignedCsr)
+{
+ KMF_RETURN err;
+ KMF_DATA csrdata = { NULL, 0 };
+
+ CLEAR_ERROR(handle, err);
+ if (err != KMF_OK)
+ return (err);
+
+ if (tbsCsr == NULL ||
+ Signkey == NULL || SignedCsr == NULL)
+ return (KMF_ERR_BAD_PARAMETER);
+
+ SignedCsr->Data = NULL;
+ SignedCsr->Length = 0;
+
+ err = DerEncodeTbsCsr((KMF_TBS_CSR *)&tbsCsr->csr, &csrdata);
+ if (err == KMF_OK) {
+ err = SignCsr(handle, &csrdata, Signkey,
+ (KMF_X509_ALGORITHM_IDENTIFIER *)
+ &tbsCsr->signature.algorithmIdentifier,
+ SignedCsr);
+ }
+
+ if (err != KMF_OK) {
+ KMF_FreeData(SignedCsr);
+ }
+ KMF_FreeData(&csrdata);
+ return (err);
+}
+
+KMF_RETURN
+KMF_ImportCRL(KMF_HANDLE_T handle, KMF_IMPORTCRL_PARAMS *params)
+{
+ KMF_PLUGIN *plugin;
+ KMF_RETURN ret;
+
+ CLEAR_ERROR(handle, ret);
+ if (ret != KMF_OK)
+ return (ret);
+
+ if (params == NULL)
+ return (KMF_ERR_BAD_PARAMETER);
+
+ switch (params->kstype) {
+ case KMF_KEYSTORE_NSS:
+ plugin = FindPlugin(handle, params->kstype);
+ break;
+
+ case KMF_KEYSTORE_OPENSSL:
+ case KMF_KEYSTORE_PK11TOKEN: /* PKCS#11 CRL is file-based */
+ plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
+ break;
+ default:
+ return (KMF_ERR_PLUGIN_NOTFOUND);
+ }
+
+ if (plugin != NULL && plugin->funclist->ImportCRL != NULL) {
+ return (plugin->funclist->ImportCRL(handle, params));
+ }
+ return (KMF_ERR_PLUGIN_NOTFOUND);
+}
+
+KMF_RETURN
+KMF_DeleteCRL(KMF_HANDLE_T handle, KMF_DELETECRL_PARAMS *params)
+{
+ KMF_PLUGIN *plugin;
+ KMF_RETURN ret;
+
+ CLEAR_ERROR(handle, ret);
+ if (ret != KMF_OK)
+ return (ret);
+
+ if (params == NULL)
+ return (KMF_ERR_BAD_PARAMETER);
+
+ switch (params->kstype) {
+ case KMF_KEYSTORE_NSS:
+ plugin = FindPlugin(handle, params->kstype);
+ break;
+
+ case KMF_KEYSTORE_OPENSSL:
+ case KMF_KEYSTORE_PK11TOKEN: /* PKCS#11 CRL is file-based */
+ plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
+ break;
+ default:
+ return (KMF_ERR_PLUGIN_NOTFOUND);
+ }
+
+ if (plugin != NULL && plugin->funclist->DeleteCRL != NULL) {
+ return (plugin->funclist->DeleteCRL(handle, params));
+ } else {
+ return (KMF_ERR_PLUGIN_NOTFOUND);
+ }
+}
+
+KMF_RETURN
+KMF_ListCRL(KMF_HANDLE_T handle, KMF_LISTCRL_PARAMS *params, char **crldata)
+{
+ KMF_PLUGIN *plugin;
+ KMF_RETURN ret;
+
+ CLEAR_ERROR(handle, ret);
+ if (ret != KMF_OK)
+ return (ret);
+
+ if (params == NULL || crldata == NULL)
+ return (KMF_ERR_BAD_PARAMETER);
+
+ switch (params->kstype) {
+ case KMF_KEYSTORE_NSS:
+ plugin = FindPlugin(handle, params->kstype);
+ break;
+
+ case KMF_KEYSTORE_OPENSSL:
+ case KMF_KEYSTORE_PK11TOKEN: /* PKCS#11 CRL is file-based */
+ plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
+ break;
+ default:
+ return (KMF_ERR_PLUGIN_NOTFOUND);
+ }
+
+ if (plugin != NULL && plugin->funclist->ListCRL != NULL) {
+ return (plugin->funclist->ListCRL(handle, params, crldata));
+ } else {
+ return (KMF_ERR_PLUGIN_NOTFOUND);
+ }
+}
+
+KMF_RETURN
+KMF_FindCRL(KMF_HANDLE_T handle, KMF_FINDCRL_PARAMS *params,
+ char **CRLNameList, int *CRLCount)
+{
+ KMF_PLUGIN *plugin;
+ KMF_RETURN ret;
+
+ CLEAR_ERROR(handle, ret);
+ if (ret != KMF_OK)
+ return (ret);
+
+ if (params == NULL ||
+ CRLCount == NULL)
+ return (KMF_ERR_BAD_PARAMETER);
+
+ plugin = FindPlugin(handle, params->kstype);
+ if (plugin != NULL && plugin->funclist->FindCRL != NULL) {
+ return (plugin->funclist->FindCRL(handle, params,
+ CRLNameList, CRLCount));
+ } else {
+ return (KMF_ERR_PLUGIN_NOTFOUND);
+ }
+}
+
+KMF_RETURN
+KMF_FindCertInCRL(KMF_HANDLE_T handle, KMF_FINDCERTINCRL_PARAMS *params)
+{
+ KMF_PLUGIN *plugin;
+ KMF_RETURN ret;
+
+ CLEAR_ERROR(handle, ret);
+ if (ret != KMF_OK)
+ return (ret);
+
+ if (params == NULL)
+ return (KMF_ERR_BAD_PARAMETER);
+
+ switch (params->kstype) {
+ case KMF_KEYSTORE_NSS:
+ plugin = FindPlugin(handle, params->kstype);
+ break;
+
+ case KMF_KEYSTORE_OPENSSL:
+ case KMF_KEYSTORE_PK11TOKEN: /* PKCS#11 CRL is file-based */
+ plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
+ break;
+ default:
+ return (KMF_ERR_PLUGIN_NOTFOUND);
+ }
+
+ if (plugin != NULL && plugin->funclist->FindCertInCRL != NULL) {
+ return (plugin->funclist->FindCertInCRL(handle, params));
+ } else {
+ return (KMF_ERR_PLUGIN_NOTFOUND);
+ }
+}
+
+KMF_RETURN
+KMF_VerifyCRLFile(KMF_HANDLE_T handle,
+ KMF_VERIFYCRL_PARAMS *params)
+{
+ KMF_PLUGIN *plugin;
+ KMF_RETURN (*verifyCRLFile)(KMF_HANDLE_T,
+ KMF_VERIFYCRL_PARAMS *);
+ KMF_RETURN ret;
+
+ CLEAR_ERROR(handle, ret);
+ if (ret != KMF_OK)
+ return (ret);
+
+ if (params == NULL)
+ return (KMF_ERR_BAD_PARAMETER);
+
+ plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
+ if (plugin == NULL || plugin->dldesc == NULL) {
+ return (KMF_ERR_PLUGIN_NOTFOUND);
+ }
+
+ verifyCRLFile = (KMF_RETURN(*)())dlsym(plugin->dldesc,
+ "OpenSSL_VerifyCRLFile");
+
+ if (verifyCRLFile == NULL) {
+ return (KMF_ERR_FUNCTION_NOT_FOUND);
+ }
+
+ return (verifyCRLFile(handle, params));
+}
+
+KMF_RETURN
+KMF_CheckCRLDate(KMF_HANDLE_T handle, KMF_CHECKCRLDATE_PARAMS *params)
+{
+ KMF_PLUGIN *plugin;
+ KMF_RETURN (*checkCRLDate)(void *,
+ KMF_CHECKCRLDATE_PARAMS *params);
+ KMF_RETURN ret;
+
+ CLEAR_ERROR(handle, ret);
+ if (ret != KMF_OK)
+ return (ret);
+
+ if (params == NULL)
+ return (KMF_ERR_BAD_PARAMETER);
+
+ plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
+ if (plugin == NULL || plugin->dldesc == NULL) {
+ return (KMF_ERR_PLUGIN_NOTFOUND);
+ }
+
+ checkCRLDate = (KMF_RETURN(*)())dlsym(plugin->dldesc,
+ "OpenSSL_CheckCRLDate");
+
+ if (checkCRLDate == NULL) {
+ return (KMF_ERR_FUNCTION_NOT_FOUND);
+ }
+
+ return (checkCRLDate(handle, params));
+
+}
+
+KMF_RETURN
+KMF_IsCRLFile(KMF_HANDLE_T handle, char *filename, KMF_ENCODE_FORMAT *pformat)
+{
+ KMF_PLUGIN *plugin;
+ KMF_RETURN (*IsCRLFileFn)(void *, char *, KMF_ENCODE_FORMAT *);
+ KMF_RETURN ret;
+
+ CLEAR_ERROR(handle, ret);
+ if (ret != KMF_OK)
+ return (ret);
+
+ if (filename == NULL || pformat == NULL) {
+ return (KMF_ERR_BAD_PARAMETER);
+ }
+
+ /*
+ * This framework function is actually implemented in the openssl
+ * plugin library, so we find the function address and call it.
+ */
+ plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
+ if (plugin == NULL || plugin->dldesc == NULL) {
+ return (KMF_ERR_PLUGIN_NOTFOUND);
+ }
+
+ IsCRLFileFn = (KMF_RETURN(*)())dlsym(plugin->dldesc,
+ "OpenSSL_IsCRLFile");
+ if (IsCRLFileFn == NULL) {
+ return (KMF_ERR_FUNCTION_NOT_FOUND);
+ }
+
+ return (IsCRLFileFn(handle, filename, pformat));
+}