Merge pull request #155 from mfleisz/certcallback

core: Added ui callback to verify certificates
This commit is contained in:
Marc-André Moreau 2011-10-18 09:59:34 -07:00
commit c03de9aeea
7 changed files with 120 additions and 22 deletions

View File

@ -218,6 +218,35 @@ static int df_process_plugin_args(rdpSettings* settings, const char* name,
return 1;
}
boolean df_verify_certificate(freerdp* instance, char* subject, char* issuer, char* fingerprint)
{
printf("Certificate details:\n");
printf("\tSubject: %s\n", subject);
printf("\tIssuer: %s\n", issuer);
printf("\tThumbprint: %s\n", fingerprint);
printf("The above X.509 certificate could not be verified, possibly because you do not have "
"the CA certificate in your certificate store, or the certificate has expired."
"Please look at the documentation on how to create local certificate store for a private CA.\n");
char answer;
while (1)
{
printf("Do you trust the above certificate? (Y/N) ");
answer = fgetc(stdin);
if (answer == 'y' || answer == 'Y')
{
return True;
}
else if (answer == 'n' || answer == 'N')
{
break;
}
}
return False;
}
static int
df_receive_channel_data(freerdp* instance, int channelId, uint8* data, int size, int flags, int total_size)
{
@ -408,6 +437,7 @@ int main(int argc, char* argv[])
instance = freerdp_new();
instance->PreConnect = df_pre_connect;
instance->PostConnect = df_post_connect;
instance->VerifyCertificate = df_verify_certificate;
instance->ReceiveChannelData = df_receive_channel_data;
instance->ContextSize = (pcContextSize) df_context_size;

View File

@ -392,6 +392,12 @@ boolean wf_post_connect(freerdp* instance)
return True;
}
boolean wf_verify_certificate(freerdp* instance, char* subject, char* issuer, char* fingerprint)
{
return True;
}
int wf_receive_channel_data(freerdp* instance, int channelId, uint8* data, int size, int flags, int total_size)
{
return freerdp_channels_data(instance, channelId, data, size, flags, total_size);
@ -636,6 +642,7 @@ INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
instance = freerdp_new();
instance->PreConnect = wf_pre_connect;
instance->PostConnect = wf_post_connect;
instance->VerifyCertificate = wf_verify_certificate;
instance->ReceiveChannelData = wf_receive_channel_data;
instance->ContextSize = (pcContextSize) wf_context_size;

View File

@ -771,6 +771,36 @@ boolean xf_authenticate(freerdp* instance, char** username, char** password, cha
return True;
}
boolean xf_verify_certificate(freerdp* instance, char* subject, char* issuer, char* fingerprint)
{
printf("Certificate details:\n");
printf("\tSubject: %s\n", subject);
printf("\tIssuer: %s\n", issuer);
printf("\tThumbprint: %s\n", fingerprint);
printf("The above X.509 certificate could not be verified, possibly because you do not have "
"the CA certificate in your certificate store, or the certificate has expired."
"Please look at the documentation on how to create local certificate store for a private CA.\n");
char answer;
while (1)
{
printf("Do you trust the above certificate? (Y/N) ");
answer = fgetc(stdin);
if (answer == 'y' || answer == 'Y')
{
return True;
}
else if (answer == 'n' || answer == 'N')
{
break;
}
}
return False;
}
int xf_process_client_args(rdpSettings* settings, const char* opt, const char* val, void* user_data)
{
int argc = 0;
@ -1049,6 +1079,7 @@ int main(int argc, char* argv[])
instance->PreConnect = xf_pre_connect;
instance->PostConnect = xf_post_connect;
instance->Authenticate = xf_authenticate;
instance->VerifyCertificate = xf_verify_certificate;
instance->ReceiveChannelData = xf_receive_channel_data;
instance->ContextSize = (pcContextSize) xf_context_size;

View File

@ -49,6 +49,7 @@ typedef void (*pcContextFree)(freerdp* instance, rdpContext* context);
typedef boolean (*pcPreConnect)(freerdp* instance);
typedef boolean (*pcPostConnect)(freerdp* instance);
typedef boolean (*pcAuthenticate)(freerdp* instance, char** username, char** password, char** domain);
typedef boolean (*pcVerifyCertificate)(freerdp* instance, char* subject, char* issuer, char* fingerprint);
typedef int (*pcSendChannelData)(freerdp* instance, int channelId, uint8* data, int size);
typedef int (*pcReceiveChannelData)(freerdp* instance, int channelId, uint8* data, int size, int flags, int total_size);
@ -85,6 +86,7 @@ struct rdp_freerdp
pcPreConnect PreConnect;
pcPostConnect PostConnect;
pcAuthenticate Authenticate;
pcVerifyCertificate VerifyCertificate;
pcSendChannelData SendChannelData;
pcReceiveChannelData ReceiveChannelData;

View File

@ -279,6 +279,34 @@ char* crypto_cert_fingerprint(X509* xcert)
return fp_buffer;
}
char* crypto_print_name(X509_NAME* name)
{
char* buffer = NULL;
BIO* outBIO = BIO_new(BIO_s_mem());
if(X509_NAME_print_ex(outBIO, name, 0, XN_FLAG_ONELINE) > 0)
{
unsigned long size = BIO_number_written(outBIO);
char* buffer = xzalloc(size);
memset(buffer, 0, size);
BIO_read(outBIO, buffer, size);
}
BIO_free(outBIO);
return buffer;
}
char* crypto_cert_subject(X509* xcert)
{
return crypto_print_name(X509_get_subject_name(xcert));
}
char* crypto_cert_issuer(X509* xcert)
{
return crypto_print_name(X509_get_issuer_name(xcert));
}
boolean x509_verify_cert(CryptoCert cert, rdpSettings* settings)
{
char* cert_loc;
@ -351,8 +379,8 @@ void crypto_cert_print_info(X509* xcert)
char* issuer;
char* subject;
subject = X509_NAME_oneline(X509_get_subject_name(xcert), NULL, 0);
issuer = X509_NAME_oneline(X509_get_issuer_name(xcert), NULL, 0);
subject = crypto_cert_subject(xcert);
issuer = crypto_cert_issuer(xcert);
fp = crypto_cert_fingerprint(xcert);
printf("Certificate details:\n");
@ -363,5 +391,8 @@ void crypto_cert_print_info(X509* xcert)
"the CA certificate in your certificate store, or the certificate has expired."
"Please look at the documentation on how to create local certificate store for a private CA.\n");
xfree(subject);
xfree(issuer);
xfree(fp);
}

