X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=openssl.c;h=d27f91878d3f47dfcd2310a2367c090a528cedfb;hp=72d97d99b9fbd09748c7b35f637ac94f1c5c1d5b;hb=873efe14859c0fb3f53a905eb346c36cf5fe7eda;hpb=52460473669cd31edd8cb8ae66c6b94c489e7e1d diff --git a/openssl.c b/openssl.c index 72d97d99..d27f9187 100644 --- a/openssl.c +++ b/openssl.c @@ -58,7 +58,7 @@ #define VALID_DATETIME_FMT "%y%m%d%H%M%SZ" #define VALID_DATETIME_BUFLEN 16 -static int generate_webpage_certificate(struct client_state *csp); +static int generate_host_certificate(struct client_state *csp); static void free_client_ssl_structures(struct client_state *csp); static void free_server_ssl_structures(struct client_state *csp); static int ssl_store_cert(struct client_state *csp, X509* crt); @@ -229,6 +229,11 @@ extern int ssl_recv_data(struct ssl_attr *ssl_attr, unsigned char *buf, size_t m ret = BIO_read(bio, buf, (int)max_length); } while (ret <= 0 && BIO_should_retry(bio)); + if (BIO_get_ssl(bio, &ssl) == 1) + { + fd = SSL_get_fd(ssl); + } + if (ret < 0) { log_ssl_errors(LOG_LEVEL_ERROR, @@ -237,11 +242,6 @@ extern int ssl_recv_data(struct ssl_attr *ssl_attr, unsigned char *buf, size_t m return -1; } - if (BIO_get_ssl(bio, &ssl) == 1) - { - fd = SSL_get_fd(ssl); - } - log_error(LOG_LEVEL_RECEIVED, "TLS from socket %d: %N", fd, ret, buf); @@ -308,7 +308,7 @@ static int ssl_store_cert(struct client_state *csp, X509* crt) */ if (!PEM_write_bio_X509(bio, crt)) { - log_ssl_errors(LOG_LEVEL_ERROR, "PEM_write_X509() failed"); + log_ssl_errors(LOG_LEVEL_ERROR, "PEM_write_bio_X509() failed"); ret = -1; goto exit; } @@ -396,6 +396,7 @@ static int ssl_store_cert(struct client_state *csp, X509* crt) } else { + int i; if (bs->type == V_ASN1_NEG_INTEGER) { if (BIO_puts(bio, " (Negative)") < 0) @@ -405,7 +406,7 @@ static int ssl_store_cert(struct client_state *csp, X509* crt) goto exit; } } - for (int i = 0; i < bs->length; i++) + for (i = 0; i < bs->length; i++) { if (BIO_printf(bio, "%02x%c", bs->data[i], ((i + 1 == bs->length) ? '\n' : ':')) <= 0) @@ -653,6 +654,13 @@ static int ssl_store_cert(struct client_state *csp, X509* crt) BIO_write(bio, &zero, 1); len = BIO_get_mem_data(bio, &bio_mem_data); + if (len <= 0) + { + log_error(LOG_LEVEL_ERROR, "BIO_get_mem_data() returned %d " + "while gathering certificate information", len); + ret = -1; + goto exit; + } encoded_text = html_encode(bio_mem_data); if (encoded_text == NULL) { @@ -775,11 +783,11 @@ extern int create_client_ssl_connection(struct client_state *csp) */ privoxy_mutex_lock(&certificate_mutex); - ret = generate_webpage_certificate(csp); + ret = generate_host_certificate(csp); if (ret < 0) { log_error(LOG_LEVEL_ERROR, - "Generate_webpage_certificate failed: %d", ret); + "generate_host_certificate failed: %d", ret); privoxy_mutex_unlock(&certificate_mutex); ret = -1; goto exit; @@ -1140,7 +1148,8 @@ extern int create_server_ssl_connection(struct client_state *csp) chain = SSL_get_peer_cert_chain(ssl); if (chain) { - for (int i = 0; i < sk_X509_num(chain); i++) + int i; + for (i = 0; i < sk_X509_num(chain); i++) { if (ssl_store_cert(csp, sk_X509_value(chain, i)) != 0) { @@ -1278,7 +1287,7 @@ extern int ssl_base64_encode(unsigned char *dst, size_t dlen, size_t *olen, const unsigned char *src, size_t slen) { *olen = 4 * ((slen/3) + ((slen%3) ? 1 : 0)) + 1; - if (*olen < dlen) + if (*olen > dlen) { return ENOBUFS; } @@ -1463,39 +1472,41 @@ exit: static int generate_key(struct client_state *csp, char **key_buf) { int ret = 0; - char* key_file_path = NULL; - BIGNUM *exp = BN_new(); - RSA *rsa = RSA_new(); - EVP_PKEY *key = EVP_PKEY_new(); + char* key_file_path; + BIGNUM *exp; + RSA *rsa; + EVP_PKEY *key; - if (exp == NULL || rsa == NULL || key == NULL) + key_file_path = make_certs_path(csp->config->certificate_directory, + (char *)csp->http->hash_of_host_hex, KEY_FILE_TYPE); + if (key_file_path == NULL) { - log_ssl_errors(LOG_LEVEL_ERROR, "RSA key memory allocation failure"); - ret = -1; - goto exit; + return -1; } - if (BN_set_word(exp, RSA_KEY_PUBLIC_EXPONENT) != 1) + /* + * Test if key already exists. If so, we don't have to create it again. + */ + if (file_exists(key_file_path) == 1) { - log_ssl_errors(LOG_LEVEL_ERROR, "Setting RSA key exponent failed"); - ret = -1; - goto exit; + freez(key_file_path); + return 0; } - key_file_path = make_certs_path(csp->config->certificate_directory, - (char *)csp->http->hash_of_host_hex, KEY_FILE_TYPE); - if (key_file_path == NULL) + exp = BN_new(); + rsa = RSA_new(); + key = EVP_PKEY_new(); + if (exp == NULL || rsa == NULL || key == NULL) { + log_ssl_errors(LOG_LEVEL_ERROR, "RSA key memory allocation failure"); ret = -1; goto exit; } - /* - * Test if key already exists. If so, we don't have to create it again. - */ - if (file_exists(key_file_path) == 1) + if (BN_set_word(exp, RSA_KEY_PUBLIC_EXPONENT) != 1) { - ret = 0; + log_ssl_errors(LOG_LEVEL_ERROR, "Setting RSA key exponent failed"); + ret = -1; goto exit; } @@ -1607,8 +1618,6 @@ static int ssl_certificate_is_invalid(const char *cert_file) if (!(cert = ssl_certificate_load(cert_file))) { - log_ssl_errors(LOG_LEVEL_ERROR, - "Error reading certificate file %s", cert_file); return 1; } @@ -1638,7 +1647,7 @@ static int ssl_certificate_is_invalid(const char *cert_file) * 3 : nid = OpenSSL NID * 4 : value = extension value * - * Returns : 0 => Error while setting extensuon data + * Returns : 0 => Error while setting extension data * 1 => It worked * *********************************************************************/ @@ -1700,7 +1709,7 @@ static int set_subject_alternative_name(X509 *cert, X509 *issuer, const char *ho /********************************************************************* * - * Function : generate_webpage_certificate + * Function : generate_host_certificate * * Description : Creates certificate file in presetted directory. * If certificate already exists, no other certificate @@ -1716,7 +1725,7 @@ static int set_subject_alternative_name(X509 *cert, X509 *issuer, const char *ho * 1 => Certificate created * *********************************************************************/ -static int generate_webpage_certificate(struct client_state *csp) +static int generate_host_certificate(struct client_state *csp) { char *key_buf = NULL; /* Buffer for created key */ X509 *issuer_cert = NULL; @@ -1755,6 +1764,15 @@ static int generate_webpage_certificate(struct client_state *csp) return -1; } + if (enforce_sane_certificate_state(cert_opt.output_file, + cert_opt.subject_key)) + { + freez(cert_opt.output_file); + freez(cert_opt.subject_key); + + return -1; + } + if (file_exists(cert_opt.output_file) == 1) { /* The file exists, but is it valid? */ @@ -1914,7 +1932,7 @@ static int generate_webpage_certificate(struct client_state *csp) serial_num = BN_new(); if (!serial_num) { - log_error(LOG_LEVEL_ERROR, "generate_webpage_certificate: memory error"); + log_error(LOG_LEVEL_ERROR, "generate_host_certificate: memory error"); ret = -1; goto exit; }