libfreerdp-utils: refactoring of certificate store
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Thu, 2 Feb 2012 22:36:07 +0000 (17:36 -0500)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Thu, 2 Feb 2012 22:36:07 +0000 (17:36 -0500)
include/freerdp/utils/certstore.h
libfreerdp-core/certificate.c
libfreerdp-core/credssp.c
libfreerdp-core/crypto.c
libfreerdp-core/crypto.h
libfreerdp-core/tls.c
libfreerdp-utils/certstore.c

index 2a5f9bd..45b8bd9 100644 (file)
@@ -1,8 +1,9 @@
+
 #ifndef __CERTSTORE_UTILS_H
 #define __CERTSTORE_UTILS_H
 
-typedef struct rdp_cert_store rdpCertStore;
-typedef struct rdp_cert_data rdpCertData;
+typedef struct rdp_certificate_data rdpCertificateData;
+typedef struct rdp_certificate_store rdpCertificateStore;
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -11,33 +12,28 @@ typedef struct rdp_cert_data rdpCertData;
 #include <freerdp/freerdp.h>
 #include <freerdp/utils/memory.h>
 
-struct rdp_cert_data
+struct rdp_certificate_data
 {
        char* hostname;
        char* fingerprint;
 };
 
-struct rdp_cert_store
+struct rdp_certificate_store
 {
        FILE* fp;
        int match;
        char* path;
        char* file;
-       char* home_path;
-       rdpCertData* certdata;
+       rdpSettings* settings;
+       rdpCertificateData* certificate_data;
 };
 
-FREERDP_API void certstore_create(rdpCertStore* certstore);
-FREERDP_API void certstore_open(rdpCertStore* certstore);
-FREERDP_API void certstore_load(rdpCertStore* certstore);
-FREERDP_API void certstore_close(rdpCertStore* certstore);
-FREERDP_API char* get_local_certloc();
-FREERDP_API rdpCertData* certdata_new(char* hostname, char* fingerprint);
-FREERDP_API void certdata_free(rdpCertData* certdata);
-FREERDP_API void certstore_init(rdpCertStore* certstore);
-FREERDP_API rdpCertStore* certstore_new(rdpCertData* certdata, char* home_path);
-FREERDP_API void certstore_free(rdpCertStore* certstore);
-FREERDP_API int cert_data_match(rdpCertStore* certstore);
-FREERDP_API void cert_data_print(rdpCertStore* certstore);
+FREERDP_API char* certificate_store_get_path(rdpCertificateStore* certificate_store);
+FREERDP_API rdpCertificateData* certificate_data_new(char* hostname, char* fingerprint);
+FREERDP_API void certificate_data_free(rdpCertificateData* certificate_data);
+FREERDP_API rdpCertificateStore* certificate_store_new(rdpSettings* settings);
+FREERDP_API void certificate_store_free(rdpCertificateStore* certificate_store);
+FREERDP_API int certificate_data_match(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data);
+FREERDP_API void certificate_data_print(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data);
 
 #endif /* __CERTSTORE_UTILS_H */
