On 2016-11-10 13:53:44 [+0200], Adrian Bunk wrote: > Control: tags -1 patch > > Not a perfect solution but sufficient for stretch is the following > change to use OpenSSL 1.0.2:
The patch attached is against 2.4.12. It is probably better to ship something more recent if at all :) Can upstream please look at it? > cu > Adrian > Sebastian
>From d22a8aad49283131472f79c9a1f369d78a397c9d Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior <sebast...@breakpoint.cc> Date: Thu, 8 Dec 2016 20:47:15 +0000 Subject: [PATCH] httest: add OpenSSL 1.1.0 support Most things are straight forward but then there is | sconfig->ssl->state=SSL_ST_ACCEPT; which I don't understand. Signed-off-by: Sebastian Andrzej Siewior <sebast...@breakpoint.cc> --- src/eval.c | 34 ++++++++++++++++--------- src/htntlm.c | 71 ++++++++++++++++++++++++++++++++++++++------------- src/htproxy.c | 4 +++ src/httest.c | 42 ++++++++++++++++++++----------- src/ssl.c | 77 +++++++++++++++++++++++++++++++++++++++++++------------- src/ssl_module.c | 21 ++++++++++++++-- 6 files changed, 185 insertions(+), 64 deletions(-) diff --git a/src/eval.c b/src/eval.c index d99cad8fc151..61268aff720d 100644 --- a/src/eval.c +++ b/src/eval.c @@ -109,6 +109,16 @@ static apr_status_t math_parse_factor(math_eval_t *hook); /************************************************************************ * Local ***********************************************************************/ +#if OPENSSL_VERSION_NUMBER < 0x10100000 + +#define sk_long_push(x, y) SKM_sk_push(long, x, y) +#define sk_long_pop(x) SKM_sk_pop(long, x) +#define sk_long_new_null() SKM_sk_new_null(long) + +#else +DEFINE_STACK_OF(long); +#endif + /** * skip spaces * @param hook IN eval instance @@ -317,7 +327,7 @@ static apr_status_t math_parse_factor(math_eval_t *hook) { case MATH_NUM: number = apr_pcalloc(hook->pool, sizeof(*number)); *number = hook->last_number * sign; - SKM_sk_push(long, hook->stack, number); + sk_long_push(hook->stack, number); math_get_token(hook); return APR_SUCCESS; break; @@ -367,8 +377,8 @@ static apr_status_t math_parse_term(math_eval_t *hook) { return status; } - right = SKM_sk_pop(long, hook->stack); - left = SKM_sk_pop(long, hook->stack); + right = sk_long_pop(hook->stack); + left = sk_long_pop(hook->stack); result = apr_pcalloc(hook->pool, sizeof(*result)); switch (token) { case MATH_MUL: @@ -388,7 +398,7 @@ static apr_status_t math_parse_term(math_eval_t *hook) { default: break; } - SKM_sk_push(long, hook->stack, result); + sk_long_push(hook->stack, result); token = math_peek_token(hook); } @@ -424,8 +434,8 @@ static apr_status_t math_parse_expression(math_eval_t *hook) { return status; } - right = SKM_sk_pop(long, hook->stack); - left = SKM_sk_pop(long, hook->stack); + right = sk_long_pop(hook->stack); + left = sk_long_pop(hook->stack); result = apr_pcalloc(hook->pool, sizeof(*result)); switch (token) { case MATH_ADD: @@ -437,7 +447,7 @@ static apr_status_t math_parse_expression(math_eval_t *hook) { default: break; } - SKM_sk_push(long, hook->stack, result); + sk_long_push(hook->stack, result); token = math_peek_token(hook); } @@ -474,8 +484,8 @@ static apr_status_t math_parse_equalit(math_eval_t *hook) { return status; } - right = SKM_sk_pop(long, hook->stack); - left = SKM_sk_pop(long, hook->stack); + right = sk_long_pop(hook->stack); + left = sk_long_pop(hook->stack); result = apr_pcalloc(hook->pool, sizeof(*result)); switch (token) { case MATH_EQ: @@ -499,7 +509,7 @@ static apr_status_t math_parse_equalit(math_eval_t *hook) { default: break; } - SKM_sk_push(long, hook->stack, result); + sk_long_push(hook->stack, result); } return APR_SUCCESS; } @@ -512,7 +522,7 @@ static apr_status_t math_parse_equalit(math_eval_t *hook) { static apr_status_t math_parse(math_eval_t * hook, long *val) { long *result; apr_status_t status = math_parse_equalit(hook); - result = SKM_sk_pop(long, hook->stack); + result = sk_long_pop(hook->stack); *val = *result; return status; } @@ -530,7 +540,7 @@ static apr_status_t math_parse(math_eval_t * hook, long *val) { math_eval_t *math_eval_make(apr_pool_t * pool) { math_eval_t *hook = apr_pcalloc(pool, sizeof(*hook)); hook->pool = pool; - hook->stack = SKM_sk_new_null(long); + hook->stack = sk_long_new_null(); hook->delimiter = apr_pstrdup(pool, "+-*/=<>!()"); return hook; diff --git a/src/htntlm.c b/src/htntlm.c index 69984a19c44f..c4e566766abd 100644 --- a/src/htntlm.c +++ b/src/htntlm.c @@ -669,6 +669,31 @@ static unsigned char * get_ntlm_hash(htntlm_t *hook) { return get_hash(hook, ntlmbuffer, (DES_cblock *)&chl); } +#if OPENSSL_VERSION_NUMBER < 0x10100000 + +static inline HMAC_CTX *HMAC_CTX_new(void) +{ + HMAC_CTX *ctx = malloc(sizeof(HMAC_CTX)); + + if (!ctx) + return NULL; + HMAC_CTX_init(ctx); + return ctx; +} + +static inline void HMAC_CTX_reset(HMAC_CTX *ctx) +{ + HMAC_CTX_init(ctx); +} + +static inline void HMAC_CTX_free(HMAC_CTX *ctx) +{ + memset(ctx, 0, sizeof(ctx)); + free(ctx); +} + +#endif + /** * Create lm2 hash out of the values stored in hook * @@ -689,7 +714,7 @@ static unsigned char * get_lm2_hash(htntlm_t *hook, uint16_t *hash_len) { char *udomain; apr_size_t udomain_len; unsigned char *buf; - HMAC_CTX hmac; + HMAC_CTX *hmac; unsigned char challenges[16]; uint64_t chl = ntlm_hton64(hook->challenge); @@ -711,11 +736,16 @@ static unsigned char * get_lm2_hash(htntlm_t *hook, uint16_t *hash_len) { memcpy(buf, uuser, uuser_len); memcpy(&buf[uuser_len], udomain, udomain_len); - HMAC_CTX_init(&hmac); - HMAC_Init_ex(&hmac, ntlm_hash, 16, md5, NULL); - HMAC_Update(&hmac, buf, uuser_len + udomain_len); + hmac = HMAC_CTX_new(); + if (!hmac) { + printf("HMAC_CTX_new() failed\n"); + exit(1); + } + HMAC_Init_ex(hmac, ntlm_hash, 16, md5, NULL); + HMAC_Update(hmac, buf, uuser_len + udomain_len); len = 16; - HMAC_Final(&hmac, ntlm2_hash, &len); + HMAC_Final(hmac, ntlm2_hash, &len); + HMAC_CTX_reset(hmac); /* 3. client challenge */ @@ -724,11 +754,11 @@ static unsigned char * get_lm2_hash(htntlm_t *hook, uint16_t *hash_len) { memcpy(challenges, &chl, 8); memcpy(&challenges[8], &hook->client_challenge, 8); - HMAC_CTX_init(&hmac); - HMAC_Init_ex(&hmac, ntlm2_hash, 16, md5, NULL); - HMAC_Update(&hmac, challenges, 16); + HMAC_Init_ex(hmac, ntlm2_hash, 16, md5, NULL); + HMAC_Update(hmac, challenges, 16); len = 16; - HMAC_Final(&hmac, lm2_hash, &len); + HMAC_Final(hmac, lm2_hash, &len); + HMAC_CTX_free(hmac); memcpy(&lm2_hash[16], &hook->client_challenge, 8); @@ -750,7 +780,7 @@ static unsigned char * get_ntlm2_hash(htntlm_t *hook, uint16_t *hash_len) { apr_size_t uuser_len; apr_size_t udomain_len; const EVP_MD *md5 = EVP_md5(); - HMAC_CTX hmac; + HMAC_CTX *hmac; unsigned char ntlm_hash[16]; unsigned char ntlm2_hash[16]; unsigned char blob_hash[16]; @@ -783,11 +813,16 @@ static unsigned char * get_ntlm2_hash(htntlm_t *hook, uint16_t *hash_len) { memcpy(part, uuser, uuser_len); memcpy(&part[uuser_len], udomain, udomain_len); - HMAC_CTX_init(&hmac); - HMAC_Init_ex(&hmac, ntlm_hash, 16, md5, NULL); - HMAC_Update(&hmac, part, uuser_len + udomain_len); + hmac = HMAC_CTX_new(); + if (!hmac) { + printf("HMAC_CTX_new() failed\n"); + exit(1); + } + HMAC_Init_ex(hmac, ntlm_hash, 16, md5, NULL); + HMAC_Update(hmac, part, uuser_len + udomain_len); len = 16; - HMAC_Final(&hmac, ntlm2_hash, &len); + HMAC_Final(hmac, ntlm2_hash, &len); + HMAC_CTX_reset(hmac); /* 3. blob */ blob = apr_pcalloc(hook->pool, 28 + ti_len + 4); @@ -814,11 +849,11 @@ static unsigned char * get_ntlm2_hash(htntlm_t *hook, uint16_t *hash_len) { } memcpy(&buf[8], blob, 28 + ti_len + 4); - HMAC_CTX_init(&hmac); - HMAC_Init_ex(&hmac, ntlm2_hash, 16, md5, NULL); - HMAC_Update(&hmac, buf, 8 + 28 + ti_len + 4); + HMAC_Init_ex(hmac, ntlm2_hash, 16, md5, NULL); + HMAC_Update(hmac, buf, 8 + 28 + ti_len + 4); len = 16; - HMAC_Final(&hmac, blob_hash, &len); + HMAC_Final(hmac, blob_hash, &len); + HMAC_CTX_free(hmac); /* 5. this value concat with the blob */ memcpy(buf, blob_hash, 16); diff --git a/src/htproxy.c b/src/htproxy.c index a1fa9b09e855..79d865c84170 100644 --- a/src/htproxy.c +++ b/src/htproxy.c @@ -1343,10 +1343,14 @@ int main(int argc, const char *const argv[]) { #ifdef RSAREF R_malloc_init(); #else +#if OPENSSL_VERSION_NUMBER < 0x10100000 CRYPTO_malloc_init(); #endif +#endif +#if OPENSSL_VERSION_NUMBER < 0x10100000 SSL_load_error_strings(); SSL_library_init(); +#endif ssl_util_thread_setup(pool); #endif diff --git a/src/httest.c b/src/httest.c index b353183137ff..67dbdaa1ecab 100644 --- a/src/httest.c +++ b/src/httest.c @@ -77,6 +77,7 @@ #include "tcp_module.h" #include "body.h" + /************************************************************************ * Defines ***********************************************************************/ @@ -488,6 +489,17 @@ int success = 1; /************************************************************************ * Private ***********************************************************************/ +#if OPENSSL_VERSION_NUMBER < 0x10100000 + +#define sk_char_new(x) SKM_sk_new(char, x) +#define sk_char_push(x, y) SKM_sk_push(char, x, y) +#define sk_char_sort(x) SKM_sk_sort(char, x) +#define sk_char_pop(x) SKM_sk_pop(char, x) + +#else + +DEFINE_STACK_OF(char); +#endif static void worker_set_global_error(worker_t *worker); static apr_status_t worker_interpret(worker_t * worker, worker_t *parent, @@ -2370,7 +2382,7 @@ static void show_commands(apr_pool_t *p, global_t *global) { char *line; fprintf(stdout, "Global commands"); - sorted = SKM_sk_new(char, commands_compare); + sorted = sk_char_new(commands_compare); for (i = 0; global_commands[i].name; i++) { if (global_commands[i].flags & COMMAND_FLAGS_DEPRECIATED) { line = apr_psprintf(p, "%s *DEPRECIATED*", @@ -2388,19 +2400,19 @@ static void show_commands(apr_pool_t *p, global_t *global) { line = apr_psprintf(p, "%s %s", global_commands[i].name, global_commands[i].syntax); } - SKM_sk_push(char, sorted, line); + sk_char_push(sorted, line); } - SKM_sk_sort(char, sorted); + sk_char_sort(sorted); - line = SKM_sk_pop(char, sorted); + line = sk_char_pop(sorted); while (line) { fprintf(stdout, "\n"); fprintf(stdout, "\t%s", line); - line = SKM_sk_pop(char, sorted); + line = sk_char_pop(sorted); } fprintf(stdout, "\n\nLocal commands"); - sorted = SKM_sk_new(char, commands_compare); + sorted = sk_char_new(commands_compare); for (i = 0; local_commands[i].name; i++) { if (local_commands[i].flags & COMMAND_FLAGS_DEPRECIATED) { line = apr_psprintf(p, "*DEPRECIATED* %s", @@ -2418,19 +2430,19 @@ static void show_commands(apr_pool_t *p, global_t *global) { line = apr_psprintf(p, "%s %s", local_commands[i].name, local_commands[i].syntax); } - SKM_sk_push(char, sorted, line); + sk_char_push(sorted, line); } - SKM_sk_sort(char, sorted); + sk_char_sort(sorted); - line = SKM_sk_pop(char, sorted); + line = sk_char_pop(sorted); while (line) { fprintf(stdout, "\n"); fprintf(stdout, "\t%s", line); - line = SKM_sk_pop(char, sorted); + line = sk_char_pop(sorted); } fprintf(stdout, "\n\nModule commands"); - sorted = SKM_sk_new(char, commands_compare); + sorted = sk_char_new(commands_compare); { apr_hash_index_t *hi; const char *module; @@ -2453,19 +2465,19 @@ static void show_commands(apr_pool_t *p, global_t *global) { line = apr_psprintf(p, "%s:%s %s", module, command, worker->short_desc?worker->short_desc:""); } - SKM_sk_push(char, sorted, line); + sk_char_push(sorted, line); } } } } } - SKM_sk_sort(char, sorted); + sk_char_sort(sorted); - line = SKM_sk_pop(char, sorted); + line = sk_char_pop(sorted); while (line) { fprintf(stdout, "\n"); fprintf(stdout, "\t%s", line); - line = SKM_sk_pop(char, sorted); + line = sk_char_pop(sorted); } fprintf(stdout, "\n\n(Get detailed help with --help-command <command>)\n"); diff --git a/src/ssl.c b/src/ssl.c index edb3ee8519f4..ce503f96acd3 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -68,16 +68,62 @@ #ifndef NUL #define NUL '\0' #endif -#define X509_NAME_get_entries(xs) (xs->entries) + #define X509_REVOKED_get_serialNumber(xs) (xs->serialNumber) -#define X509_NAME_ENTRY_get_data_ptr(xs) (xs->value->data) -#define X509_NAME_ENTRY_get_data_len(xs) (xs->value->length) -#define X509_get_signature_algorithm(xs) (xs->cert_info->signature->algorithm) -#define X509_get_key_algorithm(xs) (xs->cert_info->key->algor->algorithm) #define strEQn(s1,s2,n) (strncmp(s1,s2,n) == 0) #define strcEQ(s1,s2) (strcasecmp(s1,s2) == 0) #define strcEQn(s1,s2,n) (strncasecmp(s1,s2,n) == 0) +#if OPENSSL_VERSION_NUMBER < 0x10100000 + +#define X509_get_signature_algorithm(xs) (xs->cert_info->signature->algorithm) +#define X509_get_key_algorithm(xs) (xs->cert_info->key->algor->algorithm) +#define X509_NAME_ENTRY_get_data_ptr(xs) (xs->value->data) +#define X509_NAME_ENTRY_get_data_len(xs) (xs->value->length) + +#else + +static const ASN1_OBJECT *X509_get_signature_algorithm(const X509 *x) +{ + const X509_ALGOR *algor; + const ASN1_OBJECT *paobj; + + algor = X509_get0_tbs_sigalg(x); + X509_ALGOR_get0(&paobj, NULL, NULL, algor); + return paobj; +} + +static const ASN1_OBJECT *X509_get_key_algorithm(const X509 *x) +{ + X509_PUBKEY *pubkey; + X509_ALGOR *algor; + const ASN1_OBJECT *paobj; + + pubkey = X509_get_X509_PUBKEY(x); + X509_PUBKEY_get0_param(NULL, NULL, NULL, &algor, pubkey); + X509_ALGOR_get0(&paobj, NULL, NULL, algor); + return paobj; +} + +static inline const unsigned char * +X509_NAME_ENTRY_get_data_ptr(const X509_NAME_ENTRY *ne) +{ + ASN1_STRING *str; + + str = X509_NAME_ENTRY_get_data(ne); + return ASN1_STRING_get0_data(str); +} + +static inline int X509_NAME_ENTRY_get_data_len(const X509_NAME_ENTRY *ne) +{ + ASN1_STRING *str; + + str = X509_NAME_ENTRY_get_data(ne); + return ASN1_STRING_length(str); +} + +#endif + /************************************************************************ * Forward declaration ***********************************************************************/ @@ -545,18 +591,16 @@ static char *ssl_var_lookup_ssl_cert_dn(apr_pool_t *p, X509_NAME *xsname, const for (i = 0; ssl_var_lookup_ssl_cert_dn_rec[i].name != NULL; i++) { if (strEQn(var, ssl_var_lookup_ssl_cert_dn_rec[i].name, varlen) && strlen(ssl_var_lookup_ssl_cert_dn_rec[i].name) == varlen) { - for (j = 0; j < sk_X509_NAME_ENTRY_num((STACK_OF(X509_NAME_ENTRY) *) - X509_NAME_get_entries(xsname)); - j++) { - xsne = sk_X509_NAME_ENTRY_value((STACK_OF(X509_NAME_ENTRY) *) - X509_NAME_get_entries(xsname), j); + for (j = 0; j < X509_NAME_entry_count(xsname); j++) { + + xsne = X509_NAME_get_entry(xsname, j); n =OBJ_obj2nid((ASN1_OBJECT *)X509_NAME_ENTRY_get_object(xsne)); if (n == ssl_var_lookup_ssl_cert_dn_rec[i].nid && idx-- == 0) { - unsigned char *data = X509_NAME_ENTRY_get_data_ptr(xsne); + const unsigned char *data = X509_NAME_ENTRY_get_data_ptr(xsne); /* cast needed from unsigned char to char */ - result = apr_pstrmemdup(p, (char *)data, + result = apr_pstrmemdup(p, data, X509_NAME_ENTRY_get_data_len(xsne)); #if APR_CHARSET_EBCDIC ap_xlate_proto_from_ascii(result, X509_NAME_ENTRY_get_data_len(xsne)); @@ -661,7 +705,6 @@ static char *ssl_var_lookup_ssl_cert_PEM(apr_pool_t *p, X509 *xs) static void extract_dn(apr_table_t *t, apr_hash_t *nids, const char *pfx, X509_NAME *xn, apr_pool_t *p) { - STACK_OF(X509_NAME_ENTRY) *ents = X509_NAME_get_entries(xn); X509_NAME_ENTRY *xsne; apr_hash_t *count; int i, nid; @@ -671,10 +714,10 @@ static void extract_dn(apr_table_t *t, apr_hash_t *nids, const char *pfx, count = apr_hash_make(p); /* For each RDN... */ - for (i = 0; i < sk_X509_NAME_ENTRY_num(ents); i++) { + for (i = 0; i < X509_NAME_entry_count(xn); i++) { const char *tag; - xsne = sk_X509_NAME_ENTRY_value(ents, i); + xsne = X509_NAME_get_entry(xn, i); /* Retrieve the nid, and check whether this is one of the nids * which are to be extracted. */ @@ -682,7 +725,7 @@ static void extract_dn(apr_table_t *t, apr_hash_t *nids, const char *pfx, tag = apr_hash_get(nids, &nid, sizeof nid); if (tag) { - unsigned char *data = X509_NAME_ENTRY_get_data_ptr(xsne); + const unsigned char *data = X509_NAME_ENTRY_get_data_ptr(xsne); const char *key; int *dup; char *value; @@ -701,7 +744,7 @@ static void extract_dn(apr_table_t *t, apr_hash_t *nids, const char *pfx, } /* cast needed from 'unsigned char *' to 'char *' */ - value = apr_pstrmemdup(p, (char *)data, + value = apr_pstrmemdup(p, data, X509_NAME_ENTRY_get_data_len(xsne)); #if APR_CHARSET_EBCDIC ap_xlate_proto_from_ascii(value, X509_NAME_ENTRY_get_data_len(xsne)); diff --git a/src/ssl_module.c b/src/ssl_module.c index fcde8924c95d..5100faa25f1f 100644 --- a/src/ssl_module.c +++ b/src/ssl_module.c @@ -734,16 +734,20 @@ static int worker_set_client_method(worker_t * worker, const char *sslstr) { is_ssl = 1; config->meth = SSLv23_client_method(); } +#if OPENSSL_VERSION_NUMBER < 0x10100000 #ifndef OPENSSL_NO_SSL2 else if (strcasecmp(sslstr, "SSL2") == 0) { is_ssl = 1; config->meth = SSLv2_client_method(); } #endif +#endif +#ifndef OPENSSL_NO_SSL3_METHOD else if (strcasecmp(sslstr, "SSL3") == 0) { is_ssl = 1; config->meth = SSLv3_client_method(); } +#endif else if (strcasecmp(sslstr, "TLS1") == 0) { is_ssl = 1; config->meth = TLSv1_client_method(); @@ -781,16 +785,20 @@ static int worker_set_server_method(worker_t * worker, const char *sslstr) { is_ssl = 1; config->meth = SSLv23_server_method(); } +#if OPENSSL_VERSION_NUMBER < 0x10100000 #ifndef OPENSSL_NO_SSL2 else if (strcasecmp(sslstr, "SSL2") == 0) { is_ssl = 1; config->meth = SSLv2_server_method(); } #endif +#endif +#ifndef OPENSSL_NO_SSL3_METHOD else if (strcasecmp(sslstr, "SSL3") == 0) { is_ssl = 1; config->meth = SSLv3_server_method(); } +#endif else if (strcasecmp(sslstr, "TLS1") == 0) { is_ssl = 1; config->meth = TLSv1_server_method(); @@ -1316,8 +1324,12 @@ static apr_status_t block_SSL_GET_SESSION_ID(worker_t * worker, worker_t *parent sess = SSL_get_session(sconfig->ssl); if (sess) { - val = apr_pcalloc(ptmp, apr_base64_encode_len(sess->session_id_length)); - apr_base64_encode_binary(val, sess->session_id, sess->session_id_length); + const unsigned char *ses_val; + unsigned int ses_len; + + ses_val = SSL_SESSION_get_id(sess, &ses_len); + val = apr_pcalloc(ptmp, apr_base64_encode_len(ses_len)); + apr_base64_encode_binary(val, ses_val, ses_len); worker_var_set(parent, copy, val); } @@ -1391,7 +1403,10 @@ static apr_status_t block_SSL_RENEG_CERT(worker_t * worker, worker_t *parent, ap return APR_EACCES; } worker_ssl_handshake(worker); +#if OPENSSL_VERSION_NUMBER < 0x10100000 + /* removed as of 0131df49ee1f ("Remove the SSL state variable") */ sconfig->ssl->state=SSL_ST_ACCEPT; +#endif worker_ssl_handshake(worker); config->cert = SSL_get_peer_certificate(sconfig->ssl); @@ -1993,8 +2008,10 @@ apr_status_t ssl_module_init(global_t *global) { #ifdef RSAREF R_malloc_init(); #else +#if OPENSSL_VERSION_NUMBER < 0x10100000 CRYPTO_malloc_init(); #endif +#endif SSL_load_error_strings(); SSL_library_init(); ssl_util_thread_setup(global->pool); -- 2.10.2