summaryrefslogtreecommitdiff
path: root/usr/src/lib/libkmsagent/common/KMSAgentPKICertOpenSSL.cpp
diff options
context:
space:
mode:
authorWyllys Ingersoll <Wyllys.Ingersoll@Sun.COM>2010-06-28 16:04:11 -0700
committerWyllys Ingersoll <Wyllys.Ingersoll@Sun.COM>2010-06-28 16:04:11 -0700
commit4f14b0f29aa144cc03efdde5508ae126ae197acf (patch)
tree5292d99c7ec8374d412d58116e7bbc7279e72067 /usr/src/lib/libkmsagent/common/KMSAgentPKICertOpenSSL.cpp
parent1e49577a7fcde812700ded04431b49d67cc57d6d (diff)
downloadillumos-joyent-4f14b0f29aa144cc03efdde5508ae126ae197acf.tar.gz
PSARC 2010/195 PKCS11 KMS Provider
6944296 Solaris needs a PKCS#11 provider to allow access to KMS keystore functionality
Diffstat (limited to 'usr/src/lib/libkmsagent/common/KMSAgentPKICertOpenSSL.cpp')
-rw-r--r--usr/src/lib/libkmsagent/common/KMSAgentPKICertOpenSSL.cpp313
1 files changed, 313 insertions, 0 deletions
diff --git a/usr/src/lib/libkmsagent/common/KMSAgentPKICertOpenSSL.cpp b/usr/src/lib/libkmsagent/common/KMSAgentPKICertOpenSSL.cpp
new file mode 100644
index 0000000000..e26e8cb1f2
--- /dev/null
+++ b/usr/src/lib/libkmsagent/common/KMSAgentPKICertOpenSSL.cpp
@@ -0,0 +1,313 @@
+/*
+ * 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) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/**
+ * \file KMSAgentPKICertOpenSSL.cpp
+ */
+
+#include <stdio.h>
+#include <openssl/bio.h>
+#include <openssl/pem.h>
+
+#include "SYSCommon.h"
+#include "KMSAgentPKIimpl.h"
+
+typedef struct X509control
+{
+ X509* pX509;
+} X509control;
+
+void * InitializeCertImpl()
+{
+ X509control *pX509Control = (X509control *) malloc(sizeof(X509control));
+
+ if ( pX509Control != NULL )
+ {
+ pX509Control->pX509 = NULL;
+ }
+
+ return pX509Control;
+}
+
+/**
+ * export the Cert to a memory BIO, if error, return NULL
+ */
+BIO* SaveCertToMemoryBIO( X509control* i_pX509control )
+{
+ BIO *pMemBio = NULL;
+ int iReturn;
+
+ // create memory BIO
+ pMemBio = BIO_new(BIO_s_mem());
+
+ if(pMemBio == NULL)
+ {
+ //fixme: log -- no memory
+ return NULL;
+ }
+
+ //iReturn = PEM_write_bio_X509(pMemBio, m_pNative);
+ iReturn = PEM_write_bio_X509(pMemBio, i_pX509control->pX509);
+
+ if(!iReturn) // return 0: means error occurs
+ {
+ //fixme: log -- could not export private key
+ BIO_free(pMemBio);
+ return NULL;
+ }
+
+ return pMemBio;
+}
+
+bool SaveX509CertTofile(
+ void* const i_pImplResource,
+ const char * const i_pcFileName )
+{
+ FATAL_ASSERT( i_pImplResource != NULL && i_pcFileName );
+
+ X509control* pX509control = (X509control*)i_pImplResource;
+ // the BIO for output, need cleanup when exiting
+ BIO *pMemBio = NULL;
+ int iLength;
+ unsigned char *pData;
+ FILE *fp;
+
+ // create memory BIO
+ pMemBio = SaveCertToMemoryBIO( pX509control );
+
+ if(pMemBio == NULL)
+ {
+ return false;
+ }
+
+ // now pMemBIO != NULL, remember to free it before exiting
+ iLength = BIO_get_mem_data(pMemBio, &pData);
+
+ // open the file
+ fp = fopen(i_pcFileName, "wb");
+ if(fp == NULL)
+ {
+ //fixme: log -- could not open file for exporting Cert
+ BIO_free(pMemBio);
+ return false;
+ }
+
+ fwrite(pData, 1, iLength, fp);
+ fclose(fp);
+
+ BIO_free(pMemBio); // BIO_free close the file and clean the BIO
+ return true;
+}
+
+bool SaveX509CertToBuffer(
+ void* const i_pImplResource,
+ unsigned char * const i_pcBuffer,
+ int i_iBufferLength,
+ int * const o_pActualLength )
+{
+ FATAL_ASSERT( i_pImplResource != NULL &&
+ i_pcBuffer &&
+ o_pActualLength &&
+ i_iBufferLength > 0 );
+
+ X509control* pX509control = (X509control*)i_pImplResource;
+
+ BIO *pMemBio = NULL;
+ char *pData = NULL;
+ int iLength;
+
+ // create memory BIO
+ pMemBio = SaveCertToMemoryBIO( pX509control );
+
+ if( pMemBio == NULL )
+ {
+ //fixme: log -- no memory
+ return false;
+ }
+
+ iLength = BIO_get_mem_data( pMemBio, &pData );
+
+ // If the output buffer is a string, it needs to be NULL terminated
+ // So always append a NULL to the output
+ if(iLength + 1 > i_iBufferLength)
+ {
+ //fixme: log -- buffer too small
+ BIO_free(pMemBio);
+ return false;
+ }
+ // copy the data to given buffer
+ memcpy(i_pcBuffer, pData, iLength);
+ // NULL terminate the string
+ i_pcBuffer[iLength] = '\0';
+ *o_pActualLength = iLength;
+
+ // free memory
+ BIO_free(pMemBio);
+
+ return true;
+}
+
+/**
+ * import the Cert from a BIO, if error, return NULL
+ */
+bool LoadCertFromBIO(X509control* i_pX509control, BIO *i_pBio)
+{
+ X509 *pRequest = NULL;
+
+ if (i_pX509control == NULL) return false;
+
+ if(i_pBio == NULL) return false;
+
+ //if(m_pNative != NULL) return false; // do not allow overwrite
+ if (i_pX509control->pX509 != NULL ) return false;
+
+ pRequest=PEM_read_bio_X509(i_pBio, NULL, NULL, NULL);
+
+ if (pRequest == NULL)
+ {
+ // fixme: log: invalid certificate format
+ return false;
+ }
+ //m_pNative = pRequest;
+ i_pX509control->pX509 = pRequest;
+
+ return true;
+}
+
+bool LoadX509CertFromFile(
+ void* const i_pImplResource,
+ const char * const i_pcFileName )
+
+{
+ X509control* pX509control = (X509control*) i_pImplResource;
+ if (pX509control == NULL)
+ {
+ return false;
+ }
+
+ BIO *pFileBio=NULL;
+ bool bReturn;
+
+ pFileBio=BIO_new(BIO_s_file());
+ if (pFileBio == NULL)
+ {
+ //fixme: log -- no memory
+ return false;
+ }
+
+ if (!BIO_read_filename(pFileBio,i_pcFileName))
+ {
+ //fixme log -- could not open file
+ BIO_free(pFileBio);
+ return false;
+ }
+
+ bReturn = LoadCertFromBIO(pX509control, pFileBio);
+
+ BIO_free(pFileBio);
+
+ return bReturn;
+}
+
+
+bool LoadX509CertFromBuffer(
+ void* const i_pImplResource,
+ void* const i_pX509Cert,
+ int i_iLength)
+ {
+ X509control* pX509control = (X509control*)i_pImplResource;
+
+ if(pX509control == NULL)
+ {
+ return false;
+ }
+
+ BIO *pMemBio;
+ bool bReturn;
+ // create a mem bio from the given buffer
+ // Note that BIO_new_mem_buf() creates a BIO which never destroy the memory
+ // attached to it.
+ pMemBio = BIO_new_mem_buf(i_pX509Cert, i_iLength);
+ if (pMemBio == NULL)
+ {
+ //fixme: log -- no memory
+ return false;
+ }
+ bReturn = LoadCertFromBIO(pX509control, pMemBio);
+
+ BIO_free(pMemBio);
+
+ return bReturn;
+}
+
+void FinalizeCertImpl( void* i_pImplResource )
+{
+ if ( i_pImplResource != NULL )
+ {
+ free(i_pImplResource);
+ }
+}
+
+bool PrintX509Cert( void* const i_pImplResource )
+{
+ BIO *pMemBio;
+ char *pData;
+ int iLength,i;
+ X509control* pX509control = (X509control*)i_pImplResource;
+ pMemBio = BIO_new(BIO_s_mem());
+ if(pMemBio == NULL)
+ {
+ return false;
+ }
+
+ //X509_print(pMemBio,m_pNative);
+ X509_print(pMemBio, pX509control->pX509);
+
+ iLength = BIO_get_mem_data(pMemBio, &pData);
+
+ for(i = 0; i < iLength; i++)
+ {
+ printf("%c", pData[i]);
+ }
+
+ BIO_free(pMemBio);
+
+ return true;
+
+}
+#ifdef K_SOLARIS_PLATFORM
+void *GetCert(void* i_pImplResource )
+{
+ X509control* pX509control = (X509control*)i_pImplResource;
+ return ((void *)pX509control->pX509);
+}
+
+void SetCert(void* i_pImplResource, void *cert)
+{
+ X509control* pX509control = (X509control*)i_pImplResource;
+ pX509control->pX509 = (X509 *)cert;
+ return;
+}
+#endif