index 9c91f15..8103fcf 100644 (file)
@@ -281,31 +281,41 @@ static boolean certificate_process_server_public_signature(rdpCertificate* certi
        crypto_md5_final(md5ctx, md5hash);
 
        stream_read(s, encsig, siglen);
+
        /* Last 8 bytes shall be all zero. */
+
        for (sum = 0, i = sizeof(encsig) - 8; i < sizeof(encsig); i++)
                sum += encsig[i];
-       if (sum != 0) {
+
+       if (sum != 0)
+       {
                printf("certificate_process_server_public_signature: invalid signature\n");
                //return false;
        }
+
        siglen -= 8;
 
        crypto_rsa_public_decrypt(encsig, siglen, TSSK_KEY_LENGTH, tssk_modulus, tssk_exponent, sig);
 
        /* Verify signature. */
-       if (memcmp(md5hash, sig, sizeof(md5hash)) != 0) {
+       if (memcmp(md5hash, sig, sizeof(md5hash)) != 0)
+       {
                printf("certificate_process_server_public_signature: invalid signature\n");
                //return false;
        }
+
        /*
         * Verify rest of decrypted data:
         * The 17th byte is 0x00.
         * The 18th through 62nd bytes are each 0xFF.
         * The 63rd byte is 0x01.
         */
+
        for (sum = 0, i = 17; i < 62; i++)
                sum += sig[i];
-       if (sig[16] != 0x00 || sum != 0xFF * (62 - 17) || sig[62] != 0x01) {
+
+       if (sig[16] != 0x00 || sum != 0xFF * (62 - 17) || sig[62] != 0x01)
+       {
                printf("certificate_process_server_public_signature: invalid signature\n");
                //return false;
        }
@@ -461,83 +471,55 @@ boolean certificate_read_server_certificate(rdpCertificate* certificate, uint8*
        return true;
 }
 
-/**
- * Instantiate new certificate module.\n
- * @param rdp RDP module
- * @return new certificate module
- */
-
-rdpCertificate* certificate_new(void)
-{
-       rdpCertificate* certificate;
-
-       certificate = (rdpCertificate*) xzalloc(sizeof(rdpCertificate));
-
-       if (certificate != NULL)
-       {
-               certificate->x509_cert_chain = NULL;
-       }
-
-       return certificate;
-}
-
-/**
- * Free certificate module.
- * @param certificate certificate module to be freed
- */
-
-void certificate_free(rdpCertificate* certificate)
-{
-       if (certificate != NULL)
-       {
-               certificate_free_x509_certificate_chain(certificate->x509_cert_chain);
-
-               if (certificate->cert_info.modulus.data != NULL)
-                       freerdp_blob_free(&(certificate->cert_info.modulus));
-
-               xfree(certificate);
-       }
-}
-
-rdpKey* key_new(const char *keyfile)
+rdpKey* key_new(const char* keyfile)
 {
        rdpKey* key;
        RSA *rsa;
        FILE *fp;
 
        key = (rdpKey*) xzalloc(sizeof(rdpKey));
+
        if (key == NULL)
                return NULL;
 
        fp = fopen(keyfile, "r");
-       if (fp == NULL) {
-               printf("unable to load RSA key from %s: %s.", keyfile,
-                   strerror(errno));
+
+       if (fp == NULL)
+       {
+               printf("unable to load RSA key from %s: %s.", keyfile, strerror(errno));
                return NULL;
        }
+
        rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);
-       if (rsa == NULL) {
+
+       if (rsa == NULL)
+       {
                ERR_print_errors_fp(stdout);
                fclose(fp);
                return NULL;
        }
+
        fclose(fp);
 
-       switch (RSA_check_key(rsa)) {
-       case 0:
-               RSA_free(rsa);
-               printf("invalid RSA key in %s", keyfile);
-               return NULL;
-       case 1:
-               /* Valid key. */
-               break;
-       default:
-               ERR_print_errors_fp(stdout);
-               RSA_free(rsa);
-               return NULL;
+       switch (RSA_check_key(rsa))
+       {
+               case 0:
+                       RSA_free(rsa);
+                       printf("invalid RSA key in %s", keyfile);
+                       return NULL;
+
+               case 1:
+                       /* Valid key. */
+                       break;
+
+               default:
+                       ERR_print_errors_fp(stdout);
+                       RSA_free(rsa);
+                       return NULL;
        }
 
-       if (BN_num_bytes(rsa->e) > 4) {
+       if (BN_num_bytes(rsa->e) > 4)
+       {
                RSA_free(rsa);
                printf("RSA public exponent too large in %s", keyfile);
                return NULL;
@@ -567,3 +549,41 @@ void key_free(rdpKey* key)
                xfree(key);
        }
 }
+
+/**
+ * Instantiate new certificate module.\n
+ * @param rdp RDP module
+ * @return new certificate module
+ */
+
+rdpCertificate* certificate_new(void)
+{
+       rdpCertificate* certificate;
+
+       certificate = (rdpCertificate*) xzalloc(sizeof(rdpCertificate));
+
+       if (certificate != NULL)
+       {
+               certificate->x509_cert_chain = NULL;
+       }
+
+       return certificate;
+}
+
+/**
+ * Free certificate module.
+ * @param certificate certificate module to be freed
+ */
+
+void certificate_free(rdpCertificate* certificate)
+{
+       if (certificate != NULL)
+       {
+               certificate_free_x509_certificate_chain(certificate->x509_cert_chain);
+
+               if (certificate->cert_info.modulus.data != NULL)
+                       freerdp_blob_free(&(certificate->cert_info.modulus));
+
+               xfree(certificate);
+       }
+}
index 2b4952b..956473d 100644 (file)
@@ -136,7 +136,7 @@ int credssp_get_public_key(rdpCredssp* credssp)
                return 0;
        }
 
-       if(tls_verify_certificate(cert, credssp->transport->settings, credssp->transport->settings->hostname))
+       if (tls_verify_certificate(cert, credssp->transport->settings, credssp->transport->settings->hostname))
                tls_disconnect(credssp->transport->tls);
 
        status = crypto_cert_get_public_key(cert, &credssp->public_key);
index 426481c..1b1ada5 100644 (file)
@@ -100,8 +100,9 @@ void crypto_des3_decrypt(CryptoDes3 des3, uint32 length, const uint8* in_data, u
 {
        int len;
        EVP_DecryptUpdate(&des3->des3_ctx, out_data, &len, in_data, length);
+
        if (length != len)
-               abort();        // TODO
+               abort(); /* TODO */
 }
 
 void crypto_des3_free(CryptoDes3 des3)
@@ -190,9 +191,11 @@ exit:
 
 /*
  * Terminal Services Signing Keys.
- * Yes, Terminal Services Private Key is publically available.
+ * Yes, Terminal Services Private Key is publicly available.
  */
-const uint8 tssk_modulus[] = {
+
+const uint8 tssk_modulus[] =
+{
        0x3d, 0x3a, 0x5e, 0xbd, 0x72, 0x43, 0x3e, 0xc9,
        0x4d, 0xbb, 0xc1, 0x1e, 0x4a, 0xba, 0x5f, 0xcb,
        0x3e, 0x88, 0x20, 0x87, 0xef, 0xf5, 0xc1, 0xe2,
@@ -202,7 +205,9 @@ const uint8 tssk_modulus[] = {
        0x6c, 0x5e, 0x06, 0x09, 0x1a, 0xf5, 0x61, 0xbb,
        0x20, 0x93, 0x09, 0x5f, 0x05, 0x6d, 0xea, 0x87
 };
-const uint8 tssk_privateExponent[] = {
+
+const uint8 tssk_privateExponent[] =
+{
        0x87, 0xa7, 0x19, 0x32, 0xda, 0x11, 0x87, 0x55,
        0x58, 0x00, 0x16, 0x16, 0x25, 0x65, 0x68, 0xf8,
        0x24, 0x3e, 0xe6, 0xfa, 0xe9, 0x67, 0x49, 0x94,
@@ -212,7 +217,9 @@ const uint8 tssk_privateExponent[] = {
        0x35, 0x07, 0x79, 0x17, 0x0b, 0x51, 0x9b, 0xb3,
        0xc7, 0x10, 0x01, 0x13, 0xe7, 0x3f, 0xf3, 0x5f
 };
-const uint8 tssk_exponent[] = {
+
+const uint8 tssk_exponent[] =
+{
        0x5b, 0x7b, 0x88, 0xc0
 };
 
@@ -263,7 +270,6 @@ static void crypto_rsa_common(const uint8* input, int length, uint32 key_length,
 
 static void crypto_rsa_public(const uint8* input, int length, uint32 key_length, const uint8* modulus, const uint8* exponent, uint8* output)
 {
-
        crypto_rsa_common(input, length, key_length, modulus, exponent, EXPONENT_MAX_SIZE, output);
 }
 
@@ -372,9 +378,8 @@ char* crypto_cert_issuer(X509* xcert)
        return crypto_print_name(X509_get_issuer_name(xcert));
 }
 
-boolean x509_verify_cert(CryptoCert cert, rdpSettings* settings)
+boolean x509_verify_certificate(CryptoCert cert, char* certificate_store_path)
 {
-       char* cert_loc;
        X509_STORE_CTX* csc;
        boolean status = false;
        X509_STORE* cert_ctx = NULL;
@@ -398,12 +403,10 @@ boolean x509_verify_cert(CryptoCert cert, rdpSettings* settings)
                goto end;
 
        X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
-       cert_loc = get_local_certloc(settings->home_path);
 
-       if(cert_loc != NULL)
+       if (certificate_store_path != NULL)
        {
-               X509_LOOKUP_add_dir(lookup, cert_loc, X509_FILETYPE_ASN1);
-               xfree(cert_loc);
+               X509_LOOKUP_add_dir(lookup, certificate_store_path, X509_FILETYPE_ASN1);
        }
 
        csc = X509_STORE_CTX_new();
@@ -413,7 +416,7 @@ boolean x509_verify_cert(CryptoCert cert, rdpSettings* settings)
 
        X509_STORE_set_flags(cert_ctx, 0);
 
-       if(!X509_STORE_CTX_init(csc, cert_ctx, xcert, 0))
+       if (!X509_STORE_CTX_init(csc, cert_ctx, xcert, 0))
                goto end;
 
        if (X509_verify_cert(csc) == 1)
@@ -426,13 +429,13 @@ end:
        return status;
 }
 
-rdpCertData* crypto_get_cert_data(X509* xcert, char* hostname)
+rdpCertificateData* crypto_get_certificate_data(X509* xcert, char* hostname)
 {
        char* fp;
-       rdpCertData* certdata;
+       rdpCertificateData* certdata;
 
        fp = crypto_cert_fingerprint(xcert);
-       certdata = certdata_new(hostname, fp);
+       certdata = certificate_data_new(hostname, fp);
        xfree(fp);
 
        return certdata;
index 6b4d30b..bc02481 100644 (file)
@@ -116,8 +116,8 @@ char* crypto_cert_subject(X509* xcert);
 char* crypto_cert_issuer(X509* xcert);
 void crypto_cert_print_info(X509* xcert);
 void crypto_cert_free(CryptoCert cert);
-boolean x509_verify_cert(CryptoCert cert, rdpSettings* settings);
-rdpCertData* crypto_get_cert_data(X509* xcert, char* hostname);
+boolean x509_verify_certificate(CryptoCert cert, char* certificate_store_path);
+rdpCertificateData* crypto_get_certificate_data(X509* xcert, char* hostname);
 boolean crypto_cert_get_public_key(CryptoCert cert, rdpBlob* public_key);
 
 #define        TSSK_KEY_LENGTH 64
index bab8696..5fde2b8 100644 (file)
@@ -245,27 +245,29 @@ rdpTls* tls_new()
 int tls_verify_certificate(CryptoCert cert, rdpSettings* settings, char* hostname)
 {
        boolean status;
-       rdpCertStore* certstore;
-       status = x509_verify_cert(cert, settings);
+       rdpCertificateStore* certificate_store;
+
+       certificate_store = certificate_store_new(settings);
+
+       status = x509_verify_certificate(cert, certificate_store->path);
 
        if (status != true)
        {
                char* issuer;
                char* subject;
                char* fingerprint;
-               rdpCertData* certdata;
+               rdpCertificateData* certificate_data;
 
-               certdata = crypto_get_cert_data(cert->px509, hostname);
-               certstore = certstore_new(certdata, settings->home_path);
+               certificate_data = crypto_get_certificate_data(cert->px509, hostname);
 
-               if (cert_data_match(certstore) == 0)
-                       goto end;
+               if (certificate_data_match(certificate_store, certificate_data) == 0)
+                       return 0;
 
                issuer = crypto_cert_issuer(cert->px509);
                subject = crypto_cert_subject(cert->px509);
                fingerprint = crypto_cert_fingerprint(cert->px509);
 
-               if (certstore->match == 1)
+               if (certificate_store->match == 1)
                {
                        boolean accept_certificate = settings->ignore_certificate;
 
@@ -284,19 +286,18 @@ int tls_verify_certificate(CryptoCert cert, rdpSettings* settings, char* hostnam
                        if (!accept_certificate)
                                return 1;
 
-                       cert_data_print(certstore);
+                       certificate_data_print(certificate_store, certificate_data);
                }
-               else if (certstore->match == -1)
+               else if (certificate_store->match == -1)
                {
                        tls_print_cert_error(hostname, fingerprint);
-                       certstore_free(certstore);
+                       certificate_store_free(certificate_store);
                        return 1;
                }
-
-end:
-               certstore_free(certstore);
        }
 
+       certificate_store_free(certificate_store);
+
        return 0;
 }
 
index 3288e06..702618d 100644 (file)
 #include <freerdp/utils/file.h>
 #include <freerdp/utils/certstore.h>
 
-static const char cert_dir[] = "freerdp";
-static const char cert_loc[] = "cacert";
-static const char certstore_file[] = "known_hosts";
+static const char certificate_store_subdir[] = "cacert";
+static const char certificate_store_file[] = "known_hosts";
 
-void certstore_create(rdpCertStore* certstore)
+void certificate_store_open(rdpCertificateStore* certificate_store)
 {
-       certstore->fp = fopen((char*) certstore->file, "w+");
-
-       if (certstore->fp == NULL)
+       if (freerdp_check_file_exists(certificate_store->file) == false)
        {
-               printf("certstore_create: error opening [%s] for writing\n", certstore->file);
-               return;
-       }
-
-       fflush(certstore->fp);
-}
-
-void certstore_load(rdpCertStore* certstore)
-{
-       certstore->fp = fopen((char*) certstore->file, "r+");
-}
+               certificate_store->fp = fopen((char*) certificate_store->file, "w+");
 
-void certstore_open(rdpCertStore* certstore)
-{
-       struct stat stat_info;
+               if (certificate_store->fp == NULL)
+               {
+                       printf("certificate_store_open: error opening [%s] for writing\n", certificate_store->file);
+                       return;
+               }
 
-       if (stat((char*) certstore->file, &stat_info) != 0)
-               certstore_create(certstore);
+               fflush(certificate_store->fp);
+       }
        else
-               certstore_load(certstore);
+       {
+               certificate_store->fp = fopen((char*) certificate_store->file, "r+");
+       }
 }
 
-void certstore_close(rdpCertStore* certstore)
+void certificate_store_close(rdpCertificateStore* certstore)
 {
        if (certstore->fp != NULL)
                fclose(certstore->fp);
 }
 
-char* get_local_certloc(char* home_path)
+char* certificate_store_get_path(rdpCertificateStore* certificate_store)
 {
-       char* certloc;
-       struct stat stat_info;
-
-       if (home_path == NULL)
-               home_path = getenv("HOME");
-
-       certloc = (char*) xmalloc(strlen(home_path) + 2 + strlen(cert_dir) + 1 + strlen(cert_loc) + 1);
-       sprintf(certloc, "%s/.%s/%s", home_path, cert_dir, cert_loc);
-
-       if(stat((char*) certloc, &stat_info) != 0)
-               freerdp_mkdir(certloc);
-       
-       return certloc;
+       return certificate_store->path;
 }
 
-void certstore_init(rdpCertStore* certstore)
+void certificate_store_init(rdpCertificateStore* certificate_store)
 {
-       int length;
-       char* home_path;
-       struct stat stat_info;
+       char* config_path;
+       rdpSettings* settings;
        
-       certstore->match = 1;
-
-       if (certstore->home_path == NULL)
-               home_path = getenv("HOME");
-       else
-               home_path = certstore->home_path;
-
-       if (home_path == NULL)
-       {
-               printf("could not get home path\n");
-               return;
-       }
-
-       certstore->home_path = (char*) xstrdup(home_path);
+       certificate_store->match = 1;
+       settings = certificate_store->settings;
 
-       certstore->path = (char*) xmalloc(strlen(certstore->home_path) + 2 + strlen(cert_dir) + 1);
-       sprintf(certstore->path, "%s/.%s", certstore->home_path, cert_dir);
+       config_path = freerdp_get_config_path(settings);
+       certificate_store->path = freerdp_construct_path(config_path, (char*) certificate_store_subdir);
 
-       if (stat(certstore->path, &stat_info) != 0)
+       if (freerdp_check_file_exists(certificate_store->path) == false)
        {
-               freerdp_mkdir(certstore->path);
-               printf("creating directory %s\n", certstore->path);
+               freerdp_mkdir(certificate_store->path);
+               printf("creating directory %s\n", certificate_store->path);
        }
 
-       length = strlen(certstore->path);
-       certstore->file = (char*) xmalloc(strlen(certstore->path) + 1 + strlen(certstore_file) + 1);
-       sprintf(certstore->file, "%s/%s", certstore->path, certstore_file);
+       certificate_store->file = freerdp_construct_path(certificate_store->path, (char*) certificate_store_file);
 
-       certstore_open(certstore);
+       certificate_store_open(certificate_store);
 }
 
-rdpCertData* certdata_new(char* hostname, char* fingerprint)
-{
-       rdpCertData* certdata;
-
-       certdata = (rdpCertData*) xzalloc(sizeof(rdpCertData));
-
-       if (certdata != NULL)
-       {
-               certdata->hostname = xzalloc(strlen(hostname) + 1);
-               certdata->fingerprint = xzalloc(strlen(fingerprint) + 1);
-               sprintf(certdata->hostname, "%s", hostname);
-               sprintf(certdata->fingerprint, "%s", fingerprint);
-       }
-
-       return certdata;
-}
-
-void certdata_free(rdpCertData* certdata)
-{
-       if(certdata != NULL)
-       {
-               xfree(certdata->hostname);
-               xfree(certdata->fingerprint);
-               xfree(certdata);
-       }
-}
-
-rdpCertStore* certstore_new(rdpCertData* certdata, char* home_path)
-{
-       rdpCertStore* certstore;
-
-       certstore = (rdpCertStore*) xzalloc(sizeof(rdpCertStore));
-
-       if (certstore != NULL)
-       {
-               certstore->home_path = home_path;
-               certstore->certdata = certdata;
-               certstore_init(certstore);
-       }
-
-       return certstore;
-}
-
-void certstore_free(rdpCertStore* certstore)
-{
-       if (certstore != NULL)
-       {
-               certstore_close(certstore);
-               xfree(certstore->path);
-               xfree(certstore->file);
-               xfree(certstore->home_path);
-               certdata_free(certstore->certdata);
-               xfree(certstore);
-       }
-}
-
-int cert_data_match(rdpCertStore* certstore)
+int certificate_data_match(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data)
 {
        FILE* fp;
        int length;
        char* data;
        char* pline;
        long int size;
-       rdpCertData* cert_data;
 
-       fp = certstore->fp;
-       cert_data = certstore->certdata;
+       fp = certificate_store->fp;
 
        if (!fp)
-               return certstore->match;
+               return certificate_store->match;
 
        fseek(fp, 0, SEEK_END);
        size = ftell(fp);
@@ -191,7 +97,7 @@ int cert_data_match(rdpCertStore* certstore)
        length = fread(data, size, 1, fp);
 
        if (size < 1)
-               return certstore->match;
+               return certificate_store->match;
 
        data[size] = '\n';
        pline = strtok(data, "\n");
@@ -205,14 +111,14 @@ int cert_data_match(rdpCertStore* certstore)
                        length = strcspn(pline, " \t");
                        pline[length] = '\0';
 
-                       if (strcmp(pline, cert_data->hostname) == 0)
+                       if (strcmp(pline, certificate_data->hostname) == 0)
                        {
                                pline = &pline[length + 1];
 
-                               if (strcmp(pline, cert_data->fingerprint) == 0)
-                                       certstore->match = 0;
+                               if (strcmp(pline, certificate_data->fingerprint) == 0)
+                                       certificate_store->match = 0;
                                else
-                                       certstore->match = -1;
+                                       certificate_store->match = -1;
                                break;
                        }
                }
@@ -221,19 +127,70 @@ int cert_data_match(rdpCertStore* certstore)
        }
        xfree(data);
 
-       return certstore->match;
+       return certificate_store->match;
 }
 
-void cert_data_print(rdpCertStore* certstore)
+void certificate_data_print(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data)
 {
        FILE* fp;
 
        /* reopen in append mode */
-       fp = fopen(certstore->file, "a");
+       fp = fopen(certificate_store->file, "a");
 
        if (!fp)
                return;
 
-       fprintf(certstore->fp,"%s %s\n", certstore->certdata->hostname, certstore->certdata->fingerprint);
+       fprintf(certificate_store->fp,"%s %s\n", certificate_data->hostname, certificate_data->fingerprint);
        fclose(fp);
 }
+
+rdpCertificateData* certificate_data_new(char* hostname, char* fingerprint)
+{
+       rdpCertificateData* certdata;
+
+       certdata = (rdpCertificateData*) xzalloc(sizeof(rdpCertificateData));
+
+       if (certdata != NULL)
+       {
+               certdata->hostname = xstrdup(hostname);
+               certdata->fingerprint = xstrdup(fingerprint);
+       }
+
+       return certdata;
+}
+
+void certificate_data_free(rdpCertificateData* certificate_data)
+{
+       if (certificate_data != NULL)
+       {
+               xfree(certificate_data->hostname);
+               xfree(certificate_data->fingerprint);
+               xfree(certificate_data);
+       }
+}
+
+rdpCertificateStore* certificate_store_new(rdpSettings* settings)
+{
+       rdpCertificateStore* certificate_store;
+
+       certificate_store = (rdpCertificateStore*) xzalloc(sizeof(rdpCertificateStore));
+
+       if (certificate_store != NULL)
+       {
+               certificate_store->settings = settings;
+               certificate_store_init(certificate_store);
+       }
+
+       return certificate_store;
+}
+
+void certificate_store_free(rdpCertificateStore* certstore)
+{
+       if (certstore != NULL)
+       {
+               certificate_store_close(certstore);
+               xfree(certstore->path);
+               xfree(certstore->file);
+               xfree(certstore);
+       }
+}