998 obsolete DMA driver interfaces should be removed
[illumos-gate.git] / usr / src / lib / libkmsagent / common / KMSAgentPKIKeyOpenSSL.cpp
blobd66f1852965e532c512f2778a8b33d5bd7f01432
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
26 /**
27 * \file KMSAgentPKIKeyOpenSSL.cpp
30 #include <stdio.h>
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
40 EVP_PKEY* pPKey;
41 } PKeyControl;
43 void * InitializePKeyImpl()
45 PKeyControl *pPKeyControl =
46 (PKeyControl *) malloc(sizeof(PKeyControl));
48 if ( pPKeyControl != NULL )
50 pPKeyControl->pPKey = NULL;
53 return pPKeyControl;
56 void FinalizePKeyImpl( void * i_pPKeyImpl )
58 if ( i_pPKeyImpl != NULL )
60 free(i_pPKeyImpl);
64 #ifdef KMSUSERPKCS12
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;
73 return;
75 #endif
77 /**
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)
83 BIO *pMemBio = NULL;
84 const EVP_CIPHER *pCipher = NULL;
85 int iReturn;
87 // set cipher, if passphrase is not empty
88 if(i_pPassphrase != NULL)
90 pCipher= EVP_des_ede3_cbc(); //NULL means no password protection
93 // create memory BIO
94 pMemBio = BIO_new(BIO_s_mem());
96 if(pMemBio == NULL)
98 //fixme: log -- no memory
99 return NULL;
102 iReturn = PEM_write_bio_PrivateKey
103 (pMemBio,
104 i_pPKeyControl->pPKey,
105 pCipher,
106 NULL,0,NULL, (char*) i_pPassphrase);
108 if(!iReturn) // return 0: means error occurs
110 //fixme: log -- could not export private key
111 BIO_free(pMemBio);
112 return NULL;
115 return pMemBio;
118 bool SavePrivateKeyToBuffer(
119 void * const i_pPKeyImpl,
120 unsigned char * const i_pcBuffer,
121 int i_iBufferLength,
122 int * const o_pActualLength,
123 const char * const i_pPassphrase,
124 int i_iFormat)
126 PKeyControl* pPKeyControl = (PKeyControl*) i_pPKeyImpl;
128 FATAL_ASSERT( pPKeyControl &&
129 i_pcBuffer &&
130 i_iBufferLength > 0 &&
131 o_pActualLength );
133 BIO *pMemBio = NULL;
134 char *pData = NULL;
135 int iLength;
137 // create memory BIO
138 pMemBio = SavePrivateKeyToMemoryBIO( pPKeyControl, i_pPassphrase );
140 if(pMemBio == NULL)
142 //fixme: log -- no memory
143 return false;
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
153 BIO_free(pMemBio);
154 return false;
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;
162 // free memory
163 BIO_free(pMemBio);
165 return true;
169 * import the private key from a BIO, if error, return NULL
171 bool LoadPrivateKeyFromBIO(PKeyControl* const io_pPKeyControl,
172 BIO *i_pBio,
173 char *i_pPassphrase )
175 if (io_pPKeyControl == NULL)
177 return false;
180 EVP_PKEY *pKey = NULL;
182 if(i_pBio == NULL)
184 return false;
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);
193 if (pKey == NULL)
195 // fixme: log: invalid private key format or passphrase
196 return false;
199 io_pPKeyControl->pPKey = pKey;
201 return true;
204 bool LoadPrivateKeyFromBuffer(
205 void * const i_pPKeyImpl,
206 unsigned char * i_pcBuffer,
207 int i_iLength,
208 const char * const i_pPassphrase,
209 int i_iFormat)
211 PKeyControl* const pPKeyControl = (PKeyControl*) i_pPKeyImpl;
213 FATAL_ASSERT( i_pPKeyImpl && i_pcBuffer );
215 bool bReturn;
216 BIO *pMemBio;
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);
221 if (pMemBio == NULL)
223 //fixme: log -- no memory
224 return false;
226 bReturn = LoadPrivateKeyFromBIO( pPKeyControl,
227 pMemBio, (char *)i_pPassphrase );
229 BIO_free(pMemBio);
231 return bReturn;
235 * export the public key to a memory BIO, if error, return NULL
237 BIO* SavePublicKeyToMemoryBIO(PKeyControl* const i_pPublicKeyControl )
239 BIO *pMemBio = NULL;
241 int iReturn;
243 // create memory BIO
244 pMemBio = BIO_new(BIO_s_mem());
246 if(pMemBio == NULL)
248 //fixme: log -- no memory
249 return NULL;
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
258 BIO_free(pMemBio);
259 return NULL;
262 return pMemBio;
265 bool SavePublicKeyToBuffer(
266 void * const i_pPKeyImpl,
267 unsigned char * const i_pcBuffer,
268 int i_iBufferLength,
269 int * const o_pActualLength,
270 int i_iFormat)
272 PKeyControl* pPublicKeyControl = (PKeyControl*) i_pPKeyImpl;
274 FATAL_ASSERT( pPublicKeyControl &&
275 i_pcBuffer &&
276 i_iBufferLength > 0 &&
277 o_pActualLength );
279 BIO *pMemBio = NULL;
280 char *pData = NULL;
281 int iLength;
283 // create memory BIO
284 pMemBio = SavePublicKeyToMemoryBIO( pPublicKeyControl );
286 if(pMemBio == NULL)
288 return false;
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)
297 BIO_free(pMemBio);
298 return false;
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;
306 // free memory
307 BIO_free(pMemBio);
309 return true;
313 * import the public key from a BIO, if error, return NULL
315 bool LoadPublicKeyFromBIO(PKeyControl* const io_pPublicKeyControl,
316 BIO *i_pBio )
318 EVP_PKEY *pKey = NULL;
320 if(io_pPublicKeyControl == NULL)
322 return false;
325 if(i_pBio == NULL)
327 return false;
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);
336 if (pKey == NULL)
338 // fixme: log: invalid public key format or passphrase
339 return false;
342 io_pPublicKeyControl->pPKey = pKey;
344 return true;
347 bool LoadPublicKeyFromBuffer(
348 void * const i_pPublicKeyImpl,
349 unsigned char * i_pcBuffer,
350 int i_iLength,
351 int i_iFormat)
353 PKeyControl* const pPublicKeyControl = (PKeyControl*) i_pPublicKeyImpl;
355 FATAL_ASSERT( i_pPublicKeyImpl && i_pcBuffer );
357 bool bReturn;
358 BIO *pMemBio;
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);
363 if (pMemBio == NULL)
365 //fixme: log -- no memory
366 return false;
368 bReturn = LoadPublicKeyFromBIO( pPublicKeyControl,
369 pMemBio );
371 BIO_free(pMemBio);
373 return bReturn;
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;
391 //#if defined(DEBUG)
392 // RSA_print_fp(stdout, pRSAPublicKey, 0);
393 // printf("PublicKeyEncrypt(): RSA_size()=%d, cyphertextLen=%d\n",
394 // RSA_size(pRSAPublicKey),
395 // i_iLength);
396 //#endif
398 *o_pActualLength = RSA_public_encrypt(i_iLength,
399 i_pcPlainText,
400 o_pcCypherText,
401 pRSAPublicKey,
402 RSA_PKCS1_PADDING);
404 if ( *o_pActualLength < 0 )
406 return false;
408 else
410 return true;