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.
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.
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]
23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
27 * \file KMSAgentPKIKeyOpenSSL.cpp
31 #include <openssl/bio.h>
32 #include <openssl/pem.h>
33 #include <openssl/rsa.h>
35 #include "SYSCommon.h"
36 #include "KMSAgentPKIimpl.h"
38 typedef struct PKeyControl
43 void * InitializePKeyImpl()
45 PKeyControl
*pPKeyControl
=
46 (PKeyControl
*) malloc(sizeof(PKeyControl
));
48 if ( pPKeyControl
!= NULL
)
50 pPKeyControl
->pPKey
= NULL
;
56 void FinalizePKeyImpl( void * i_pPKeyImpl
)
58 if ( i_pPKeyImpl
!= NULL
)
65 void *GetPKey(void *i_pPKeyImpl
) {
66 PKeyControl
* pPKeyControl
= (PKeyControl
*) i_pPKeyImpl
;
67 return ((void *)pPKeyControl
->pPKey
);
70 void SetPKey(void *i_pPKeyImpl
, void *pKey
) {
71 PKeyControl
* pPKeyControl
= (PKeyControl
*) i_pPKeyImpl
;
72 pPKeyControl
->pPKey
= (EVP_PKEY
*)pKey
;
78 * export the private key to a memory BIO, if error, return NULL
80 BIO
* SavePrivateKeyToMemoryBIO(PKeyControl
* const i_pPKeyControl
,
81 const char * const i_pPassphrase
)
84 const EVP_CIPHER
*pCipher
= NULL
;
87 // set cipher, if passphrase is not empty
88 if(i_pPassphrase
!= NULL
)
90 pCipher
= EVP_des_ede3_cbc(); //NULL means no password protection
94 pMemBio
= BIO_new(BIO_s_mem());
98 //fixme: log -- no memory
102 iReturn
= PEM_write_bio_PrivateKey
104 i_pPKeyControl
->pPKey
,
106 NULL
,0,NULL
, (char*) i_pPassphrase
);
108 if(!iReturn
) // return 0: means error occurs
110 //fixme: log -- could not export private key
118 bool SavePrivateKeyToBuffer(
119 void * const i_pPKeyImpl
,
120 unsigned char * const i_pcBuffer
,
122 int * const o_pActualLength
,
123 const char * const i_pPassphrase
,
126 PKeyControl
* pPKeyControl
= (PKeyControl
*) i_pPKeyImpl
;
128 FATAL_ASSERT( pPKeyControl
&&
130 i_iBufferLength
> 0 &&
138 pMemBio
= SavePrivateKeyToMemoryBIO( pPKeyControl
, i_pPassphrase
);
142 //fixme: log -- no memory
146 iLength
= BIO_get_mem_data(pMemBio
, &pData
);
148 // If the output buffer is a string, it needs to be NULL terminated
149 // So always append a NULL to the output
150 if(iLength
+ 1 > i_iBufferLength
)
152 //fixme: log -- buffer too small
156 // copy the data to given buffer
157 memcpy(i_pcBuffer
, pData
, iLength
);
158 // NULL terminate the string
159 i_pcBuffer
[iLength
] = '\0';
160 *o_pActualLength
= iLength
;
169 * import the private key from a BIO, if error, return NULL
171 bool LoadPrivateKeyFromBIO(PKeyControl
* const io_pPKeyControl
,
173 char *i_pPassphrase
)
175 if (io_pPKeyControl
== NULL
)
180 EVP_PKEY
*pKey
= NULL
;
187 if ( io_pPKeyControl
!= NULL
&& io_pPKeyControl
->pPKey
!= NULL
)
189 return false; // do not allow overwrite
192 pKey
=PEM_read_bio_PrivateKey(i_pBio
,NULL
,NULL
,i_pPassphrase
);
195 // fixme: log: invalid private key format or passphrase
199 io_pPKeyControl
->pPKey
= pKey
;
204 bool LoadPrivateKeyFromBuffer(
205 void * const i_pPKeyImpl
,
206 unsigned char * i_pcBuffer
,
208 const char * const i_pPassphrase
,
211 PKeyControl
* const pPKeyControl
= (PKeyControl
*) i_pPKeyImpl
;
213 FATAL_ASSERT( i_pPKeyImpl
&& i_pcBuffer
);
217 // create a mem bio from the given buffer
218 // Note that BIO_new_mem_buf() creates a BIO which never
219 // destroy the memory attached to it.
220 pMemBio
= BIO_new_mem_buf(i_pcBuffer
, i_iLength
);
223 //fixme: log -- no memory
226 bReturn
= LoadPrivateKeyFromBIO( pPKeyControl
,
227 pMemBio
, (char *)i_pPassphrase
);
235 * export the public key to a memory BIO, if error, return NULL
237 BIO
* SavePublicKeyToMemoryBIO(PKeyControl
* const i_pPublicKeyControl
)
244 pMemBio
= BIO_new(BIO_s_mem());
248 //fixme: log -- no memory
252 iReturn
= PEM_write_bio_PUBKEY(pMemBio
,
253 i_pPublicKeyControl
->pPKey
);
255 if(!iReturn
) // return 0: means error occurs
257 //fixme: log -- could not export private key
265 bool SavePublicKeyToBuffer(
266 void * const i_pPKeyImpl
,
267 unsigned char * const i_pcBuffer
,
269 int * const o_pActualLength
,
272 PKeyControl
* pPublicKeyControl
= (PKeyControl
*) i_pPKeyImpl
;
274 FATAL_ASSERT( pPublicKeyControl
&&
276 i_iBufferLength
> 0 &&
284 pMemBio
= SavePublicKeyToMemoryBIO( pPublicKeyControl
);
291 iLength
= BIO_get_mem_data(pMemBio
, &pData
);
293 // If the output buffer is a string, it needs to be NULL terminated
294 // So always append a NULL to the output
295 if(iLength
+ 1 > i_iBufferLength
)
300 // copy the data to given buffer
301 memcpy(i_pcBuffer
, pData
, iLength
);
302 // NULL terminate the string
303 i_pcBuffer
[iLength
] = '\0';
304 *o_pActualLength
= iLength
;
313 * import the public key from a BIO, if error, return NULL
315 bool LoadPublicKeyFromBIO(PKeyControl
* const io_pPublicKeyControl
,
318 EVP_PKEY
*pKey
= NULL
;
320 if(io_pPublicKeyControl
== NULL
)
330 if ( io_pPublicKeyControl
!= NULL
&& io_pPublicKeyControl
->pPKey
!= NULL
)
332 return false; // do not allow overwrite
335 pKey
= PEM_read_bio_PUBKEY(i_pBio
, NULL
, NULL
, NULL
);
338 // fixme: log: invalid public key format or passphrase
342 io_pPublicKeyControl
->pPKey
= pKey
;
347 bool LoadPublicKeyFromBuffer(
348 void * const i_pPublicKeyImpl
,
349 unsigned char * i_pcBuffer
,
353 PKeyControl
* const pPublicKeyControl
= (PKeyControl
*) i_pPublicKeyImpl
;
355 FATAL_ASSERT( i_pPublicKeyImpl
&& i_pcBuffer
);
359 // create a mem bio from the given buffer
360 // Note that BIO_new_mem_buf() creates a BIO which never
361 // destroy the memory attached to it.
362 pMemBio
= BIO_new_mem_buf(i_pcBuffer
, i_iLength
);
365 //fixme: log -- no memory
368 bReturn
= LoadPublicKeyFromBIO( pPublicKeyControl
,
376 bool PublicKeyEncrypt (int i_iLength
,
377 const unsigned char * const i_pcPlainText
,
378 unsigned char * const o_pcCypherText
,
379 int * const o_pActualLength
,
380 void * pPKeyControl
)
382 FATAL_ASSERT( i_pcPlainText
);
383 FATAL_ASSERT( o_pcCypherText
);
384 FATAL_ASSERT( o_pActualLength
);
385 FATAL_ASSERT( pPKeyControl
);
387 PKeyControl
*pKeyControl
= (PKeyControl
*)pPKeyControl
;
388 EVP_PKEY
* pEVP_PKEY
= pKeyControl
->pPKey
;
389 RSA
* pRSAPublicKey
= pEVP_PKEY
->pkey
.rsa
;
392 // RSA_print_fp(stdout, pRSAPublicKey, 0);
393 // printf("PublicKeyEncrypt(): RSA_size()=%d, cyphertextLen=%d\n",
394 // RSA_size(pRSAPublicKey),
398 *o_pActualLength
= RSA_public_encrypt(i_iLength
,
404 if ( *o_pActualLength
< 0 )