libfreerdp-utils: refactoring of certificate store
This commit is contained in:
parent
8cd639dcb1
commit
bae5de89e1
@ -1,8 +1,9 @@
|
|||||||
|
|
||||||
#ifndef __CERTSTORE_UTILS_H
|
#ifndef __CERTSTORE_UTILS_H
|
||||||
#define __CERTSTORE_UTILS_H
|
#define __CERTSTORE_UTILS_H
|
||||||
|
|
||||||
typedef struct rdp_cert_store rdpCertStore;
|
typedef struct rdp_certificate_data rdpCertificateData;
|
||||||
typedef struct rdp_cert_data rdpCertData;
|
typedef struct rdp_certificate_store rdpCertificateStore;
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -11,33 +12,28 @@ typedef struct rdp_cert_data rdpCertData;
|
|||||||
#include <freerdp/freerdp.h>
|
#include <freerdp/freerdp.h>
|
||||||
#include <freerdp/utils/memory.h>
|
#include <freerdp/utils/memory.h>
|
||||||
|
|
||||||
struct rdp_cert_data
|
struct rdp_certificate_data
|
||||||
{
|
{
|
||||||
char* hostname;
|
char* hostname;
|
||||||
char* fingerprint;
|
char* fingerprint;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rdp_cert_store
|
struct rdp_certificate_store
|
||||||
{
|
{
|
||||||
FILE* fp;
|
FILE* fp;
|
||||||
int match;
|
int match;
|
||||||
char* path;
|
char* path;
|
||||||
char* file;
|
char* file;
|
||||||
char* home_path;
|
rdpSettings* settings;
|
||||||
rdpCertData* certdata;
|
rdpCertificateData* certificate_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
FREERDP_API void certstore_create(rdpCertStore* certstore);
|
FREERDP_API char* certificate_store_get_path(rdpCertificateStore* certificate_store);
|
||||||
FREERDP_API void certstore_open(rdpCertStore* certstore);
|
FREERDP_API rdpCertificateData* certificate_data_new(char* hostname, char* fingerprint);
|
||||||
FREERDP_API void certstore_load(rdpCertStore* certstore);
|
FREERDP_API void certificate_data_free(rdpCertificateData* certificate_data);
|
||||||
FREERDP_API void certstore_close(rdpCertStore* certstore);
|
FREERDP_API rdpCertificateStore* certificate_store_new(rdpSettings* settings);
|
||||||
FREERDP_API char* get_local_certloc();
|
FREERDP_API void certificate_store_free(rdpCertificateStore* certificate_store);
|
||||||
FREERDP_API rdpCertData* certdata_new(char* hostname, char* fingerprint);
|
FREERDP_API int certificate_data_match(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data);
|
||||||
FREERDP_API void certdata_free(rdpCertData* certdata);
|
FREERDP_API void certificate_data_print(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data);
|
||||||
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);
|
|
||||||
|
|
||||||
#endif /* __CERTSTORE_UTILS_H */
|
#endif /* __CERTSTORE_UTILS_H */
|
||||||
|
@ -281,31 +281,41 @@ static boolean certificate_process_server_public_signature(rdpCertificate* certi
|
|||||||
crypto_md5_final(md5ctx, md5hash);
|
crypto_md5_final(md5ctx, md5hash);
|
||||||
|
|
||||||
stream_read(s, encsig, siglen);
|
stream_read(s, encsig, siglen);
|
||||||
|
|
||||||
/* Last 8 bytes shall be all zero. */
|
/* Last 8 bytes shall be all zero. */
|
||||||
|
|
||||||
for (sum = 0, i = sizeof(encsig) - 8; i < sizeof(encsig); i++)
|
for (sum = 0, i = sizeof(encsig) - 8; i < sizeof(encsig); i++)
|
||||||
sum += encsig[i];
|
sum += encsig[i];
|
||||||
if (sum != 0) {
|
|
||||||
|
if (sum != 0)
|
||||||
|
{
|
||||||
printf("certificate_process_server_public_signature: invalid signature\n");
|
printf("certificate_process_server_public_signature: invalid signature\n");
|
||||||
//return false;
|
//return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
siglen -= 8;
|
siglen -= 8;
|
||||||
|
|
||||||
crypto_rsa_public_decrypt(encsig, siglen, TSSK_KEY_LENGTH, tssk_modulus, tssk_exponent, sig);
|
crypto_rsa_public_decrypt(encsig, siglen, TSSK_KEY_LENGTH, tssk_modulus, tssk_exponent, sig);
|
||||||
|
|
||||||
/* Verify signature. */
|
/* 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");
|
printf("certificate_process_server_public_signature: invalid signature\n");
|
||||||
//return false;
|
//return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Verify rest of decrypted data:
|
* Verify rest of decrypted data:
|
||||||
* The 17th byte is 0x00.
|
* The 17th byte is 0x00.
|
||||||
* The 18th through 62nd bytes are each 0xFF.
|
* The 18th through 62nd bytes are each 0xFF.
|
||||||
* The 63rd byte is 0x01.
|
* The 63rd byte is 0x01.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (sum = 0, i = 17; i < 62; i++)
|
for (sum = 0, i = 17; i < 62; i++)
|
||||||
sum += sig[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");
|
printf("certificate_process_server_public_signature: invalid signature\n");
|
||||||
//return false;
|
//return false;
|
||||||
}
|
}
|
||||||
@ -461,6 +471,85 @@ boolean certificate_read_server_certificate(rdpCertificate* certificate, uint8*
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BN_num_bytes(rsa->e) > 4)
|
||||||
|
{
|
||||||
|
RSA_free(rsa);
|
||||||
|
printf("RSA public exponent too large in %s", keyfile);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
freerdp_blob_alloc(&key->modulus, BN_num_bytes(rsa->n));
|
||||||
|
BN_bn2bin(rsa->n, key->modulus.data);
|
||||||
|
crypto_reverse(key->modulus.data, key->modulus.length);
|
||||||
|
freerdp_blob_alloc(&key->private_exponent, BN_num_bytes(rsa->d));
|
||||||
|
BN_bn2bin(rsa->d, key->private_exponent.data);
|
||||||
|
crypto_reverse(key->private_exponent.data, key->private_exponent.length);
|
||||||
|
memset(key->exponent, 0, sizeof(key->exponent));
|
||||||
|
BN_bn2bin(rsa->e, key->exponent + sizeof(key->exponent) - BN_num_bytes(rsa->e));
|
||||||
|
crypto_reverse(key->exponent, sizeof(key->exponent));
|
||||||
|
|
||||||
|
RSA_free(rsa);
|
||||||
|
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
void key_free(rdpKey* key)
|
||||||
|
{
|
||||||
|
if (key != NULL)
|
||||||
|
{
|
||||||
|
freerdp_blob_free(&key->modulus);
|
||||||
|
freerdp_blob_free(&key->private_exponent);
|
||||||
|
xfree(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiate new certificate module.\n
|
* Instantiate new certificate module.\n
|
||||||
* @param rdp RDP module
|
* @param rdp RDP module
|
||||||
@ -498,72 +587,3 @@ void certificate_free(rdpCertificate* certificate)
|
|||||||
xfree(certificate);
|
xfree(certificate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (BN_num_bytes(rsa->e) > 4) {
|
|
||||||
RSA_free(rsa);
|
|
||||||
printf("RSA public exponent too large in %s", keyfile);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
freerdp_blob_alloc(&key->modulus, BN_num_bytes(rsa->n));
|
|
||||||
BN_bn2bin(rsa->n, key->modulus.data);
|
|
||||||
crypto_reverse(key->modulus.data, key->modulus.length);
|
|
||||||
freerdp_blob_alloc(&key->private_exponent, BN_num_bytes(rsa->d));
|
|
||||||
BN_bn2bin(rsa->d, key->private_exponent.data);
|
|
||||||
crypto_reverse(key->private_exponent.data, key->private_exponent.length);
|
|
||||||
memset(key->exponent, 0, sizeof(key->exponent));
|
|
||||||
BN_bn2bin(rsa->e, key->exponent + sizeof(key->exponent) - BN_num_bytes(rsa->e));
|
|
||||||
crypto_reverse(key->exponent, sizeof(key->exponent));
|
|
||||||
|
|
||||||
RSA_free(rsa);
|
|
||||||
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
void key_free(rdpKey* key)
|
|
||||||
{
|
|
||||||
if (key != NULL)
|
|
||||||
{
|
|
||||||
freerdp_blob_free(&key->modulus);
|
|
||||||
freerdp_blob_free(&key->private_exponent);
|
|
||||||
xfree(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -100,8 +100,9 @@ void crypto_des3_decrypt(CryptoDes3 des3, uint32 length, const uint8* in_data, u
|
|||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
EVP_DecryptUpdate(&des3->des3_ctx, out_data, &len, in_data, length);
|
EVP_DecryptUpdate(&des3->des3_ctx, out_data, &len, in_data, length);
|
||||||
|
|
||||||
if (length != len)
|
if (length != len)
|
||||||
abort(); // TODO
|
abort(); /* TODO */
|
||||||
}
|
}
|
||||||
|
|
||||||
void crypto_des3_free(CryptoDes3 des3)
|
void crypto_des3_free(CryptoDes3 des3)
|
||||||
@ -190,9 +191,11 @@ exit:
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Terminal Services Signing Keys.
|
* 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,
|
0x3d, 0x3a, 0x5e, 0xbd, 0x72, 0x43, 0x3e, 0xc9,
|
||||||
0x4d, 0xbb, 0xc1, 0x1e, 0x4a, 0xba, 0x5f, 0xcb,
|
0x4d, 0xbb, 0xc1, 0x1e, 0x4a, 0xba, 0x5f, 0xcb,
|
||||||
0x3e, 0x88, 0x20, 0x87, 0xef, 0xf5, 0xc1, 0xe2,
|
0x3e, 0x88, 0x20, 0x87, 0xef, 0xf5, 0xc1, 0xe2,
|
||||||
@ -202,7 +205,9 @@ const uint8 tssk_modulus[] = {
|
|||||||
0x6c, 0x5e, 0x06, 0x09, 0x1a, 0xf5, 0x61, 0xbb,
|
0x6c, 0x5e, 0x06, 0x09, 0x1a, 0xf5, 0x61, 0xbb,
|
||||||
0x20, 0x93, 0x09, 0x5f, 0x05, 0x6d, 0xea, 0x87
|
0x20, 0x93, 0x09, 0x5f, 0x05, 0x6d, 0xea, 0x87
|
||||||
};
|
};
|
||||||
const uint8 tssk_privateExponent[] = {
|
|
||||||
|
const uint8 tssk_privateExponent[] =
|
||||||
|
{
|
||||||
0x87, 0xa7, 0x19, 0x32, 0xda, 0x11, 0x87, 0x55,
|
0x87, 0xa7, 0x19, 0x32, 0xda, 0x11, 0x87, 0x55,
|
||||||
0x58, 0x00, 0x16, 0x16, 0x25, 0x65, 0x68, 0xf8,
|
0x58, 0x00, 0x16, 0x16, 0x25, 0x65, 0x68, 0xf8,
|
||||||
0x24, 0x3e, 0xe6, 0xfa, 0xe9, 0x67, 0x49, 0x94,
|
0x24, 0x3e, 0xe6, 0xfa, 0xe9, 0x67, 0x49, 0x94,
|
||||||
@ -212,7 +217,9 @@ const uint8 tssk_privateExponent[] = {
|
|||||||
0x35, 0x07, 0x79, 0x17, 0x0b, 0x51, 0x9b, 0xb3,
|
0x35, 0x07, 0x79, 0x17, 0x0b, 0x51, 0x9b, 0xb3,
|
||||||
0xc7, 0x10, 0x01, 0x13, 0xe7, 0x3f, 0xf3, 0x5f
|
0xc7, 0x10, 0x01, 0x13, 0xe7, 0x3f, 0xf3, 0x5f
|
||||||
};
|
};
|
||||||
const uint8 tssk_exponent[] = {
|
|
||||||
|
const uint8 tssk_exponent[] =
|
||||||
|
{
|
||||||
0x5b, 0x7b, 0x88, 0xc0
|
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)
|
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);
|
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));
|
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;
|
X509_STORE_CTX* csc;
|
||||||
boolean status = false;
|
boolean status = false;
|
||||||
X509_STORE* cert_ctx = NULL;
|
X509_STORE* cert_ctx = NULL;
|
||||||
@ -398,12 +403,10 @@ boolean x509_verify_cert(CryptoCert cert, rdpSettings* settings)
|
|||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
|
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);
|
X509_LOOKUP_add_dir(lookup, certificate_store_path, X509_FILETYPE_ASN1);
|
||||||
xfree(cert_loc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
csc = X509_STORE_CTX_new();
|
csc = X509_STORE_CTX_new();
|
||||||
@ -426,13 +429,13 @@ end:
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
rdpCertData* crypto_get_cert_data(X509* xcert, char* hostname)
|
rdpCertificateData* crypto_get_certificate_data(X509* xcert, char* hostname)
|
||||||
{
|
{
|
||||||
char* fp;
|
char* fp;
|
||||||
rdpCertData* certdata;
|
rdpCertificateData* certdata;
|
||||||
|
|
||||||
fp = crypto_cert_fingerprint(xcert);
|
fp = crypto_cert_fingerprint(xcert);
|
||||||
certdata = certdata_new(hostname, fp);
|
certdata = certificate_data_new(hostname, fp);
|
||||||
xfree(fp);
|
xfree(fp);
|
||||||
|
|
||||||
return certdata;
|
return certdata;
|
||||||
|
@ -116,8 +116,8 @@ char* crypto_cert_subject(X509* xcert);
|
|||||||
char* crypto_cert_issuer(X509* xcert);
|
char* crypto_cert_issuer(X509* xcert);
|
||||||
void crypto_cert_print_info(X509* xcert);
|
void crypto_cert_print_info(X509* xcert);
|
||||||
void crypto_cert_free(CryptoCert cert);
|
void crypto_cert_free(CryptoCert cert);
|
||||||
boolean x509_verify_cert(CryptoCert cert, rdpSettings* settings);
|
boolean x509_verify_certificate(CryptoCert cert, char* certificate_store_path);
|
||||||
rdpCertData* crypto_get_cert_data(X509* xcert, char* hostname);
|
rdpCertificateData* crypto_get_certificate_data(X509* xcert, char* hostname);
|
||||||
boolean crypto_cert_get_public_key(CryptoCert cert, rdpBlob* public_key);
|
boolean crypto_cert_get_public_key(CryptoCert cert, rdpBlob* public_key);
|
||||||
|
|
||||||
#define TSSK_KEY_LENGTH 64
|
#define TSSK_KEY_LENGTH 64
|
||||||
|
@ -245,27 +245,29 @@ rdpTls* tls_new()
|
|||||||
int tls_verify_certificate(CryptoCert cert, rdpSettings* settings, char* hostname)
|
int tls_verify_certificate(CryptoCert cert, rdpSettings* settings, char* hostname)
|
||||||
{
|
{
|
||||||
boolean status;
|
boolean status;
|
||||||
rdpCertStore* certstore;
|
rdpCertificateStore* certificate_store;
|
||||||
status = x509_verify_cert(cert, settings);
|
|
||||||
|
certificate_store = certificate_store_new(settings);
|
||||||
|
|
||||||
|
status = x509_verify_certificate(cert, certificate_store->path);
|
||||||
|
|
||||||
if (status != true)
|
if (status != true)
|
||||||
{
|
{
|
||||||
char* issuer;
|
char* issuer;
|
||||||
char* subject;
|
char* subject;
|
||||||
char* fingerprint;
|
char* fingerprint;
|
||||||
rdpCertData* certdata;
|
rdpCertificateData* certificate_data;
|
||||||
|
|
||||||
certdata = crypto_get_cert_data(cert->px509, hostname);
|
certificate_data = crypto_get_certificate_data(cert->px509, hostname);
|
||||||
certstore = certstore_new(certdata, settings->home_path);
|
|
||||||
|
|
||||||
if (cert_data_match(certstore) == 0)
|
if (certificate_data_match(certificate_store, certificate_data) == 0)
|
||||||
goto end;
|
return 0;
|
||||||
|
|
||||||
issuer = crypto_cert_issuer(cert->px509);
|
issuer = crypto_cert_issuer(cert->px509);
|
||||||
subject = crypto_cert_subject(cert->px509);
|
subject = crypto_cert_subject(cert->px509);
|
||||||
fingerprint = crypto_cert_fingerprint(cert->px509);
|
fingerprint = crypto_cert_fingerprint(cert->px509);
|
||||||
|
|
||||||
if (certstore->match == 1)
|
if (certificate_store->match == 1)
|
||||||
{
|
{
|
||||||
boolean accept_certificate = settings->ignore_certificate;
|
boolean accept_certificate = settings->ignore_certificate;
|
||||||
|
|
||||||
@ -284,19 +286,18 @@ int tls_verify_certificate(CryptoCert cert, rdpSettings* settings, char* hostnam
|
|||||||
if (!accept_certificate)
|
if (!accept_certificate)
|
||||||
return 1;
|
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);
|
tls_print_cert_error(hostname, fingerprint);
|
||||||
certstore_free(certstore);
|
certificate_store_free(certificate_store);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
|
||||||
certstore_free(certstore);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
certificate_store_free(certificate_store);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,168 +20,74 @@
|
|||||||
#include <freerdp/utils/file.h>
|
#include <freerdp/utils/file.h>
|
||||||
#include <freerdp/utils/certstore.h>
|
#include <freerdp/utils/certstore.h>
|
||||||
|
|
||||||
static const char cert_dir[] = "freerdp";
|
static const char certificate_store_subdir[] = "cacert";
|
||||||
static const char cert_loc[] = "cacert";
|
static const char certificate_store_file[] = "known_hosts";
|
||||||
static const char certstore_file[] = "known_hosts";
|
|
||||||
|
|
||||||
void certstore_create(rdpCertStore* certstore)
|
void certificate_store_open(rdpCertificateStore* certificate_store)
|
||||||
{
|
{
|
||||||
certstore->fp = fopen((char*) certstore->file, "w+");
|
if (freerdp_check_file_exists(certificate_store->file) == false)
|
||||||
|
{
|
||||||
|
certificate_store->fp = fopen((char*) certificate_store->file, "w+");
|
||||||
|
|
||||||
if (certstore->fp == NULL)
|
if (certificate_store->fp == NULL)
|
||||||
{
|
{
|
||||||
printf("certstore_create: error opening [%s] for writing\n", certstore->file);
|
printf("certificate_store_open: error opening [%s] for writing\n", certificate_store->file);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fflush(certstore->fp);
|
fflush(certificate_store->fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void certstore_load(rdpCertStore* certstore)
|
|
||||||
{
|
|
||||||
certstore->fp = fopen((char*) certstore->file, "r+");
|
|
||||||
}
|
|
||||||
|
|
||||||
void certstore_open(rdpCertStore* certstore)
|
|
||||||
{
|
|
||||||
struct stat stat_info;
|
|
||||||
|
|
||||||
if (stat((char*) certstore->file, &stat_info) != 0)
|
|
||||||
certstore_create(certstore);
|
|
||||||
else
|
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)
|
if (certstore->fp != NULL)
|
||||||
fclose(certstore->fp);
|
fclose(certstore->fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
char* get_local_certloc(char* home_path)
|
char* certificate_store_get_path(rdpCertificateStore* certificate_store)
|
||||||
{
|
{
|
||||||
char* certloc;
|
return certificate_store->path;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void certstore_init(rdpCertStore* certstore)
|
void certificate_store_init(rdpCertificateStore* certificate_store)
|
||||||
{
|
{
|
||||||
int length;
|
char* config_path;
|
||||||
char* home_path;
|
rdpSettings* settings;
|
||||||
struct stat stat_info;
|
|
||||||
|
|
||||||
certstore->match = 1;
|
certificate_store->match = 1;
|
||||||
|
settings = certificate_store->settings;
|
||||||
|
|
||||||
if (certstore->home_path == NULL)
|
config_path = freerdp_get_config_path(settings);
|
||||||
home_path = getenv("HOME");
|
certificate_store->path = freerdp_construct_path(config_path, (char*) certificate_store_subdir);
|
||||||
else
|
|
||||||
home_path = certstore->home_path;
|
|
||||||
|
|
||||||
if (home_path == NULL)
|
if (freerdp_check_file_exists(certificate_store->path) == false)
|
||||||
{
|
{
|
||||||
printf("could not get home path\n");
|
freerdp_mkdir(certificate_store->path);
|
||||||
return;
|
printf("creating directory %s\n", certificate_store->path);
|
||||||
}
|
}
|
||||||
|
|
||||||
certstore->home_path = (char*) xstrdup(home_path);
|
certificate_store->file = freerdp_construct_path(certificate_store->path, (char*) certificate_store_file);
|
||||||
|
|
||||||
certstore->path = (char*) xmalloc(strlen(certstore->home_path) + 2 + strlen(cert_dir) + 1);
|
certificate_store_open(certificate_store);
|
||||||
sprintf(certstore->path, "%s/.%s", certstore->home_path, cert_dir);
|
|
||||||
|
|
||||||
if (stat(certstore->path, &stat_info) != 0)
|
|
||||||
{
|
|
||||||
freerdp_mkdir(certstore->path);
|
|
||||||
printf("creating directory %s\n", certstore->path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
length = strlen(certstore->path);
|
int certificate_data_match(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data)
|
||||||
certstore->file = (char*) xmalloc(strlen(certstore->path) + 1 + strlen(certstore_file) + 1);
|
|
||||||
sprintf(certstore->file, "%s/%s", certstore->path, certstore_file);
|
|
||||||
|
|
||||||
certstore_open(certstore);
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
FILE* fp;
|
FILE* fp;
|
||||||
int length;
|
int length;
|
||||||
char* data;
|
char* data;
|
||||||
char* pline;
|
char* pline;
|
||||||
long int size;
|
long int size;
|
||||||
rdpCertData* cert_data;
|
|
||||||
|
|
||||||
fp = certstore->fp;
|
fp = certificate_store->fp;
|
||||||
cert_data = certstore->certdata;
|
|
||||||
|
|
||||||
if (!fp)
|
if (!fp)
|
||||||
return certstore->match;
|
return certificate_store->match;
|
||||||
|
|
||||||
fseek(fp, 0, SEEK_END);
|
fseek(fp, 0, SEEK_END);
|
||||||
size = ftell(fp);
|
size = ftell(fp);
|
||||||
@ -191,7 +97,7 @@ int cert_data_match(rdpCertStore* certstore)
|
|||||||
length = fread(data, size, 1, fp);
|
length = fread(data, size, 1, fp);
|
||||||
|
|
||||||
if (size < 1)
|
if (size < 1)
|
||||||
return certstore->match;
|
return certificate_store->match;
|
||||||
|
|
||||||
data[size] = '\n';
|
data[size] = '\n';
|
||||||
pline = strtok(data, "\n");
|
pline = strtok(data, "\n");
|
||||||
@ -205,14 +111,14 @@ int cert_data_match(rdpCertStore* certstore)
|
|||||||
length = strcspn(pline, " \t");
|
length = strcspn(pline, " \t");
|
||||||
pline[length] = '\0';
|
pline[length] = '\0';
|
||||||
|
|
||||||
if (strcmp(pline, cert_data->hostname) == 0)
|
if (strcmp(pline, certificate_data->hostname) == 0)
|
||||||
{
|
{
|
||||||
pline = &pline[length + 1];
|
pline = &pline[length + 1];
|
||||||
|
|
||||||
if (strcmp(pline, cert_data->fingerprint) == 0)
|
if (strcmp(pline, certificate_data->fingerprint) == 0)
|
||||||
certstore->match = 0;
|
certificate_store->match = 0;
|
||||||
else
|
else
|
||||||
certstore->match = -1;
|
certificate_store->match = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -221,19 +127,70 @@ int cert_data_match(rdpCertStore* certstore)
|
|||||||
}
|
}
|
||||||
xfree(data);
|
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;
|
FILE* fp;
|
||||||
|
|
||||||
/* reopen in append mode */
|
/* reopen in append mode */
|
||||||
fp = fopen(certstore->file, "a");
|
fp = fopen(certificate_store->file, "a");
|
||||||
|
|
||||||
if (!fp)
|
if (!fp)
|
||||||
return;
|
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);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user