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
InitializePKeyImpl()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
FinalizePKeyImpl(void * i_pPKeyImpl)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
GetPKey(void * i_pPKeyImpl)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
SetPKey(void * i_pPKeyImpl,void * pKey)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 */
SavePrivateKeyToMemoryBIO(PKeyControl * const i_pPKeyControl,const char * const i_pPassphrase)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
SavePrivateKeyToBuffer(void * const i_pPKeyImpl,unsigned char * const i_pcBuffer,int i_iBufferLength,int * const o_pActualLength,const char * const i_pPassphrase,int i_iFormat)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 */
LoadPrivateKeyFromBIO(PKeyControl * const io_pPKeyControl,BIO * i_pBio,char * i_pPassphrase)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
LoadPrivateKeyFromBuffer(void * const i_pPKeyImpl,unsigned char * i_pcBuffer,int i_iLength,const char * const i_pPassphrase,int i_iFormat)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 */
SavePublicKeyToMemoryBIO(PKeyControl * const i_pPublicKeyControl)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
SavePublicKeyToBuffer(void * const i_pPKeyImpl,unsigned char * const i_pcBuffer,int i_iBufferLength,int * const o_pActualLength,int i_iFormat)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 */
LoadPublicKeyFromBIO(PKeyControl * const io_pPublicKeyControl,BIO * i_pBio)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
LoadPublicKeyFromBuffer(void * const i_pPublicKeyImpl,unsigned char * i_pcBuffer,int i_iLength,int i_iFormat)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
PublicKeyEncrypt(int i_iLength,const unsigned char * const i_pcPlainText,unsigned char * const o_pcCypherText,int * const o_pActualLength,void * pPKeyControl)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