View File

@ -109,7 +109,9 @@ void crypto_hmac_free(CryptoHmac hmac);
typedef struct crypto_cert_struct* CryptoCert;
CryptoCert crypto_cert_read(uint8* data, uint32 length);
char* cypto_cert_fingerprint(X509* xcert);
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_cert(CryptoCert cert, rdpSettings* settings);

View File

@ -259,27 +259,22 @@ int tls_verify_certificate(CryptoCert cert, rdpSettings* settings, char* hostnam
if (certstore->match == 1)
{
char answer;
crypto_cert_print_info(cert->px509);
char* issuer = crypto_cert_issuer(cert->px509);
char* subject = crypto_cert_subject(cert->px509);
char* fingerprint = crypto_cert_fingerprint(cert->px509);
#ifndef _WIN32
while (1)
{
printf("Do you trust the above certificate? (Y/N) ");
answer = fgetc(stdin);
boolean accept_certificate = False;
freerdp* instance = (freerdp*)settings->instance;
if (answer == 'y' || answer == 'Y')
{
cert_data_print(certstore);
break;
}
else if (answer == 'n' || answer == 'N')
{
certstore_free(certstore);
return 1;
}
}
#endif
if(instance->VerifyCertificate)
accept_certificate = instance->VerifyCertificate(instance, subject, issuer, fingerprint);
xfree(issuer);
xfree(subject);
xfree(fingerprint);
if(!accept_certificate)
return 1;
}
else if (certstore->match == -1)
{