1*12720SWyllys.Ingersoll@Sun.COM /* 2*12720SWyllys.Ingersoll@Sun.COM * CDDL HEADER START 3*12720SWyllys.Ingersoll@Sun.COM * 4*12720SWyllys.Ingersoll@Sun.COM * The contents of this file are subject to the terms of the 5*12720SWyllys.Ingersoll@Sun.COM * Common Development and Distribution License (the "License"). 6*12720SWyllys.Ingersoll@Sun.COM * You may not use this file except in compliance with the License. 7*12720SWyllys.Ingersoll@Sun.COM * 8*12720SWyllys.Ingersoll@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*12720SWyllys.Ingersoll@Sun.COM * or http://www.opensolaris.org/os/licensing. 10*12720SWyllys.Ingersoll@Sun.COM * See the License for the specific language governing permissions 11*12720SWyllys.Ingersoll@Sun.COM * and limitations under the License. 12*12720SWyllys.Ingersoll@Sun.COM * 13*12720SWyllys.Ingersoll@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 14*12720SWyllys.Ingersoll@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*12720SWyllys.Ingersoll@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 16*12720SWyllys.Ingersoll@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 17*12720SWyllys.Ingersoll@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 18*12720SWyllys.Ingersoll@Sun.COM * 19*12720SWyllys.Ingersoll@Sun.COM * CDDL HEADER END 20*12720SWyllys.Ingersoll@Sun.COM */ 21*12720SWyllys.Ingersoll@Sun.COM 22*12720SWyllys.Ingersoll@Sun.COM /* 23*12720SWyllys.Ingersoll@Sun.COM * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 24*12720SWyllys.Ingersoll@Sun.COM */ 25*12720SWyllys.Ingersoll@Sun.COM 26*12720SWyllys.Ingersoll@Sun.COM /** 27*12720SWyllys.Ingersoll@Sun.COM * \file KMSAgentPKIKeyOpenSSL.cpp 28*12720SWyllys.Ingersoll@Sun.COM */ 29*12720SWyllys.Ingersoll@Sun.COM 30*12720SWyllys.Ingersoll@Sun.COM #include <stdio.h> 31*12720SWyllys.Ingersoll@Sun.COM #include <openssl/bio.h> 32*12720SWyllys.Ingersoll@Sun.COM #include <openssl/pem.h> 33*12720SWyllys.Ingersoll@Sun.COM #include <openssl/rsa.h> 34*12720SWyllys.Ingersoll@Sun.COM 35*12720SWyllys.Ingersoll@Sun.COM #include "SYSCommon.h" 36*12720SWyllys.Ingersoll@Sun.COM #include "KMSAgentPKIimpl.h" 37*12720SWyllys.Ingersoll@Sun.COM 38*12720SWyllys.Ingersoll@Sun.COM typedef struct PKeyControl 39*12720SWyllys.Ingersoll@Sun.COM { 40*12720SWyllys.Ingersoll@Sun.COM EVP_PKEY* pPKey; 41*12720SWyllys.Ingersoll@Sun.COM } PKeyControl; 42*12720SWyllys.Ingersoll@Sun.COM 43*12720SWyllys.Ingersoll@Sun.COM void * InitializePKeyImpl() 44*12720SWyllys.Ingersoll@Sun.COM { 45*12720SWyllys.Ingersoll@Sun.COM PKeyControl *pPKeyControl = 46*12720SWyllys.Ingersoll@Sun.COM (PKeyControl *) malloc(sizeof(PKeyControl)); 47*12720SWyllys.Ingersoll@Sun.COM 48*12720SWyllys.Ingersoll@Sun.COM if ( pPKeyControl != NULL ) 49*12720SWyllys.Ingersoll@Sun.COM { 50*12720SWyllys.Ingersoll@Sun.COM pPKeyControl->pPKey = NULL; 51*12720SWyllys.Ingersoll@Sun.COM } 52*12720SWyllys.Ingersoll@Sun.COM 53*12720SWyllys.Ingersoll@Sun.COM return pPKeyControl; 54*12720SWyllys.Ingersoll@Sun.COM } 55*12720SWyllys.Ingersoll@Sun.COM 56*12720SWyllys.Ingersoll@Sun.COM void FinalizePKeyImpl( void * i_pPKeyImpl ) 57*12720SWyllys.Ingersoll@Sun.COM { 58*12720SWyllys.Ingersoll@Sun.COM if ( i_pPKeyImpl != NULL ) 59*12720SWyllys.Ingersoll@Sun.COM { 60*12720SWyllys.Ingersoll@Sun.COM free(i_pPKeyImpl); 61*12720SWyllys.Ingersoll@Sun.COM } 62*12720SWyllys.Ingersoll@Sun.COM } 63*12720SWyllys.Ingersoll@Sun.COM 64*12720SWyllys.Ingersoll@Sun.COM #ifdef KMSUSERPKCS12 65*12720SWyllys.Ingersoll@Sun.COM void *GetPKey(void *i_pPKeyImpl) { 66*12720SWyllys.Ingersoll@Sun.COM PKeyControl* pPKeyControl = (PKeyControl*) i_pPKeyImpl; 67*12720SWyllys.Ingersoll@Sun.COM return ((void *)pPKeyControl->pPKey); 68*12720SWyllys.Ingersoll@Sun.COM } 69*12720SWyllys.Ingersoll@Sun.COM 70*12720SWyllys.Ingersoll@Sun.COM void SetPKey(void *i_pPKeyImpl, void *pKey) { 71*12720SWyllys.Ingersoll@Sun.COM PKeyControl* pPKeyControl = (PKeyControl*) i_pPKeyImpl; 72*12720SWyllys.Ingersoll@Sun.COM pPKeyControl->pPKey = (EVP_PKEY *)pKey; 73*12720SWyllys.Ingersoll@Sun.COM return; 74*12720SWyllys.Ingersoll@Sun.COM } 75*12720SWyllys.Ingersoll@Sun.COM #endif 76*12720SWyllys.Ingersoll@Sun.COM 77*12720SWyllys.Ingersoll@Sun.COM /** 78*12720SWyllys.Ingersoll@Sun.COM * export the private key to a memory BIO, if error, return NULL 79*12720SWyllys.Ingersoll@Sun.COM */ 80*12720SWyllys.Ingersoll@Sun.COM BIO* SavePrivateKeyToMemoryBIO(PKeyControl* const i_pPKeyControl, 81*12720SWyllys.Ingersoll@Sun.COM const char * const i_pPassphrase) 82*12720SWyllys.Ingersoll@Sun.COM { 83*12720SWyllys.Ingersoll@Sun.COM BIO *pMemBio = NULL; 84*12720SWyllys.Ingersoll@Sun.COM const EVP_CIPHER *pCipher = NULL; 85*12720SWyllys.Ingersoll@Sun.COM int iReturn; 86*12720SWyllys.Ingersoll@Sun.COM 87*12720SWyllys.Ingersoll@Sun.COM // set cipher, if passphrase is not empty 88*12720SWyllys.Ingersoll@Sun.COM if(i_pPassphrase != NULL) 89*12720SWyllys.Ingersoll@Sun.COM { 90*12720SWyllys.Ingersoll@Sun.COM pCipher= EVP_des_ede3_cbc(); //NULL means no password protection 91*12720SWyllys.Ingersoll@Sun.COM } 92*12720SWyllys.Ingersoll@Sun.COM 93*12720SWyllys.Ingersoll@Sun.COM // create memory BIO 94*12720SWyllys.Ingersoll@Sun.COM pMemBio = BIO_new(BIO_s_mem()); 95*12720SWyllys.Ingersoll@Sun.COM 96*12720SWyllys.Ingersoll@Sun.COM if(pMemBio == NULL) 97*12720SWyllys.Ingersoll@Sun.COM { 98*12720SWyllys.Ingersoll@Sun.COM //fixme: log -- no memory 99*12720SWyllys.Ingersoll@Sun.COM return NULL; 100*12720SWyllys.Ingersoll@Sun.COM } 101*12720SWyllys.Ingersoll@Sun.COM 102*12720SWyllys.Ingersoll@Sun.COM iReturn = PEM_write_bio_PrivateKey 103*12720SWyllys.Ingersoll@Sun.COM (pMemBio, 104*12720SWyllys.Ingersoll@Sun.COM i_pPKeyControl->pPKey, 105*12720SWyllys.Ingersoll@Sun.COM pCipher, 106*12720SWyllys.Ingersoll@Sun.COM NULL,0,NULL, (char*) i_pPassphrase); 107*12720SWyllys.Ingersoll@Sun.COM 108*12720SWyllys.Ingersoll@Sun.COM if(!iReturn) // return 0: means error occurs 109*12720SWyllys.Ingersoll@Sun.COM { 110*12720SWyllys.Ingersoll@Sun.COM //fixme: log -- could not export private key 111*12720SWyllys.Ingersoll@Sun.COM BIO_free(pMemBio); 112*12720SWyllys.Ingersoll@Sun.COM return NULL; 113*12720SWyllys.Ingersoll@Sun.COM } 114*12720SWyllys.Ingersoll@Sun.COM 115*12720SWyllys.Ingersoll@Sun.COM return pMemBio; 116*12720SWyllys.Ingersoll@Sun.COM } 117*12720SWyllys.Ingersoll@Sun.COM 118*12720SWyllys.Ingersoll@Sun.COM bool SavePrivateKeyToBuffer( 119*12720SWyllys.Ingersoll@Sun.COM void * const i_pPKeyImpl, 120*12720SWyllys.Ingersoll@Sun.COM unsigned char * const i_pcBuffer, 121*12720SWyllys.Ingersoll@Sun.COM int i_iBufferLength, 122*12720SWyllys.Ingersoll@Sun.COM int * const o_pActualLength, 123*12720SWyllys.Ingersoll@Sun.COM const char * const i_pPassphrase, 124*12720SWyllys.Ingersoll@Sun.COM int i_iFormat) 125*12720SWyllys.Ingersoll@Sun.COM { 126*12720SWyllys.Ingersoll@Sun.COM PKeyControl* pPKeyControl = (PKeyControl*) i_pPKeyImpl; 127*12720SWyllys.Ingersoll@Sun.COM 128*12720SWyllys.Ingersoll@Sun.COM FATAL_ASSERT( pPKeyControl && 129*12720SWyllys.Ingersoll@Sun.COM i_pcBuffer && 130*12720SWyllys.Ingersoll@Sun.COM i_iBufferLength > 0 && 131*12720SWyllys.Ingersoll@Sun.COM o_pActualLength ); 132*12720SWyllys.Ingersoll@Sun.COM 133*12720SWyllys.Ingersoll@Sun.COM BIO *pMemBio = NULL; 134*12720SWyllys.Ingersoll@Sun.COM char *pData = NULL; 135*12720SWyllys.Ingersoll@Sun.COM int iLength; 136*12720SWyllys.Ingersoll@Sun.COM 137*12720SWyllys.Ingersoll@Sun.COM // create memory BIO 138*12720SWyllys.Ingersoll@Sun.COM pMemBio = SavePrivateKeyToMemoryBIO( pPKeyControl, i_pPassphrase ); 139*12720SWyllys.Ingersoll@Sun.COM 140*12720SWyllys.Ingersoll@Sun.COM if(pMemBio == NULL) 141*12720SWyllys.Ingersoll@Sun.COM { 142*12720SWyllys.Ingersoll@Sun.COM //fixme: log -- no memory 143*12720SWyllys.Ingersoll@Sun.COM return false; 144*12720SWyllys.Ingersoll@Sun.COM } 145*12720SWyllys.Ingersoll@Sun.COM 146*12720SWyllys.Ingersoll@Sun.COM iLength = BIO_get_mem_data(pMemBio, &pData); 147*12720SWyllys.Ingersoll@Sun.COM 148*12720SWyllys.Ingersoll@Sun.COM // If the output buffer is a string, it needs to be NULL terminated 149*12720SWyllys.Ingersoll@Sun.COM // So always append a NULL to the output 150*12720SWyllys.Ingersoll@Sun.COM if(iLength + 1 > i_iBufferLength) 151*12720SWyllys.Ingersoll@Sun.COM { 152*12720SWyllys.Ingersoll@Sun.COM //fixme: log -- buffer too small 153*12720SWyllys.Ingersoll@Sun.COM BIO_free(pMemBio); 154*12720SWyllys.Ingersoll@Sun.COM return false; 155*12720SWyllys.Ingersoll@Sun.COM } 156*12720SWyllys.Ingersoll@Sun.COM // copy the data to given buffer 157*12720SWyllys.Ingersoll@Sun.COM memcpy(i_pcBuffer, pData, iLength); 158*12720SWyllys.Ingersoll@Sun.COM // NULL terminate the string 159*12720SWyllys.Ingersoll@Sun.COM i_pcBuffer[iLength] = '\0'; 160*12720SWyllys.Ingersoll@Sun.COM *o_pActualLength = iLength; 161*12720SWyllys.Ingersoll@Sun.COM 162*12720SWyllys.Ingersoll@Sun.COM // free memory 163*12720SWyllys.Ingersoll@Sun.COM BIO_free(pMemBio); 164*12720SWyllys.Ingersoll@Sun.COM 165*12720SWyllys.Ingersoll@Sun.COM return true; 166*12720SWyllys.Ingersoll@Sun.COM } 167*12720SWyllys.Ingersoll@Sun.COM 168*12720SWyllys.Ingersoll@Sun.COM /** 169*12720SWyllys.Ingersoll@Sun.COM * import the private key from a BIO, if error, return NULL 170*12720SWyllys.Ingersoll@Sun.COM */ 171*12720SWyllys.Ingersoll@Sun.COM bool LoadPrivateKeyFromBIO(PKeyControl* const io_pPKeyControl, 172*12720SWyllys.Ingersoll@Sun.COM BIO *i_pBio, 173*12720SWyllys.Ingersoll@Sun.COM char *i_pPassphrase ) 174*12720SWyllys.Ingersoll@Sun.COM { 175*12720SWyllys.Ingersoll@Sun.COM if (io_pPKeyControl == NULL) 176*12720SWyllys.Ingersoll@Sun.COM { 177*12720SWyllys.Ingersoll@Sun.COM return false; 178*12720SWyllys.Ingersoll@Sun.COM } 179*12720SWyllys.Ingersoll@Sun.COM 180*12720SWyllys.Ingersoll@Sun.COM EVP_PKEY *pKey = NULL; 181*12720SWyllys.Ingersoll@Sun.COM 182*12720SWyllys.Ingersoll@Sun.COM if(i_pBio == NULL) 183*12720SWyllys.Ingersoll@Sun.COM { 184*12720SWyllys.Ingersoll@Sun.COM return false; 185*12720SWyllys.Ingersoll@Sun.COM } 186*12720SWyllys.Ingersoll@Sun.COM 187*12720SWyllys.Ingersoll@Sun.COM if ( io_pPKeyControl != NULL && io_pPKeyControl->pPKey != NULL ) 188*12720SWyllys.Ingersoll@Sun.COM { 189*12720SWyllys.Ingersoll@Sun.COM return false; // do not allow overwrite 190*12720SWyllys.Ingersoll@Sun.COM } 191*12720SWyllys.Ingersoll@Sun.COM 192*12720SWyllys.Ingersoll@Sun.COM pKey=PEM_read_bio_PrivateKey(i_pBio,NULL,NULL,i_pPassphrase); 193*12720SWyllys.Ingersoll@Sun.COM if (pKey == NULL) 194*12720SWyllys.Ingersoll@Sun.COM { 195*12720SWyllys.Ingersoll@Sun.COM // fixme: log: invalid private key format or passphrase 196*12720SWyllys.Ingersoll@Sun.COM return false; 197*12720SWyllys.Ingersoll@Sun.COM } 198*12720SWyllys.Ingersoll@Sun.COM 199*12720SWyllys.Ingersoll@Sun.COM io_pPKeyControl->pPKey = pKey; 200*12720SWyllys.Ingersoll@Sun.COM 201*12720SWyllys.Ingersoll@Sun.COM return true; 202*12720SWyllys.Ingersoll@Sun.COM } 203*12720SWyllys.Ingersoll@Sun.COM 204*12720SWyllys.Ingersoll@Sun.COM bool LoadPrivateKeyFromBuffer( 205*12720SWyllys.Ingersoll@Sun.COM void * const i_pPKeyImpl, 206*12720SWyllys.Ingersoll@Sun.COM unsigned char * i_pcBuffer, 207*12720SWyllys.Ingersoll@Sun.COM int i_iLength, 208*12720SWyllys.Ingersoll@Sun.COM const char * const i_pPassphrase, 209*12720SWyllys.Ingersoll@Sun.COM int i_iFormat) 210*12720SWyllys.Ingersoll@Sun.COM { 211*12720SWyllys.Ingersoll@Sun.COM PKeyControl* const pPKeyControl = (PKeyControl*) i_pPKeyImpl; 212*12720SWyllys.Ingersoll@Sun.COM 213*12720SWyllys.Ingersoll@Sun.COM FATAL_ASSERT( i_pPKeyImpl && i_pcBuffer ); 214*12720SWyllys.Ingersoll@Sun.COM 215*12720SWyllys.Ingersoll@Sun.COM bool bReturn; 216*12720SWyllys.Ingersoll@Sun.COM BIO *pMemBio; 217*12720SWyllys.Ingersoll@Sun.COM // create a mem bio from the given buffer 218*12720SWyllys.Ingersoll@Sun.COM // Note that BIO_new_mem_buf() creates a BIO which never 219*12720SWyllys.Ingersoll@Sun.COM // destroy the memory attached to it. 220*12720SWyllys.Ingersoll@Sun.COM pMemBio = BIO_new_mem_buf(i_pcBuffer, i_iLength); 221*12720SWyllys.Ingersoll@Sun.COM if (pMemBio == NULL) 222*12720SWyllys.Ingersoll@Sun.COM { 223*12720SWyllys.Ingersoll@Sun.COM //fixme: log -- no memory 224*12720SWyllys.Ingersoll@Sun.COM return false; 225*12720SWyllys.Ingersoll@Sun.COM } 226*12720SWyllys.Ingersoll@Sun.COM bReturn = LoadPrivateKeyFromBIO( pPKeyControl, 227*12720SWyllys.Ingersoll@Sun.COM pMemBio, (char *)i_pPassphrase ); 228*12720SWyllys.Ingersoll@Sun.COM 229*12720SWyllys.Ingersoll@Sun.COM BIO_free(pMemBio); 230*12720SWyllys.Ingersoll@Sun.COM 231*12720SWyllys.Ingersoll@Sun.COM return bReturn; 232*12720SWyllys.Ingersoll@Sun.COM } 233*12720SWyllys.Ingersoll@Sun.COM 234*12720SWyllys.Ingersoll@Sun.COM /** 235*12720SWyllys.Ingersoll@Sun.COM * export the public key to a memory BIO, if error, return NULL 236*12720SWyllys.Ingersoll@Sun.COM */ 237*12720SWyllys.Ingersoll@Sun.COM BIO* SavePublicKeyToMemoryBIO(PKeyControl* const i_pPublicKeyControl ) 238*12720SWyllys.Ingersoll@Sun.COM { 239*12720SWyllys.Ingersoll@Sun.COM BIO *pMemBio = NULL; 240*12720SWyllys.Ingersoll@Sun.COM 241*12720SWyllys.Ingersoll@Sun.COM int iReturn; 242*12720SWyllys.Ingersoll@Sun.COM 243*12720SWyllys.Ingersoll@Sun.COM // create memory BIO 244*12720SWyllys.Ingersoll@Sun.COM pMemBio = BIO_new(BIO_s_mem()); 245*12720SWyllys.Ingersoll@Sun.COM 246*12720SWyllys.Ingersoll@Sun.COM if(pMemBio == NULL) 247*12720SWyllys.Ingersoll@Sun.COM { 248*12720SWyllys.Ingersoll@Sun.COM //fixme: log -- no memory 249*12720SWyllys.Ingersoll@Sun.COM return NULL; 250*12720SWyllys.Ingersoll@Sun.COM } 251*12720SWyllys.Ingersoll@Sun.COM 252*12720SWyllys.Ingersoll@Sun.COM iReturn = PEM_write_bio_PUBKEY(pMemBio, 253*12720SWyllys.Ingersoll@Sun.COM i_pPublicKeyControl->pPKey ); 254*12720SWyllys.Ingersoll@Sun.COM 255*12720SWyllys.Ingersoll@Sun.COM if(!iReturn) // return 0: means error occurs 256*12720SWyllys.Ingersoll@Sun.COM { 257*12720SWyllys.Ingersoll@Sun.COM //fixme: log -- could not export private key 258*12720SWyllys.Ingersoll@Sun.COM BIO_free(pMemBio); 259*12720SWyllys.Ingersoll@Sun.COM return NULL; 260*12720SWyllys.Ingersoll@Sun.COM } 261*12720SWyllys.Ingersoll@Sun.COM 262*12720SWyllys.Ingersoll@Sun.COM return pMemBio; 263*12720SWyllys.Ingersoll@Sun.COM } 264*12720SWyllys.Ingersoll@Sun.COM 265*12720SWyllys.Ingersoll@Sun.COM bool SavePublicKeyToBuffer( 266*12720SWyllys.Ingersoll@Sun.COM void * const i_pPKeyImpl, 267*12720SWyllys.Ingersoll@Sun.COM unsigned char * const i_pcBuffer, 268*12720SWyllys.Ingersoll@Sun.COM int i_iBufferLength, 269*12720SWyllys.Ingersoll@Sun.COM int * const o_pActualLength, 270*12720SWyllys.Ingersoll@Sun.COM int i_iFormat) 271*12720SWyllys.Ingersoll@Sun.COM { 272*12720SWyllys.Ingersoll@Sun.COM PKeyControl* pPublicKeyControl = (PKeyControl*) i_pPKeyImpl; 273*12720SWyllys.Ingersoll@Sun.COM 274*12720SWyllys.Ingersoll@Sun.COM FATAL_ASSERT( pPublicKeyControl && 275*12720SWyllys.Ingersoll@Sun.COM i_pcBuffer && 276*12720SWyllys.Ingersoll@Sun.COM i_iBufferLength > 0 && 277*12720SWyllys.Ingersoll@Sun.COM o_pActualLength ); 278*12720SWyllys.Ingersoll@Sun.COM 279*12720SWyllys.Ingersoll@Sun.COM BIO *pMemBio = NULL; 280*12720SWyllys.Ingersoll@Sun.COM char *pData = NULL; 281*12720SWyllys.Ingersoll@Sun.COM int iLength; 282*12720SWyllys.Ingersoll@Sun.COM 283*12720SWyllys.Ingersoll@Sun.COM // create memory BIO 284*12720SWyllys.Ingersoll@Sun.COM pMemBio = SavePublicKeyToMemoryBIO( pPublicKeyControl ); 285*12720SWyllys.Ingersoll@Sun.COM 286*12720SWyllys.Ingersoll@Sun.COM if(pMemBio == NULL) 287*12720SWyllys.Ingersoll@Sun.COM { 288*12720SWyllys.Ingersoll@Sun.COM return false; 289*12720SWyllys.Ingersoll@Sun.COM } 290*12720SWyllys.Ingersoll@Sun.COM 291*12720SWyllys.Ingersoll@Sun.COM iLength = BIO_get_mem_data(pMemBio, &pData); 292*12720SWyllys.Ingersoll@Sun.COM 293*12720SWyllys.Ingersoll@Sun.COM // If the output buffer is a string, it needs to be NULL terminated 294*12720SWyllys.Ingersoll@Sun.COM // So always append a NULL to the output 295*12720SWyllys.Ingersoll@Sun.COM if(iLength + 1 > i_iBufferLength) 296*12720SWyllys.Ingersoll@Sun.COM { 297*12720SWyllys.Ingersoll@Sun.COM BIO_free(pMemBio); 298*12720SWyllys.Ingersoll@Sun.COM return false; 299*12720SWyllys.Ingersoll@Sun.COM } 300*12720SWyllys.Ingersoll@Sun.COM // copy the data to given buffer 301*12720SWyllys.Ingersoll@Sun.COM memcpy(i_pcBuffer, pData, iLength); 302*12720SWyllys.Ingersoll@Sun.COM // NULL terminate the string 303*12720SWyllys.Ingersoll@Sun.COM i_pcBuffer[iLength] = '\0'; 304*12720SWyllys.Ingersoll@Sun.COM *o_pActualLength = iLength; 305*12720SWyllys.Ingersoll@Sun.COM 306*12720SWyllys.Ingersoll@Sun.COM // free memory 307*12720SWyllys.Ingersoll@Sun.COM BIO_free(pMemBio); 308*12720SWyllys.Ingersoll@Sun.COM 309*12720SWyllys.Ingersoll@Sun.COM return true; 310*12720SWyllys.Ingersoll@Sun.COM } 311*12720SWyllys.Ingersoll@Sun.COM 312*12720SWyllys.Ingersoll@Sun.COM /** 313*12720SWyllys.Ingersoll@Sun.COM * import the public key from a BIO, if error, return NULL 314*12720SWyllys.Ingersoll@Sun.COM */ 315*12720SWyllys.Ingersoll@Sun.COM bool LoadPublicKeyFromBIO(PKeyControl* const io_pPublicKeyControl, 316*12720SWyllys.Ingersoll@Sun.COM BIO *i_pBio ) 317*12720SWyllys.Ingersoll@Sun.COM { 318*12720SWyllys.Ingersoll@Sun.COM EVP_PKEY *pKey = NULL; 319*12720SWyllys.Ingersoll@Sun.COM 320*12720SWyllys.Ingersoll@Sun.COM if(io_pPublicKeyControl == NULL) 321*12720SWyllys.Ingersoll@Sun.COM { 322*12720SWyllys.Ingersoll@Sun.COM return false; 323*12720SWyllys.Ingersoll@Sun.COM } 324*12720SWyllys.Ingersoll@Sun.COM 325*12720SWyllys.Ingersoll@Sun.COM if(i_pBio == NULL) 326*12720SWyllys.Ingersoll@Sun.COM { 327*12720SWyllys.Ingersoll@Sun.COM return false; 328*12720SWyllys.Ingersoll@Sun.COM } 329*12720SWyllys.Ingersoll@Sun.COM 330*12720SWyllys.Ingersoll@Sun.COM if ( io_pPublicKeyControl != NULL && io_pPublicKeyControl->pPKey != NULL ) 331*12720SWyllys.Ingersoll@Sun.COM { 332*12720SWyllys.Ingersoll@Sun.COM return false; // do not allow overwrite 333*12720SWyllys.Ingersoll@Sun.COM } 334*12720SWyllys.Ingersoll@Sun.COM 335*12720SWyllys.Ingersoll@Sun.COM pKey = PEM_read_bio_PUBKEY(i_pBio, NULL, NULL, NULL); 336*12720SWyllys.Ingersoll@Sun.COM if (pKey == NULL) 337*12720SWyllys.Ingersoll@Sun.COM { 338*12720SWyllys.Ingersoll@Sun.COM // fixme: log: invalid public key format or passphrase 339*12720SWyllys.Ingersoll@Sun.COM return false; 340*12720SWyllys.Ingersoll@Sun.COM } 341*12720SWyllys.Ingersoll@Sun.COM 342*12720SWyllys.Ingersoll@Sun.COM io_pPublicKeyControl->pPKey = pKey; 343*12720SWyllys.Ingersoll@Sun.COM 344*12720SWyllys.Ingersoll@Sun.COM return true; 345*12720SWyllys.Ingersoll@Sun.COM } 346*12720SWyllys.Ingersoll@Sun.COM 347*12720SWyllys.Ingersoll@Sun.COM bool LoadPublicKeyFromBuffer( 348*12720SWyllys.Ingersoll@Sun.COM void * const i_pPublicKeyImpl, 349*12720SWyllys.Ingersoll@Sun.COM unsigned char * i_pcBuffer, 350*12720SWyllys.Ingersoll@Sun.COM int i_iLength, 351*12720SWyllys.Ingersoll@Sun.COM int i_iFormat) 352*12720SWyllys.Ingersoll@Sun.COM { 353*12720SWyllys.Ingersoll@Sun.COM PKeyControl* const pPublicKeyControl = (PKeyControl*) i_pPublicKeyImpl; 354*12720SWyllys.Ingersoll@Sun.COM 355*12720SWyllys.Ingersoll@Sun.COM FATAL_ASSERT( i_pPublicKeyImpl && i_pcBuffer ); 356*12720SWyllys.Ingersoll@Sun.COM 357*12720SWyllys.Ingersoll@Sun.COM bool bReturn; 358*12720SWyllys.Ingersoll@Sun.COM BIO *pMemBio; 359*12720SWyllys.Ingersoll@Sun.COM // create a mem bio from the given buffer 360*12720SWyllys.Ingersoll@Sun.COM // Note that BIO_new_mem_buf() creates a BIO which never 361*12720SWyllys.Ingersoll@Sun.COM // destroy the memory attached to it. 362*12720SWyllys.Ingersoll@Sun.COM pMemBio = BIO_new_mem_buf(i_pcBuffer, i_iLength); 363*12720SWyllys.Ingersoll@Sun.COM if (pMemBio == NULL) 364*12720SWyllys.Ingersoll@Sun.COM { 365*12720SWyllys.Ingersoll@Sun.COM //fixme: log -- no memory 366*12720SWyllys.Ingersoll@Sun.COM return false; 367*12720SWyllys.Ingersoll@Sun.COM } 368*12720SWyllys.Ingersoll@Sun.COM bReturn = LoadPublicKeyFromBIO( pPublicKeyControl, 369*12720SWyllys.Ingersoll@Sun.COM pMemBio ); 370*12720SWyllys.Ingersoll@Sun.COM 371*12720SWyllys.Ingersoll@Sun.COM BIO_free(pMemBio); 372*12720SWyllys.Ingersoll@Sun.COM 373*12720SWyllys.Ingersoll@Sun.COM return bReturn; 374*12720SWyllys.Ingersoll@Sun.COM } 375*12720SWyllys.Ingersoll@Sun.COM 376*12720SWyllys.Ingersoll@Sun.COM bool PublicKeyEncrypt (int i_iLength, 377*12720SWyllys.Ingersoll@Sun.COM const unsigned char * const i_pcPlainText, 378*12720SWyllys.Ingersoll@Sun.COM unsigned char * const o_pcCypherText, 379*12720SWyllys.Ingersoll@Sun.COM int * const o_pActualLength, 380*12720SWyllys.Ingersoll@Sun.COM void * pPKeyControl ) 381*12720SWyllys.Ingersoll@Sun.COM { 382*12720SWyllys.Ingersoll@Sun.COM FATAL_ASSERT( i_pcPlainText ); 383*12720SWyllys.Ingersoll@Sun.COM FATAL_ASSERT( o_pcCypherText ); 384*12720SWyllys.Ingersoll@Sun.COM FATAL_ASSERT( o_pActualLength ); 385*12720SWyllys.Ingersoll@Sun.COM FATAL_ASSERT( pPKeyControl ); 386*12720SWyllys.Ingersoll@Sun.COM 387*12720SWyllys.Ingersoll@Sun.COM PKeyControl *pKeyControl = (PKeyControl *)pPKeyControl; 388*12720SWyllys.Ingersoll@Sun.COM EVP_PKEY * pEVP_PKEY = pKeyControl->pPKey; 389*12720SWyllys.Ingersoll@Sun.COM RSA * pRSAPublicKey = pEVP_PKEY->pkey.rsa; 390*12720SWyllys.Ingersoll@Sun.COM 391*12720SWyllys.Ingersoll@Sun.COM //#if defined(DEBUG) 392*12720SWyllys.Ingersoll@Sun.COM // RSA_print_fp(stdout, pRSAPublicKey, 0); 393*12720SWyllys.Ingersoll@Sun.COM // printf("PublicKeyEncrypt(): RSA_size()=%d, cyphertextLen=%d\n", 394*12720SWyllys.Ingersoll@Sun.COM // RSA_size(pRSAPublicKey), 395*12720SWyllys.Ingersoll@Sun.COM // i_iLength); 396*12720SWyllys.Ingersoll@Sun.COM //#endif 397*12720SWyllys.Ingersoll@Sun.COM 398*12720SWyllys.Ingersoll@Sun.COM *o_pActualLength = RSA_public_encrypt(i_iLength, 399*12720SWyllys.Ingersoll@Sun.COM i_pcPlainText, 400*12720SWyllys.Ingersoll@Sun.COM o_pcCypherText, 401*12720SWyllys.Ingersoll@Sun.COM pRSAPublicKey, 402*12720SWyllys.Ingersoll@Sun.COM RSA_PKCS1_PADDING); 403*12720SWyllys.Ingersoll@Sun.COM 404*12720SWyllys.Ingersoll@Sun.COM if ( *o_pActualLength < 0 ) 405*12720SWyllys.Ingersoll@Sun.COM { 406*12720SWyllys.Ingersoll@Sun.COM return false; 407*12720SWyllys.Ingersoll@Sun.COM } 408*12720SWyllys.Ingersoll@Sun.COM else 409*12720SWyllys.Ingersoll@Sun.COM { 410*12720SWyllys.Ingersoll@Sun.COM return true; 411*12720SWyllys.Ingersoll@Sun.COM } 412*12720SWyllys.Ingersoll@Sun.COM } 413