1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22/* 23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 26/** 27 * \file KMSAgentPKICertOpenSSL.cpp 28 */ 29 30#include <stdio.h> 31#include <openssl/bio.h> 32#include <openssl/pem.h> 33 34#include "SYSCommon.h" 35#include "KMSAgentPKIimpl.h" 36 37typedef struct X509control 38{ 39 X509* pX509; 40} X509control; 41 42void * InitializeCertImpl() 43{ 44 X509control *pX509Control = (X509control *) malloc(sizeof(X509control)); 45 46 if ( pX509Control != NULL ) 47 { 48 pX509Control->pX509 = NULL; 49 } 50 51 return pX509Control; 52} 53 54/** 55 * export the Cert to a memory BIO, if error, return NULL 56 */ 57BIO* SaveCertToMemoryBIO( X509control* i_pX509control ) 58{ 59 BIO *pMemBio = NULL; 60 int iReturn; 61 62 // create memory BIO 63 pMemBio = BIO_new(BIO_s_mem()); 64 65 if(pMemBio == NULL) 66 { 67 //fixme: log -- no memory 68 return NULL; 69 } 70 71 //iReturn = PEM_write_bio_X509(pMemBio, m_pNative); 72 iReturn = PEM_write_bio_X509(pMemBio, i_pX509control->pX509); 73 74 if(!iReturn) // return 0: means error occurs 75 { 76 //fixme: log -- could not export private key 77 BIO_free(pMemBio); 78 return NULL; 79 } 80 81 return pMemBio; 82} 83 84bool SaveX509CertTofile( 85 void* const i_pImplResource, 86 const char * const i_pcFileName ) 87{ 88 FATAL_ASSERT( i_pImplResource != NULL && i_pcFileName ); 89 90 X509control* pX509control = (X509control*)i_pImplResource; 91 // the BIO for output, need cleanup when exiting 92 BIO *pMemBio = NULL; 93 int iLength; 94 unsigned char *pData; 95 FILE *fp; 96 97 // create memory BIO 98 pMemBio = SaveCertToMemoryBIO( pX509control ); 99 100 if(pMemBio == NULL) 101 { 102 return false; 103 } 104 105 // now pMemBIO != NULL, remember to free it before exiting 106 iLength = BIO_get_mem_data(pMemBio, &pData); 107 108 // open the file 109 fp = fopen(i_pcFileName, "wb"); 110 if(fp == NULL) 111 { 112 //fixme: log -- could not open file for exporting Cert 113 BIO_free(pMemBio); 114 return false; 115 } 116 117 fwrite(pData, 1, iLength, fp); 118 fclose(fp); 119 120 BIO_free(pMemBio); // BIO_free close the file and clean the BIO 121 return true; 122} 123 124bool SaveX509CertToBuffer( 125 void* const i_pImplResource, 126 unsigned char * const i_pcBuffer, 127 int i_iBufferLength, 128 int * const o_pActualLength ) 129{ 130 FATAL_ASSERT( i_pImplResource != NULL && 131 i_pcBuffer && 132 o_pActualLength && 133 i_iBufferLength > 0 ); 134 135 X509control* pX509control = (X509control*)i_pImplResource; 136 137 BIO *pMemBio = NULL; 138 char *pData = NULL; 139 int iLength; 140 141 // create memory BIO 142 pMemBio = SaveCertToMemoryBIO( pX509control ); 143 144 if( pMemBio == NULL ) 145 { 146 //fixme: log -- no memory 147 return false; 148 } 149 150 iLength = BIO_get_mem_data( pMemBio, &pData ); 151 152 // If the output buffer is a string, it needs to be NULL terminated 153 // So always append a NULL to the output 154 if(iLength + 1 > i_iBufferLength) 155 { 156 //fixme: log -- buffer too small 157 BIO_free(pMemBio); 158 return false; 159 } 160 // copy the data to given buffer 161 memcpy(i_pcBuffer, pData, iLength); 162 // NULL terminate the string 163 i_pcBuffer[iLength] = '\0'; 164 *o_pActualLength = iLength; 165 166 // free memory 167 BIO_free(pMemBio); 168 169 return true; 170} 171 172/** 173 * import the Cert from a BIO, if error, return NULL 174 */ 175bool LoadCertFromBIO(X509control* i_pX509control, BIO *i_pBio) 176{ 177 X509 *pRequest = NULL; 178 179 if (i_pX509control == NULL) return false; 180 181 if(i_pBio == NULL) return false; 182 183 //if(m_pNative != NULL) return false; // do not allow overwrite 184 if (i_pX509control->pX509 != NULL ) return false; 185 186 pRequest=PEM_read_bio_X509(i_pBio, NULL, NULL, NULL); 187 188 if (pRequest == NULL) 189 { 190 // fixme: log: invalid certificate format 191 return false; 192 } 193 //m_pNative = pRequest; 194 i_pX509control->pX509 = pRequest; 195 196 return true; 197} 198 199bool LoadX509CertFromFile( 200 void* const i_pImplResource, 201 const char * const i_pcFileName ) 202 203{ 204 X509control* pX509control = (X509control*) i_pImplResource; 205 if (pX509control == NULL) 206 { 207 return false; 208 } 209 210 BIO *pFileBio=NULL; 211 bool bReturn; 212 213 pFileBio=BIO_new(BIO_s_file()); 214 if (pFileBio == NULL) 215 { 216 //fixme: log -- no memory 217 return false; 218 } 219 220 if (!BIO_read_filename(pFileBio,i_pcFileName)) 221 { 222 //fixme log -- could not open file 223 BIO_free(pFileBio); 224 return false; 225 } 226 227 bReturn = LoadCertFromBIO(pX509control, pFileBio); 228 229 BIO_free(pFileBio); 230 231 return bReturn; 232} 233 234 235bool LoadX509CertFromBuffer( 236 void* const i_pImplResource, 237 void* const i_pX509Cert, 238 int i_iLength) 239 { 240 X509control* pX509control = (X509control*)i_pImplResource; 241 242 if(pX509control == NULL) 243 { 244 return false; 245 } 246 247 BIO *pMemBio; 248 bool bReturn; 249 // create a mem bio from the given buffer 250 // Note that BIO_new_mem_buf() creates a BIO which never destroy the memory 251 // attached to it. 252 pMemBio = BIO_new_mem_buf(i_pX509Cert, i_iLength); 253 if (pMemBio == NULL) 254 { 255 //fixme: log -- no memory 256 return false; 257 } 258 bReturn = LoadCertFromBIO(pX509control, pMemBio); 259 260 BIO_free(pMemBio); 261 262 return bReturn; 263} 264 265void FinalizeCertImpl( void* i_pImplResource ) 266{ 267 if ( i_pImplResource != NULL ) 268 { 269 free(i_pImplResource); 270 } 271} 272 273bool PrintX509Cert( void* const i_pImplResource ) 274{ 275 BIO *pMemBio; 276 char *pData; 277 int iLength,i; 278 X509control* pX509control = (X509control*)i_pImplResource; 279 pMemBio = BIO_new(BIO_s_mem()); 280 if(pMemBio == NULL) 281 { 282 return false; 283 } 284 285 //X509_print(pMemBio,m_pNative); 286 X509_print(pMemBio, pX509control->pX509); 287 288 iLength = BIO_get_mem_data(pMemBio, &pData); 289 290 for(i = 0; i < iLength; i++) 291 { 292 printf("%c", pData[i]); 293 } 294 295 BIO_free(pMemBio); 296 297 return true; 298 299} 300#ifdef K_SOLARIS_PLATFORM 301void *GetCert(void* i_pImplResource ) 302{ 303 X509control* pX509control = (X509control*)i_pImplResource; 304 return ((void *)pX509control->pX509); 305} 306 307void SetCert(void* i_pImplResource, void *cert) 308{ 309 X509control* pX509control = (X509control*)i_pImplResource; 310 pX509control->pX509 = (X509 *)cert; 311 return; 312} 313#endif 314