Fix C language APIs of client
authoryuseok.jeon <yuseok.jeon@samsung.com>
Thu, 10 Jul 2014 06:29:39 +0000 (15:29 +0900)
committerBartlomiej Grzelewski <b.grzelewski@samsung.com>
Fri, 12 Sep 2014 12:58:50 +0000 (14:58 +0200)
Change-Id: I0fa3f99328d61f67ca97ac7bbdc851d09dbe5002

src/include/ckmc/ckmc-manager.h
src/include/ckmc/ckmc-type.h
src/manager/client-capi/ckmc-manager.cpp
src/manager/client-capi/ckmc-type.cpp

index 2e5cac8..239d4f1 100644 (file)
@@ -24,6 +24,7 @@
 #ifndef CKMC_MANAGER_H
 #define CKMC_MANAGER_H
 
+#include <stddef.h>
 #include <sys/types.h>
 #include <ckmc/ckmc-type.h>
 
@@ -35,21 +36,21 @@ extern "C" {
 int ckm_save_key(const char *alias, const ckm_key key, const ckm_policy policy);
 int ckm_remove_key(const char *alias);
 int ckm_get_key(const char *alias, const char *password, ckm_key **key);
-int ckm_get_key_alias_list(const ckm_alias_list** alias_list);
+int ckm_get_key_alias_list(ckm_alias_list** alias_list);
 
 int ckm_save_cert(const char *alias, const ckm_cert cert, const ckm_policy policy);
 int ckm_remove_cert(const char *alias);
 int ckm_get_cert(const char *alias, const char *password, const ckm_cert **cert);
-int ckm_get_cert_alias_list(const ckm_alias_list** alias_list);
+int ckm_get_cert_alias_list(ckm_alias_list** alias_list);
 
 int ckm_save_data(const char *alias, ckm_raw_buffer data, const ckm_policy policy);
 int ckm_remove_data(const char *alias);
 int ckm_get_data(const char *alias, const char *password, ckm_raw_buffer **data);
-int ckm_get_data_alias_list(const ckm_alias_list** alias_list);
+int ckm_get_data_alias_list(ckm_alias_list** alias_list);
 
 
 // crypto functions
-int ckm_create_key_pair_rsa(const int size, const char *private_key_alias, const char *public_key_alias, const ckm_policy policy_private_key, const ckm_policy policy_public_key);
+int ckm_create_key_pair_rsa(const size_t size, const char *private_key_alias, const char *public_key_alias, const ckm_policy policy_private_key, const ckm_policy policy_public_key);
 int ckm_create_key_pair_ecdsa(const ckm_ec_type type, const char *private_key_alias, const char *public_key_alias, const ckm_policy policy_private_key, const ckm_policy policy_public_key);
 int ckm_create_signature(const char *private_key_alias, const char *password, const ckm_raw_buffer message, const ckm_hash_algo hash, const ckm_rsa_padding_algo padding, ckm_raw_buffer **signature);
 int ckm_verify_signature(const char *public_key_alias, const char *password, const ckm_raw_buffer message, const ckm_raw_buffer signature, const ckm_hash_algo hash, const ckm_rsa_padding_algo padding);
index 468875e..c6d762b 100644 (file)
@@ -23,6 +23,7 @@
 #ifndef CKMC_TYPE_H
 #define CKMC_TYPE_H
 
+#include <stddef.h>
 
 #define KEY_MANAGER_CAPI __attribute__((visibility("default")))
 
@@ -65,18 +66,13 @@ typedef enum ckm_hash_algo_t {
 } ckm_hash_algo;
 
 typedef enum ckm_rsa_padding_algo_t {
-    CKM_XRSA_PKCS1_PADDING,
-    CKM_XRSA_X931_PADDING
+    CKM_PKCS1_PADDING,
+    CKM_X931_PADDING
 } ckm_rsa_padding_algo;
 
-typedef enum ckm_cert_form_t {
-    CKM_CERT_FORM_DER,
-    CKM_CERT_FORM_DER_BASE64
-} ckm_cert_form;
-
 typedef struct ckm_raw_buff_t{
        unsigned char* data;
-       unsigned int   size;
+       size_t         size;
 } ckm_raw_buffer;
 
 typedef struct ckm_policy_t {
@@ -87,15 +83,15 @@ typedef struct ckm_policy_t {
 
 typedef struct ckm_key_t {
        unsigned char* raw_key;
-       unsigned int   key_size;
+       size_t         key_size;
        ckm_key_type   key_type;
        char*          password;  // byte array used to encrypt data inside CKM
 } ckm_key;
 
 typedef struct ckm_cert_t {
-       unsigned char* raw_cert;
-       unsigned int   cert_size;
-       ckm_cert_form  data_format;
+       unsigned char*  raw_cert;
+       size_t          cert_size;
+       ckm_data_format data_format;
 } ckm_cert;
 
 typedef struct ckm_alias_list_t {
@@ -109,13 +105,13 @@ typedef struct ckm_cert_list_t {
 } ckm_cert_list;
 
 
-ckm_key *ckm_key_new(unsigned char *raw_key, unsigned int key_size, ckm_key_type key_type, char *password);
+ckm_key *ckm_key_new(unsigned char *raw_key, size_t key_size, ckm_key_type key_type, char *password);
 void ckm_key_free(ckm_key *key);
 
-ckm_raw_buffer * ckm_buffer_new(unsigned char *data, unsigned int size);
+ckm_raw_buffer * ckm_buffer_new(unsigned char *data, size_t size);
 void ckm_buffer_free(ckm_raw_buffer *buffer);
 
-ckm_cert *ckm_cert_new(unsigned char *raw_cert, unsigned int cert_size, ckm_cert_form data_format);
+ckm_cert *ckm_cert_new(unsigned char *raw_cert, size_t cert_size, ckm_data_format data_format);
 
 void ckm_cert_free(ckm_cert *cert);
 
index 7e2d1a3..fd0c53f 100644 (file)
@@ -25,6 +25,7 @@
 #include <ckmc/ckmc-type.h>
 #include <ckmc/ckmc-manager.h>
 #include <ckmc/ckmc-error.h>
+#include <iostream>
 
 bool _toBool(ckm_bool ckmBool)
 {
@@ -34,6 +35,13 @@ bool _toBool(ckm_bool ckmBool)
        return false;
 }
 
+std::string _tostring(const char *str)
+{
+       if(str == NULL)
+               return std::string();
+       return std::string(str);
+}
+
 CKM::Certificate _toCkmCertificate(const ckm_cert *cert)
 {
        CKM::RawBuffer buffer(cert->raw_cert, cert->raw_cert + cert->cert_size);
@@ -50,7 +58,7 @@ ckm_cert_list *_toNewCkmCertList(CKM::CertificateVector &certVector)
        for(it = certVector.begin(); it != certVector.end(); it++) {
                CKM::RawBuffer rawBuffer = it->getDER();
                unsigned char *rawCert = reinterpret_cast<unsigned char*>(rawBuffer.data());
-               ckm_cert *pcert = ckm_cert_new( rawCert, rawBuffer.size(), CKM_CERT_FORM_DER);
+               ckm_cert *pcert = ckm_cert_new( rawCert, rawBuffer.size(), CKM_FORM_DER);
                if(pcert == NULL) {
                        return NULL;
                }
@@ -78,10 +86,9 @@ int ckm_save_key(const char *alias, const ckm_key key, const ckm_policy policy)
                        return CKM_API_ERROR_INPUT_PARAM;
        }
        CKM::RawBuffer buffer(key.raw_key, key.raw_key + key.key_size);
-       std::string password(key.password);
-       CKM::Key ckmKey(buffer,password);
+       CKM::Key ckmKey(buffer, _tostring(key.password));
 
-       CKM::Policy storePolicy(policy.password, _toBool(policy.extractable), _toBool(policy.restricted));
+       CKM::Policy storePolicy(_tostring(policy.password), _toBool(policy.extractable), _toBool(policy.restricted));
 
        return mgr.saveKey(ckmAlias, ckmKey, storePolicy);
 }
@@ -112,7 +119,7 @@ int ckm_get_key(const char *alias, const char *password, ckm_key **key)
        CKM::Alias ckmAlias(alias);
 
        CKM::Manager mgr;
-       if( (ret = mgr.getKey(ckmAlias, std::string(password), ckmKey)) != CKM_API_SUCCESS) {
+       if( (ret = mgr.getKey(ckmAlias, _tostring(password), ckmKey)) != CKM_API_SUCCESS) {
                return ret;
        }
 
@@ -127,7 +134,7 @@ int ckm_get_key(const char *alias, const char *password, ckm_key **key)
 }
 
 KEY_MANAGER_CAPI
-int ckm_get_key_alias_list(const ckm_alias_list** alias_list)
+int ckm_get_key_alias_list(ckm_alias_list** alias_list)
 {
        int ret;
        CKM::Key ckmKey;
@@ -165,7 +172,7 @@ int ckm_save_cert(const char *alias, const ckm_cert cert, const ckm_policy polic
        }
        CKM::Certificate ckmCert = _toCkmCertificate(&cert);
 
-       CKM::Policy storePolicy(policy.password, _toBool(policy.extractable), _toBool(policy.restricted));
+       CKM::Policy storePolicy(_tostring(policy.password), _toBool(policy.extractable), _toBool(policy.restricted));
 
        CKM::Manager mgr;
        return mgr.saveCertificate(ckmAlias, ckmCert, storePolicy);
@@ -195,12 +202,12 @@ int ckm_get_cert(const char *alias, const char *password, const ckm_cert **cert)
        CKM::Alias ckmAlias(alias);
 
        CKM::Manager mgr;
-       if( (ret = mgr.getCertificate(ckmAlias, std::string(password), ckmCert)) != CKM_API_SUCCESS) {
+       if( (ret = mgr.getCertificate(ckmAlias, _tostring(password), ckmCert)) != CKM_API_SUCCESS) {
                return ret;
        }
 
        unsigned char *rawCert = reinterpret_cast<unsigned char*>(ckmCert.getDER().data());
-       *cert = ckm_cert_new( rawCert, ckmCert.getDER().size(), CKM_CERT_FORM_DER);
+       *cert = ckm_cert_new( rawCert, ckmCert.getDER().size(), CKM_FORM_DER);
        if(*cert == NULL) {
                return CKM_API_ERROR_OUT_OF_MEMORY;
        }else {
@@ -209,7 +216,7 @@ int ckm_get_cert(const char *alias, const char *password, const ckm_cert **cert)
 }
 
 KEY_MANAGER_CAPI
-int ckm_get_cert_alias_list(const ckm_alias_list** alias_list) {
+int ckm_get_cert_alias_list(ckm_alias_list** alias_list) {
        int ret;
        CKM::Key ckmKey;
 
@@ -246,7 +253,7 @@ int ckm_save_data(const char *alias, ckm_raw_buffer data, const ckm_policy polic
        }
        CKM::RawBuffer buffer(data.data, data.data + data.size);
 
-       CKM::Policy storePolicy(policy.password, _toBool(policy.extractable), _toBool(policy.restricted));
+       CKM::Policy storePolicy(_tostring(policy.password), _toBool(policy.extractable), _toBool(policy.restricted));
 
        CKM::Manager mgr;
        return mgr.saveData(ckmAlias, buffer, storePolicy);
@@ -276,7 +283,7 @@ int ckm_get_data(const char *alias, const char *password, ckm_raw_buffer **data)
        CKM::Alias ckmAlias(alias);
 
        CKM::Manager mgr;
-       if( (ret = mgr.getData(ckmAlias, std::string(password), ckmBuff)) != CKM_API_SUCCESS) {
+       if( (ret = mgr.getData(ckmAlias, _tostring(password), ckmBuff)) != CKM_API_SUCCESS) {
                return ret;
        }
 
@@ -290,7 +297,7 @@ int ckm_get_data(const char *alias, const char *password, ckm_raw_buffer **data)
 }
 
 KEY_MANAGER_CAPI
-int ckm_get_data_alias_list(const ckm_alias_list** alias_list){
+int ckm_get_data_alias_list(ckm_alias_list** alias_list){
        int ret;
        CKM::Key ckmKey;
 
@@ -315,20 +322,26 @@ int ckm_get_data_alias_list(const ckm_alias_list** alias_list){
 }
 
 KEY_MANAGER_CAPI
-int ckm_create_key_pair_rsa(const int size,
+int ckm_create_key_pair_rsa(const size_t size,
                                                        const char *private_key_alias,
                                                        const char *public_key_alias,
                                                        const ckm_policy policy_private_key,
                                                        const ckm_policy policy_public_key)
 {
+       int ret;
        CKM::Manager mgr;
 
        CKM::Alias ckmPrivakeKeyAlias(private_key_alias);
        CKM::Alias ckmPublicKeyAlias(public_key_alias);
-       CKM::Policy ckmPrivateKeyPolicy(policy_private_key.password, _toBool(policy_private_key.extractable), _toBool(policy_private_key.restricted));
-       CKM::Policy ckmPublicKeyPolicy(policy_public_key.password, _toBool(policy_public_key.extractable), _toBool(policy_public_key.restricted));
+       CKM::Policy ckmPrivateKeyPolicy(_tostring(policy_private_key.password), _toBool(policy_private_key.extractable), _toBool(policy_private_key.restricted));
+       CKM::Policy ckmPublicKeyPolicy(_tostring(policy_public_key.password), _toBool(policy_public_key.extractable), _toBool(policy_public_key.restricted));
+
+       if( (ret = mgr.createKeyPairRSA(size, ckmPrivakeKeyAlias, ckmPublicKeyAlias, ckmPrivateKeyPolicy, ckmPublicKeyPolicy))
+                       != CKM_API_SUCCESS) {
+               return ret;
+       }
 
-    return mgr.createKeyPairRSA(size, ckmPrivakeKeyAlias, ckmPublicKeyAlias, ckmPrivateKeyPolicy, ckmPublicKeyPolicy);
+       return CKM_API_SUCCESS;
 }
 
 KEY_MANAGER_CAPI
@@ -338,15 +351,21 @@ int ckm_create_key_pair_ecdsa(const ckm_ec_type type,
                                                        const ckm_policy policy_private_key,
                                                        const ckm_policy policy_public_key)
 {
+       int ret;
        CKM::Manager mgr;
 
        CKM::ElipticCurve ckmType = static_cast<CKM::ElipticCurve>(static_cast<int>(type));
        CKM::Alias ckmPrivakeKeyAlias(private_key_alias);
        CKM::Alias ckmPublicKeyAlias(public_key_alias);
-       CKM::Policy ckmPrivateKeyPolicy(policy_private_key.password, _toBool(policy_private_key.extractable), _toBool(policy_private_key.restricted));
-       CKM::Policy ckmPublicKeyPolicy(policy_public_key.password, _toBool(policy_public_key.extractable), _toBool(policy_public_key.restricted));
+       CKM::Policy ckmPrivateKeyPolicy(_tostring(policy_private_key.password), _toBool(policy_private_key.extractable), _toBool(policy_private_key.restricted));
+       CKM::Policy ckmPublicKeyPolicy(_tostring(policy_public_key.password), _toBool(policy_public_key.extractable), _toBool(policy_public_key.restricted));
+
+       if( (ret - mgr.createKeyPairECDSA(ckmType, ckmPrivakeKeyAlias, ckmPublicKeyAlias, ckmPrivateKeyPolicy, ckmPublicKeyPolicy))
+                       != CKM_API_SUCCESS) {
+               return ret;
+       }
 
-       return mgr.createKeyPairECDSA(ckmType, ckmPrivakeKeyAlias, ckmPublicKeyAlias, ckmPrivateKeyPolicy, ckmPublicKeyPolicy);
+       return CKM_API_SUCCESS;
 }
 
 KEY_MANAGER_CAPI
@@ -368,7 +387,7 @@ int ckm_create_signature(const char *private_key_alias,
 
        if( (ret = mgr.createSignature(
                        ckmPrivakeKeyAlias,
-                       password,
+                       _tostring(password),
                        ckmMessage,
                        ckmHashAlgo,
                        ckmPadding,
@@ -406,7 +425,7 @@ int ckm_verify_signature(const char *public_key_alias,
 
        if( (ret = mgr.verifySignature(
                        ckmPublicKeyAlias,
-                       password,
+                       _tostring(password),
                        ckmMessage,
                        ckmSignature,
                        ckmHashAlgo,
@@ -424,13 +443,11 @@ int ckm_get_cert_chain(const ckm_cert *cert, const ckm_cert_list *untrustedcerts
        CKM::Manager mgr;
        CKM::CertificateVector ckmCertChain;
 
-
        if(cert->raw_cert == NULL || cert->cert_size <= 0) {
                return CKM_API_ERROR_INPUT_PARAM;
        }
-       CKM::RawBuffer buffer(cert->raw_cert, cert->raw_cert + cert->cert_size);
-       CKM::DataFormat dataFormat = static_cast<CKM::DataFormat>(static_cast<int>(cert->data_format));
-       CKM::Certificate ckmCert(buffer, dataFormat);
+
+       CKM::Certificate ckmCert = _toCkmCertificate(cert);
 
        CKM::CertificateVector ckmUntrustedCerts;
        if(untrustedcerts != NULL) {
@@ -441,14 +458,16 @@ int ckm_get_cert_chain(const ckm_cert *cert, const ckm_cert_list *untrustedcerts
                        next = current->next;
 
                        if(current->cert == NULL){
-                               return CKM_API_ERROR_INPUT_PARAM;
+                               continue;
                        }
-                       CKM::Certificate ckmCert = _toCkmCertificate(current->cert);
-                       ckmUntrustedCerts.push_back(ckmCert);
+
+                       CKM::Certificate tmpCkmCert = _toCkmCertificate(current->cert);
+                       ckmUntrustedCerts.push_back(tmpCkmCert);
                }while(next != NULL);
        }
 
-       if( (ret = mgr.getCertificateChain(ckmCert, ckmUntrustedCerts, ckmCertChain)) != CKM_API_SUCCESS) {
+       ret = mgr.getCertificateChain(ckmCert, ckmUntrustedCerts, ckmCertChain);
+       if( ret != CKM_API_SUCCESS) {
                return ret;
        }
 
index 56dcfa7..9ca611c 100644 (file)
@@ -22,7 +22,9 @@
 
 
 #include <string.h>
+#include <stdio.h>
 #include <stdlib.h>
+#include <ckm/ckm-type.h>
 #include <ckmc/ckmc-type.h>
 #include <ckmc/ckmc-error.h>
 #include <openssl/x509v3.h>
@@ -34,7 +36,7 @@ int _ckm_load_cert_from_x509(X509 *xCert, ckm_cert **cert);
 
 
 KEY_MANAGER_CAPI
-ckm_key *ckm_key_new(unsigned char *raw_key, unsigned int key_size, ckm_key_type key_type, char *password)
+ckm_key *ckm_key_new(unsigned char *raw_key, size_t key_size, ckm_key_type key_type, char *password)
 {
        ckm_key *pkey = new ckm_key;
        if(pkey == NULL)
@@ -74,14 +76,16 @@ void ckm_key_free(ckm_key *key)
 
        if(key->password != NULL)
                free(key->password);
-       if(key->raw_key != NULL)
+       if(key->raw_key != NULL) {
+               memset(key->raw_key, 0, key->key_size);
                free(key->raw_key);
+       }
 
        free(key);
 }
 
 KEY_MANAGER_CAPI
-ckm_raw_buffer * ckm_buffer_new(unsigned char *data, unsigned int size)
+ckm_raw_buffer * ckm_buffer_new(unsigned char *data, size_t size)
 {
        ckm_raw_buffer *pbuff = new ckm_raw_buffer;
        if(pbuff == NULL)
@@ -105,13 +109,15 @@ void ckm_buffer_free(ckm_raw_buffer *buffer)
        if(buffer == NULL)
                return;
 
-       if(buffer->data != NULL)
+       if(buffer->data != NULL) {
+               memset(buffer->data, 0, buffer->size);
                free(buffer->data);
+       }
        free(buffer);
 }
 
 KEY_MANAGER_CAPI
-ckm_cert *ckm_cert_new(unsigned char *raw_cert, unsigned int cert_size, ckm_cert_form data_format)
+ckm_cert *ckm_cert_new(unsigned char *raw_cert, size_t cert_size, ckm_data_format data_format)
 {
        ckm_cert *pcert = new ckm_cert;
        if(pcert == NULL)
@@ -166,8 +172,8 @@ int ckm_load_from_pkcs12_file(const char *file_path, const char *passphrase, ckm
                X509* x509Cert;
                STACK_OF(X509)* ca;
 
-       public:
                int ret;
+       public:
                ckm_key *retPrivateKey;
                ckm_cert *retCkmCert;
                ckm_cert_list *retCaCertList;
@@ -202,7 +208,7 @@ int ckm_load_from_pkcs12_file(const char *file_path, const char *passphrase, ckm
                                if(retCkmCert != NULL)
                                        ckm_cert_free(retCkmCert);
                                if(retCaCertList != NULL)
-                                       ckm_cert_list_free(retCaCertList);
+                                       ckm_cert_list_all_free(retCaCertList);
                        }
                };
 
@@ -231,15 +237,17 @@ int ckm_load_from_pkcs12_file(const char *file_path, const char *passphrase, ckm
                }
 
                int toCkmKey() {
-                       int prikeyLen = 0;
-                       if((prikeyLen = i2d_PrivateKey(pkey, NULL)) < 0) {
-                               return CKM_API_ERROR_OUT_OF_MEMORY;
-                       }
-                       unsigned char arrayPrikey[sizeof(unsigned char) * prikeyLen];
-                       unsigned char *pPrikey = arrayPrikey;
-                       if((prikeyLen = i2d_PrivateKey(pkey, &pPrikey)) < 0) {
-                               return CKM_API_ERROR_OUT_OF_MEMORY;
-                       }
+                       BIO *bkey = BIO_new(BIO_s_mem());
+
+                       i2d_PrivateKey_bio(bkey, pkey);
+
+                   CKM::RawBuffer output(8196);
+                   int size = BIO_read(bkey, output.data(), output.size());
+                       BIO_free_all(bkey);
+                   if (size <= 0) {
+                       return CKM_API_ERROR_INVALID_FORMAT;
+                   }
+                   output.resize(size);
 
                        int type = EVP_PKEY_type(pkey->type);
                        ckm_key_type key_type = CKM_KEY_NONE;
@@ -256,7 +264,8 @@ int ckm_load_from_pkcs12_file(const char *file_path, const char *passphrase, ckm
                        }
 
                        char *nullPassword = NULL;
-                       retPrivateKey = ckm_key_new(pPrikey, sizeof(unsigned char) * prikeyLen, key_type, nullPassword);
+
+                       retPrivateKey = ckm_key_new(output.data(), size, key_type, nullPassword);
 
                        return CKM_API_SUCCESS;
                }
@@ -265,12 +274,16 @@ int ckm_load_from_pkcs12_file(const char *file_path, const char *passphrase, ckm
                        X509* popedCert = NULL;
                        ckm_cert *popedCkmCert = NULL;
                        ckm_cert_list *tmpCertList = NULL;
-                       retCaCertList = tmpCertList;
                        while((popedCert = sk_X509_pop(ca)) != NULL) {
                                if( (ret =_ckm_load_cert_from_x509(popedCert, &popedCkmCert)) != CKM_API_SUCCESS) {
                                        return CKM_API_ERROR_OUT_OF_MEMORY;
                                }
-                               tmpCertList = ckm_cert_list_add(tmpCertList, popedCkmCert);
+                               if(tmpCertList == NULL) { // first
+                                       tmpCertList = ckm_cert_list_new(popedCkmCert);
+                                       retCaCertList = tmpCertList;
+                               }else {
+                                       tmpCertList = ckm_cert_list_add(tmpCertList, popedCkmCert);
+                               }
                        }
                        return CKM_API_SUCCESS;
                }
@@ -292,6 +305,7 @@ int ckm_load_from_pkcs12_file(const char *file_path, const char *passphrase, ckm
        if((ret = converter.toCaCkmCertList()) != CKM_API_SUCCESS) {
                return ret;
        }
+
        *private_key = converter.retPrivateKey;
        *ckmcert = converter.retCkmCert;
        *ca_cert_list = converter.retCaCertList;
@@ -305,8 +319,10 @@ void ckm_cert_free(ckm_cert *cert)
        if(cert == NULL)
                return;
 
-       if(cert->raw_cert != NULL)
+       if(cert->raw_cert != NULL) {
+               memset(cert->raw_cert, 0, cert->cert_size);
                free(cert->raw_cert);
+       }
        free(cert);
 }
 
@@ -420,22 +436,23 @@ void ckm_cert_list_all_free(ckm_cert_list *first)
 
 int _ckm_load_cert_from_x509(X509 *xCert, ckm_cert **cert)
 {
-       int certLen;
-       unsigned char* bufCert = NULL;
-
        if(xCert == NULL) {
                return CKM_API_ERROR_INVALID_FORMAT;
        }
 
-       /* load certificate into buffer */
-       if((certLen = i2d_X509(xCert, NULL)) < 0) {
-               return CKM_API_ERROR_INVALID_FORMAT;
-       }
-       unsigned char arrayCert[sizeof(unsigned char) * certLen];
-       bufCert = arrayCert;
-       i2d_X509(xCert, &bufCert);
+       BIO *bcert = BIO_new(BIO_s_mem());
+
+       i2d_X509_bio(bcert, xCert);
+
+    CKM::RawBuffer output(8196);
+    int size = BIO_read(bcert, output.data(), output.size());
+       BIO_free_all(bcert);
+    if (size <= 0) {
+        return CKM_API_ERROR_INVALID_FORMAT;
+    }
+    output.resize(size);
 
-       *cert = ckm_cert_new(bufCert, certLen, CKM_CERT_FORM_DER);
+       *cert = ckm_cert_new(output.data(), output.size(), CKM_FORM_DER);
 
        return CKM_API_SUCCESS;
 }