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
37 typedef struct X509control
38 {
39 X509* pX509;
40 } X509control;
41
InitializeCertImpl()42 void * 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 */
SaveCertToMemoryBIO(X509control * i_pX509control)57 BIO* 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
SaveX509CertTofile(void * const i_pImplResource,const char * const i_pcFileName)84 bool 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
SaveX509CertToBuffer(void * const i_pImplResource,unsigned char * const i_pcBuffer,int i_iBufferLength,int * const o_pActualLength)124 bool 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 */
LoadCertFromBIO(X509control * i_pX509control,BIO * i_pBio)175 bool 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
LoadX509CertFromFile(void * const i_pImplResource,const char * const i_pcFileName)199 bool 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
LoadX509CertFromBuffer(void * const i_pImplResource,void * const i_pX509Cert,int i_iLength)235 bool 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
FinalizeCertImpl(void * i_pImplResource)265 void FinalizeCertImpl( void* i_pImplResource )
266 {
267 if ( i_pImplResource != NULL )
268 {
269 free(i_pImplResource);
270 }
271 }
272
PrintX509Cert(void * const i_pImplResource)273 bool 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
GetCert(void * i_pImplResource)301 void *GetCert(void* i_pImplResource )
302 {
303 X509control* pX509control = (X509control*)i_pImplResource;
304 return ((void *)pX509control->pX509);
305 }
306
SetCert(void * i_pImplResource,void * cert)307 void SetCert(void* i_pImplResource, void *cert)
308 {
309 X509control* pX509control = (X509control*)i_pImplResource;
310 pX509control->pX509 = (X509 *)cert;
311 return;
312 }
313 #endif
314