diff options
Diffstat (limited to 'usr/src/lib/libkmsagent/common/KMSAgentPKICertOpenSSL.cpp')
| -rw-r--r-- | usr/src/lib/libkmsagent/common/KMSAgentPKICertOpenSSL.cpp | 313 | 
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 | 
