xref: /onnv-gate/usr/src/lib/libkmsagent/common/KMSAgentPKICert.cpp (revision 12720:3db6e0082404)
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 KMSAgentPKICert.cpp
28*12720SWyllys.Ingersoll@Sun.COM  *
29*12720SWyllys.Ingersoll@Sun.COM  *  This is an implementation of PKICommon.h CCertificate class.
30*12720SWyllys.Ingersoll@Sun.COM  */
31*12720SWyllys.Ingersoll@Sun.COM 
32*12720SWyllys.Ingersoll@Sun.COM #include <stdio.h>
33*12720SWyllys.Ingersoll@Sun.COM #include <memory.h>
34*12720SWyllys.Ingersoll@Sun.COM #include <time.h>
35*12720SWyllys.Ingersoll@Sun.COM #include <string.h>
36*12720SWyllys.Ingersoll@Sun.COM 
37*12720SWyllys.Ingersoll@Sun.COM #ifdef KMSUSERPKCS12
38*12720SWyllys.Ingersoll@Sun.COM #include <openssl/bio.h>
39*12720SWyllys.Ingersoll@Sun.COM #include <openssl/evp.h>
40*12720SWyllys.Ingersoll@Sun.COM #include <openssl/conf.h>
41*12720SWyllys.Ingersoll@Sun.COM #include <openssl/err.h>
42*12720SWyllys.Ingersoll@Sun.COM #include <openssl/asn1.h>
43*12720SWyllys.Ingersoll@Sun.COM #include <openssl/x509.h>
44*12720SWyllys.Ingersoll@Sun.COM #include <openssl/x509v3.h>
45*12720SWyllys.Ingersoll@Sun.COM #include <openssl/objects.h>
46*12720SWyllys.Ingersoll@Sun.COM #include <openssl/pem.h>
47*12720SWyllys.Ingersoll@Sun.COM #include <openssl/pkcs12.h>
48*12720SWyllys.Ingersoll@Sun.COM #endif
49*12720SWyllys.Ingersoll@Sun.COM 
50*12720SWyllys.Ingersoll@Sun.COM #include "SYSCommon.h"
51*12720SWyllys.Ingersoll@Sun.COM #include "KMSAgentPKICommon.h"
52*12720SWyllys.Ingersoll@Sun.COM #include "KMSAgentPKIimpl.h"
53*12720SWyllys.Ingersoll@Sun.COM 
54*12720SWyllys.Ingersoll@Sun.COM /////////////////////////////////////////////////////////////////////////
55*12720SWyllys.Ingersoll@Sun.COM // CCertificate
56*12720SWyllys.Ingersoll@Sun.COM //
CCertificate()57*12720SWyllys.Ingersoll@Sun.COM CCertificate::CCertificate()
58*12720SWyllys.Ingersoll@Sun.COM {
59*12720SWyllys.Ingersoll@Sun.COM    m_pCertImpl = InitializeCertImpl();
60*12720SWyllys.Ingersoll@Sun.COM 
61*12720SWyllys.Ingersoll@Sun.COM    FATAL_ASSERT( m_pCertImpl != NULL );
62*12720SWyllys.Ingersoll@Sun.COM }
63*12720SWyllys.Ingersoll@Sun.COM 
64*12720SWyllys.Ingersoll@Sun.COM 
~CCertificate()65*12720SWyllys.Ingersoll@Sun.COM CCertificate::~CCertificate()
66*12720SWyllys.Ingersoll@Sun.COM {
67*12720SWyllys.Ingersoll@Sun.COM    if ( m_pCertImpl != NULL )
68*12720SWyllys.Ingersoll@Sun.COM    {
69*12720SWyllys.Ingersoll@Sun.COM       FinalizeCertImpl( m_pCertImpl );
70*12720SWyllys.Ingersoll@Sun.COM    }
71*12720SWyllys.Ingersoll@Sun.COM }
72*12720SWyllys.Ingersoll@Sun.COM 
73*12720SWyllys.Ingersoll@Sun.COM /**
74*12720SWyllys.Ingersoll@Sun.COM  * Save - This OVERLOADED method saves the Cert into a file
75*12720SWyllys.Ingersoll@Sun.COM  *  @param i_pcFileName      - filename of file to save into
76*12720SWyllys.Ingersoll@Sun.COM  *  @param i_iFormat         - IGNORED
77*12720SWyllys.Ingersoll@Sun.COM  *
78*12720SWyllys.Ingersoll@Sun.COM  *  @returns bool   - success (true = successful)
79*12720SWyllys.Ingersoll@Sun.COM  */
Save(const char * const i_pcFileName,int i_iFormat)80*12720SWyllys.Ingersoll@Sun.COM bool CCertificate::Save( const char * const i_pcFileName,
81*12720SWyllys.Ingersoll@Sun.COM                          int i_iFormat )
82*12720SWyllys.Ingersoll@Sun.COM {
83*12720SWyllys.Ingersoll@Sun.COM    return SaveX509CertTofile( m_pCertImpl, i_pcFileName );
84*12720SWyllys.Ingersoll@Sun.COM }
85*12720SWyllys.Ingersoll@Sun.COM 
86*12720SWyllys.Ingersoll@Sun.COM /**
87*12720SWyllys.Ingersoll@Sun.COM  *  Save - This OVERLOADED method saves the Cert into a buffer
88*12720SWyllys.Ingersoll@Sun.COM  *  @param i_pcBuffer       - buffer to save into
89*12720SWyllys.Ingersoll@Sun.COM  *  @param i_BufferLength   - length of buffer to save
90*12720SWyllys.Ingersoll@Sun.COM  *  @param o_pActualLength  - length of buffer saved
91*12720SWyllys.Ingersoll@Sun.COM  *  @param i_iFormat         - IGNORED
92*12720SWyllys.Ingersoll@Sun.COM  *
93*12720SWyllys.Ingersoll@Sun.COM  *  @returns bool   - success (true = successful)
94*12720SWyllys.Ingersoll@Sun.COM  */
Save(unsigned char * const i_pcBuffer,int i_iBufferLength,int * const o_pActualLength,int i_iFormat)95*12720SWyllys.Ingersoll@Sun.COM bool CCertificate::Save( unsigned char * const      i_pcBuffer,
96*12720SWyllys.Ingersoll@Sun.COM                          int                        i_iBufferLength,
97*12720SWyllys.Ingersoll@Sun.COM                          int * const                o_pActualLength,
98*12720SWyllys.Ingersoll@Sun.COM                          int                        i_iFormat )
99*12720SWyllys.Ingersoll@Sun.COM {
100*12720SWyllys.Ingersoll@Sun.COM    return SaveX509CertToBuffer( m_pCertImpl,
101*12720SWyllys.Ingersoll@Sun.COM                                 i_pcBuffer,
102*12720SWyllys.Ingersoll@Sun.COM                                 i_iBufferLength,
103*12720SWyllys.Ingersoll@Sun.COM                                 o_pActualLength );
104*12720SWyllys.Ingersoll@Sun.COM }
105*12720SWyllys.Ingersoll@Sun.COM 
106*12720SWyllys.Ingersoll@Sun.COM /**
107*12720SWyllys.Ingersoll@Sun.COM  * Load
108*12720SWyllys.Ingersoll@Sun.COM  * This OVERLOADED method loads the Cert from a FILE
109*12720SWyllys.Ingersoll@Sun.COM  * @param i_pcFileName   - name of file to load from
110*12720SWyllys.Ingersoll@Sun.COM  * @param i_iFormat      -  IGNORED
111*12720SWyllys.Ingersoll@Sun.COM  *
112*12720SWyllys.Ingersoll@Sun.COM  * @returns bool   - success (true = successful)
113*12720SWyllys.Ingersoll@Sun.COM  */
114*12720SWyllys.Ingersoll@Sun.COM 
Load(const char * const i_pcFileName,int i_iFormat)115*12720SWyllys.Ingersoll@Sun.COM bool CCertificate::Load( const char * const i_pcFileName,
116*12720SWyllys.Ingersoll@Sun.COM                          int                i_iFormat )
117*12720SWyllys.Ingersoll@Sun.COM {
118*12720SWyllys.Ingersoll@Sun.COM    return LoadX509CertFromFile( m_pCertImpl, i_pcFileName );
119*12720SWyllys.Ingersoll@Sun.COM }
120*12720SWyllys.Ingersoll@Sun.COM 
121*12720SWyllys.Ingersoll@Sun.COM /**
122*12720SWyllys.Ingersoll@Sun.COM  * Load
123*12720SWyllys.Ingersoll@Sun.COM  * This OVERLOADED method loads the Cert from a buffer
124*12720SWyllys.Ingersoll@Sun.COM  * @param i_pcBuffer   - buffer to load from
125*12720SWyllys.Ingersoll@Sun.COM  * @param i_iLength    - amount to load from buffer
126*12720SWyllys.Ingersoll@Sun.COM  * @param i_iFormat    -  IGNORED
127*12720SWyllys.Ingersoll@Sun.COM  *
128*12720SWyllys.Ingersoll@Sun.COM  * @returns bool   - success (true = successful)
129*12720SWyllys.Ingersoll@Sun.COM  */
Load(unsigned char * const i_pcBuffer,int i_iLength,int i_iFormat)130*12720SWyllys.Ingersoll@Sun.COM bool CCertificate::Load( unsigned char * const i_pcBuffer,
131*12720SWyllys.Ingersoll@Sun.COM                          int                   i_iLength,
132*12720SWyllys.Ingersoll@Sun.COM                          int                   i_iFormat )
133*12720SWyllys.Ingersoll@Sun.COM {
134*12720SWyllys.Ingersoll@Sun.COM    return LoadX509CertFromBuffer( m_pCertImpl, i_pcBuffer, i_iLength );
135*12720SWyllys.Ingersoll@Sun.COM }
136*12720SWyllys.Ingersoll@Sun.COM 
137*12720SWyllys.Ingersoll@Sun.COM /**
138*12720SWyllys.Ingersoll@Sun.COM  * Dump
139*12720SWyllys.Ingersoll@Sun.COM  * dump the readable format to standard output
140*12720SWyllys.Ingersoll@Sun.COM  * @returns bool   - success (true = successful)
141*12720SWyllys.Ingersoll@Sun.COM  */
Dump()142*12720SWyllys.Ingersoll@Sun.COM bool CCertificate::Dump()
143*12720SWyllys.Ingersoll@Sun.COM {
144*12720SWyllys.Ingersoll@Sun.COM    return PrintX509Cert( m_pCertImpl );
145*12720SWyllys.Ingersoll@Sun.COM }
146*12720SWyllys.Ingersoll@Sun.COM 
147*12720SWyllys.Ingersoll@Sun.COM #ifdef KMSUSERPKCS12
148*12720SWyllys.Ingersoll@Sun.COM bool
LoadPKCS12CertAndKey(char * filename,int i_iFormat,CPrivateKey * i_pPrivateKey,char * i_pPassphrase)149*12720SWyllys.Ingersoll@Sun.COM CCertificate::LoadPKCS12CertAndKey(
150*12720SWyllys.Ingersoll@Sun.COM 	char *filename,
151*12720SWyllys.Ingersoll@Sun.COM 	int i_iFormat,
152*12720SWyllys.Ingersoll@Sun.COM         CPrivateKey *i_pPrivateKey,
153*12720SWyllys.Ingersoll@Sun.COM 	char *i_pPassphrase)
154*12720SWyllys.Ingersoll@Sun.COM {
155*12720SWyllys.Ingersoll@Sun.COM 	BIO *pFileBio= NULL;
156*12720SWyllys.Ingersoll@Sun.COM 	X509 *pRequest =NULL;
157*12720SWyllys.Ingersoll@Sun.COM 
158*12720SWyllys.Ingersoll@Sun.COM 	pFileBio = BIO_new(BIO_s_file());
159*12720SWyllys.Ingersoll@Sun.COM 	if (pFileBio == NULL)
160*12720SWyllys.Ingersoll@Sun.COM 		return false;
161*12720SWyllys.Ingersoll@Sun.COM 	if (!BIO_read_filename(pFileBio, filename)) {
162*12720SWyllys.Ingersoll@Sun.COM 		BIO_free(pFileBio);
163*12720SWyllys.Ingersoll@Sun.COM 		return (false);
164*12720SWyllys.Ingersoll@Sun.COM 	}
165*12720SWyllys.Ingersoll@Sun.COM 
166*12720SWyllys.Ingersoll@Sun.COM 	switch( i_iFormat ) {
167*12720SWyllys.Ingersoll@Sun.COM 		case FILE_FORMAT_DER:
168*12720SWyllys.Ingersoll@Sun.COM 
169*12720SWyllys.Ingersoll@Sun.COM 		pRequest=d2i_X509_bio(pFileBio, NULL);
170*12720SWyllys.Ingersoll@Sun.COM 		if (pRequest == NULL) {
171*12720SWyllys.Ingersoll@Sun.COM 			// fixme: log: invalid certificate format
172*12720SWyllys.Ingersoll@Sun.COM 			return false;
173*12720SWyllys.Ingersoll@Sun.COM 		}
174*12720SWyllys.Ingersoll@Sun.COM 		break;
175*12720SWyllys.Ingersoll@Sun.COM 
176*12720SWyllys.Ingersoll@Sun.COM 		case FILE_FORMAT_PEM:
177*12720SWyllys.Ingersoll@Sun.COM 
178*12720SWyllys.Ingersoll@Sun.COM 		pRequest=PEM_read_bio_X509(pFileBio, NULL, NULL, NULL);
179*12720SWyllys.Ingersoll@Sun.COM 		if (pRequest == NULL) {
180*12720SWyllys.Ingersoll@Sun.COM 			// fixme: log: invalid certificate format
181*12720SWyllys.Ingersoll@Sun.COM 			return false;
182*12720SWyllys.Ingersoll@Sun.COM 		}
183*12720SWyllys.Ingersoll@Sun.COM 		break;
184*12720SWyllys.Ingersoll@Sun.COM 
185*12720SWyllys.Ingersoll@Sun.COM 		case FILE_FORMAT_PKCS12:
186*12720SWyllys.Ingersoll@Sun.COM 		PKCS12* pPKCS12Request = d2i_PKCS12_bio(pFileBio, NULL);
187*12720SWyllys.Ingersoll@Sun.COM 		if (pPKCS12Request == NULL) {
188*12720SWyllys.Ingersoll@Sun.COM 			// fixme: log: invalid certificate format
189*12720SWyllys.Ingersoll@Sun.COM 			return false;
190*12720SWyllys.Ingersoll@Sun.COM 		}
191*12720SWyllys.Ingersoll@Sun.COM 
192*12720SWyllys.Ingersoll@Sun.COM 		// convert PKCS12 to X509
193*12720SWyllys.Ingersoll@Sun.COM 		EVP_PKEY *pKeyTemp = NULL;
194*12720SWyllys.Ingersoll@Sun.COM 		if (!PKCS12_parse(pPKCS12Request, i_pPassphrase,
195*12720SWyllys.Ingersoll@Sun.COM 		    &pKeyTemp, &pRequest, NULL)) {
196*12720SWyllys.Ingersoll@Sun.COM 			// fixme: log: invalid certificate format or passphrase
197*12720SWyllys.Ingersoll@Sun.COM 			PKCS12_free(pPKCS12Request);
198*12720SWyllys.Ingersoll@Sun.COM 			return false;
199*12720SWyllys.Ingersoll@Sun.COM 		}
200*12720SWyllys.Ingersoll@Sun.COM 
201*12720SWyllys.Ingersoll@Sun.COM 		if (pKeyTemp && i_pPrivateKey) {
202*12720SWyllys.Ingersoll@Sun.COM 			i_pPrivateKey->SetNative((void *)pKeyTemp);
203*12720SWyllys.Ingersoll@Sun.COM 		} else if (pKeyTemp)
204*12720SWyllys.Ingersoll@Sun.COM 			EVP_PKEY_free(pKeyTemp);
205*12720SWyllys.Ingersoll@Sun.COM 
206*12720SWyllys.Ingersoll@Sun.COM 		PKCS12_free(pPKCS12Request);
207*12720SWyllys.Ingersoll@Sun.COM 		break;
208*12720SWyllys.Ingersoll@Sun.COM 	}
209*12720SWyllys.Ingersoll@Sun.COM 	if (pRequest != NULL) {
210*12720SWyllys.Ingersoll@Sun.COM 		SetCert(m_pCertImpl, (void *)pRequest);
211*12720SWyllys.Ingersoll@Sun.COM 	}
212*12720SWyllys.Ingersoll@Sun.COM 
213*12720SWyllys.Ingersoll@Sun.COM 	return (true);
214*12720SWyllys.Ingersoll@Sun.COM }
215*12720SWyllys.Ingersoll@Sun.COM 
216*12720SWyllys.Ingersoll@Sun.COM void *
SaveCertToPKCS12MemoryBIO(CPrivateKey * i_pPrivateKey,char * i_sPassphrase)217*12720SWyllys.Ingersoll@Sun.COM CCertificate::SaveCertToPKCS12MemoryBIO(
218*12720SWyllys.Ingersoll@Sun.COM 	CPrivateKey* i_pPrivateKey,
219*12720SWyllys.Ingersoll@Sun.COM 	char *i_sPassphrase)
220*12720SWyllys.Ingersoll@Sun.COM {
221*12720SWyllys.Ingersoll@Sun.COM     BIO *pMemBio = NULL;
222*12720SWyllys.Ingersoll@Sun.COM     int iReturn;
223*12720SWyllys.Ingersoll@Sun.COM 
224*12720SWyllys.Ingersoll@Sun.COM     // create memory BIO
225*12720SWyllys.Ingersoll@Sun.COM     pMemBio = BIO_new(BIO_s_mem());
226*12720SWyllys.Ingersoll@Sun.COM 
227*12720SWyllys.Ingersoll@Sun.COM     if(pMemBio == NULL)
228*12720SWyllys.Ingersoll@Sun.COM     {
229*12720SWyllys.Ingersoll@Sun.COM         //fixme: log -- no memory
230*12720SWyllys.Ingersoll@Sun.COM         return NULL;
231*12720SWyllys.Ingersoll@Sun.COM     }
232*12720SWyllys.Ingersoll@Sun.COM 
233*12720SWyllys.Ingersoll@Sun.COM     PKCS12 *p12 = PKCS12_create(i_sPassphrase,
234*12720SWyllys.Ingersoll@Sun.COM                     NULL,
235*12720SWyllys.Ingersoll@Sun.COM                     (EVP_PKEY *)i_pPrivateKey->GetNative(),
236*12720SWyllys.Ingersoll@Sun.COM                     (X509 *)GetCert(m_pCertImpl),
237*12720SWyllys.Ingersoll@Sun.COM                     NULL,
238*12720SWyllys.Ingersoll@Sun.COM                     0,
239*12720SWyllys.Ingersoll@Sun.COM                     0,
240*12720SWyllys.Ingersoll@Sun.COM                     0,
241*12720SWyllys.Ingersoll@Sun.COM                     0,
242*12720SWyllys.Ingersoll@Sun.COM                     0);
243*12720SWyllys.Ingersoll@Sun.COM     if ( ! p12 )
244*12720SWyllys.Ingersoll@Sun.COM     {
245*12720SWyllys.Ingersoll@Sun.COM         return NULL;
246*12720SWyllys.Ingersoll@Sun.COM     }
247*12720SWyllys.Ingersoll@Sun.COM 
248*12720SWyllys.Ingersoll@Sun.COM     // now pMemBIO != NULL, remember to free it before exiting
249*12720SWyllys.Ingersoll@Sun.COM     iReturn = i2d_PKCS12_bio(pMemBio, p12);
250*12720SWyllys.Ingersoll@Sun.COM 
251*12720SWyllys.Ingersoll@Sun.COM     if(!iReturn) // return 0: means error occurs
252*12720SWyllys.Ingersoll@Sun.COM     {
253*12720SWyllys.Ingersoll@Sun.COM         //fixme: log -- could not export private key
254*12720SWyllys.Ingersoll@Sun.COM         BIO_free(pMemBio);
255*12720SWyllys.Ingersoll@Sun.COM         return NULL;
256*12720SWyllys.Ingersoll@Sun.COM     }
257*12720SWyllys.Ingersoll@Sun.COM 
258*12720SWyllys.Ingersoll@Sun.COM     return (void *)pMemBio;
259*12720SWyllys.Ingersoll@Sun.COM }
260*12720SWyllys.Ingersoll@Sun.COM 
261*12720SWyllys.Ingersoll@Sun.COM bool
SavePKCS12(unsigned char * i_pcBuffer,int i_iBufferLength,int * o_pActualLength,CPrivateKey * i_pPrivateKey,char * i_sPassphrase)262*12720SWyllys.Ingersoll@Sun.COM CCertificate::SavePKCS12(
263*12720SWyllys.Ingersoll@Sun.COM 	unsigned char *i_pcBuffer,
264*12720SWyllys.Ingersoll@Sun.COM 	int i_iBufferLength,
265*12720SWyllys.Ingersoll@Sun.COM 	int *o_pActualLength,
266*12720SWyllys.Ingersoll@Sun.COM 	CPrivateKey* i_pPrivateKey,
267*12720SWyllys.Ingersoll@Sun.COM 	char* i_sPassphrase )
268*12720SWyllys.Ingersoll@Sun.COM {
269*12720SWyllys.Ingersoll@Sun.COM     BIO *pMemBio = NULL;
270*12720SWyllys.Ingersoll@Sun.COM     char *pData = NULL;
271*12720SWyllys.Ingersoll@Sun.COM     int iLength;
272*12720SWyllys.Ingersoll@Sun.COM 
273*12720SWyllys.Ingersoll@Sun.COM     // sanity check
274*12720SWyllys.Ingersoll@Sun.COM     if(i_pcBuffer == NULL) return false;
275*12720SWyllys.Ingersoll@Sun.COM     if(i_iBufferLength <= 0) return false;
276*12720SWyllys.Ingersoll@Sun.COM     if(o_pActualLength == NULL) return false;
277*12720SWyllys.Ingersoll@Sun.COM 
278*12720SWyllys.Ingersoll@Sun.COM     // create memory BIO
279*12720SWyllys.Ingersoll@Sun.COM     pMemBio = (BIO *)SaveCertToPKCS12MemoryBIO(i_pPrivateKey, i_sPassphrase);
280*12720SWyllys.Ingersoll@Sun.COM 
281*12720SWyllys.Ingersoll@Sun.COM     if(pMemBio == NULL)
282*12720SWyllys.Ingersoll@Sun.COM     {
283*12720SWyllys.Ingersoll@Sun.COM         //fixme: log -- no memory
284*12720SWyllys.Ingersoll@Sun.COM         return false;
285*12720SWyllys.Ingersoll@Sun.COM     }
286*12720SWyllys.Ingersoll@Sun.COM 
287*12720SWyllys.Ingersoll@Sun.COM     iLength = BIO_get_mem_data(pMemBio, &pData);
288*12720SWyllys.Ingersoll@Sun.COM 
289*12720SWyllys.Ingersoll@Sun.COM     // If the output buffer is a string, it needs to be NULL terminated
290*12720SWyllys.Ingersoll@Sun.COM     // So always append a NULL to the output
291*12720SWyllys.Ingersoll@Sun.COM     if(iLength + 1 > i_iBufferLength)
292*12720SWyllys.Ingersoll@Sun.COM     {
293*12720SWyllys.Ingersoll@Sun.COM         //fixme: log -- buffer too small
294*12720SWyllys.Ingersoll@Sun.COM         BIO_free(pMemBio);
295*12720SWyllys.Ingersoll@Sun.COM         return false;
296*12720SWyllys.Ingersoll@Sun.COM     }
297*12720SWyllys.Ingersoll@Sun.COM     // copy the data to given buffer
298*12720SWyllys.Ingersoll@Sun.COM     memcpy(i_pcBuffer, pData, iLength);
299*12720SWyllys.Ingersoll@Sun.COM     // NULL terminate the string
300*12720SWyllys.Ingersoll@Sun.COM     i_pcBuffer[iLength] = '\0';
301*12720SWyllys.Ingersoll@Sun.COM     *o_pActualLength = iLength;
302*12720SWyllys.Ingersoll@Sun.COM 
303*12720SWyllys.Ingersoll@Sun.COM     // free memory
304*12720SWyllys.Ingersoll@Sun.COM     BIO_free(pMemBio);
305*12720SWyllys.Ingersoll@Sun.COM 
306*12720SWyllys.Ingersoll@Sun.COM     return true;
307*12720SWyllys.Ingersoll@Sun.COM }
308*12720SWyllys.Ingersoll@Sun.COM #endif /* PKCS12 */
309