diff --git a/.gitignore b/.gitignore index 99a76ffaa..0dcd5daa7 100644 --- a/.gitignore +++ b/.gitignore @@ -14,8 +14,9 @@ Makefile *.cproject *.settings -# Doxygen +# Documentation docs/api +client/X11/xfreerdp.1 # Mac OS X .DS_Store diff --git a/libfreerdp-core/crypto.c b/libfreerdp-core/crypto.c index f0df9a209..9aa65f0ab 100644 --- a/libfreerdp-core/crypto.c +++ b/libfreerdp-core/crypto.c @@ -190,85 +190,112 @@ void crypto_nonce(uint8* nonce, int size) RAND_bytes((void*) nonce, size); } -char* crypto_cert_fingerprint(X509 *xcert) +char* crypto_cert_fingerprint(X509* xcert) { - unsigned char fp[EVP_MAX_MD_SIZE]; - int i; + char* p; + int i = 0; + char* fp_buffer; unsigned int fp_len; - X509_digest(xcert,EVP_sha1(),fp,&fp_len); - char *fp_buf=xzalloc(3*fp_len); - char *p = fp_buf; + unsigned char fp[EVP_MAX_MD_SIZE]; + + X509_digest(xcert, EVP_sha1(), fp, &fp_len); + + fp_buffer = xzalloc(3 * fp_len); + p = fp_buffer; + for (i = 0; i < fp_len - 1; i++) { sprintf(p, "%02x:", fp[i]); - p = (char*) &fp_buf[i * 3]; + p = (char*) &fp_buffer[i * 3]; } - sprintf(p, "%02x", fp[i]); - return fp_buf; + sprintf(p, "%02x", fp[i]); + + return fp_buffer; } boolean x509_verify_cert(CryptoCert cert) { - X509 *xcert=cert->px509; - char *cert_loc; - int ret=0; - X509_STORE *cert_ctx=NULL; - X509_LOOKUP *lookup=NULL; - X509_STORE_CTX *csc; - cert_ctx=X509_STORE_new(); + char* cert_loc; + X509_STORE_CTX* csc; + boolean status = False; + X509_STORE* cert_ctx = NULL; + X509_LOOKUP* lookup = NULL; + X509* xcert = cert->px509; + + cert_ctx = X509_STORE_new(); + if (cert_ctx == NULL) goto end; + OpenSSL_add_all_algorithms(); - lookup=X509_STORE_add_lookup(cert_ctx,X509_LOOKUP_file()); + lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file()); + if (lookup == NULL) goto end; - lookup=X509_STORE_add_lookup(cert_ctx,X509_LOOKUP_hash_dir()); + + lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_hash_dir()); + if (lookup == NULL) goto end; - X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT); - cert_loc=get_local_certloc(); - if(cert_loc!=NULL) + + X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); + cert_loc = get_local_certloc(); + + if(cert_loc != NULL) { - X509_LOOKUP_add_dir(lookup,cert_loc,X509_FILETYPE_ASN1); + X509_LOOKUP_add_dir(lookup, cert_loc, X509_FILETYPE_ASN1); xfree(cert_loc); } + csc = X509_STORE_CTX_new(); + if (csc == NULL) goto end; + 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; - int i=X509_verify_cert(csc); + + if (X509_verify_cert(csc) == 1) + status = True; + X509_STORE_CTX_free(csc); X509_STORE_free(cert_ctx); - ret=0; - end: - ret = (i > 0); - return(ret); + +end: + return status; } -rdpCertdata* crypto_get_certdata(X509 *xcert,char* hostname) +rdpCertdata* crypto_get_certdata(X509* xcert, char* hostname) { + char* fp; rdpCertdata* certdata; - char *fp; - fp=crypto_cert_fingerprint(xcert); - certdata=certdata_new(hostname,fp); + + fp = crypto_cert_fingerprint(xcert); + certdata = certdata_new(hostname, fp); xfree(fp); + return certdata; } -void crypto_cert_printinfo(X509 *xcert) +void crypto_cert_printinfo(X509* xcert) { - char *subject; - char *issuer; - char *fp; - subject=X509_NAME_oneline(X509_get_subject_name(xcert),NULL,0); - issuer=X509_NAME_oneline(X509_get_issuer_name(xcert),NULL,0); - fp=crypto_cert_fingerprint(xcert); - printf("Cerificate details:\n"); - printf("\tSubject : %s\n",subject); - printf("\tIssuer : %s\n",issuer); - printf("\tThumbprint (sha1) : %s\n",fp); - printf("The above x509 certificate couldn't be verified.Possibly because you do not have the CA cetificate in your certstore or certificate has expired.\nPlease look at the docs on how to create local certstore for private CA.\n"); + char* fp; + 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); + fp = crypto_cert_fingerprint(xcert); + + printf("Certificate details:\n"); + printf("\tSubject: %s\n", subject); + printf("\tIssuer: %s\n", issuer); + printf("\tThumbprint: %s\n", fp); + 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"); + xfree(fp); } diff --git a/libfreerdp-core/crypto.h b/libfreerdp-core/crypto.h index c73827b96..b63ff16c4 100644 --- a/libfreerdp-core/crypto.h +++ b/libfreerdp-core/crypto.h @@ -89,7 +89,7 @@ void crypto_cert_printinfo(X509* xcert); void crypto_cert_free(CryptoCert cert); boolean x509_verify_cert(CryptoCert cert); boolean crypto_cert_verify(CryptoCert server_cert, CryptoCert cacert); -rdpCertdata* crypto_get_certdata(X509 *xcert,char* hostname); +rdpCertdata* crypto_get_certdata(X509* xcert, char* hostname); boolean crypto_cert_get_public_key(CryptoCert cert, rdpBlob* public_key); void crypto_rsa_encrypt(uint8* input, int length, uint32 key_length, uint8* modulus, uint8* exponent, uint8* output); diff --git a/libfreerdp-core/tls.c b/libfreerdp-core/tls.c index 40edc9e65..c5760f0bd 100644 --- a/libfreerdp-core/tls.c +++ b/libfreerdp-core/tls.c @@ -248,28 +248,34 @@ rdpTls* tls_new() return tls; } -int tls_verify_certificate(CryptoCert cert,char* hostname) +int tls_verify_certificate(CryptoCert cert, char* hostname) { boolean ret; - ret=x509_verify_cert(cert); - if(!ret) + ret = x509_verify_cert(cert); + + if (!ret) { rdpCertdata* certdata; - certdata=crypto_get_certdata(cert->px509,hostname); - rdpCertstore* certstore=certstore_new(certdata); - if(match_certdata(certstore)==0) + certdata = crypto_get_certdata(cert->px509, hostname); + rdpCertstore* certstore = certstore_new(certdata); + + if (match_certdata(certstore) == 0) goto end; - if(certstore->match==1) + + if (certstore->match == 1) { - crypto_cert_printinfo(cert->px509); char answer; + crypto_cert_printinfo(cert->px509); + while(1) { - printf("Do you trust the above certificate? (Y/N)"); + printf("Do you trust the above certificate? (Y/N) "); answer=fgetc(stdin); + if(answer=='y' || answer =='Y') - { - print_certdata(certstore);break; + { + print_certdata(certstore); + break; } else if(answer=='n' || answer=='N') { @@ -278,15 +284,17 @@ int tls_verify_certificate(CryptoCert cert,char* hostname) } } } - else if(certstore->match==-1) + else if (certstore->match == -1) { tls_print_cert_error(); certstore_free(certstore); return 1; } - end: + +end: certstore_free(certstore); } + return 0; } @@ -295,7 +303,7 @@ void tls_print_cert_error() printf("#####################################\n"); printf("##############WARNING################\n"); printf("#####################################\n"); - printf("The thumbprint of certificate recieved\n"); + printf("The thumbprint of certificate received\n"); printf("did not match the stored thumbprint.You\n"); printf("might be a victim of MAN in the MIDDLE\n"); printf("ATTACK.It is also possible that server's\n");