diff options
author | Yves-Alexis Perez <corsac@debian.org> | 2016-06-28 16:24:27 +0200 |
---|---|---|
committer | Yves-Alexis Perez <corsac@debian.org> | 2016-06-28 16:24:27 +0200 |
commit | db2a27dbddad0168c967ee304d3b8bff8f626d33 (patch) | |
tree | 6f63f36d9035a1cbf8d27236002f5e9c6dfb1357 /debian/patches | |
parent | 6d75481e2b71c6c9fc48bfeb9e1faa6d5fb64c64 (diff) | |
download | vyos-strongswan-db2a27dbddad0168c967ee304d3b8bff8f626d33.tar.gz vyos-strongswan-db2a27dbddad0168c967ee304d3b8bff8f626d33.zip |
Add patch to port to OpenSSL 1.1.0
* debian/patches:
- 05_port-openssl-1.1.0 added, port to OpenSSL 1.1.0. closes: #828561
Diffstat (limited to 'debian/patches')
-rw-r--r-- | debian/patches/05_port-openssl-1.1.0.patch | 1121 | ||||
-rw-r--r-- | debian/patches/series | 1 |
2 files changed, 1122 insertions, 0 deletions
diff --git a/debian/patches/05_port-openssl-1.1.0.patch b/debian/patches/05_port-openssl-1.1.0.patch new file mode 100644 index 000000000..471511e78 --- /dev/null +++ b/debian/patches/05_port-openssl-1.1.0.patch @@ -0,0 +1,1121 @@ +diff --git a/src/libstrongswan/plugins/openssl/openssl_crl.c b/src/libstrongswan/plugins/openssl/openssl_crl.c +index cb02c663ca0b..20bac6be57dc 100644 +--- a/src/libstrongswan/plugins/openssl/openssl_crl.c ++++ b/src/libstrongswan/plugins/openssl/openssl_crl.c +@@ -46,6 +46,17 @@ + #include <collections/enumerator.h> + #include <credentials/certificates/x509.h> + ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++static inline void X509_CRL_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg, const X509_CRL *crl) { ++ if (psig) { *psig = crl->signature; } ++ if (palg) { *palg = crl->sig_alg; } ++} ++#define X509_REVOKED_get0_serialNumber(r) ({ (r)->serialNumber; }) ++#define X509_REVOKED_get0_revocationDate(r) ({ (r)->revocationDate; }) ++#define X509_CRL_get0_extensions(c) ({ (c)->crl->extensions; }) ++#define X509_ALGOR_get0(oid, ppt, ppv, alg) ({ *(oid) = (alg)->algorithm; }) ++#endif ++ + typedef struct private_openssl_crl_t private_openssl_crl_t; + + /** +@@ -141,11 +152,13 @@ METHOD(enumerator_t, crl_enumerate, bool, + revoked = sk_X509_REVOKED_value(this->stack, this->i); + if (serial) + { +- *serial = openssl_asn1_str2chunk(revoked->serialNumber); ++ *serial = openssl_asn1_str2chunk( ++ X509_REVOKED_get0_serialNumber(revoked)); + } + if (date) + { +- *date = openssl_asn1_to_time(revoked->revocationDate); ++ *date = openssl_asn1_to_time( ++ X509_REVOKED_get0_revocationDate(revoked)); + } + if (reason) + { +@@ -231,6 +244,7 @@ METHOD(certificate_t, issued_by, bool, + chunk_t fingerprint, tbs; + public_key_t *key; + x509_t *x509; ++ ASN1_BIT_STRING *sig; + bool valid; + + if (issuer->get_type(issuer) != CERT_X509) +@@ -266,9 +280,14 @@ METHOD(certificate_t, issued_by, bool, + { + return FALSE; + } ++ /* i2d_re_X509_CRL_tbs() was added with 1.1.0 when X509_CRL became opaque */ ++#if OPENSSL_VERSION_NUMBER >= 0x10100000L ++ tbs = openssl_i2chunk(re_X509_CRL_tbs, this->crl); ++#else + tbs = openssl_i2chunk(X509_CRL_INFO, this->crl->crl); +- valid = key->verify(key, this->scheme, tbs, +- openssl_asn1_str2chunk(this->crl->signature)); ++#endif ++ X509_CRL_get0_signature(&sig, NULL, this->crl); ++ valid = key->verify(key, this->scheme, tbs, openssl_asn1_str2chunk(sig)); + free(tbs.ptr); + key->destroy(key); + if (valid && scheme) +@@ -448,7 +467,7 @@ static bool parse_extensions(private_openssl_crl_t *this) + X509_EXTENSION *ext; + STACK_OF(X509_EXTENSION) *extensions; + +- extensions = this->crl->crl->extensions; ++ extensions = X509_CRL_get0_extensions(this->crl); + if (extensions) + { + num = sk_X509_EXTENSION_num(extensions); +@@ -494,6 +513,8 @@ static bool parse_extensions(private_openssl_crl_t *this) + static bool parse_crl(private_openssl_crl_t *this) + { + const unsigned char *ptr = this->encoding.ptr; ++ ASN1_OBJECT *oid; ++ X509_ALGOR *alg; + + this->crl = d2i_X509_CRL(NULL, &ptr, this->encoding.len); + if (!this->crl) +@@ -501,14 +522,28 @@ static bool parse_crl(private_openssl_crl_t *this) + return FALSE; + } + ++ X509_CRL_get0_signature(NULL, &alg, this->crl); ++ X509_ALGOR_get0(&oid, NULL, NULL, alg); ++#if OPENSSL_VERSION_NUMBER < 0x10100000L + if (!chunk_equals( + openssl_asn1_obj2chunk(this->crl->crl->sig_alg->algorithm), + openssl_asn1_obj2chunk(this->crl->sig_alg->algorithm))) + { + return FALSE; + } +- this->scheme = signature_scheme_from_oid(openssl_asn1_known_oid( +- this->crl->sig_alg->algorithm)); ++#elif 0 ++ /* FIXME: we currently can't do this if X509_CRL is opaque (>= 1.1.0) as ++ * X509_CRL_get0_tbs_sigalg() does not exist and there does not seem to be ++ * another easy way to get the algorithm from the tbsCertList of the CRL */ ++ alg = X509_CRL_get0_tbs_sigalg(this->crl); ++ X509_ALGOR_get0(&oid_tbs, NULL, NULL, alg); ++ if (!chunk_equals(openssl_asn1_obj2chunk(oid), ++ openssl_asn1_obj2chunk(oid_tbs))) ++ { ++ return FALSE; ++ } ++#endif ++ this->scheme = signature_scheme_from_oid(openssl_asn1_known_oid(oid)); + + this->issuer = openssl_x509_name2id(X509_CRL_get_issuer(this->crl)); + if (!this->issuer) +diff --git a/src/libstrongswan/plugins/openssl/openssl_crypter.c b/src/libstrongswan/plugins/openssl/openssl_crypter.c +index 26f4700b81e8..a690adbcd2c0 100644 +--- a/src/libstrongswan/plugins/openssl/openssl_crypter.c ++++ b/src/libstrongswan/plugins/openssl/openssl_crypter.c +@@ -93,8 +93,10 @@ static char* lookup_algorithm(u_int16_t ikev2_algo, size_t *key_size) + static bool crypt(private_openssl_crypter_t *this, chunk_t data, chunk_t iv, + chunk_t *dst, int enc) + { ++ EVP_CIPHER_CTX *ctx; + int len; + u_char *out; ++ bool success = FALSE; + + out = data.ptr; + if (dst) +@@ -102,16 +104,19 @@ static bool crypt(private_openssl_crypter_t *this, chunk_t data, chunk_t iv, + *dst = chunk_alloc(data.len); + out = dst->ptr; + } +- EVP_CIPHER_CTX ctx; +- EVP_CIPHER_CTX_init(&ctx); +- return EVP_CipherInit_ex(&ctx, this->cipher, NULL, NULL, NULL, enc) && +- EVP_CIPHER_CTX_set_padding(&ctx, 0) /* disable padding */ && +- EVP_CIPHER_CTX_set_key_length(&ctx, this->key.len) && +- EVP_CipherInit_ex(&ctx, NULL, NULL, this->key.ptr, iv.ptr, enc) && +- EVP_CipherUpdate(&ctx, out, &len, data.ptr, data.len) && +- /* since padding is disabled this does nothing */ +- EVP_CipherFinal_ex(&ctx, out + len, &len) && +- EVP_CIPHER_CTX_cleanup(&ctx); ++ ctx = EVP_CIPHER_CTX_new(); ++ if (EVP_CipherInit_ex(ctx, this->cipher, NULL, NULL, NULL, enc) && ++ EVP_CIPHER_CTX_set_padding(ctx, 0) /* disable padding */ && ++ EVP_CIPHER_CTX_set_key_length(ctx, this->key.len) && ++ EVP_CipherInit_ex(ctx, NULL, NULL, this->key.ptr, iv.ptr, enc) && ++ EVP_CipherUpdate(ctx, out, &len, data.ptr, data.len) && ++ /* since padding is disabled this does nothing */ ++ EVP_CipherFinal_ex(ctx, out + len, &len)) ++ { ++ success = TRUE; ++ } ++ EVP_CIPHER_CTX_free(ctx); ++ return success; + } + + METHOD(crypter_t, decrypt, bool, +@@ -129,13 +134,13 @@ METHOD(crypter_t, encrypt, bool, + METHOD(crypter_t, get_block_size, size_t, + private_openssl_crypter_t *this) + { +- return this->cipher->block_size; ++ return EVP_CIPHER_block_size(this->cipher); + } + + METHOD(crypter_t, get_iv_size, size_t, + private_openssl_crypter_t *this) + { +- return this->cipher->iv_len; ++ return EVP_CIPHER_iv_length(this->cipher); + } + + METHOD(crypter_t, get_key_size, size_t, +diff --git a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c +index 49ec4880480f..f08dfff7e8f1 100644 +--- a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c ++++ b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c +@@ -22,9 +22,17 @@ + #include <openssl/dh.h> + + #include "openssl_diffie_hellman.h" ++#include "openssl_util.h" + + #include <utils/debug.h> + ++/* these were added with 1.1.0 when DH was made opaque */ ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++OPENSSL_KEY_FALLBACK(DH, key, pub_key, priv_key) ++OPENSSL_KEY_FALLBACK(DH, pqg, p, q, g) ++#define DH_set_length(dh, len) ({ (dh)->length = len; 1; }) ++#endif ++ + typedef struct private_openssl_diffie_hellman_t private_openssl_diffie_hellman_t; + + /** +@@ -65,10 +73,12 @@ struct private_openssl_diffie_hellman_t { + METHOD(diffie_hellman_t, get_my_public_value, bool, + private_openssl_diffie_hellman_t *this, chunk_t *value) + { ++ const BIGNUM *pubkey; ++ + *value = chunk_alloc(DH_size(this->dh)); + memset(value->ptr, 0, value->len); +- BN_bn2bin(this->dh->pub_key, +- value->ptr + value->len - BN_num_bytes(this->dh->pub_key)); ++ DH_get0_key(this->dh, &pubkey, NULL); ++ BN_bn2bin(pubkey, value->ptr + value->len - BN_num_bytes(pubkey)); + return TRUE; + } + +@@ -116,8 +126,15 @@ METHOD(diffie_hellman_t, set_other_public_value, bool, + METHOD(diffie_hellman_t, set_private_value, bool, + private_openssl_diffie_hellman_t *this, chunk_t value) + { +- if (BN_bin2bn(value.ptr, value.len, this->dh->priv_key)) ++ BIGNUM *privkey; ++ ++ privkey = BN_bin2bn(value.ptr, value.len, NULL); ++ if (privkey) + { ++ if (!DH_set0_key(this->dh, NULL, privkey)) ++ { ++ return FALSE; ++ } + chunk_clear(&this->shared_secret); + this->computed = FALSE; + return DH_generate_key(this->dh); +@@ -136,16 +153,29 @@ METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t, + */ + static status_t set_modulus(private_openssl_diffie_hellman_t *this) + { ++ BIGNUM *p, *g; ++ + diffie_hellman_params_t *params = diffie_hellman_get_params(this->group); + if (!params) + { + return NOT_FOUND; + } +- this->dh->p = BN_bin2bn(params->prime.ptr, params->prime.len, NULL); +- this->dh->g = BN_bin2bn(params->generator.ptr, params->generator.len, NULL); ++ p = BN_bin2bn(params->prime.ptr, params->prime.len, NULL); ++ g = BN_bin2bn(params->generator.ptr, params->generator.len, NULL); ++ if (!DH_set0_pqg(this->dh, p, NULL, g)) ++ { ++ return FAILED; ++ } + if (params->exp_len != params->prime.len) + { +- this->dh->length = params->exp_len * 8; ++#ifdef OPENSSL_IS_BORINGSSL ++ this->dh->priv_length = params->exp_len * 8; ++#else ++ if (!DH_set_length(this->dh, params->exp_len * 8)) ++ { ++ return FAILED; ++ } ++#endif + } + return SUCCESS; + } +@@ -166,6 +196,7 @@ openssl_diffie_hellman_t *openssl_diffie_hellman_create( + diffie_hellman_group_t group, chunk_t g, chunk_t p) + { + private_openssl_diffie_hellman_t *this; ++ const BIGNUM *privkey; + + INIT(this, + .public = { +@@ -194,8 +225,12 @@ openssl_diffie_hellman_t *openssl_diffie_hellman_create( + + if (group == MODP_CUSTOM) + { +- this->dh->p = BN_bin2bn(p.ptr, p.len, NULL); +- this->dh->g = BN_bin2bn(g.ptr, g.len, NULL); ++ if (!DH_set0_pqg(this->dh, BN_bin2bn(p.ptr, p.len, NULL), NULL, ++ BN_bin2bn(g.ptr, g.len, NULL))) ++ { ++ destroy(this); ++ return NULL; ++ } + } + else + { +@@ -213,9 +248,8 @@ openssl_diffie_hellman_t *openssl_diffie_hellman_create( + destroy(this); + return NULL; + } +- DBG2(DBG_LIB, "size of DH secret exponent: %d bits", +- BN_num_bits(this->dh->priv_key)); +- ++ DH_get0_key(this->dh, NULL, &privkey); ++ DBG2(DBG_LIB, "size of DH secret exponent: %d bits", BN_num_bits(privkey)); + return &this->public; + } + +diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c +index bc7884c99b01..24fe623eb410 100644 +--- a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c ++++ b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c +@@ -28,6 +28,10 @@ + #include <openssl/ecdsa.h> + #include <openssl/x509.h> + ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++OPENSSL_KEY_FALLBACK(ECDSA_SIG, r, s) ++#endif ++ + typedef struct private_openssl_ec_private_key_t private_openssl_ec_private_key_t; + + /** +@@ -59,15 +63,17 @@ bool openssl_ec_fingerprint(EC_KEY *ec, cred_encoding_type_t type, chunk_t *fp); + static bool build_signature(private_openssl_ec_private_key_t *this, + chunk_t hash, chunk_t *signature) + { +- bool built = FALSE; ++ const BIGNUM *r, *s; + ECDSA_SIG *sig; ++ bool built = FALSE; + + sig = ECDSA_do_sign(hash.ptr, hash.len, this->ec); + if (sig) + { ++ ECDSA_SIG_get0(sig, &r, &s); + /* concatenate BNs r/s to a signature chunk */ + built = openssl_bn_cat(EC_FIELD_ELEMENT_LEN(EC_KEY_get0_group(this->ec)), +- sig->r, sig->s, signature); ++ r, s, signature); + ECDSA_SIG_free(sig); + } + return built; +diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c +index 21dcb0120710..a1e56fc5e386 100644 +--- a/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c ++++ b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c +@@ -27,6 +27,10 @@ + #include <openssl/ecdsa.h> + #include <openssl/x509.h> + ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++OPENSSL_KEY_FALLBACK(ECDSA_SIG, r, s) ++#endif ++ + typedef struct private_openssl_ec_public_key_t private_openssl_ec_public_key_t; + + /** +@@ -55,14 +59,23 @@ struct private_openssl_ec_public_key_t { + static bool verify_signature(private_openssl_ec_public_key_t *this, + chunk_t hash, chunk_t signature) + { +- bool valid = FALSE; ++ BIGNUM *r, *s; + ECDSA_SIG *sig; ++ bool valid = FALSE; + + sig = ECDSA_SIG_new(); + if (sig) + { +- /* split the signature chunk in r and s */ +- if (openssl_bn_split(signature, sig->r, sig->s)) ++ r = BN_new(); ++ s = BN_new(); ++ if (!openssl_bn_split(signature, r, s)) ++ { ++ BN_free(r); ++ BN_free(s); ++ ECDSA_SIG_free(sig); ++ return FALSE; ++ } ++ if (ECDSA_SIG_set0(sig, r, s)) + { + valid = (ECDSA_do_verify(hash.ptr, hash.len, sig, this->ec) == 1); + } +diff --git a/src/libstrongswan/plugins/openssl/openssl_gcm.c b/src/libstrongswan/plugins/openssl/openssl_gcm.c +index 147e4afb449e..6bbe4af9560c 100644 +--- a/src/libstrongswan/plugins/openssl/openssl_gcm.c ++++ b/src/libstrongswan/plugins/openssl/openssl_gcm.c +@@ -71,7 +71,7 @@ struct private_aead_t { + static bool crypt(private_aead_t *this, chunk_t data, chunk_t assoc, chunk_t iv, + u_char *out, int enc) + { +- EVP_CIPHER_CTX ctx; ++ EVP_CIPHER_CTX *ctx; + u_char nonce[NONCE_LEN]; + bool success = FALSE; + int len; +@@ -79,29 +79,29 @@ static bool crypt(private_aead_t *this, chunk_t data, chunk_t assoc, chunk_t iv, + memcpy(nonce, this->salt, SALT_LEN); + memcpy(nonce + SALT_LEN, iv.ptr, IV_LEN); + +- EVP_CIPHER_CTX_init(&ctx); +- EVP_CIPHER_CTX_set_padding(&ctx, 0); +- if (!EVP_CipherInit_ex(&ctx, this->cipher, NULL, NULL, NULL, enc) || +- !EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, NONCE_LEN, NULL) || +- !EVP_CipherInit_ex(&ctx, NULL, NULL, this->key.ptr, nonce, enc)) ++ ctx = EVP_CIPHER_CTX_new(); ++ EVP_CIPHER_CTX_set_padding(ctx, 0); ++ if (!EVP_CipherInit_ex(ctx, this->cipher, NULL, NULL, NULL, enc) || ++ !EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, NONCE_LEN, NULL) || ++ !EVP_CipherInit_ex(ctx, NULL, NULL, this->key.ptr, nonce, enc)) + { + goto done; + } +- if (!enc && !EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_TAG, this->icv_size, ++ if (!enc && !EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, this->icv_size, + data.ptr + data.len)) + { /* set ICV for verification on decryption */ + goto done; + } +- if (assoc.len && !EVP_CipherUpdate(&ctx, NULL, &len, assoc.ptr, assoc.len)) ++ if (assoc.len && !EVP_CipherUpdate(ctx, NULL, &len, assoc.ptr, assoc.len)) + { /* set AAD if specified */ + goto done; + } +- if (!EVP_CipherUpdate(&ctx, out, &len, data.ptr, data.len) || +- !EVP_CipherFinal_ex(&ctx, out + len, &len)) ++ if (!EVP_CipherUpdate(ctx, out, &len, data.ptr, data.len) || ++ !EVP_CipherFinal_ex(ctx, out + len, &len)) + { /* EVP_CipherFinal_ex fails if ICV is incorrect on decryption */ + goto done; + } +- if (enc && !EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, this->icv_size, ++ if (enc && !EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, this->icv_size, + out + data.len)) + { /* copy back the ICV when encrypting */ + goto done; +@@ -109,7 +109,7 @@ static bool crypt(private_aead_t *this, chunk_t data, chunk_t assoc, chunk_t iv, + success = TRUE; + + done: +- EVP_CIPHER_CTX_cleanup(&ctx); ++ EVP_CIPHER_CTX_free(ctx); + return success; + } + +@@ -152,7 +152,7 @@ METHOD(aead_t, decrypt, bool, + METHOD(aead_t, get_block_size, size_t, + private_aead_t *this) + { +- return this->cipher->block_size; ++ return EVP_CIPHER_block_size(this->cipher); + } + + METHOD(aead_t, get_icv_size, size_t, +diff --git a/src/libstrongswan/plugins/openssl/openssl_hmac.c b/src/libstrongswan/plugins/openssl/openssl_hmac.c +index 065187a8c301..6498cb4d6f98 100644 +--- a/src/libstrongswan/plugins/openssl/openssl_hmac.c ++++ b/src/libstrongswan/plugins/openssl/openssl_hmac.c +@@ -68,7 +68,14 @@ struct private_mac_t { + /** + * Current HMAC context + */ +- HMAC_CTX hmac; ++ HMAC_CTX *hmac; ++ ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++ /** ++ * Static context for OpenSSL < 1.1.0 ++ */ ++ HMAC_CTX hmac_ctx; ++#endif + + /** + * Key set on HMAC_CTX? +@@ -80,14 +87,14 @@ METHOD(mac_t, set_key, bool, + private_mac_t *this, chunk_t key) + { + #if OPENSSL_VERSION_NUMBER >= 0x10000000L +- if (HMAC_Init_ex(&this->hmac, key.ptr, key.len, this->hasher, NULL)) ++ if (HMAC_Init_ex(this->hmac, key.ptr, key.len, this->hasher, NULL)) + { + this->key_set = TRUE; + return TRUE; + } + return FALSE; + #else /* OPENSSL_VERSION_NUMBER < 1.0 */ +- HMAC_Init_ex(&this->hmac, key.ptr, key.len, this->hasher, NULL); ++ HMAC_Init_ex(this->hmac, key.ptr, key.len, this->hasher, NULL); + this->key_set = TRUE; + return TRUE; + #endif +@@ -101,7 +108,7 @@ METHOD(mac_t, get_mac, bool, + return FALSE; + } + #if OPENSSL_VERSION_NUMBER >= 0x10000000L +- if (!HMAC_Update(&this->hmac, data.ptr, data.len)) ++ if (!HMAC_Update(this->hmac, data.ptr, data.len)) + { + return FALSE; + } +@@ -109,17 +116,17 @@ METHOD(mac_t, get_mac, bool, + { + return TRUE; + } +- if (!HMAC_Final(&this->hmac, out, NULL)) ++ if (!HMAC_Final(this->hmac, out, NULL)) + { + return FALSE; + } + #else /* OPENSSL_VERSION_NUMBER < 1.0 */ +- HMAC_Update(&this->hmac, data.ptr, data.len); ++ HMAC_Update(this->hmac, data.ptr, data.len); + if (out == NULL) + { + return TRUE; + } +- HMAC_Final(&this->hmac, out, NULL); ++ HMAC_Final(this->hmac, out, NULL); + #endif + return set_key(this, chunk_empty); + } +@@ -133,7 +140,11 @@ METHOD(mac_t, get_mac_size, size_t, + METHOD(mac_t, destroy, void, + private_mac_t *this) + { +- HMAC_CTX_cleanup(&this->hmac); ++#if OPENSSL_VERSION_NUMBER >= 0x10100000L ++ HMAC_CTX_free(this->hmac); ++#else ++ HMAC_CTX_cleanup(&this->hmac_ctx); ++#endif + free(this); + } + +@@ -167,7 +178,12 @@ static mac_t *hmac_create(hash_algorithm_t algo) + return NULL; + } + +- HMAC_CTX_init(&this->hmac); ++#if OPENSSL_VERSION_NUMBER >= 0x10100000L ++ this->hmac = HMAC_CTX_new(); ++#else ++ HMAC_CTX_init(&this->hmac_ctx); ++ this->hmac = &this->hmac_ctx; ++#endif + + return &this->public; + } +diff --git a/src/libstrongswan/plugins/openssl/openssl_pkcs12.c b/src/libstrongswan/plugins/openssl/openssl_pkcs12.c +index d16b2cc0569f..705e96c695f6 100644 +--- a/src/libstrongswan/plugins/openssl/openssl_pkcs12.c ++++ b/src/libstrongswan/plugins/openssl/openssl_pkcs12.c +@@ -23,6 +23,10 @@ + #include <library.h> + #include <credentials/sets/mem_cred.h> + ++#ifdef OPENSSL_IS_BORINGSSL ++#define EVP_PKEY_base_id(p) EVP_PKEY_type(p->type) ++#endif ++ + typedef struct private_pkcs12_t private_pkcs12_t; + + /** +@@ -110,7 +114,7 @@ static bool add_key(private_pkcs12_t *this, EVP_PKEY *private) + { /* no private key is ok */ + return TRUE; + } +- switch (EVP_PKEY_type(private->type)) ++ switch (EVP_PKEY_base_id(private)) + { + case EVP_PKEY_RSA: + type = KEY_RSA; +diff --git a/src/libstrongswan/plugins/openssl/openssl_pkcs7.c b/src/libstrongswan/plugins/openssl/openssl_pkcs7.c +index 891e829ae827..f10987c8d037 100644 +--- a/src/libstrongswan/plugins/openssl/openssl_pkcs7.c ++++ b/src/libstrongswan/plugins/openssl/openssl_pkcs7.c +@@ -29,6 +29,10 @@ + + #include <openssl/cms.h> + ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++#define X509_ATTRIBUTE_get0_object(attr) ({ (attr)->object; }) ++#endif ++ + typedef struct private_openssl_pkcs7_t private_openssl_pkcs7_t; + + /** +@@ -432,11 +436,11 @@ METHOD(pkcs7_t, get_attribute, bool, + for (i = 0; i < CMS_signed_get_attr_count(si); i++) + { + attr = CMS_signed_get_attr(si, i); +- if (!attr->single && sk_ASN1_TYPE_num(attr->value.set) == 1 && +- openssl_asn1_known_oid(attr->object) == oid) ++ if (X509_ATTRIBUTE_count(attr) == 1 && ++ openssl_asn1_known_oid(X509_ATTRIBUTE_get0_object(attr)) == oid) + { + /* get first value in SET */ +- type = sk_ASN1_TYPE_value(attr->value.set, 0); ++ type = X509_ATTRIBUTE_get0_type(attr, 0); + chunk = wrapped = openssl_i2chunk(ASN1_TYPE, type); + if (asn1_unwrap(&chunk, &chunk) != 0x100 /* ASN1_INVALID */) + { +diff --git a/src/libstrongswan/plugins/openssl/openssl_plugin.c b/src/libstrongswan/plugins/openssl/openssl_plugin.c +index aeb9be409b77..3e3b986dffc0 100644 +--- a/src/libstrongswan/plugins/openssl/openssl_plugin.c ++++ b/src/libstrongswan/plugins/openssl/openssl_plugin.c +@@ -66,6 +66,11 @@ struct private_openssl_plugin_t { + }; + + /** ++ * OpenSSL is thread-safe since 1.1.0 ++ */ ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++ ++/** + * Array of static mutexs, with CRYPTO_num_locks() mutex + */ + static mutex_t **mutex = NULL; +@@ -227,6 +232,14 @@ static void threading_cleanup() + cleanup->destroy(cleanup); + } + ++#else /* OPENSSL_VERSION_NUMBER */ ++ ++#define threading_init() ++ ++#define threading_cleanup() ++ ++#endif ++ + /** + * Seed the OpenSSL RNG, if required + */ +@@ -502,8 +515,14 @@ METHOD(plugin_t, get_features, int, + METHOD(plugin_t, destroy, void, + private_openssl_plugin_t *this) + { ++/* OpenSSL 1.1.0 cleans up itself at exit and while OPENSSL_cleanup() exists we ++ * can't call it as we couldn't re-initialize the library (as required by the ++ * unit tests and the Android app) */ ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++#ifndef OPENSSL_IS_BORINGSSL + CONF_modules_free(); + OBJ_cleanup(); ++#endif + EVP_cleanup(); + #ifndef OPENSSL_NO_ENGINE + ENGINE_cleanup(); +@@ -511,6 +530,7 @@ METHOD(plugin_t, destroy, void, + CRYPTO_cleanup_all_ex_data(); + threading_cleanup(); + ERR_free_strings(); ++#endif /* OPENSSL_VERSION_NUMBER */ + + free(this); + } +@@ -553,10 +573,23 @@ plugin_t *openssl_plugin_create() + }, + ); + ++#if OPENSSL_VERSION_NUMBER >= 0x10100000L ++ /* note that we can't call OPENSSL_cleanup() when the plugin is destroyed ++ * as we couldn't initialize the library again afterwards */ ++ OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG | ++ OPENSSL_INIT_ENGINE_ALL_BUILTIN, NULL); ++#else /* OPENSSL_VERSION_NUMBER */ + threading_init(); +- ++#ifndef OPENSSL_IS_BORINGSSL + OPENSSL_config(NULL); ++#endif + OpenSSL_add_all_algorithms(); ++#ifndef OPENSSL_NO_ENGINE ++ /* activate support for hardware accelerators */ ++ ENGINE_load_builtin_engines(); ++ ENGINE_register_all_complete(); ++#endif /* OPENSSL_NO_ENGINE */ ++#endif /* OPENSSL_VERSION_NUMBER */ + + #ifdef OPENSSL_FIPS + /* we do this here as it may have been enabled via openssl.conf */ +@@ -565,12 +598,6 @@ plugin_t *openssl_plugin_create() + "openssl FIPS mode(%d) - %sabled ", fips_mode, fips_mode ? "en" : "dis"); + #endif /* OPENSSL_FIPS */ + +-#ifndef OPENSSL_NO_ENGINE +- /* activate support for hardware accelerators */ +- ENGINE_load_builtin_engines(); +- ENGINE_register_all_complete(); +-#endif /* OPENSSL_NO_ENGINE */ +- + if (!seed_rng()) + { + DBG1(DBG_CFG, "no RNG found to seed OpenSSL"); +diff --git a/src/libstrongswan/plugins/openssl/openssl_rng.c b/src/libstrongswan/plugins/openssl/openssl_rng.c +index c807bb607262..884594620aeb 100644 +--- a/src/libstrongswan/plugins/openssl/openssl_rng.c ++++ b/src/libstrongswan/plugins/openssl/openssl_rng.c +@@ -49,13 +49,6 @@ struct private_openssl_rng_t { + METHOD(rng_t, get_bytes, bool, + private_openssl_rng_t *this, size_t bytes, u_int8_t *buffer) + { +- if (this->quality == RNG_WEAK) +- { +- /* RAND_pseudo_bytes() returns 1 if returned bytes are strong, +- * 0 if of not. Both is acceptable for RNG_WEAK. */ +- return RAND_pseudo_bytes((char*)buffer, bytes) != -1; +- } +- /* A 0 return value is a failure for RAND_bytes() */ + return RAND_bytes((char*)buffer, bytes) == 1; + } + +diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c +index de02f302d6c7..485e0bbc722a 100644 +--- a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c ++++ b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c +@@ -20,6 +20,7 @@ + + #include "openssl_rsa_private_key.h" + #include "openssl_rsa_public_key.h" ++#include "openssl_util.h" + + #include <utils/debug.h> + +@@ -35,6 +36,12 @@ + */ + #define PUBLIC_EXPONENT 0x10001 + ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++OPENSSL_KEY_FALLBACK(RSA, key, n, e, d) ++OPENSSL_KEY_FALLBACK(RSA, factors, p, q) ++OPENSSL_KEY_FALLBACK(RSA, crt_params, dmp1, dmq1, iqmp) ++#endif ++ + typedef struct private_openssl_rsa_private_key_t private_openssl_rsa_private_key_t; + + /** +@@ -436,22 +443,38 @@ openssl_rsa_private_key_t *openssl_rsa_private_key_load(key_type_t type, + } + else if (n.ptr && e.ptr && d.ptr && p.ptr && q.ptr && coeff.ptr) + { ++ BIGNUM *bn_n, *bn_e, *bn_d, *bn_p, *bn_q; ++ BIGNUM *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL; ++ + this->rsa = RSA_new(); +- this->rsa->n = BN_bin2bn((const u_char*)n.ptr, n.len, NULL); +- this->rsa->e = BN_bin2bn((const u_char*)e.ptr, e.len, NULL); +- this->rsa->d = BN_bin2bn((const u_char*)d.ptr, d.len, NULL); +- this->rsa->p = BN_bin2bn((const u_char*)p.ptr, p.len, NULL); +- this->rsa->q = BN_bin2bn((const u_char*)q.ptr, q.len, NULL); ++ ++ bn_n = BN_bin2bn((const u_char*)n.ptr, n.len, NULL); ++ bn_e = BN_bin2bn((const u_char*)e.ptr, e.len, NULL); ++ bn_d = BN_bin2bn((const u_char*)d.ptr, d.len, NULL); ++ if (!RSA_set0_key(this->rsa, bn_n, bn_e, bn_d)) ++ { ++ destroy(this); ++ return NULL; ++ ++ } ++ bn_p = BN_bin2bn((const u_char*)p.ptr, p.len, NULL); ++ bn_q = BN_bin2bn((const u_char*)q.ptr, q.len, NULL); ++ if (!RSA_set0_factors(this->rsa, bn_p, bn_q)) ++ { ++ destroy(this); ++ return NULL; ++ } + if (exp1.ptr) + { +- this->rsa->dmp1 = BN_bin2bn((const u_char*)exp1.ptr, exp1.len, NULL); ++ dmp1 = BN_bin2bn((const u_char*)exp1.ptr, exp1.len, NULL); + } + if (exp2.ptr) + { +- this->rsa->dmq1 = BN_bin2bn((const u_char*)exp2.ptr, exp2.len, NULL); ++ dmq1 = BN_bin2bn((const u_char*)exp2.ptr, exp2.len, NULL); + } +- this->rsa->iqmp = BN_bin2bn((const u_char*)coeff.ptr, coeff.len, NULL); +- if (RSA_check_key(this->rsa) == 1) ++ iqmp = BN_bin2bn((const u_char*)coeff.ptr, coeff.len, NULL); ++ if (RSA_set0_crt_params(this->rsa, dmp1, dmq1, iqmp) && ++ RSA_check_key(this->rsa) == 1) + { + return &this->public; + } +diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c +index db928569f31f..d66d5016e81c 100644 +--- a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c ++++ b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c +@@ -28,6 +28,10 @@ + #include <openssl/rsa.h> + #include <openssl/x509.h> + ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++OPENSSL_KEY_FALLBACK(RSA, key, n, e, d) ++#endif ++ + typedef struct private_openssl_rsa_public_key_t private_openssl_rsa_public_key_t; + + /** +@@ -224,11 +228,13 @@ bool openssl_rsa_fingerprint(RSA *rsa, cred_encoding_type_t type, chunk_t *fp) + break; + default: + { ++ const BIGNUM *bn_n, *bn_e; + chunk_t n = chunk_empty, e = chunk_empty; + bool success = FALSE; + +- if (openssl_bn2chunk(rsa->n, &n) && +- openssl_bn2chunk(rsa->e, &e)) ++ RSA_get0_key(rsa, &bn_n, &bn_e, NULL); ++ if (openssl_bn2chunk(bn_n, &n) && ++ openssl_bn2chunk(bn_e, &e)) + { + success = lib->encoding->encode(lib->encoding, type, rsa, fp, + CRED_PART_RSA_MODULUS, n, +@@ -297,10 +303,12 @@ METHOD(public_key_t, get_encoding, bool, + } + default: + { ++ const BIGNUM *bn_n, *bn_e; + chunk_t n = chunk_empty, e = chunk_empty; + +- if (openssl_bn2chunk(this->rsa->n, &n) && +- openssl_bn2chunk(this->rsa->e, &e)) ++ RSA_get0_key(this->rsa, &bn_n, &bn_e, NULL); ++ if (openssl_bn2chunk(bn_n, &n) && ++ openssl_bn2chunk(bn_e, &e)) + { + success = lib->encoding->encode(lib->encoding, type, NULL, + encoding, CRED_PART_RSA_MODULUS, n, +@@ -416,10 +424,15 @@ openssl_rsa_public_key_t *openssl_rsa_public_key_load(key_type_t type, + } + else if (n.ptr && e.ptr && type == KEY_RSA) + { ++ BIGNUM *bn_n, *bn_e; ++ + this->rsa = RSA_new(); +- this->rsa->n = BN_bin2bn((const u_char*)n.ptr, n.len, NULL); +- this->rsa->e = BN_bin2bn((const u_char*)e.ptr, e.len, NULL); +- return &this->public; ++ bn_n = BN_bin2bn((const u_char*)n.ptr, n.len, NULL); ++ bn_e = BN_bin2bn((const u_char*)e.ptr, e.len, NULL); ++ if (RSA_set0_key(this->rsa, bn_n, bn_e, NULL)) ++ { ++ return &this->public; ++ } + } + destroy(this); + return NULL; +diff --git a/src/libstrongswan/plugins/openssl/openssl_util.c b/src/libstrongswan/plugins/openssl/openssl_util.c +index 2f981370174b..84749616a353 100644 +--- a/src/libstrongswan/plugins/openssl/openssl_util.c ++++ b/src/libstrongswan/plugins/openssl/openssl_util.c +@@ -22,6 +22,12 @@ + #include <openssl/evp.h> + #include <openssl/x509.h> + ++/* these were added with 1.1.0 when ASN1_OBJECT was made opaque */ ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++#define OBJ_get0_data(o) ((o)->data) ++#define OBJ_length(o) ((o)->length) ++#endif ++ + /** + * Described in header. + */ +@@ -70,7 +76,8 @@ error: + /** + * Described in header. + */ +-bool openssl_bn_cat(int len, BIGNUM *a, BIGNUM *b, chunk_t *chunk) ++bool openssl_bn_cat(const int len, const BIGNUM *a, const BIGNUM *b, ++ chunk_t *chunk) + { + int offset; + +@@ -127,7 +134,7 @@ bool openssl_bn_split(chunk_t chunk, BIGNUM *a, BIGNUM *b) + /** + * Described in header. + */ +-bool openssl_bn2chunk(BIGNUM *bn, chunk_t *chunk) ++bool openssl_bn2chunk(const BIGNUM *bn, chunk_t *chunk) + { + *chunk = chunk_alloc(BN_num_bytes(bn)); + if (BN_bn2bin(bn, chunk->ptr) == chunk->len) +@@ -149,7 +156,7 @@ chunk_t openssl_asn1_obj2chunk(ASN1_OBJECT *asn1) + { + if (asn1) + { +- return chunk_create((u_char*)asn1->data, asn1->length); ++ return chunk_create((u_char*)OBJ_get0_data(asn1), OBJ_length(asn1)); + } + return chunk_empty; + } +diff --git a/src/libstrongswan/plugins/openssl/openssl_util.h b/src/libstrongswan/plugins/openssl/openssl_util.h +index 2db073139214..9621d5c138b3 100644 +--- a/src/libstrongswan/plugins/openssl/openssl_util.h ++++ b/src/libstrongswan/plugins/openssl/openssl_util.h +@@ -60,7 +60,8 @@ bool openssl_hash_chunk(int hash_type, chunk_t data, chunk_t *hash); + * @param chunk resulting chunk + * @return TRUE on success, FALSE otherwise + */ +-bool openssl_bn_cat(int len, BIGNUM *a, BIGNUM *b, chunk_t *chunk); ++bool openssl_bn_cat(const int len, const BIGNUM *a, const BIGNUM *b, ++ chunk_t *chunk); + + /** + * Splits a chunk into two bignums of equal binary length. +@@ -80,7 +81,7 @@ bool openssl_bn_split(chunk_t chunk, BIGNUM *a, BIGNUM *b); + * @param chunk the chunk (data gets allocated) + * @return TRUE on success, FALSE otherwise + */ +-bool openssl_bn2chunk(BIGNUM *bn, chunk_t *chunk); ++bool openssl_bn2chunk(const BIGNUM *bn, chunk_t *chunk); + + /** + * Allocate a chunk using the i2d function of a given object +@@ -134,4 +135,36 @@ int openssl_asn1_known_oid(ASN1_OBJECT *obj); + */ + time_t openssl_asn1_to_time(ASN1_TIME *time); + ++/** ++ * Macros to define fallback getters/setters to access keys (BIGNUM*) for types ++ * that were made opaque with OpenSSL 1.1.0. ++ */ ++#define OPENSSL_KEY_FALLBACK(...) VA_ARGS_DISPATCH(OPENSSL_KEY_FALLBACK, __VA_ARGS__)(__VA_ARGS__) ++#define OPENSSL_KEY_FALLBACK3(type, k1, k2) \ ++static inline void type##_get0(const type *o, const BIGNUM **k1, const BIGNUM **k2) { \ ++ if (k1) *k1 = o->k1; \ ++ if (k2) *k2 = o->k2; } \ ++static inline int type##_set0(type *o, BIGNUM *k1, BIGNUM *k2) { \ ++ if (k1) { BN_clear_free(o->k1); o->k1 = k1; } \ ++ if (k2) { BN_clear_free(o->k2); o->k2 = k2; } \ ++ return 1; } ++#define OPENSSL_KEY_FALLBACK4(type, name, k1, k2) \ ++static inline void type##_get0_##name(const type *o, const BIGNUM **k1, const BIGNUM **k2) { \ ++ if (k1) *k1 = o->k1; \ ++ if (k2) *k2 = o->k2; } \ ++static inline int type##_set0_##name(type *o, BIGNUM *k1, BIGNUM *k2) { \ ++ if (k1) { BN_clear_free(o->k1); o->k1 = k1; } \ ++ if (k2) { BN_clear_free(o->k2); o->k2 = k2; } \ ++ return 1; } ++#define OPENSSL_KEY_FALLBACK5(type, name, k1, k2, k3) \ ++static inline void type##_get0_##name(const type *o, const BIGNUM **k1, const BIGNUM **k2, const BIGNUM **k3) { \ ++ if (k1) *k1 = o->k1; \ ++ if (k2) *k2 = o->k2; \ ++ if (k3) *k3 = o->k3; } \ ++static inline int type##_set0_##name(type *o, BIGNUM *k1, BIGNUM *k2, BIGNUM *k3) { \ ++ if (k1) { BN_clear_free(o->k1); o->k1 = k1; } \ ++ if (k2) { BN_clear_free(o->k2); o->k2 = k2; } \ ++ if (k3) { BN_clear_free(o->k3); o->k3 = k3; } \ ++ return 1; } ++ + #endif /** OPENSSL_UTIL_H_ @}*/ +diff --git a/src/libstrongswan/plugins/openssl/openssl_x509.c b/src/libstrongswan/plugins/openssl/openssl_x509.c +index 7a5b206dddfb..f82080730aa3 100644 +--- a/src/libstrongswan/plugins/openssl/openssl_x509.c ++++ b/src/libstrongswan/plugins/openssl/openssl_x509.c +@@ -60,6 +60,22 @@ + #define OPENSSL_NO_RFC3779 + #endif + ++/* added with 1.0.2 */ ++#if OPENSSL_VERSION_NUMBER < 0x10002000L ++static inline void X509_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg, const X509 *x) { ++ if (psig) { *psig = x->signature; } ++ if (palg) { *palg = x->sig_alg; } ++} ++#endif ++ ++/* added with 1.1.0 when X509 etc. was made opaque */ ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++#define X509_get0_extensions(x509) ({ (x509)->cert_info->extensions; }) ++#define X509_get0_tbs_sigalg(x509) ({ (x509)->cert_info->signature; }) ++#define X509_ALGOR_get0(oid, ppt, ppv, alg) ({ *(oid) = (alg)->algorithm; }) ++#define X509_PUBKEY_get0_param(oid, pk, len, pa, pub) X509_ALGOR_get0(oid, NULL, NULL, (pub)->algor) ++#endif ++ + typedef struct private_openssl_x509_t private_openssl_x509_t; + + /** +@@ -380,6 +396,7 @@ METHOD(certificate_t, issued_by, bool, + public_key_t *key; + bool valid; + x509_t *x509 = (x509_t*)issuer; ++ ASN1_BIT_STRING *sig; + chunk_t tbs; + + if (&this->public.x509.interface == issuer) +@@ -413,9 +430,14 @@ METHOD(certificate_t, issued_by, bool, + { + return FALSE; + } ++ /* i2d_re_X509_tbs() was added with 1.1.0 when X509 was made opaque */ ++#if OPENSSL_VERSION_NUMBER >= 0x10100000L ++ tbs = openssl_i2chunk(re_X509_tbs, this->x509); ++#else + tbs = openssl_i2chunk(X509_CINF, this->x509->cert_info); +- valid = key->verify(key, this->scheme, tbs, +- openssl_asn1_str2chunk(this->x509->signature)); ++#endif ++ X509_get0_signature(&sig, NULL, this->x509); ++ valid = key->verify(key, this->scheme, tbs, openssl_asn1_str2chunk(sig)); + free(tbs.ptr); + key->destroy(key); + if (valid && scheme) +@@ -850,7 +872,7 @@ static void parse_ipAddrBlock_ext_fam(private_openssl_x509_t *this, + return; + } + +- afi = v3_addr_get_afi(fam); ++ afi = X509v3_addr_get_afi(fam); + switch (afi) + { + case IANA_AFI_IPV4: +@@ -871,7 +893,7 @@ static void parse_ipAddrBlock_ext_fam(private_openssl_x509_t *this, + for (i = 0; i < sk_IPAddressOrRange_num(list); i++) + { + aor = sk_IPAddressOrRange_value(list, i); +- if (v3_addr_get_range(aor, afi, from.ptr, to.ptr, from.len) > 0) ++ if (X509v3_addr_get_range(aor, afi, from.ptr, to.ptr, from.len) > 0) + { + ts = traffic_selector_create_from_bytes(0, type, from, 0, to, 65535); + if (ts) +@@ -897,7 +919,7 @@ static bool parse_ipAddrBlock_ext(private_openssl_x509_t *this, + return FALSE; + } + +- if (!v3_addr_is_canonical(blocks)) ++ if (!X509v3_addr_is_canonical(blocks)) + { + sk_IPAddressFamily_free(blocks); + return FALSE; +@@ -964,7 +986,7 @@ static bool parse_extensions(private_openssl_x509_t *this) + STACK_OF(X509_EXTENSION) *extensions; + int i, num; + +- extensions = this->x509->cert_info->extensions; ++ extensions = X509_get0_extensions(this->x509); + if (extensions) + { + num = sk_X509_EXTENSION_num(extensions); +@@ -1041,6 +1063,8 @@ static bool parse_certificate(private_openssl_x509_t *this) + const unsigned char *ptr = this->encoding.ptr; + hasher_t *hasher; + chunk_t chunk; ++ ASN1_OBJECT *oid, *oid_tbs; ++ X509_ALGOR *alg; + + this->x509 = d2i_X509(NULL, &ptr, this->encoding.len); + if (!this->x509) +@@ -1057,7 +1081,12 @@ static bool parse_certificate(private_openssl_x509_t *this) + this->subject = openssl_x509_name2id(X509_get_subject_name(this->x509)); + this->issuer = openssl_x509_name2id(X509_get_issuer_name(this->x509)); + +- switch (openssl_asn1_known_oid(this->x509->cert_info->key->algor->algorithm)) ++ if (!X509_PUBKEY_get0_param(&oid, NULL, NULL, NULL, ++ X509_get_X509_PUBKEY(this->x509))) ++ { ++ return FALSE; ++ } ++ switch (openssl_asn1_known_oid(oid)) + { + case OID_RSA_ENCRYPTION: + this->pubkey = lib->creds->create(lib->creds, +@@ -1086,14 +1115,18 @@ static bool parse_certificate(private_openssl_x509_t *this) + this->notBefore = openssl_asn1_to_time(X509_get_notBefore(this->x509)); + this->notAfter = openssl_asn1_to_time(X509_get_notAfter(this->x509)); + +- if (!chunk_equals( +- openssl_asn1_obj2chunk(this->x509->cert_info->signature->algorithm), +- openssl_asn1_obj2chunk(this->x509->sig_alg->algorithm))) ++ /* while X509_ALGOR_cmp() is declared in the headers of older OpenSSL ++ * versions, at least on Ubuntu 14.04 it is not actually defined */ ++ X509_get0_signature(NULL, &alg, this->x509); ++ X509_ALGOR_get0(&oid, NULL, NULL, alg); ++ alg = X509_get0_tbs_sigalg(this->x509); ++ X509_ALGOR_get0(&oid_tbs, NULL, NULL, alg); ++ if (!chunk_equals(openssl_asn1_obj2chunk(oid), ++ openssl_asn1_obj2chunk(oid_tbs))) + { + return FALSE; + } +- this->scheme = signature_scheme_from_oid(openssl_asn1_known_oid( +- this->x509->sig_alg->algorithm)); ++ this->scheme = signature_scheme_from_oid(openssl_asn1_known_oid(oid)); + + if (!parse_extensions(this)) + { +diff --git a/src/libstrongswan/utils/leak_detective.c b/src/libstrongswan/utils/leak_detective.c +index 99f4843ad6c6..f9bbd8ae4f77 100644 +--- a/src/libstrongswan/utils/leak_detective.c ++++ b/src/libstrongswan/utils/leak_detective.c +@@ -562,6 +562,10 @@ char *whitelist[] = { + "ECDSA_do_sign_ex", + "ECDSA_verify", + "RSA_new_method", ++ /* OpenSSL 1.1.0 does not cleanup anymore until the library is unloaded */ ++ "OPENSSL_init_crypto", ++ "CRYPTO_THREAD_lock_new", ++ "ERR_add_error_data", + /* OpenSSL libssl */ + "SSL_COMP_get_compression_methods", + /* NSPR */ +@@ -837,6 +841,18 @@ HOOK(void, free, void *ptr) + + if (!enabled || thread_disabled->get(thread_disabled)) + { ++ /* after deinitialization we might have to free stuff we allocated ++ * while we were enabled */ ++ if (!first_header.magic && ptr) ++ { ++ hdr = ptr - sizeof(memory_header_t); ++ tail = ptr + hdr->bytes; ++ if (hdr->magic == MEMORY_HEADER_MAGIC && ++ tail->magic == MEMORY_TAIL_MAGIC) ++ { ++ ptr = hdr; ++ } ++ } + real_free(ptr); + return; + } +@@ -953,6 +969,7 @@ METHOD(leak_detective_t, destroy, void, + lock->destroy(lock); + thread_disabled->destroy(thread_disabled); + free(this); ++ first_header.magic = 0; + first_header.next = NULL; + } + diff --git a/debian/patches/series b/debian/patches/series index 6d7cc1dfa..491deb407 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1,3 +1,4 @@ 01_fix-manpages.patch 03_systemd-service.patch 04_disable-libtls-tests.patch +05_port-openssl-1.1.0.patch |