+++ /dev/null
-
-#ifndef __CERTSTORE_UTILS_H
-#define __CERTSTORE_UTILS_H
-
-typedef struct rdp_certificate_data rdpCertificateData;
-typedef struct rdp_certificate_store rdpCertificateStore;
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <freerdp/api.h>
-#include <freerdp/freerdp.h>
-#include <freerdp/utils/memory.h>
-
-struct rdp_certificate_data
-{
- char* hostname;
- char* fingerprint;
-};
-
-struct rdp_certificate_store
-{
- FILE* fp;
- int match;
- char* path;
- char* file;
- rdpSettings* settings;
- rdpCertificateData* certificate_data;
-};
-
-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 */
* FreeRDP: A Remote Desktop Protocol Client
* Certificate Handling
*
+ * Copyright 2011 Jiten Pathy
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
#include <openssl/pem.h>
#include <openssl/rsa.h>
+#include <freerdp/utils/file.h>
+
+static const char certificate_store_dir[] = "cacert";
+static const char certificate_known_hosts_file[] = "known_hosts";
+
#include "certificate.h"
/**
}
}
+void certificate_store_init(rdpCertificateStore* certificate_store)
+{
+ char* config_path;
+ rdpSettings* settings;
+
+ settings = certificate_store->settings;
+
+ config_path = freerdp_get_config_path(settings);
+ certificate_store->path = freerdp_construct_path(config_path, (char*) certificate_store_dir);
+
+ if (freerdp_check_file_exists(certificate_store->path) == false)
+ {
+ freerdp_mkdir(certificate_store->path);
+ printf("creating directory %s\n", certificate_store->path);
+ }
+
+ certificate_store->file = freerdp_construct_path(config_path, (char*) certificate_known_hosts_file);
+
+ if (freerdp_check_file_exists(certificate_store->file) == false)
+ {
+ certificate_store->fp = fopen((char*) certificate_store->file, "w+");
+
+ if (certificate_store->fp == NULL)
+ {
+ printf("certificate_store_open: error opening [%s] for writing\n", certificate_store->file);
+ return;
+ }
+
+ fflush(certificate_store->fp);
+ }
+ else
+ {
+ certificate_store->fp = fopen((char*) certificate_store->file, "r+");
+ }
+}
+
+int certificate_data_match(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data)
+{
+ FILE* fp;
+ int length;
+ char* data;
+ char* pline;
+ int match = 1;
+ long int size;
+
+ fp = certificate_store->fp;
+
+ if (!fp)
+ return match;
+
+ fseek(fp, 0, SEEK_END);
+ size = ftell(fp);
+ fseek(fp, 0, SEEK_SET);
+
+ data = (char*) xmalloc(size + 1);
+ length = fread(data, size, 1, fp);
+
+ if (size < 1)
+ return match;
+
+ data[size] = '\n';
+ pline = strtok(data, "\n");
+
+ while (pline != NULL)
+ {
+ length = strlen(pline);
+
+ if (length > 0)
+ {
+ length = strcspn(pline, " \t");
+ pline[length] = '\0';
+
+ if (strcmp(pline, certificate_data->hostname) == 0)
+ {
+ pline = &pline[length + 1];
+
+ if (strcmp(pline, certificate_data->fingerprint) == 0)
+ match = 0;
+ else
+ match = -1;
+ break;
+ }
+ }
+
+ pline = strtok(NULL, "\n");
+ }
+ xfree(data);
+
+ return match;
+}
+
+void certificate_data_print(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data)
+{
+ FILE* fp;
+
+ /* reopen in append mode */
+ fp = fopen(certificate_store->file, "a");
+
+ if (!fp)
+ return;
+
+ 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)
+ {
+ if (certstore->fp != NULL)
+ fclose(certstore->fp);
+
+ xfree(certstore->path);
+ xfree(certstore->file);
+ xfree(certstore);
+ }
+}
+
/**
* Instantiate new certificate module.\n
* @param rdp RDP module
* @return new certificate module
*/
-rdpCertificate* certificate_new(void)
+rdpCertificate* certificate_new()
{
rdpCertificate* certificate;
#ifndef __CERTIFICATE_H
#define __CERTIFICATE_H
+typedef struct rdp_certificate_data rdpCertificateData;
+typedef struct rdp_certificate_store rdpCertificateStore;
+
#include "rdp.h"
#include "ber.h"
#include "crypto.h"
#define CERT_PERMANENTLY_ISSUED 0x00000000
#define CERT_TEMPORARILY_ISSUED 0x80000000
-#define SIGNATURE_ALG_RSA 0x00000001
-#define KEY_EXCHANGE_ALG_RSA 0x00000001
+#define SIGNATURE_ALG_RSA 0x00000001
+#define KEY_EXCHANGE_ALG_RSA 0x00000001
#define BB_RSA_KEY_BLOB 6
#define BB_RSA_SIGNATURE_BLOB 8
uint8 exponent[4];
};
+struct rdp_certificate_data
+{
+ char* hostname;
+ char* fingerprint;
+};
+
+struct rdp_certificate_store
+{
+ FILE* fp;
+ char* path;
+ char* file;
+ rdpSettings* settings;
+ rdpCertificateData* certificate_data;
+};
+
+rdpCertificateData* certificate_data_new(char* hostname, char* fingerprint);
+void certificate_data_free(rdpCertificateData* certificate_data);
+rdpCertificateStore* certificate_store_new(rdpSettings* settings);
+void certificate_store_free(rdpCertificateStore* certificate_store);
+int certificate_data_match(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data);
+void certificate_data_print(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data);
+
void certificate_read_x509_certificate(rdpCertBlob* cert, rdpCertInfo* info);
rdpX509CertChain* certificate_new_x509_certificate_chain(uint32 count);
boolean certificate_read_server_x509_certificate_chain(rdpCertificate* certificate, STREAM* s);
boolean certificate_read_server_certificate(rdpCertificate* certificate, uint8* server_cert, int length);
-rdpCertificate* certificate_new(void);
+rdpCertificate* certificate_new();
void certificate_free(rdpCertificate* certificate);
rdpKey* key_new(const char *keyfile);
return 0;
}
- if (tls_verify_certificate(cert, credssp->transport->settings, credssp->transport->settings->hostname))
+ if (tls_verify_certificate(credssp->transport->tls, cert, credssp->transport->settings->hostname))
tls_disconnect(credssp->transport->tls);
status = crypto_cert_get_public_key(cert, &credssp->public_key);
#include <freerdp/freerdp.h>
#include <freerdp/utils/blob.h>
#include <freerdp/utils/memory.h>
-#include <freerdp/utils/certstore.h>
struct crypto_sha1_struct
{
void crypto_hmac_free(CryptoHmac hmac);
typedef struct crypto_cert_struct* CryptoCert;
+
+#include "certificate.h"
+
CryptoCert crypto_cert_read(uint8* data, uint32 length);
char* crypto_cert_fingerprint(X509* xcert);
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_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);
return status;
}
-boolean tls_print_error(char *func, SSL *connection, int value)
+boolean tls_print_error(char* func, SSL* connection, int value)
{
switch (SSL_get_error(connection, value))
{
}
}
-CryptoCert tls_get_certificate(rdpTls * tls)
+CryptoCert tls_get_certificate(rdpTls* tls)
{
CryptoCert cert;
X509* server_cert;
return cert;
}
-rdpTls* tls_new()
-{
- rdpTls* tls;
-
- tls = (rdpTls*) xzalloc(sizeof(rdpTls));
-
- if (tls != NULL)
- {
- SSL_load_error_strings();
- SSL_library_init();
- }
-
- return tls;
-}
-
-int tls_verify_certificate(CryptoCert cert, rdpSettings* settings, char* hostname)
+int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname)
{
+ int match;
boolean status;
- rdpCertificateStore* certificate_store;
- certificate_store = certificate_store_new(settings);
-
- status = x509_verify_certificate(cert, certificate_store->path);
+ status = x509_verify_certificate(cert, tls->certificate_store->path);
if (status != true)
{
certificate_data = crypto_get_certificate_data(cert->px509, hostname);
- if (certificate_data_match(certificate_store, certificate_data) == 0)
+ match = certificate_data_match(tls->certificate_store, certificate_data);
+
+ if (match == 0)
return 0;
issuer = crypto_cert_issuer(cert->px509);
subject = crypto_cert_subject(cert->px509);
fingerprint = crypto_cert_fingerprint(cert->px509);
- if (certificate_store->match == 1)
+ if (match == 1)
{
- boolean accept_certificate = settings->ignore_certificate;
+ boolean accept_certificate = tls->settings->ignore_certificate;
if (!accept_certificate)
{
- freerdp* instance = (freerdp*) settings->instance;
+ freerdp* instance = (freerdp*) tls->settings->instance;
if (instance->VerifyCertificate)
accept_certificate = instance->VerifyCertificate(instance, subject, issuer, fingerprint);
if (!accept_certificate)
return 1;
- certificate_data_print(certificate_store, certificate_data);
+ certificate_data_print(tls->certificate_store, certificate_data);
}
- else if (certificate_store->match == -1)
+ else if (match == -1)
{
- tls_print_cert_error(hostname, fingerprint);
- certificate_store_free(certificate_store);
+ tls_print_certificate_error(hostname, fingerprint);
return 1;
}
}
- certificate_store_free(certificate_store);
-
return 0;
}
-void tls_print_cert_error(char* hostname, char* fingerprint)
+void tls_print_certificate_error(char* hostname, char* fingerprint)
{
printf("The host key for %s has changed\n", hostname);
printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
printf("Host key verification failed.\n");
}
+rdpTls* tls_new(rdpSettings* settings)
+{
+ rdpTls* tls;
+
+ tls = (rdpTls*) xzalloc(sizeof(rdpTls));
+
+ if (tls != NULL)
+ {
+ SSL_load_error_strings();
+ SSL_library_init();
+
+ tls->settings = settings;
+ tls->certificate_store = certificate_store_new(settings);
+ }
+
+ return tls;
+}
+
void tls_free(rdpTls* tls)
{
if (tls != NULL)
{
if (tls->ssl)
SSL_free(tls->ssl);
+
if (tls->ctx)
SSL_CTX_free(tls->ctx);
+
+ certificate_store_free(tls->certificate_store);
+
xfree(tls);
}
}
#define __TLS_H
#include "crypto.h"
+#include "certificate.h"
#include <openssl/ssl.h>
#include <openssl/err.h>
SSL* ssl;
int sockfd;
SSL_CTX* ctx;
+ rdpSettings* settings;
+ rdpCertificateStore* certificate_store;
};
boolean tls_connect(rdpTls* tls);
boolean tls_accept(rdpTls* tls, const char* cert_file, const char* privatekey_file);
boolean tls_disconnect(rdpTls* tls);
+
int tls_read(rdpTls* tls, uint8* data, int length);
int tls_write(rdpTls* tls, uint8* data, int length);
+
CryptoCert tls_get_certificate(rdpTls* tls);
-int tls_verify_certificate(CryptoCert cert, rdpSettings* settings, char* hostname);
-void tls_print_cert_error();
+int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname);
+void tls_print_certificate_error();
+
boolean tls_print_error(char* func, SSL* connection, int value);
-rdpTls* tls_new();
+
+rdpTls* tls_new(rdpSettings* settings);
void tls_free(rdpTls* tls);
#endif /* __TLS_H */
boolean transport_connect_tls(rdpTransport* transport)
{
if (transport->tls == NULL)
- transport->tls = tls_new();
+ transport->tls = tls_new(transport->settings);
transport->layer = TRANSPORT_LAYER_TLS;
transport->tls->sockfd = transport->tcp->sockfd;
boolean transport_connect_nla(rdpTransport* transport)
{
if (transport->tls == NULL)
- transport->tls = tls_new();
+ transport->tls = tls_new(transport->settings);
transport->layer = TRANSPORT_LAYER_TLS;
transport->tls->sockfd = transport->tcp->sockfd;
boolean transport_accept_tls(rdpTransport* transport)
{
if (transport->tls == NULL)
- transport->tls = tls_new();
+ transport->tls = tls_new(transport->settings);
transport->layer = TRANSPORT_LAYER_TLS;
transport->tls->sockfd = transport->tcp->sockfd;
boolean transport_accept_nla(rdpTransport* transport)
{
if (transport->tls == NULL)
- transport->tls = tls_new();
+ transport->tls = tls_new(transport->settings);
transport->layer = TRANSPORT_LAYER_TLS;
transport->tls->sockfd = transport->tcp->sockfd;
rail.c
rect.c
registry.c
- certstore.c
semaphore.c
signal.c
sleep.c
+++ /dev/null
-/**
- * FreeRDP: A Remote Desktop Protocol Client
- * certstore Utils
- *
- * Copyright 2011 Jiten Pathy
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <freerdp/utils/file.h>
-#include <freerdp/utils/certstore.h>
-
-static const char certificate_store_subdir[] = "cacert";
-static const char certificate_store_file[] = "known_hosts";
-
-void certificate_store_open(rdpCertificateStore* certificate_store)
-{
- if (freerdp_check_file_exists(certificate_store->file) == false)
- {
- certificate_store->fp = fopen((char*) certificate_store->file, "w+");
-
- if (certificate_store->fp == NULL)
- {
- printf("certificate_store_open: error opening [%s] for writing\n", certificate_store->file);
- return;
- }
-
- fflush(certificate_store->fp);
- }
- else
- {
- certificate_store->fp = fopen((char*) certificate_store->file, "r+");
- }
-}
-
-void certificate_store_close(rdpCertificateStore* certstore)
-{
- if (certstore->fp != NULL)
- fclose(certstore->fp);
-}
-
-char* certificate_store_get_path(rdpCertificateStore* certificate_store)
-{
- return certificate_store->path;
-}
-
-void certificate_store_init(rdpCertificateStore* certificate_store)
-{
- char* config_path;
- rdpSettings* settings;
-
- certificate_store->match = 1;
- settings = certificate_store->settings;
-
- config_path = freerdp_get_config_path(settings);
- certificate_store->path = freerdp_construct_path(config_path, (char*) certificate_store_subdir);
-
- if (freerdp_check_file_exists(certificate_store->path) == false)
- {
- freerdp_mkdir(certificate_store->path);
- printf("creating directory %s\n", certificate_store->path);
- }
-
- certificate_store->file = freerdp_construct_path(certificate_store->path, (char*) certificate_store_file);
-
- certificate_store_open(certificate_store);
-}
-
-int certificate_data_match(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data)
-{
- FILE* fp;
- int length;
- char* data;
- char* pline;
- long int size;
-
- fp = certificate_store->fp;
-
- if (!fp)
- return certificate_store->match;
-
- fseek(fp, 0, SEEK_END);
- size = ftell(fp);
- fseek(fp, 0, SEEK_SET);
-
- data = (char*) xmalloc(size + 1);
- length = fread(data, size, 1, fp);
-
- if (size < 1)
- return certificate_store->match;
-
- data[size] = '\n';
- pline = strtok(data, "\n");
-
- while (pline != NULL)
- {
- length = strlen(pline);
-
- if (length > 0)
- {
- length = strcspn(pline, " \t");
- pline[length] = '\0';
-
- if (strcmp(pline, certificate_data->hostname) == 0)
- {
- pline = &pline[length + 1];
-
- if (strcmp(pline, certificate_data->fingerprint) == 0)
- certificate_store->match = 0;
- else
- certificate_store->match = -1;
- break;
- }
- }
-
- pline = strtok(NULL, "\n");
- }
- xfree(data);
-
- return certificate_store->match;
-}
-
-void certificate_data_print(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data)
-{
- FILE* fp;
-
- /* reopen in append mode */
- fp = fopen(certificate_store->file, "a");
-
- if (!fp)
- return;
-
- 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);
- }
-}