Add --tls-cert-profile option for mbedtls builds
PATCH 1/1 Add --tls-cert-profile option for mbedtls builds
This allows the user to specify what certificate crypto algorithms to support. The supported profiles are 'preferred' (default), 'legacy' and 'suiteb', as discussed in <[email protected]...>
(https://www.mail-archive.com/[email protected]/msg14214.html).
This only implements the feature for mbed TLS builds, because for mbed it is both more easy to implement and the most relevant because mbed TLS 2+ is by default somewhat restrictive by requiring 2048-bit+ for RSA keys.
--- src/openvpn/options.c | 8 ++++++++ src/openvpn/options.h | 1 + src/openvpn/ssl.c | 3 +++ src/openvpn/ssl_backend.h | 10 ++++++++++ src/openvpn/ssl_mbedtls.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++ src/openvpn/ssl_mbedtls.h | 1 + src/openvpn/ssl_openssl.c | 6 ++++++ 7 files changed, 80 insertions(+)
src/openvpn/options.c +8 -0
@@ -873,6 +873,7 @@ init_options(struct options *o, const bool init_gc) o->renegotiate_seconds =3600 ; o->handshake_window =60 ; o->transition_window =3600 ; + o->tls_cert_profile ="preferred" ; o->ecdh_curve =NULL ;#ifdef ENABLE_X509ALTUSERNAME o->x509_username_field =X509_USERNAME_FIELD_DEFAULT ;
@@ -1752,6 +1753,7 @@ show_settings(const struct options *o)SHOW_STR (cryptoapi_cert);#endif SHOW_STR (cipher_list); +SHOW_STR (tls_cert_profile);SHOW_STR (tls_verify);SHOW_STR (tls_export_cert);SHOW_INT (verify_x509_type);
@@ -2734,6 +2736,7 @@ options_postprocess_verify_ce(const struct options *options, const struct connecMUST_BE_UNDEF (pkcs12_file);#endif MUST_BE_UNDEF (cipher_list); +MUST_BE_UNDEF (tls_cert_profile);MUST_BE_UNDEF (tls_verify);MUST_BE_UNDEF (tls_export_cert);MUST_BE_UNDEF (verify_x509_name);
@@ -7813,6 +7816,11 @@ add_option(struct options *options,VERIFY_PERMISSION (OPT_P_GENERAL ); options->cipher_list = p[1 ]; } +else if (streq (p[0 ],"tls-cert-profile" ) && p[1 ] && !p[2 ]) + { +VERIFY_PERMISSION (OPT_P_GENERAL ); + options->tls_cert_profile = p[1 ]; + }else if (streq (p[0 ],"crl-verify" ) && p[1 ] && ((p[2 ] &&streq (p[2 ],"dir" )) || (p[2 ] &&streq (p[1 ],INLINE_FILE_TAG ) ) || !p[2 ]) && !p[3 ]) {
src/openvpn/options.h +1 -0
@@ -500,6 +500,7 @@ struct optionsconst char *priv_key_file;const char *pkcs12_file;const char *cipher_list; +const char *tls_cert_profile;const char *ecdh_curve;const char *tls_verify;int verify_x509_type;
src/openvpn/ssl.c +3 -0
@@ -702,6 +702,9 @@ init_ssl(const struct options *options, struct tls_root_ctx *new_ctx)/* Allowable ciphers */ tls_ctx_restrict_ciphers (new_ctx, options->cipher_list); +/* Restrict allowed certificate crypto algorithms */ +tls_ctx_set_cert_profile (new_ctx, options->tls_cert_profile); +#ifdef ENABLE_CRYPTO_MBEDTLS /* Personalise the random by mixing in the certificate */ tls_ctx_personalise_random (new_ctx);
src/openvpn/ssl_backend.h +10 -0
@@ -178,6 +178,16 @@ void tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags);void tls_ctx_restrict_ciphers (struct tls_root_ctx *ctx,const char *ciphers);/** +* Set the TLS certificate profile. The profile defines which crypto +* algorithms may be used in the supplied certificate. +* +* @param ctx TLS context to restrict, must be valid. +* @param profile The profile name ('preferred', 'legacy' or 'suiteb'). +* May NOT be NULL. +*/ +void tls_ctx_set_cert_profile (struct tls_root_ctx *ctx,const char *profile); + +/** * Check our certificate notBefore and notAfter fields, and warn if the cert is * either not yet valid or has expired. Note that this is a non-fatal error, * since we compare against the system time, which might be incorrect.
src/openvpn/ssl_mbedtls.c +51 -0
69 lines not on this page · raw message
src/openvpn/ssl_mbedtls.h +1 -0
@@ -83,6 +83,7 @@ struct tls_root_ctx {struct external_context *external_key;/**< Management external key */ #endif int *allowed_ciphers;/**< List of allowed ciphers for this connection */ +mbedtls_x509_crt_profile cert_profile;/**< Allowed certificate types */ };struct key_state_ssl {
src/openvpn/ssl_openssl.c +6 -0
@@ -384,6 +384,12 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) }void +tls_ctx_set_cert_profile (struct tls_root_ctx *ctx,const char *profile) +{ +msg (M_WARN ,"WARNING: --tls-cert-profile not supported for OpenSSL" ); +} + +void tls_ctx_check_cert_time (const struct tls_root_ctx *ctx) {int ret;
Signature · 1 line
2.7.4
Quoted 20 lines · Steffan Karger
This allows the user to specify what certificate crypto algorithms to support. The supported profiles are 'preferred' (default), 'legacy' and 'suiteb', as discussed in <[email protected]....>
(https://www.mail-archive.com/[email protected]/msg14214.html).This only implements the feature for mbed TLS builds, because for mbed it is both more easy to implement and the most relevant because mbed TLS 2+ is by default somewhat restrictive by requiring 2048-bit+ for RSA keys.
Signed-off-by Steffan Karger <[email protected]...>--- src/openvpn/options.c | 8 ++++++++ src/openvpn/options.h | 1 + src/openvpn/ssl.c | 3 +++ src/openvpn/ssl_backend.h | 10 ++++++++++ src/openvpn/ssl_mbedtls.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++ src/openvpn/ssl_mbedtls.h | 1 + src/openvpn/ssl_openssl.c | 6 ++++++ 7 files changed, 80 insertions(+)
[...snip...]
Quoted 4 lines
src/openvpn/ssl_mbedtls.c +0
-0
[...snip...]
src/openvpn/ssl_mbedtls.c tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) · line 285
Quoted 4 lines
void
src/openvpn/ssl_mbedtls.c +3
-0+tls_ctx_set_cert_profile(struct tls_root_ctx *ctx, const char *profile) +{ +if (0 ==strcmp (profile,"preferred" ))
While you do say in the docs that profile MAY NOT be NULL, this will cause a SEGV if it happens. Wouldn't it be better better to either report an error or ASSERT() if profile == NULL?
Quoted 16 lines
src/openvpn/ssl_mbedtls.c +16
-0+ { + ctx->cert_profile = openvpn_x509_crt_profile_preferred; + } + else if (0 == strcmp(profile, "legacy")) + { + ctx->cert_profile = openvpn_x509_crt_profile_legacy; + } + else if (0 == strcmp(profile, "suiteb")) + { + ctx->cert_profile = openvpn_x509_crt_profile_suiteb; + } + else + { +msg (M_FATAL ,"ERROR: Invalid cert profile: %s" , profile); + } +}
[...snip...]
src/openvpn/ssl_openssl.c tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) · line 391
Quoted 11 lines
src/openvpn/ssl_openssl.c +5
-0@@ -384,6 +384,12 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) }void +tls_ctx_set_cert_profile (struct tls_root_ctx *ctx,const char *profile) +{ +msg (M_WARN ,"WARNING: --tls-cert-profile not supported for OpenSSL" ); +} +
While I do understand the use of M_WARN here. Wouldn't it be better to use M__NONFATAL and make it more a like an "INFO" log line instead. --tls-cert-profile is a brand new feature, where certificate profiles are not (yet?) implemented for OpenSSL. So that's strictly not a warning of more critical aspects. But it is however important to highlight it.
Otherwise, I think this makes sense. It would be good to have something similar for OpenSSL too, to be feature complete against mbed TLS.
It seems usage() is lacking details about --tls-cert-profile for the --help screen.
I have reviewed this by also comparing the implementation to what's done in OpenVPN 3 [1]. The profile declaration and enabling it seems to be very much aligned. (on a side note, I have already added a default profile for "legacy" in Fedora, as many users complained about OpenVPN breaking on Fedora 26 and newer, which also looks fairly recognisable to what is done here).
I will run some real tests tomorrow. But quick smoke testing looks good.
Signature · 4 lines
kind regards, David Sommerseth OpenVPN Technologies, Inc
PATCH v2 1/1 Add --tls-cert-profile option for mbedtls builds
This allows the user to specify what certificate crypto algorithms to support. The supported profiles are 'preferred' (default), 'legacy' and 'suiteb', as discussed in <[email protected]...>
(https://www.mail-archive.com/[email protected]/msg14214.html).
This only implements the feature for mbed TLS builds, because for mbed it is both more easy to implement and the most relevant because mbed TLS 2+ is by default somewhat restrictive by requiring 2048-bit+ for RSA keys.
---
v2:
- add documentation (manpage, Changes.rst and --help)
- no longer print a warning message on each startup for OpenSSL builds
Changes.rst | 28 +++++++++++++++----------- doc/openvpn.8 | 19 ++++++++++++++++++ src/openvpn/options.c | 14 ++++++++++++- src/openvpn/options.h | 1 + src/openvpn/ssl.c | 3 +++ src/openvpn/ssl_backend.h | 10 ++++++++++ src/openvpn/ssl_mbedtls.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++ src/openvpn/ssl_mbedtls.h | 1 + src/openvpn/ssl_openssl.c | 6 ++++++ 9 files changed, 120 insertions(+), 13 deletions(-)
Changes.rst +16 -12
@@ -306,15 +306,19 @@ Maintainer-visible changes Version 2.4.1 ============= - - ``--remote-cert-ku`` now only requires the certificate to have at least the - bits set of one of the values in the supplied list, instead of requiring an - exact match to one of the values in the list. - - ``--remote-cert-tls`` now only requires that a keyUsage is present in the - certificate, and leaves the verification of the value up to the crypto - library, which has more information (i.e. the key exchange method in use) - to verify that the keyUsage is correct. - - ``--ns-cert-type`` is deprecated. Use ``--remote-cert-tls`` instead. - The nsCertType x509 extension is very old, and barely used. - ``--remote-cert-tls`` uses the far more common keyUsage and extendedKeyUsage - extension instead. Make sure your certificates carry these to be able to - use ``--remote-cert-tls``. +- ``--remote-cert-ku`` now only requires the certificate to have at least the + bits set of one of the values in the supplied list, instead of requiring an + exact match to one of the values in the list. +- ``--remote-cert-tls`` now only requires that a keyUsage is present in the + certificate, and leaves the verification of the value up to the crypto + library, which has more information (i.e. the key exchange method in use) + to verify that the keyUsage is correct. +- ``--ns-cert-type`` is deprecated. Use ``--remote-cert-tls`` instead. + The nsCertType x509 extension is very old, and barely used. + ``--remote-cert-tls`` uses the far more common keyUsage and extendedKeyUsage + extension instead. Make sure your certificates carry these to be able to + use ``--remote-cert-tls``. +- The new option ``--tls-cert-profile`` can be used to restrict the set of + allowed crypto algorithms in TLS certificates in mbed TLS builds. The + 'legacy' profile can be used to re-enable support for SHA1 and 1024-bit RSA + keys.
doc/openvpn.8 +19 -0
@@ -4878,6 +4878,25 @@ when using PolarSSL or OpenSSL. .\"********************************************************* .TP +.B \-\-tls\-cert\-profile profile +Set the allowed cryptographic algorithms for certificates according to +.B profile\fN. + +The following profiles are supported: + +.B preferred +(default): SHA2 and newer, RSA 2048-bit+, any elliptic curve. + +.B legacy +: SHA1 and newer, RSA 2048-bit+, any elliptic curve. + +.B suiteb +: SHA256/SHA384, ECDSA with P-256 or P-384. + +This option is only supported for mbed TLS builds. OpenSSL builds accept any +certificate that OpenSSL accepts. +.\"********************************************************* +.TP .B \-\-tls\-timeout n Packet retransmit timeout on TLS control channel if no acknowledgment from remote within
src/openvpn/options.c +13 -1
@@ -598,6 +598,8 @@ static const char usage_message[] =#endif "--tls-cipher l : A list l of allowable TLS ciphers separated by : (optional).\n" " : Use --show-tls to see a list of supported TLS ciphers.\n" +"--tls-cert-profile p : Set the allowed certificate crypto algorithm profile\n" +" (default=%s).\n" "--tls-timeout n : Packet retransmit timeout on TLS control channel\n" " if no ACK from remote within n seconds (default=%d).\n" "--reneg-bytes n : Renegotiate data chan. key after n bytes sent and recvd.\n"
@@ -871,6 +873,7 @@ init_options(struct options *o, const bool init_gc) o->renegotiate_seconds =3600 ; o->handshake_window =60 ; o->transition_window =3600 ; + o->tls_cert_profile ="preferred" ; o->ecdh_curve =NULL ;#ifdef ENABLE_X509ALTUSERNAME o->x509_username_field =X509_USERNAME_FIELD_DEFAULT ;
@@ -1749,6 +1752,7 @@ show_settings(const struct options *o)SHOW_STR (cryptoapi_cert);#endif SHOW_STR (cipher_list); +SHOW_STR (tls_cert_profile);SHOW_STR (tls_verify);SHOW_STR (tls_export_cert);SHOW_INT (verify_x509_type);
@@ -2723,6 +2727,7 @@ options_postprocess_verify_ce(const struct options *options, const struct connecMUST_BE_UNDEF (pkcs12_file);#endif MUST_BE_UNDEF (cipher_list); +MUST_BE_UNDEF (tls_cert_profile);MUST_BE_UNDEF (tls_verify);MUST_BE_UNDEF (tls_export_cert);MUST_BE_UNDEF (verify_x509_name);
@@ -4074,7 +4079,7 @@ usage(void) o.verbosity, o.authname, o.ciphername, o.replay_window, o.replay_time, - o.tls_timeout, o.renegotiate_seconds, + o.tls_cert_profile, o.tls_timeout, o.renegotiate_seconds, o.handshake_window, o.transition_window);#else /* ifdef ENABLE_CRYPTO */ fprintf(fp, usage_message,
@@ -7797,6 +7802,13 @@ add_option(struct options *options,VERIFY_PERMISSION (OPT_P_GENERAL ); options->cipher_list = p[1 ]; } +#ifdef ENABLE_CRYPTO_MBEDTLS + else if (streq(p[0], "tls-cert-profile") && p[1] && !p[2]) + { +VERIFY_PERMISSION (OPT_P_GENERAL ); + options->tls_cert_profile = p[1 ]; + } +#endif else if (streq(p[0], "crl-verify") && p[1] && ((p[2] && streq(p[2], "dir")) || (p[2] && streq(p[1], INLINE_FILE_TAG) ) || !p[2]) && !p[3]) {
src/openvpn/options.h +1 -0
@@ -499,6 +499,7 @@ struct optionsconst char *priv_key_file;const char *pkcs12_file;const char *cipher_list; +const char *tls_cert_profile;const char *ecdh_curve;const char *tls_verify;int verify_x509_type;
src/openvpn/ssl.c +3 -0
@@ -702,6 +702,9 @@ init_ssl(const struct options *options, struct tls_root_ctx *new_ctx)/* Allowable ciphers */ tls_ctx_restrict_ciphers (new_ctx, options->cipher_list); +/* Restrict allowed certificate crypto algorithms */ +tls_ctx_set_cert_profile (new_ctx, options->tls_cert_profile); +#ifdef ENABLE_CRYPTO_MBEDTLS /* Personalise the random by mixing in the certificate */ tls_ctx_personalise_random (new_ctx);
src/openvpn/ssl_backend.h +10 -0
@@ -178,6 +178,16 @@ void tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags);void tls_ctx_restrict_ciphers (struct tls_root_ctx *ctx,const char *ciphers);/** +* Set the TLS certificate profile. The profile defines which crypto +* algorithms may be used in the supplied certificate. +* +* @param ctx TLS context to restrict, must be valid. +* @param profile The profile name ('preferred', 'legacy' or 'suiteb'). +* Defaults to 'preferred' if NULL. +*/ +void tls_ctx_set_cert_profile (struct tls_root_ctx *ctx,const char *profile); + +/** * Check our certificate notBefore and notAfter fields, and warn if the cert is * either not yet valid or has expired. Note that this is a non-fatal error, * since we compare against the system time, which might be incorrect.
src/openvpn/ssl_mbedtls.c +51 -0
69 lines not on this page · raw message
src/openvpn/ssl_mbedtls.h +1 -0
@@ -83,6 +83,7 @@ struct tls_root_ctx {struct external_context *external_key;/**< Management external key */ #endif int *allowed_ciphers;/**< List of allowed ciphers for this connection */ +mbedtls_x509_crt_profile cert_profile;/**< Allowed certificate types */ };struct key_state_ssl {
src/openvpn/ssl_openssl.c +6 -0
@@ -381,6 +381,12 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) }void +tls_ctx_set_cert_profile (struct tls_root_ctx *ctx,const char *profile) +{ +/* TODO --tls-cert-profile not supported for OpenSSL builds */ +} + +void tls_ctx_check_cert_time (const struct tls_root_ctx *ctx) {int ret;
Signature · 1 line
2.7.4
Quoted 20 lines · Steffan Karger
Version 2.4.1
=============
- - ``--remote-cert-ku`` now only requires the certificate to have at least theChanges.rst +6
-11- bits set of one of the values in the supplied list, instead of requiring an - exact match to one of the values in the list. - - ``--remote-cert-tls`` now only requires that a keyUsage is present in the - certificate, and leaves the verification of the value up to the crypto - library, which has more information (i.e. the key exchange method in use) - to verify that the keyUsage is correct. - - ``--ns-cert-type`` is deprecated. Use ``--remote-cert-tls`` instead. - The nsCertType x509 extension is very old, and barely used. - ``--remote-cert-tls`` uses the far more common keyUsage and extendedKeyUsage - extension instead. Make sure your certificates carry these to be able to - use ``--remote-cert-tls``. +- ``--remote-cert-ku`` now only requires the certificate to have at least the + bits set of one of the values in the supplied list, instead of requiring an + exact match to one of the values in the list. +- ``--remote-cert-tls`` now only requires that a keyUsage is present in the + certificate, and leaves the verification of the value up to the crypto + library, which has more information (i.e. the key exchange method in use)
Changes.rst Maintainer-visible changes · line 324
Quoted 10 lines
Changes.rst +10
-0+ to verify that the keyUsage is correct. +- ``--ns-cert-type`` is deprecated. Use ``--remote-cert-tls`` instead. + The nsCertType x509 extension is very old, and barely used. + ``--remote-cert-tls`` uses the far more common keyUsage and extendedKeyUsage + extension instead. Make sure your certificates carry these to be able to + use ``--remote-cert-tls``. +- The new option ``--tls-cert-profile`` can be used to restrict the set of + allowed crypto algorithms in TLS certificates in mbed TLS builds. The + 'legacy' profile can be used to re-enable support for SHA1 and 1024-bit RSA + keys.
Hrmpf, this should of course get a new section '2.4.2'... Let me know if you want a v3, or whether this can be fixed on-the-fly. Apologies!
-Steffan
Quoted 32 lines · Steffan Karger
Quoted 20 lines · Steffan Karger
Version 2.4.1
=============
- - ``--remote-cert-ku`` now only requires the certificate to have at least theChanges.rst +6
-11- bits set of one of the values in the supplied list, instead of requiring an - exact match to one of the values in the list. - - ``--remote-cert-tls`` now only requires that a keyUsage is present in the - certificate, and leaves the verification of the value up to the crypto - library, which has more information (i.e. the key exchange method in use) - to verify that the keyUsage is correct. - - ``--ns-cert-type`` is deprecated. Use ``--remote-cert-tls`` instead. - The nsCertType x509 extension is very old, and barely used. - ``--remote-cert-tls`` uses the far more common keyUsage and extendedKeyUsage - extension instead. Make sure your certificates carry these to be able to - use ``--remote-cert-tls``. +- ``--remote-cert-ku`` now only requires the certificate to have at least the + bits set of one of the values in the supplied list, instead of requiring an + exact match to one of the values in the list. +- ``--remote-cert-tls`` now only requires that a keyUsage is present in the + certificate, and leaves the verification of the value up to the crypto + library, which has more information (i.e. the key exchange method in use)Changes.rst Maintainer-visible changes · line 324
Quoted 10 lines
Changes.rst +10
-0+ to verify that the keyUsage is correct. +- ``--ns-cert-type`` is deprecated. Use ``--remote-cert-tls`` instead. + The nsCertType x509 extension is very old, and barely used. + ``--remote-cert-tls`` uses the far more common keyUsage and extendedKeyUsage + extension instead. Make sure your certificates carry these to be able to + use ``--remote-cert-tls``. +- The new option ``--tls-cert-profile`` can be used to restrict the set of + allowed crypto algorithms in TLS certificates in mbed TLS builds. The + 'legacy' profile can be used to re-enable support for SHA1 and 1024-bit RSA + keys.
Quoted 2 lines
Hrmpf, this should of course get a new section '2.4.2'... Let me know if you want a v3, or whether this can be fixed on-the-fly. Apologies!
No problem. I don't mind moving things to a 2.4.2 section.
I'm however a bit puzzled of the "non-changes" (well, the indenting is changing, unless I'm blind to other changes) to --remote-cert-cu, --remote-cert-tls and --ns-cert-type. If we want to change the indenting, I think that should be kept in a separate patch, and keep --tls-cert-profile as a patch of its own.
Otherwise, Changes.rst tools fine to me.
On a more generic note to this patch. I wonder if we should keep "legacy" the default in the v2.4 branch. In the Fedora 26 (and Rawhide/27) builds I had to do something similar [1] to keep users happy. As OpenVPN isn't ready for OpenSSL v1.1, I had to switch to mbed TLS. Unfortunately that haven't been as successful as I really hoped it would be, but that's an entirely different story (and mail thread). As long as the Fedora builds need to be built with mbed TLS, I will need to ensure 'legacy' is the default there for a while. For the coming Fedora Rawhide (which will be F28), I can make some announcements preparing users to move to stricter defaults.
Signature · 4 lines
kind regards, David Sommerseth OpenVPN Technologies, Inc
Quoted 5 lines · David Sommerseth
I'm however a bit puzzled of the "non-changes" (well, the indenting is changing, unless I'm blind to other changes) to --remote-cert-cu, --remote-cert-tls and --ns-cert-type. If we want to change the indenting, I think that should be kept in a separate patch, and keep --tls-cert-profile as a patch of its own.
Ah, indeed. The indenting change is needed to make Github parse the rst correctly. Feel free to remove the indenting changes and I'll send a follow-up patch doing just that.
Quoted 11 lines
On a more generic note to this patch. I wonder if we should keep "legacy" the default in the v2.4 branch. In the Fedora 26 (and Rawhide/27) builds I had to do something similar [1] to keep users happy. As OpenVPN isn't ready for OpenSSL v1.1, I had to switch to mbed TLS. Unfortunately that haven't been as successful as I really hoped it would be, but that's an entirely different story (and mail thread). As long as the Fedora builds need to be built with mbed TLS, I will need to ensure 'legacy' is the default there for a while. For the coming Fedora Rawhide (which will be F28), I can make some announcements preparing users to move to stricter defaults.
Quoted 2 lines
The current mbed TLS builds already reject legacy crypto (except the fedora packaged build, apparently). With this patch users have the ability to use legacy stuff again, but I would prefer to not go any further than that. I think we should encourage people to drop the legacy. Just like the browser vendors are doing.
And for Fedora, they chose to experience intense pain when they chose to go for OpenSSL 1.1 this fast, that's their problem I guess... If they want to be that cutting edge, they should also stop using legacy crypto.
And otherwise, it will be a simple patch in the fedora packaging.
-Steffan
Quoted 10 lines · Steffan Karger
Quoted 5 lines · David Sommerseth
I'm however a bit puzzled of the "non-changes" (well, the indenting is changing, unless I'm blind to other changes) to --remote-cert-cu, --remote-cert-tls and --ns-cert-type. If we want to change the indenting, I think that should be kept in a separate patch, and keep --tls-cert-profile as a patch of its own.
Ah, indeed. The indenting change is needed to make Github parse the rst correctly. Feel free to remove the indenting changes and I'll send a follow-up patch doing just that.
Thanks! I'll have a closer look and test the patch again.
Quoted 11 lines
Quoted 11 lines
On a more generic note to this patch. I wonder if we should keep "legacy" the default in the v2.4 branch. In the Fedora 26 (and Rawhide/27) builds I had to do something similar [1] to keep users happy. As OpenVPN isn't ready for OpenSSL v1.1, I had to switch to mbed TLS. Unfortunately that haven't been as successful as I really hoped it would be, but that's an entirely different story (and mail thread). As long as the Fedora builds need to be built with mbed TLS, I will need to ensure 'legacy' is the default there for a while. For the coming Fedora Rawhide (which will be F28), I can make some announcements preparing users to move to stricter defaults.
Quoted 8 lines
Quoted 2 lines
The current mbed TLS builds already reject legacy crypto (except the fedora packaged build, apparently). With this patch users have the ability to use legacy stuff again, but I would prefer to not go any further than that. I think we should encourage people to drop the legacy. Just like the browser vendors are doing.
I do agree. But the pain as a package maintainer is quite noticeable when you're getting complaints about configurations this breaks. In fact, I got quite some dissatisfied remarks even for moving from 2.3 to 2.4 on the OpenSSL builds (F25 + EPEL) - as that also broke some setups
- mostly due to our option parser now doesn't ignore configuration errors any more or we actually implement the dual stack IPv4/IPv6 properly on the transport side. For mbedtls, the biggest issue now is the lack of PKCS#11 and PKCS#12 support. For PKCS#11, that is moving forward as the Fedora mbedtls package now enables that feature. PKCS#12 seems to be a far harder nut to crack.
Quoted 4 lines
And for Fedora, they chose to experience intense pain when they chose to go for OpenSSL 1.1 this fast, that's their problem I guess... If they want to be that cutting edge, they should also stop using legacy crypto.
And otherwise, it will be a simple patch in the fedora packaging.
Well, they do make things move forward fast. And they do a lot of work to get upstream projects moving towards OpenSSL 1.1. As there is a major Fedora release roughly every 6 months, it is a fast moving target.
But Fedora users as side, they know each major release is a huge step forward in many areas. For most OpenVPN users, regardless of OS or distro, they are used to the more sloppy legacy crypto support of OpenSSL. So enforcing a stricter set of crypto parameters in OpenVPN v2.4 only on mbed TLS seems a bit odd to me. And it is a big hassle for our users.
The reason I now receive more noise about these things nowadays is actually that I've pushed forward for mbed TLS to actually be able to provide a somewhat functional OpenVPN package in Fedora. So the amount of OpenVPN users with mbed TLS suddenly got a considerable lift. Unfortunately, many of them are looking forward for OpenVPN switching back to OpenSSL. So being smart here, may actually make it more interesting for users to look more into mbed TLS later on. If all they remember from mbed TLS that it broke OpenVPN configurations, that's not a good "sales argument".
So we do need to find a good compromise between modern security and our users, regardless of if they are Fedora users or not. Hence I think pushing forward for 'preferred' in v2.4 is too early. I agree we can do that in v2.5/git master though, as that does give us time to communicate this to users and perhaps even do something similar for the OpenSSL builds as well.
And it is also a bit challenging to defend, at least for me, that mbed TLS based builds are more conservative and stricter on the security parameters than OpenVPN builds against OpenSSL - especially when the OpenVPN version itself is the same. I do understand and agree that it is needed to move forward, but that must be done in a way which doesn't alienate us with our users.
And this is basically the same argument why James have moved OpenVPN 3 builds against mbed TLS also use the 'legacy' profile as default. My initial port from PolarSSL 1.3 to mbed TLS 2.3 for OpenVPN 3 did what you suggest, raise the security requirements.
Signature · 4 lines
kind regards, David Sommerseth OpenVPN Technologies, Inc
Hi,
Quoted 41 lines · David Sommerseth
Quoted 12 lines · Steffan Karger
Quoted 11 lines · David Sommerseth
On a more generic note to this patch. I wonder if we should keep "legacy" the default in the v2.4 branch. In the Fedora 26 (and Rawhide/27) builds I had to do something similar [1] to keep users happy. As OpenVPN isn't ready for OpenSSL v1.1, I had to switch to mbed TLS. Unfortunately that haven't been as successful as I really hoped it would be, but that's an entirely different story (and mail thread). As long as the Fedora builds need to be built with mbed TLS, I will need to ensure 'legacy' is the default there for a while. For the coming Fedora Rawhide (which will be F28), I can make some announcements preparing users to move to stricter defaults.
Quoted 8 lines
Quoted 2 lines
The current mbed TLS builds already reject legacy crypto (except the fedora packaged build, apparently). With this patch users have the ability to use legacy stuff again, but I would prefer to not go any further than that. I think we should encourage people to drop the legacy. Just like the browser vendors are doing.
I do agree. But the pain as a package maintainer is quite noticeable when you're getting complaints about configurations this breaks. In fact, I got quite some dissatisfied remarks even for moving from 2.3 to 2.4 on the OpenSSL builds (F25 + EPEL) - as that also broke some setups
- mostly due to our option parser now doesn't ignore configuration errors any more or we actually implement the dual stack IPv4/IPv6 properly on the transport side.[..snip..]
Quoted 4 lines
And for Fedora, they chose to experience intense pain when they chose to go for OpenSSL 1.1 this fast, that's their problem I guess... If they want to be that cutting edge, they should also stop using legacy crypto.
And otherwise, it will be a simple patch in the fedora packaging.Well, they do make things move forward fast. And they do a lot of work to get upstream projects moving towards OpenSSL 1.1. As there is a major Fedora release roughly every 6 months, it is a fast moving target.
Quoted 5 lines
But Fedora users as side, they know each major release is a huge step forward in many areas. For most OpenVPN users, regardless of OS or distro, they are used to the more sloppy legacy crypto support of OpenSSL. So enforcing a stricter set of crypto parameters in OpenVPN v2.4 only on mbed TLS seems a bit odd to me.
I agree - which is why I plan to add similar behaviour to the OpenSSL builds. I'm convinced by the argument to better aligning OpenSSL and mbed TLS behaviour, so I agree that we should default to 'legacy' as long as the OpenSSL counterpart is missing.
Do you prefer a v3?
The thing I still don't buy is that we have to jump through hoops because Fedora pushes openssl 1.1 (even though 1.0.2 is fine and supported and all), but we have to keep enabling deprecated crypto *by default* that people should not be using anymore, and can easily re-enable with a --enable-old-cruft flag if they really want to.
-Steffan
Quoted 50 lines · Steffan Karger
Hi,
Quoted 41 lines · David Sommerseth
Quoted 12 lines · Steffan Karger
Quoted 11 lines · David Sommerseth
On a more generic note to this patch. I wonder if we should keep "legacy" the default in the v2.4 branch. In the Fedora 26 (and Rawhide/27) builds I had to do something similar [1] to keep users happy. As OpenVPN isn't ready for OpenSSL v1.1, I had to switch to mbed TLS. Unfortunately that haven't been as successful as I really hoped it would be, but that's an entirely different story (and mail thread). As long as the Fedora builds need to be built with mbed TLS, I will need to ensure 'legacy' is the default there for a while. For the coming Fedora Rawhide (which will be F28), I can make some announcements preparing users to move to stricter defaults.
Quoted 8 lines
Quoted 2 lines
The current mbed TLS builds already reject legacy crypto (except the fedora packaged build, apparently). With this patch users have the ability to use legacy stuff again, but I would prefer to not go any further than that. I think we should encourage people to drop the legacy. Just like the browser vendors are doing.
I do agree. But the pain as a package maintainer is quite noticeable when you're getting complaints about configurations this breaks. In fact, I got quite some dissatisfied remarks even for moving from 2.3 to 2.4 on the OpenSSL builds (F25 + EPEL) - as that also broke some setups
- mostly due to our option parser now doesn't ignore configuration errors any more or we actually implement the dual stack IPv4/IPv6 properly on the transport side.[..snip..]
Quoted 4 lines
And for Fedora, they chose to experience intense pain when they chose to go for OpenSSL 1.1 this fast, that's their problem I guess... If they want to be that cutting edge, they should also stop using legacy crypto.
And otherwise, it will be a simple patch in the fedora packaging.Well, they do make things move forward fast. And they do a lot of work to get upstream projects moving towards OpenSSL 1.1. As there is a major Fedora release roughly every 6 months, it is a fast moving target.
Quoted 5 lines
But Fedora users as side, they know each major release is a huge step forward in many areas. For most OpenVPN users, regardless of OS or distro, they are used to the more sloppy legacy crypto support of OpenSSL. So enforcing a stricter set of crypto parameters in OpenVPN v2.4 only on mbed TLS seems a bit odd to me.
Quoted 6 lines
I agree - which is why I plan to add similar behaviour to the OpenSSL builds. I'm convinced by the argument to better aligning OpenSSL and mbed TLS behaviour, so I agree that we should default to 'legacy' as long as the OpenSSL counterpart is missing.
Do you prefer a v3?
I think it's needed to improve some details in the man page and Changes.rst. Perhaps also extend the man page to state that --tls-cert-profile is currently a NOOP builds against OpenSSL?
For git master (future v2.5) I have no issues having 'preferred' being the default. And we need to start announcing that things will be
stricter in v2.5 already now. But for v2.4 I think we should go for
'legacy' as the default.
Quoted 5 lines
The thing I still don't buy is that we have to jump through hoops because Fedora pushes openssl 1.1 (even though 1.0.2 is fine and supported and all), but we have to keep enabling deprecated crypto *by default* that people should not be using anymore, and can easily re-enable with a --enable-old-cruft flag if they really want to.
Fedora was just an example of what was needed to avoid a rebellious revolution against the package maintainer. But it illustrates the trickiness of pushing such changes too quickly to a user base. Hence, how I see it, for the whole OpenVPN user base regardless of OS/distro, to have legacy being the default for v2.4 users. Which also aligns well with the default chosen for the OpenVPN 3 user base (which includes all OpenVPN Connect users).
But be sure, I think we need to move towards 'preferred'. But doing it in a good way for all.
Signature · 4 lines
kind regards, David Sommerseth OpenVPN Technologies, Inc
PATCH v3 1/1 Add --tls-cert-profile option for mbedtls builds
This allows the user to specify what certificate crypto algorithms to support. The supported profiles are 'preferred' (default), 'legacy' and 'suiteb', as discussed in <[email protected]...>
(https://www.mail-archive.com/[email protected]/msg14214.html).
This only implements the feature for mbed TLS builds, because for mbed it is both more easy to implement and the most relevant because mbed TLS 2+ is by default somewhat restrictive by requiring 2048-bit+ for RSA keys.
---
v2:
- add documentation (manpage, Changes.rst and --help)
- no longer print a warning message on each startup for OpenSSL builds
v3:
- remove format changes in unrelated items (introduced in v2)
- Update Changes.rst text to reflect that the default in 2.4.2 is 'legacy' and the default in 2.5 will be 'preferred' (as discussed on the ML).
- This patch is for the master branch only now (due to the default).
Changes.rst | 19 +++++++++++++++++- doc/openvpn.8 | 19 ++++++++++++++++++ src/openvpn/options.c | 14 ++++++++++++- src/openvpn/options.h | 1 + src/openvpn/ssl.c | 3 +++ src/openvpn/ssl_backend.h | 10 ++++++++++ src/openvpn/ssl_mbedtls.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++ src/openvpn/ssl_mbedtls.h | 1 + src/openvpn/ssl_openssl.c | 6 ++++++ 9 files changed, 122 insertions(+), 2 deletions(-)
Changes.rst +18 -1
@@ -1,6 +1,15 @@ -Overview of changes in 2.4 +Overview of changes in 2.5 ========================== +User-visible Changes +-------------------- +- (For mbed TLS buils) The default certificate profile is now "preferred", + which means that only SHA2+, RSA-2048+ and EC certs are accepted. Legacy + crypto can be re-enabled by setting ``--tls-cert-profile legacy``. + + +Overview of changes in 2.4 +========================== New features ------------
@@ -318,3 +327,11 @@ Version 2.4.1 ``--remote-cert-tls`` uses the far more common keyUsage and extendedKeyUsage extension instead. Make sure your certificates carry these to be able to use ``--remote-cert-tls``. + +Version 2.4.2 +============= +- The new option ``--tls-cert-profile`` can be used to restrict the set of + allowed crypto algorithms in TLS certificates in mbed TLS builds. The + default profile is 'legacy' for now, which allows SHA1+, RSA-1024+ and any + elliptic curve certificates. The default will be changed to the 'preferred' + profile in the future, which requires SHA2+, RSA-2048+ and any curve.
doc/openvpn.8 +19 -0
@@ -4879,6 +4879,25 @@ when using PolarSSL or OpenSSL. .\"********************************************************* .TP +.B \-\-tls\-cert\-profile profile +Set the allowed cryptographic algorithms for certificates according to +.B profile\fN. + +The following profiles are supported: + +.B preferred +(default): SHA2 and newer, RSA 2048-bit+, any elliptic curve. + +.B legacy +: SHA1 and newer, RSA 2048-bit+, any elliptic curve. + +.B suiteb +: SHA256/SHA384, ECDSA with P-256 or P-384. + +This option is only supported for mbed TLS builds. OpenSSL builds accept any +certificate that OpenSSL accepts. +.\"********************************************************* +.TP .B \-\-tls\-timeout n Packet retransmit timeout on TLS control channel if no acknowledgment from remote within
src/openvpn/options.c +13 -1
@@ -599,6 +599,8 @@ static const char usage_message[] =#endif "--tls-cipher l : A list l of allowable TLS ciphers separated by : (optional).\n" " : Use --show-tls to see a list of supported TLS ciphers.\n" +"--tls-cert-profile p : Set the allowed certificate crypto algorithm profile\n" +" (default=%s).\n" "--tls-timeout n : Packet retransmit timeout on TLS control channel\n" " if no ACK from remote within n seconds (default=%d).\n" "--reneg-bytes n : Renegotiate data chan. key after n bytes sent and recvd.\n"
@@ -873,6 +875,7 @@ init_options(struct options *o, const bool init_gc) o->renegotiate_seconds =3600 ; o->handshake_window =60 ; o->transition_window =3600 ; + o->tls_cert_profile ="preferred" ; o->ecdh_curve =NULL ;#ifdef ENABLE_X509ALTUSERNAME o->x509_username_field =X509_USERNAME_FIELD_DEFAULT ;
@@ -1752,6 +1755,7 @@ show_settings(const struct options *o)SHOW_STR (cryptoapi_cert);#endif SHOW_STR (cipher_list); +SHOW_STR (tls_cert_profile);SHOW_STR (tls_verify);SHOW_STR (tls_export_cert);SHOW_INT (verify_x509_type);
@@ -2734,6 +2738,7 @@ options_postprocess_verify_ce(const struct options *options, const struct connecMUST_BE_UNDEF (pkcs12_file);#endif MUST_BE_UNDEF (cipher_list); +MUST_BE_UNDEF (tls_cert_profile);MUST_BE_UNDEF (tls_verify);MUST_BE_UNDEF (tls_export_cert);MUST_BE_UNDEF (verify_x509_name);
@@ -4090,7 +4095,7 @@ usage(void) o.verbosity, o.authname, o.ciphername, o.replay_window, o.replay_time, - o.tls_timeout, o.renegotiate_seconds, + o.tls_cert_profile, o.tls_timeout, o.renegotiate_seconds, o.handshake_window, o.transition_window);#else /* ifdef ENABLE_CRYPTO */ fprintf(fp, usage_message,
@@ -7813,6 +7818,13 @@ add_option(struct options *options,VERIFY_PERMISSION (OPT_P_GENERAL ); options->cipher_list = p[1 ]; } +#ifdef ENABLE_CRYPTO_MBEDTLS + else if (streq(p[0], "tls-cert-profile") && p[1] && !p[2]) + { +VERIFY_PERMISSION (OPT_P_GENERAL ); + options->tls_cert_profile = p[1 ]; + } +#endif else if (streq(p[0], "crl-verify") && p[1] && ((p[2] && streq(p[2], "dir")) || (p[2] && streq(p[1], INLINE_FILE_TAG) ) || !p[2]) && !p[3]) {
src/openvpn/options.h +1 -0
@@ -500,6 +500,7 @@ struct optionsconst char *priv_key_file;const char *pkcs12_file;const char *cipher_list; +const char *tls_cert_profile;const char *ecdh_curve;const char *tls_verify;int verify_x509_type;
src/openvpn/ssl.c +3 -0
@@ -702,6 +702,9 @@ init_ssl(const struct options *options, struct tls_root_ctx *new_ctx)/* Allowable ciphers */ tls_ctx_restrict_ciphers (new_ctx, options->cipher_list); +/* Restrict allowed certificate crypto algorithms */ +tls_ctx_set_cert_profile (new_ctx, options->tls_cert_profile); +#ifdef ENABLE_CRYPTO_MBEDTLS /* Personalise the random by mixing in the certificate */ tls_ctx_personalise_random (new_ctx);
src/openvpn/ssl_backend.h +10 -0
@@ -178,6 +178,16 @@ void tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags);void tls_ctx_restrict_ciphers (struct tls_root_ctx *ctx,const char *ciphers);/** +* Set the TLS certificate profile. The profile defines which crypto +* algorithms may be used in the supplied certificate. +* +* @param ctx TLS context to restrict, must be valid. +* @param profile The profile name ('preferred', 'legacy' or 'suiteb'). +* Defaults to 'preferred' if NULL. +*/ +void tls_ctx_set_cert_profile (struct tls_root_ctx *ctx,const char *profile); + +/** * Check our certificate notBefore and notAfter fields, and warn if the cert is * either not yet valid or has expired. Note that this is a non-fatal error, * since we compare against the system time, which might be incorrect.
src/openvpn/ssl_mbedtls.c +51 -0
69 lines not on this page · raw message
src/openvpn/ssl_mbedtls.h +1 -0
@@ -83,6 +83,7 @@ struct tls_root_ctx {struct external_context *external_key;/**< Management external key */ #endif int *allowed_ciphers;/**< List of allowed ciphers for this connection */ +mbedtls_x509_crt_profile cert_profile;/**< Allowed certificate types */ };struct key_state_ssl {
src/openvpn/ssl_openssl.c +6 -0
@@ -384,6 +384,12 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) }void +tls_ctx_set_cert_profile (struct tls_root_ctx *ctx,const char *profile) +{ +/* TODO --tls-cert-profile not supported for OpenSSL builds */ +} + +void tls_ctx_check_cert_time (const struct tls_root_ctx *ctx) {int ret;
Signature · 1 line
2.7.4
PATCH 1/1 Add --tls-cert-profile option for mbedtls builds
This allows the user to specify what certificate crypto algorithms to support. The supported profiles are 'preferred', 'legacy' (default) and 'suiteb', as discussed in <[email protected]...>
(https://www.mail-archive.com/[email protected]/msg14214.html).
This only implements the feature for mbed TLS builds, because for mbed it is both more easy to implement and the most relevant because mbed TLS 2+ is by default somewhat restrictive by requiring 2048-bit+ for RSA keys.
In contrast with the patch for the master branch, this patch uses 'legacy' as the default profile following discussion on the openvpn-devel mailing list.
---
This patch is a cherry-picked and adjusted version of the v3 patch for master. The only difference being that this patch uses 'legacy' as the default profile and documents that.
Changes.rst | 8 ++++++++ doc/openvpn.8 | 22 ++++++++++++++++++++ src/openvpn/options.c | 14 ++++++++++++- src/openvpn/options.h | 1 + src/openvpn/ssl.c | 3 +++ src/openvpn/ssl_backend.h | 10 ++++++++++ src/openvpn/ssl_mbedtls.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++ src/openvpn/ssl_mbedtls.h | 1 + src/openvpn/ssl_openssl.c | 6 ++++++ 9 files changed, 115 insertions(+), 1 deletion(-)
Changes.rst +8 -0
@@ -318,3 +318,11 @@ Version 2.4.1 ``--remote-cert-tls`` uses the far more common keyUsage and extendedKeyUsage extension instead. Make sure your certificates carry these to be able to use ``--remote-cert-tls``. + +Version 2.4.2 +============= +- The new option ``--tls-cert-profile`` can be used to restrict the set of + allowed crypto algorithms in TLS certificates in mbed TLS builds. The + default profile is 'legacy' for now, which allows SHA1+, RSA-1024+ and any + elliptic curve certificates. The default will be changed to the 'preferred' + profile in the future, which requires SHA2+, RSA-2048+ and any curve.
doc/openvpn.8 +22 -0
@@ -4879,6 +4879,28 @@ when using PolarSSL or OpenSSL. .\"********************************************************* .TP +.B \-\-tls\-cert\-profile profile +Set the allowed cryptographic algorithms for certificates according to +.B profile\fN. + +The following profiles are supported: + +.B preferred +: SHA2 and newer, RSA 2048-bit+, any elliptic curve. + +.B legacy +(default): SHA1 and newer, RSA 2048-bit+, any elliptic curve. + +.B suiteb +: SHA256/SHA384, ECDSA with P-256 or P-384. + +This option is only supported for mbed TLS builds. OpenSSL builds accept any +certificate that OpenSSL accepts. + +OpenVPN will migrate to 'preferred' as default in the future. Please ensure +that your keys already comply. +.\"********************************************************* +.TP .B \-\-tls\-timeout n Packet retransmit timeout on TLS control channel if no acknowledgment from remote within
src/openvpn/options.c +13 -1
@@ -599,6 +599,8 @@ static const char usage_message[] =#endif "--tls-cipher l : A list l of allowable TLS ciphers separated by : (optional).\n" " : Use --show-tls to see a list of supported TLS ciphers.\n" +"--tls-cert-profile p : Set the allowed certificate crypto algorithm profile\n" +" (default=%s).\n" "--tls-timeout n : Packet retransmit timeout on TLS control channel\n" " if no ACK from remote within n seconds (default=%d).\n" "--reneg-bytes n : Renegotiate data chan. key after n bytes sent and recvd.\n"
@@ -873,6 +875,7 @@ init_options(struct options *o, const bool init_gc) o->renegotiate_seconds =3600 ; o->handshake_window =60 ; o->transition_window =3600 ; + o->tls_cert_profile ="legacy" ; o->ecdh_curve =NULL ;#ifdef ENABLE_X509ALTUSERNAME o->x509_username_field =X509_USERNAME_FIELD_DEFAULT ;
@@ -1752,6 +1755,7 @@ show_settings(const struct options *o)SHOW_STR (cryptoapi_cert);#endif SHOW_STR (cipher_list); +SHOW_STR (tls_cert_profile);SHOW_STR (tls_verify);SHOW_STR (tls_export_cert);SHOW_INT (verify_x509_type);
@@ -2734,6 +2738,7 @@ options_postprocess_verify_ce(const struct options *options, const struct connecMUST_BE_UNDEF (pkcs12_file);#endif MUST_BE_UNDEF (cipher_list); +MUST_BE_UNDEF (tls_cert_profile);MUST_BE_UNDEF (tls_verify);MUST_BE_UNDEF (tls_export_cert);MUST_BE_UNDEF (verify_x509_name);
@@ -4090,7 +4095,7 @@ usage(void) o.verbosity, o.authname, o.ciphername, o.replay_window, o.replay_time, - o.tls_timeout, o.renegotiate_seconds, + o.tls_cert_profile, o.tls_timeout, o.renegotiate_seconds, o.handshake_window, o.transition_window);#else /* ifdef ENABLE_CRYPTO */ fprintf(fp, usage_message,
@@ -7813,6 +7818,13 @@ add_option(struct options *options,VERIFY_PERMISSION (OPT_P_GENERAL ); options->cipher_list = p[1 ]; } +#ifdef ENABLE_CRYPTO_MBEDTLS + else if (streq(p[0], "tls-cert-profile") && p[1] && !p[2]) + { +VERIFY_PERMISSION (OPT_P_GENERAL ); + options->tls_cert_profile = p[1 ]; + } +#endif else if (streq(p[0], "crl-verify") && p[1] && ((p[2] && streq(p[2], "dir")) || (p[2] && streq(p[1], INLINE_FILE_TAG) ) || !p[2]) && !p[3]) {
src/openvpn/options.h +1 -0
@@ -500,6 +500,7 @@ struct optionsconst char *priv_key_file;const char *pkcs12_file;const char *cipher_list; +const char *tls_cert_profile;const char *ecdh_curve;const char *tls_verify;int verify_x509_type;
src/openvpn/ssl.c +3 -0
@@ -702,6 +702,9 @@ init_ssl(const struct options *options, struct tls_root_ctx *new_ctx)/* Allowable ciphers */ tls_ctx_restrict_ciphers (new_ctx, options->cipher_list); +/* Restrict allowed certificate crypto algorithms */ +tls_ctx_set_cert_profile (new_ctx, options->tls_cert_profile); +#ifdef ENABLE_CRYPTO_MBEDTLS /* Personalise the random by mixing in the certificate */ tls_ctx_personalise_random (new_ctx);
src/openvpn/ssl_backend.h +10 -0
@@ -178,6 +178,16 @@ void tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags);void tls_ctx_restrict_ciphers (struct tls_root_ctx *ctx,const char *ciphers);/** +* Set the TLS certificate profile. The profile defines which crypto +* algorithms may be used in the supplied certificate. +* +* @param ctx TLS context to restrict, must be valid. +* @param profile The profile name ('preferred', 'legacy' or 'suiteb'). +* Defaults to 'preferred' if NULL. +*/ +void tls_ctx_set_cert_profile (struct tls_root_ctx *ctx,const char *profile); + +/** * Check our certificate notBefore and notAfter fields, and warn if the cert is * either not yet valid or has expired. Note that this is a non-fatal error, * since we compare against the system time, which might be incorrect.
src/openvpn/ssl_mbedtls.c +51 -0
69 lines not on this page · raw message
src/openvpn/ssl_mbedtls.h +1 -0
@@ -83,6 +83,7 @@ struct tls_root_ctx {struct external_context *external_key;/**< Management external key */ #endif int *allowed_ciphers;/**< List of allowed ciphers for this connection */ +mbedtls_x509_crt_profile cert_profile;/**< Allowed certificate types */ };struct key_state_ssl {
src/openvpn/ssl_openssl.c +6 -0
@@ -384,6 +384,12 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) }void +tls_ctx_set_cert_profile (struct tls_root_ctx *ctx,const char *profile) +{ +/* TODO --tls-cert-profile not supported for OpenSSL builds */ +} + +void tls_ctx_check_cert_time (const struct tls_root_ctx *ctx) {int ret;
Signature · 1 line
2.7.4
Am 14.04.17 um 17:40 schrieb Steffan Karger:
Quoted 9 lines
This allows the user to specify what certificate crypto algorithms to support. The supported profiles are 'preferred' (default), 'legacy' and 'suiteb', as discussed in <[email protected]...>
(https://www.mail-archive.com/[email protected]/msg14214.html).This only implements the feature for mbed TLS builds, because for mbed it is both more easy to implement and the most relevant because mbed TLS 2+ is by default somewhat restrictive by requiring 2048-bit+ for RSA keys.
ACK so far as the code goes. As for the whole MD5 stuff is at the moment blowing up with OSSL 1.1, we need a md5 allowing option (with a fat warning probably).
And the other thing is that OpenSSL has a similar feature in 1.1:
Security levels. Which can be specified as part of tls-cipher or set independently by
https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_security_level.html
The levels are similar to the proposed level here but not identical. Should we somehow align these two features? Configuring it for one library in tls-cipher and for the other in tls-cert-profile is bit strange.
Also shouldn't be tls-min-version included in the preferred/legacy options?
And suiteb would be tls-cipher SUITEB128 in OpenSSL
Arne
Hi,
Quoted 6 lines · Arne Schwabe
Am 14.04.17 um 17:40 schrieb Steffan Karger:
Quoted 5 lines
This allows the user to specify what certificate crypto algorithms to support. The supported profiles are 'preferred' (default), 'legacy' and 'suiteb', as discussed in <[email protected]...>
(https://www.mail-archive.com/[email protected]/msg14214.html).
Quoted 8 lines
Quoted 4 lines
This only implements the feature for mbed TLS builds, because for mbed it is both more easy to implement and the most relevant because mbed TLS 2+ is by default somewhat restrictive by requiring 2048-bit+ for RSA keys.
ACK so far as the code goes. As for the whole MD5 stuff is at the moment blowing up with OSSL 1.1, we need a md5 allowing option (with a fat warning probably).
To be honest, I think we shouldn't do anything to allow MD5. The first set of certificates with colliding MD5 digests was demonstrated in 2005!
We should really stop supporting broken setups and just tell people to
move to SHA2.
Quoted 8 lines
And the other thing is that OpenSSL has a similar feature in 1.1:
Security levels. Which can be specified as part of tls-cipher or set independently by
https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_security_level.htmlThe levels are similar to the proposed level here but not identical. Should we somehow align these two features? Configuring it for one library in tls-cipher and for the other in tls-cert-profile is bit strange.
Yeah, I'll look into the callbacks they mention, to see if we can easily align both libraries. Would be nice.
Quoted 1 line
Also shouldn't be tls-min-version included in the preferred/legacy options?
Hm, for now we explicitly chose --tls-cert-profile, which is separate from --tls-verion-min, such that people can still easily upgrade the one even if the other is keeping them back (e.g. due to a non-cooperating CA, or smart card).
-Steffan
Hi,
Quoted 8 lines · Steffan Karger
v2:
- add documentation (manpage,Changes.rstand --help)
- no longer print a warning message on each startup for OpenSSL builds
v3:
- remove format changes in unrelated items (introduced in v2)
- UpdateChanges.rsttext to reflect that the default in 2.4.2 is 'legacy' and the default in 2.5 will be 'preferred' (as discussed on the ML).
- This patch is for the master branch only now (due to the default).
I've applied this to "master", added "--tls-cert-profile legacy" to my openvpn command line, and my FreeBSD 10.3 + mbedTLS 2.6.0 t_client tests came back to "all tests passed".
So from that point of view, this is a necessary addition.
OTOH, it adds a command line option that will lead to a fatal error on an OpenSSL build, which I'm not happy about (read: it will break the buildslave for openssl builds then...) - so even if we do not have the functionality for OpenSSL yet, we should still understand the option and then print out a warning.
(Also it - obviously - does not apply to master anymore, due to surrounding code changes)
David: Steffan said you did not like this patch -> we should discuss how to improve this / what is missing.
gert
Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
//www.muc.de/~gert/
Gert Doering - Munich, Germany [email protected]...
fax: +49-89-35655025 [email protected]...PATCH v4 1/1 Add --tls-cert-profile option for mbedtls builds
From: Steffan Karger <[email protected]...>
This allows the user to specify what certificate crypto algorithms to support. The supported profiles are 'preferred', 'legacy' (default) and 'suiteb', as discussed in <[email protected]...>
(https://www.mail-archive.com/[email protected]/msg14214.html).
This only implements the feature for mbed TLS builds, because for mbed it is both more easy to implement and the most relevant because mbed TLS 2+ is by default somewhat restrictive by requiring 2048-bit+ for RSA keys.
This patch uses 'legacy' as the default profile following discussion on the openvpn-devel mailing list. This way this patch can be applied to both the release/2.4 and master branches. I'll send a follow-up patch for the master branch to change the default to 'preferred' later.
---
v2:
- add documentation (manpage, Changes.rst and --help)
- no longer print a warning message on each startup for OpenSSL builds
v3:
- remove format changes in unrelated items (introduced in v2)
- Update Changes.rst text to reflect that the default in 2.4.2 is 'legacy' and the default in 2.5 will be 'preferred' (as discussed on the ML).
- This patch is for the master branch only now (due to the default).
v4:
- Ignore the option for OpenSSL builds, instead of rejecting the option and refusing to start.
- Patch is for master and release/2.4 again. A follow-up patch will change the default for master later on.
Changes.rst | 12 +++++++++++ doc/openvpn.8 | 22 ++++++++++++++++++++ src/openvpn/options.c | 16 ++++++++++++++- src/openvpn/options.h | 1 + src/openvpn/ssl.c | 3 +++ src/openvpn/ssl_backend.h | 10 ++++++++++ src/openvpn/ssl_mbedtls.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++ src/openvpn/ssl_mbedtls.h | 1 + src/openvpn/ssl_openssl.c | 6 ++++++ 9 files changed, 121 insertions(+), 1 deletion(-)
Changes.rst +12 -0
@@ -321,6 +321,18 @@ Maintainer-visible changes i386/i686 builds on RHEL5. +Version 2.4.5 +============= + +New features +------------ +- The new option ``--tls-cert-profile`` can be used to restrict the set of + allowed crypto algorithms in TLS certificates in mbed TLS builds. The + default profile is 'legacy' for now, which allows SHA1+, RSA-1024+ and any + elliptic curve certificates. The default will be changed to the 'preferred' + profile in the future, which requires SHA2+, RSA-2048+ and any curve. + + Version 2.4.3 =============
doc/openvpn.8 +22 -0
@@ -4917,6 +4917,28 @@ when using mbed TLS or OpenSSL. .\"********************************************************* .TP +.B \-\-tls\-cert\-profile profile +Set the allowed cryptographic algorithms for certificates according to +.B profile\fN. + +The following profiles are supported: + +.B preferred +: SHA2 and newer, RSA 2048-bit+, any elliptic curve. + +.B legacy +(default): SHA1 and newer, RSA 2048-bit+, any elliptic curve. + +.B suiteb +: SHA256/SHA384, ECDSA with P-256 or P-384. + +This option is only supported for mbed TLS builds. OpenSSL builds accept any +certificate that OpenSSL accepts. + +OpenVPN will migrate to 'preferred' as default in the future. Please ensure +that your keys already comply. +.\"********************************************************* +.TP .B \-\-tls\-timeout n Packet retransmit timeout on TLS control channel if no acknowledgment from remote within
src/openvpn/options.c +15 -1
@@ -599,6 +599,8 @@ static const char usage_message[] =#endif "--tls-cipher l : A list l of allowable TLS ciphers separated by : (optional).\n" " : Use --show-tls to see a list of supported TLS ciphers.\n" +"--tls-cert-profile p : Set the allowed certificate crypto algorithm profile\n" +" (default=%s).\n" "--tls-timeout n : Packet retransmit timeout on TLS control channel\n" " if no ACK from remote within n seconds (default=%d).\n" "--reneg-bytes n : Renegotiate data chan. key after n bytes sent and recvd.\n"
@@ -872,6 +874,7 @@ init_options(struct options *o, const bool init_gc) o->renegotiate_seconds =3600 ; o->handshake_window =60 ; o->transition_window =3600 ; + o->tls_cert_profile ="legacy" ; o->ecdh_curve =NULL ;#ifdef ENABLE_X509ALTUSERNAME o->x509_username_field =X509_USERNAME_FIELD_DEFAULT ;
@@ -1750,6 +1753,7 @@ show_settings(const struct options *o)SHOW_STR (cryptoapi_cert);#endif SHOW_STR (cipher_list); +SHOW_STR (tls_cert_profile);SHOW_STR (tls_verify);SHOW_STR (tls_export_cert);SHOW_INT (verify_x509_type);
@@ -2729,6 +2733,7 @@ options_postprocess_verify_ce(const struct options *options, const struct connecMUST_BE_UNDEF (pkcs12_file);#endif MUST_BE_UNDEF (cipher_list); +MUST_BE_UNDEF (tls_cert_profile);MUST_BE_UNDEF (tls_verify);MUST_BE_UNDEF (tls_export_cert);MUST_BE_UNDEF (verify_x509_name);
@@ -4086,7 +4091,7 @@ usage(void) o.verbosity, o.authname, o.ciphername, o.replay_window, o.replay_time, - o.tls_timeout, o.renegotiate_seconds, + o.tls_cert_profile, o.tls_timeout, o.renegotiate_seconds, o.handshake_window, o.transition_window);#else /* ifdef ENABLE_CRYPTO */ fprintf(fp, usage_message,
@@ -7831,6 +7836,15 @@ add_option(struct options *options,VERIFY_PERMISSION (OPT_P_GENERAL ); options->cipher_list = p[1 ]; } +else if (streq (p[0 ],"tls-cert-profile" ) && p[1 ] && !p[2 ]) + { +VERIFY_PERMISSION (OPT_P_GENERAL ); +#ifdef ENABLE_CRYPTO_MBEDTLS + options->tls_cert_profile = p[1 ]; +#else +msg (M_WARN ,"WARNING: --tls-cert-profile is not yet implemented for OpenSSL, ignoring option." ); +#endif + }else if (streq (p[0 ],"crl-verify" ) && p[1 ] && ((p[2 ] &&streq (p[2 ],"dir" )) || (p[2 ] &&streq (p[1 ],INLINE_FILE_TAG ) ) || !p[2 ]) && !p[3 ]) {
src/openvpn/options.h +1 -0
@@ -502,6 +502,7 @@ struct optionsconst char *priv_key_file;const char *pkcs12_file;const char *cipher_list; +const char *tls_cert_profile;const char *ecdh_curve;const char *tls_verify;int verify_x509_type;
src/openvpn/ssl.c +3 -0
@@ -621,6 +621,9 @@ init_ssl(const struct options *options, struct tls_root_ctx *new_ctx)* cipher restrictions before loading certificates */ tls_ctx_restrict_ciphers (new_ctx, options->cipher_list); +/* Restrict allowed certificate crypto algorithms */ +tls_ctx_set_cert_profile (new_ctx, options->tls_cert_profile); +tls_ctx_set_options (new_ctx, options->ssl_flags);if (options->pkcs12_file)
src/openvpn/ssl_backend.h +10 -0
@@ -176,6 +176,16 @@ void tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags);*/ void tls_ctx_restrict_ciphers (struct tls_root_ctx *ctx,const char *ciphers); +/** +* Set the TLS certificate profile. The profile defines which crypto +* algorithms may be used in the supplied certificate. +* +* @param ctx TLS context to restrict, must be valid. +* @param profile The profile name ('preferred', 'legacy' or 'suiteb'). +* Defaults to 'preferred' if NULL. +*/ +void tls_ctx_set_cert_profile (struct tls_root_ctx *ctx,const char *profile); +/** * Check our certificate notBefore and notAfter fields, and warn if the cert is * either not yet valid or has expired. Note that this is a non-fatal error,
src/openvpn/ssl_mbedtls.c +51 -0
69 lines not on this page · raw message
src/openvpn/ssl_mbedtls.h +1 -0
@@ -82,6 +82,7 @@ struct tls_root_ctx {struct external_context *external_key;/**< Management external key */ #endif int *allowed_ciphers;/**< List of allowed ciphers for this connection */ +mbedtls_x509_crt_profile cert_profile;/**< Allowed certificate types */ };struct key_state_ssl {
src/openvpn/ssl_openssl.c +6 -0
@@ -383,6 +383,12 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) } } +void +tls_ctx_set_cert_profile (struct tls_root_ctx *ctx,const char *profile) +{ +/* TODO --tls-cert-profile not supported for OpenSSL builds */ +} +void tls_ctx_check_cert_time (const struct tls_root_ctx *ctx) {
Signature · 1 line
2.14.1
Hi,
Quoted 11 lines · Steffan Karger
From: Steffan Karger <[email protected]...>
This allows the user to specify what certificate crypto algorithms to support. The supported profiles are 'preferred', 'legacy' (default) and 'suiteb', as discussed in <[email protected]....>
(https://www.mail-archive.com/[email protected]/msg14214.html).This only implements the feature for mbed TLS builds, because for mbed it is both more easy to implement and the most relevant because mbed TLS 2+ is by default somewhat restrictive by requiring 2048-bit+ for RSA keys.
Quoted 6 lines
This patch uses 'legacy' as the default profile following discussion on the openvpn-devel mailing list. This way this patch can be applied to both the release/2.4 and master branches. I'll send a follow-up patch for the master branch to change the default to 'preferred' later.
Signed-off-by Steffan Karger <[email protected]...>
The test consisted in configuring a server and a client with certificates signed with SHA1.
With the default settings, the client was able to connect to the server.
When setting the cert profile to "preferred" on either one, the latter complained about unacceptable signature.
This proved that the patch is working as expected.
To note: the server and the clients both start even though they are using a certificate that is signed with a non-acceptable signature (for their profile). mbedTLS could be improved to reject a certificate when signed with an algorithm that is not part of the allowed profile.
Cheers,
Quoted 297 lines
---
v2:
- add documentation (manpage,Changes.rstand --help)
- no longer print a warning message on each startup for OpenSSL builds
v3:
- remove format changes in unrelated items (introduced in v2)
- UpdateChanges.rsttext to reflect that the default in 2.4.2 is 'legacy' and the default in 2.5 will be 'preferred' (as discussed on the ML).
- This patch is for the master branch only now (due to the default).
v4:
- Ignore the option for OpenSSL builds, instead of rejecting the option and refusing to start.
- Patch is for master and release/2.4 again. A follow-up patch will change the default for master later on.Changes.rst | 12 +++++++++++ doc/openvpn.8 | 22 ++++++++++++++++++++ src/openvpn/options.c | 16 ++++++++++++++- src/openvpn/options.h | 1 + src/openvpn/ssl.c | 3 +++ src/openvpn/ssl_backend.h | 10 ++++++++++ src/openvpn/ssl_mbedtls.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++ src/openvpn/ssl_mbedtls.h | 1 + src/openvpn/ssl_openssl.c | 6 ++++++ 9 files changed, 121 insertions(+), 1 deletion(-)Changes.rst +12
-0@@ -321,6 +321,18 @@ Maintainer-visible changes i386/i686 builds on RHEL5. +Version 2.4.5 +============= + +New features +------------ +- The new option ``--tls-cert-profile`` can be used to restrict the set of + allowed crypto algorithms in TLS certificates in mbed TLS builds. The + default profile is 'legacy' for now, which allows SHA1+, RSA-1024+ and any + elliptic curve certificates. The default will be changed to the 'preferred' + profile in the future, which requires SHA2+, RSA-2048+ and any curve. + + Version 2.4.3 =============doc/openvpn.8 +22
-0@@ -4917,6 +4917,28 @@ when using mbed TLS or OpenSSL. .\"********************************************************* .TP +.B \-\-tls\-cert\-profile profile +Set the allowed cryptographic algorithms for certificates according to +.B profile\fN. + +The following profiles are supported: + +.B preferred +: SHA2 and newer, RSA 2048-bit+, any elliptic curve. + +.B legacy +(default): SHA1 and newer, RSA 2048-bit+, any elliptic curve. + +.B suiteb +: SHA256/SHA384, ECDSA with P-256 or P-384. + +This option is only supported for mbed TLS builds. OpenSSL builds accept any +certificate that OpenSSL accepts. + +OpenVPN will migrate to 'preferred' as default in the future. Please ensure +that your keys already comply. +.\"********************************************************* +.TP .B \-\-tls\-timeout n Packet retransmit timeout on TLS control channel if no acknowledgment from remote withinsrc/openvpn/options.c +15
-1@@ -599,6 +599,8 @@ static const char usage_message[] =#endif "--tls-cipher l : A list l of allowable TLS ciphers separated by : (optional).\n" " : Use --show-tls to see a list of supported TLS ciphers.\n" +"--tls-cert-profile p : Set the allowed certificate crypto algorithm profile\n" +" (default=%s).\n" "--tls-timeout n : Packet retransmit timeout on TLS control channel\n" " if no ACK from remote within n seconds (default=%d).\n" "--reneg-bytes n : Renegotiate data chan. key after n bytes sent and recvd.\n" @@ -872,6 +874,7 @@ init_options(struct options *o, const bool init_gc) o->renegotiate_seconds =3600 ; o->handshake_window =60 ; o->transition_window =3600 ; + o->tls_cert_profile ="legacy" ; o->ecdh_curve =NULL ;#ifdef ENABLE_X509ALTUSERNAME o->x509_username_field =X509_USERNAME_FIELD_DEFAULT ;@@ -1750,6 +1753,7 @@ show_settings(const struct options *o)SHOW_STR (cryptoapi_cert);#endif SHOW_STR (cipher_list); +SHOW_STR (tls_cert_profile);SHOW_STR (tls_verify);SHOW_STR (tls_export_cert);SHOW_INT (verify_x509_type);@@ -2729,6 +2733,7 @@ options_postprocess_verify_ce(const struct options *options, const struct connecMUST_BE_UNDEF (pkcs12_file);#endif MUST_BE_UNDEF (cipher_list); +MUST_BE_UNDEF (tls_cert_profile);MUST_BE_UNDEF (tls_verify);MUST_BE_UNDEF (tls_export_cert);MUST_BE_UNDEF (verify_x509_name);@@ -4086,7 +4091,7 @@ usage(void) o.verbosity, o.authname, o.ciphername, o.replay_window, o.replay_time, - o.tls_timeout, o.renegotiate_seconds, + o.tls_cert_profile, o.tls_timeout, o.renegotiate_seconds, o.handshake_window, o.transition_window);#else /* ifdef ENABLE_CRYPTO */ fprintf(fp, usage_message,@@ -7831,6 +7836,15 @@ add_option(struct options *options,VERIFY_PERMISSION (OPT_P_GENERAL ); options->cipher_list = p[1 ]; } +else if (streq (p[0 ],"tls-cert-profile" ) && p[1 ] && !p[2 ]) + { +VERIFY_PERMISSION (OPT_P_GENERAL ); +#ifdef ENABLE_CRYPTO_MBEDTLS + options->tls_cert_profile = p[1 ]; +#else +msg (M_WARN ,"WARNING: --tls-cert-profile is not yet implemented for OpenSSL, ignoring option." ); +#endif + }else if (streq (p[0 ],"crl-verify" ) && p[1 ] && ((p[2 ] &&streq (p[2 ],"dir" )) || (p[2 ] &&streq (p[1 ],INLINE_FILE_TAG ) ) || !p[2 ]) && !p[3 ]) {src/openvpn/options.h +1
-0@@ -502,6 +502,7 @@ struct optionsconst char *priv_key_file;const char *pkcs12_file;const char *cipher_list; +const char *tls_cert_profile;const char *ecdh_curve;const char *tls_verify;int verify_x509_type;src/openvpn/ssl.c +3
-0@@ -621,6 +621,9 @@ init_ssl(const struct options *options, struct tls_root_ctx *new_ctx)* cipher restrictions before loading certificates */ tls_ctx_restrict_ciphers (new_ctx, options->cipher_list); +/* Restrict allowed certificate crypto algorithms */ +tls_ctx_set_cert_profile (new_ctx, options->tls_cert_profile); +tls_ctx_set_options (new_ctx, options->ssl_flags);if (options->pkcs12_file)src/openvpn/ssl_backend.h +10
-0@@ -176,6 +176,16 @@ void tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags);*/ void tls_ctx_restrict_ciphers (struct tls_root_ctx *ctx,const char *ciphers); +/** +* Set the TLS certificate profile. The profile defines which crypto +* algorithms may be used in the supplied certificate. +* +* @param ctx TLS context to restrict, must be valid. +* @param profile The profile name ('preferred', 'legacy' or 'suiteb'). +* Defaults to 'preferred' if NULL. +*/ +void tls_ctx_set_cert_profile (struct tls_root_ctx *ctx,const char *profile); +/** * Check our certificate notBefore and notAfter fields, and warn if the cert is * either not yet valid or has expired. Note that this is a non-fatal error, src/openvpn/ssl_mbedtls.c +51
-0@@ -62,6 +62,34 @@#include <mbedtls/pem.h> #include <mbedtls/sha256.h> +static const mbedtls_x509_crt_profile openvpn_x509_crt_profile_legacy = +{ +/* Hashes from SHA-1 and above */ +MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA1 ) | +MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_RIPEMD160 ) | +MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA224 ) | +MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA256 ) | +MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA384 ) | +MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA512 ), +0xFFFFFFF ,/* Any PK alg */ +0xFFFFFFF ,/* Any curve */ +1024 ,/* RSA-1024 and larger */ +}; + +static const mbedtls_x509_crt_profile openvpn_x509_crt_profile_preferred = +{ +/* SHA-2 and above */ +MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA224 ) | +MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA256 ) | +MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA384 ) | +MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA512 ), +0xFFFFFFF ,/* Any PK alg */ +0xFFFFFFF ,/* Any curve */ +2048 ,/* RSA-2048 and larger */ +}; + +#define openvpn_x509_crt_profile_suiteb mbedtls_x509_crt_profile_suiteb; +void tls_init_lib (void ) {@@ -250,6 +278,27 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers)free (tmp_ciphers_orig); } +void +tls_ctx_set_cert_profile (struct tls_root_ctx *ctx,const char *profile) +{ +if (!profile ||0 ==strcmp (profile,"preferred" )) + { + ctx->cert_profile = openvpn_x509_crt_profile_preferred; + } +else if (0 ==strcmp (profile,"legacy" )) + { + ctx->cert_profile = openvpn_x509_crt_profile_legacy; + } +else if (0 ==strcmp (profile,"suiteb" )) + { + ctx->cert_profile = openvpn_x509_crt_profile_suiteb; + } +else + { +msg (M_FATAL ,"ERROR: Invalid cert profile: %s" , profile); + } +} +void tls_ctx_check_cert_time (const struct tls_root_ctx *ctx) {@@ -917,6 +966,8 @@ key_state_ssl_init(struct key_state_ssl *ks_ssl,mbedtls_ssl_conf_rng (&ks_ssl->ssl_config, mbedtls_ctr_drbg_random,rand_ctx_get ()); +mbedtls_ssl_conf_cert_profile (&ks_ssl->ssl_config, &ssl_ctx->cert_profile); +if (ssl_ctx->allowed_ciphers) {mbedtls_ssl_conf_ciphersuites (&ks_ssl->ssl_config, ssl_ctx->allowed_ciphers);src/openvpn/ssl_mbedtls.h +1
-0@@ -82,6 +82,7 @@ struct tls_root_ctx {struct external_context *external_key;/**< Management external key */ #endif int *allowed_ciphers;/**< List of allowed ciphers for this connection */ +mbedtls_x509_crt_profile cert_profile;/**< Allowed certificate types */ };struct key_state_ssl {src/openvpn/ssl_openssl.c +6
-0@@ -383,6 +383,12 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) } } +void +tls_ctx_set_cert_profile (struct tls_root_ctx *ctx,const char *profile) +{ +/* TODO --tls-cert-profile not supported for OpenSSL builds */ +} +void tls_ctx_check_cert_time (const struct tls_root_ctx *ctx) {
Signature · 1 line
Antonio Quartulli
Hi,
Quoted 76 lines · Steffan Karger
From: Steffan Karger <[email protected]...>
This allows the user to specify what certificate crypto algorithms to support. The supported profiles are 'preferred', 'legacy' (default) and 'suiteb', as discussed in <[email protected]....>
(https://www.mail-archive.com/[email protected]/msg14214.html).This only implements the feature for mbed TLS builds, because for mbed it is both more easy to implement and the most relevant because mbed TLS 2+ is by default somewhat restrictive by requiring 2048-bit+ for RSA keys.
This patch uses 'legacy' as the default profile following discussion on the openvpn-devel mailing list. This way this patch can be applied to both the release/2.4 and master branches. I'll send a follow-up patch for the master branch to change the default to 'preferred' later.
Signed-off-by Steffan Karger <[email protected]...>---
v2:
- add documentation (manpage,Changes.rstand --help)
- no longer print a warning message on each startup for OpenSSL builds
v3:
- remove format changes in unrelated items (introduced in v2)
- UpdateChanges.rsttext to reflect that the default in 2.4.2 is 'legacy' and the default in 2.5 will be 'preferred' (as discussed on the ML).
- This patch is for the master branch only now (due to the default).
v4:
- Ignore the option for OpenSSL builds, instead of rejecting the option and refusing to start.
- Patch is for master and release/2.4 again. A follow-up patch will change the default for master later on.Changes.rst | 12 +++++++++++ doc/openvpn.8 | 22 ++++++++++++++++++++ src/openvpn/options.c | 16 ++++++++++++++- src/openvpn/options.h | 1 + src/openvpn/ssl.c | 3 +++ src/openvpn/ssl_backend.h | 10 ++++++++++ src/openvpn/ssl_mbedtls.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++ src/openvpn/ssl_mbedtls.h | 1 + src/openvpn/ssl_openssl.c | 6 ++++++ 9 files changed, 121 insertions(+), 1 deletion(-)Changes.rst +12
-0@@ -321,6 +321,18 @@ Maintainer-visible changes i386/i686 builds on RHEL5. +Version 2.4.5 +============= + +New features +------------ +- The new option ``--tls-cert-profile`` can be used to restrict the set of + allowed crypto algorithms in TLS certificates in mbed TLS builds. The + default profile is 'legacy' for now, which allows SHA1+, RSA-1024+ and any + elliptic curve certificates. The default will be changed to the 'preferred' + profile in the future, which requires SHA2+, RSA-2048+ and any curve. + + Version 2.4.3 =============doc/openvpn.8 +2
-0@@ -4917,6 +4917,28 @@ when using mbed TLS or OpenSSL. .\"********************************************************* .TP +.B \-\-tls\-cert\-profile profile +Set the allowed cryptographic algorithms for certificates according to
doc/openvpn.8 when using mbed TLS or · line 4931
Quoted 10 lines
doc/openvpn.8 +10
-0+.B profile\fN. + +The following profiles are supported: + +.B preferred +: SHA2 and newer, RSA 2048-bit+, any elliptic curve. + +.B legacy +(default): SHA1 and newer, RSA 2048-bit+, any elliptic curve. +
don't you think it would be better to put legacy as first profile? That would sort the list from the weakest to the strongest profile.
Quoted 61 lines
doc/openvpn.8 +10
-0+.B suiteb +: SHA256/SHA384, ECDSA with P-256 or P-384. + +This option is only supported for mbed TLS builds. OpenSSL builds accept any +certificate that OpenSSL accepts. + +OpenVPN will migrate to 'preferred' as default in the future. Please ensure +that your keys already comply. +.\"********************************************************* +.TP .B \-\-tls\-timeout n Packet retransmit timeout on TLS control channel if no acknowledgment from remote withinsrc/openvpn/options.c +6
-1@@ -599,6 +599,8 @@ static const char usage_message[] =#endif "--tls-cipher l : A list l of allowable TLS ciphers separated by : (optional).\n" " : Use --show-tls to see a list of supported TLS ciphers.\n" +"--tls-cert-profile p : Set the allowed certificate crypto algorithm profile\n" +" (default=%s).\n" "--tls-timeout n : Packet retransmit timeout on TLS control channel\n" " if no ACK from remote within n seconds (default=%d).\n" "--reneg-bytes n : Renegotiate data chan. key after n bytes sent and recvd.\n" @@ -872,6 +874,7 @@ init_options(struct options *o, const bool init_gc) o->renegotiate_seconds =3600 ; o->handshake_window =60 ; o->transition_window =3600 ; + o->tls_cert_profile ="legacy" ; o->ecdh_curve =NULL ;#ifdef ENABLE_X509ALTUSERNAME o->x509_username_field =X509_USERNAME_FIELD_DEFAULT ;@@ -1750,6 +1753,7 @@ show_settings(const struct options *o)SHOW_STR (cryptoapi_cert);#endif SHOW_STR (cipher_list); +SHOW_STR (tls_cert_profile);SHOW_STR (tls_verify);SHOW_STR (tls_export_cert);SHOW_INT (verify_x509_type);@@ -2729,6 +2733,7 @@ options_postprocess_verify_ce(const struct options *options, const struct connecMUST_BE_UNDEF (pkcs12_file);#endif MUST_BE_UNDEF (cipher_list); +MUST_BE_UNDEF (tls_cert_profile);MUST_BE_UNDEF (tls_verify);MUST_BE_UNDEF (tls_export_cert);MUST_BE_UNDEF (verify_x509_name);@@ -4086,7 +4091,7 @@ usage(void) o.verbosity, o.authname, o.ciphername, o.replay_window, o.replay_time, - o.tls_timeout, o.renegotiate_seconds, + o.tls_cert_profile, o.tls_timeout, o.renegotiate_seconds, o.handshake_window, o.transition_window);#else /* ifdef ENABLE_CRYPTO */ fprintf(fp, usage_message,@@ -7831,6 +7836,15 @@ add_option(struct options *options,VERIFY_PERMISSION (OPT_P_GENERAL );
src/openvpn/options.c add_option(struct options *options, · line 7846
Quoted 10 lines
src/openvpn/options.c +8
-0options->cipher_list = p[1 ]; } +else if (streq (p[0 ],"tls-cert-profile" ) && p[1 ] && !p[2 ]) + { +VERIFY_PERMISSION (OPT_P_GENERAL ); +#ifdef ENABLE_CRYPTO_MBEDTLS + options->tls_cert_profile = p[1 ]; +#else +msg (M_WARN ,"WARNING: --tls-cert-profile is not yet implemented for OpenSSL, ignoring option." ); +#endif
rather than polluting this code with a new ifdef, wouldn't it be meaningful to print this message in the openssl routine doing the SSL context setup?
This way we get rid of the ifdef and the "openssl" specific code (which is just the msg()) would reside in the openssl code.
after all this is not an exception on the parsing of the option, but it's an exception on how the value is used.
Quoted 91 lines
src/openvpn/options.c +1
-0+ }else if (streq (p[0 ],"crl-verify" ) && p[1 ] && ((p[2 ] &&streq (p[2 ],"dir" )) || (p[2 ] &&streq (p[1 ],INLINE_FILE_TAG ) ) || !p[2 ]) && !p[3 ]) {src/openvpn/options.h +1
-0@@ -502,6 +502,7 @@ struct optionsconst char *priv_key_file;const char *pkcs12_file;const char *cipher_list; +const char *tls_cert_profile;const char *ecdh_curve;const char *tls_verify;int verify_x509_type;src/openvpn/ssl.c +3
-0@@ -621,6 +621,9 @@ init_ssl(const struct options *options, struct tls_root_ctx *new_ctx)* cipher restrictions before loading certificates */ tls_ctx_restrict_ciphers (new_ctx, options->cipher_list); +/* Restrict allowed certificate crypto algorithms */ +tls_ctx_set_cert_profile (new_ctx, options->tls_cert_profile); +tls_ctx_set_options (new_ctx, options->ssl_flags);if (options->pkcs12_file)src/openvpn/ssl_backend.h +10
-0@@ -176,6 +176,16 @@ void tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags);*/ void tls_ctx_restrict_ciphers (struct tls_root_ctx *ctx,const char *ciphers); +/** +* Set the TLS certificate profile. The profile defines which crypto +* algorithms may be used in the supplied certificate. +* +* @param ctx TLS context to restrict, must be valid. +* @param profile The profile name ('preferred', 'legacy' or 'suiteb'). +* Defaults to 'preferred' if NULL. +*/ +void tls_ctx_set_cert_profile (struct tls_root_ctx *ctx,const char *profile); +/** * Check our certificate notBefore and notAfter fields, and warn if the cert is * either not yet valid or has expired. Note that this is a non-fatal error, src/openvpn/ssl_mbedtls.c +28
-0@@ -62,6 +62,34 @@#include <mbedtls/pem.h> #include <mbedtls/sha256.h> +static const mbedtls_x509_crt_profile openvpn_x509_crt_profile_legacy = +{ +/* Hashes from SHA-1 and above */ +MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA1 ) | +MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_RIPEMD160 ) | +MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA224 ) | +MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA256 ) | +MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA384 ) | +MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA512 ), +0xFFFFFFF ,/* Any PK alg */ +0xFFFFFFF ,/* Any curve */ +1024 ,/* RSA-1024 and larger */ +}; + +static const mbedtls_x509_crt_profile openvpn_x509_crt_profile_preferred = +{ +/* SHA-2 and above */ +MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA224 ) | +MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA256 ) | +MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA384 ) | +MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA512 ), +0xFFFFFFF ,/* Any PK alg */ +0xFFFFFFF ,/* Any curve */ +2048 ,/* RSA-2048 and larger */ +}; + +#define openvpn_x509_crt_profile_suiteb mbedtls_x509_crt_profile_suiteb; +void tls_init_lib (void ) {
src/openvpn/ssl_mbedtls.c tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) · line 284
Quoted 7 lines
src/openvpn/ssl_mbedtls.c +4
-0@@ -250,6 +278,27 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers)free (tmp_ciphers_orig); } +void +tls_ctx_set_cert_profile (struct tls_root_ctx *ctx,const char *profile) +{ +if (!profile ||0 ==strcmp (profile,"preferred" ))
can profile really be null? Given that we are assigning it a default value in init_options() I think we could rather use an assert() here? so we make sure the developer will always set an explicit default?
Quoted 59 lines
src/openvpn/ssl_mbedtls.c +19
-0+ { + ctx->cert_profile = openvpn_x509_crt_profile_preferred; + } + else if (0 == strcmp(profile, "legacy")) + { + ctx->cert_profile = openvpn_x509_crt_profile_legacy; + } + else if (0 == strcmp(profile, "suiteb")) + { + ctx->cert_profile = openvpn_x509_crt_profile_suiteb; + } + else + { +msg (M_FATAL ,"ERROR: Invalid cert profile: %s" , profile); + } +} +void tls_ctx_check_cert_time (const struct tls_root_ctx *ctx) {@@ -917,6 +966,8 @@ key_state_ssl_init(struct key_state_ssl *ks_ssl,mbedtls_ssl_conf_rng (&ks_ssl->ssl_config, mbedtls_ctr_drbg_random,rand_ctx_get ()); +mbedtls_ssl_conf_cert_profile (&ks_ssl->ssl_config, &ssl_ctx->cert_profile); +if (ssl_ctx->allowed_ciphers) {mbedtls_ssl_conf_ciphersuites (&ks_ssl->ssl_config, ssl_ctx->allowed_ciphers);src/openvpn/ssl_mbedtls.h +1
-0@@ -82,6 +82,7 @@ struct tls_root_ctx {struct external_context *external_key;/**< Management external key */ #endif int *allowed_ciphers;/**< List of allowed ciphers for this connection */ +mbedtls_x509_crt_profile cert_profile;/**< Allowed certificate types */ };struct key_state_ssl {src/openvpn/ssl_openssl.c +6
-0@@ -383,6 +383,12 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) } } +void +tls_ctx_set_cert_profile (struct tls_root_ctx *ctx,const char *profile) +{ +/* TODO --tls-cert-profile not supported for OpenSSL builds */ +} +void tls_ctx_check_cert_time (const struct tls_root_ctx *ctx) {
Signature · 1 line
Antonio Quartulli
Hi,
Quoted 82 lines · Antonio Quartulli
Quoted 81 lines · Steffan Karger
From: Steffan Karger <[email protected]...>
This allows the user to specify what certificate crypto algorithms to support. The supported profiles are 'preferred', 'legacy' (default) and 'suiteb', as discussed in <[email protected]...>
(https://www.mail-archive.com/[email protected]/msg14214.html).This only implements the feature for mbed TLS builds, because for mbed it is both more easy to implement and the most relevant because mbed TLS 2+ is by default somewhat restrictive by requiring 2048-bit+ for RSA keys.
This patch uses 'legacy' as the default profile following discussion on the openvpn-devel mailing list. This way this patch can be applied to both the release/2.4 and master branches. I'll send a follow-up patch for the master branch to change the default to 'preferred' later.
Signed-off-by Steffan Karger <[email protected]...>---
v2:
- add documentation (manpage,Changes.rstand --help)
- no longer print a warning message on each startup for OpenSSL builds
v3:
- remove format changes in unrelated items (introduced in v2)
- UpdateChanges.rsttext to reflect that the default in 2.4.2 is 'legacy' and the default in 2.5 will be 'preferred' (as discussed on the ML).
- This patch is for the master branch only now (due to the default).
v4:
- Ignore the option for OpenSSL builds, instead of rejecting the option and refusing to start.
- Patch is for master and release/2.4 again. A follow-up patch will change the default for master later on.Changes.rst | 12 +++++++++++ doc/openvpn.8 | 22 ++++++++++++++++++++ src/openvpn/options.c | 16 ++++++++++++++- src/openvpn/options.h | 1 + src/openvpn/ssl.c | 3 +++ src/openvpn/ssl_backend.h | 10 ++++++++++ src/openvpn/ssl_mbedtls.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++ src/openvpn/ssl_mbedtls.h | 1 + src/openvpn/ssl_openssl.c | 6 ++++++ 9 files changed, 121 insertions(+), 1 deletion(-)Changes.rst +12
-0@@ -321,6 +321,18 @@ Maintainer-visible changes i386/i686 builds on RHEL5. +Version 2.4.5 +============= + +New features +------------ +- The new option ``--tls-cert-profile`` can be used to restrict the set of + allowed crypto algorithms in TLS certificates in mbed TLS builds. The + default profile is 'legacy' for now, which allows SHA1+, RSA-1024+ and any + elliptic curve certificates. The default will be changed to the 'preferred' + profile in the future, which requires SHA2+, RSA-2048+ and any curve. + + Version 2.4.3 =============doc/openvpn.8 +7
-0@@ -4917,6 +4917,28 @@ when using mbed TLS or OpenSSL. .\"********************************************************* .TP +.B \-\-tls\-cert\-profile profile +Set the allowed cryptographic algorithms for certificates according to +.B profile\fN. + +The following profiles are supported: + +.B preferred
Quoted 8 lines
doc/openvpn.8 when using mbed TLS or · line 4931
Quoted 5 lines
doc/openvpn.8 +5
-0+: SHA2 and newer, RSA 2048-bit+, any elliptic curve. + +.B legacy +(default): SHA1 and newer, RSA 2048-bit+, any elliptic curve. +don't you think it would be better to put legacy as first profile? That would sort the list from the weakest to the strongest profile.
When I wrote the original patch, "preferred" was the default and I wanted to have the default first. But now that "legacy" is the default, I agree that it's better to put that first. Will fix.
Quoted 76 lines
Quoted 61 lines
doc/openvpn.8 +10
-0+.B suiteb +: SHA256/SHA384, ECDSA with P-256 or P-384. + +This option is only supported for mbed TLS builds. OpenSSL builds accept any +certificate that OpenSSL accepts. + +OpenVPN will migrate to 'preferred' as default in the future. Please ensure +that your keys already comply. +.\"********************************************************* +.TP .B \-\-tls\-timeout n Packet retransmit timeout on TLS control channel if no acknowledgment from remote withinsrc/openvpn/options.c +6
-1@@ -599,6 +599,8 @@ static const char usage_message[] =#endif "--tls-cipher l : A list l of allowable TLS ciphers separated by : (optional).\n" " : Use --show-tls to see a list of supported TLS ciphers.\n" +"--tls-cert-profile p : Set the allowed certificate crypto algorithm profile\n" +" (default=%s).\n" "--tls-timeout n : Packet retransmit timeout on TLS control channel\n" " if no ACK from remote within n seconds (default=%d).\n" "--reneg-bytes n : Renegotiate data chan. key after n bytes sent and recvd.\n" @@ -872,6 +874,7 @@ init_options(struct options *o, const bool init_gc) o->renegotiate_seconds =3600 ; o->handshake_window =60 ; o->transition_window =3600 ; + o->tls_cert_profile ="legacy" ; o->ecdh_curve =NULL ;#ifdef ENABLE_X509ALTUSERNAME o->x509_username_field =X509_USERNAME_FIELD_DEFAULT ;@@ -1750,6 +1753,7 @@ show_settings(const struct options *o)SHOW_STR (cryptoapi_cert);#endif SHOW_STR (cipher_list); +SHOW_STR (tls_cert_profile);SHOW_STR (tls_verify);SHOW_STR (tls_export_cert);SHOW_INT (verify_x509_type);@@ -2729,6 +2733,7 @@ options_postprocess_verify_ce(const struct options *options, const struct connecMUST_BE_UNDEF (pkcs12_file);#endif MUST_BE_UNDEF (cipher_list); +MUST_BE_UNDEF (tls_cert_profile);MUST_BE_UNDEF (tls_verify);MUST_BE_UNDEF (tls_export_cert);MUST_BE_UNDEF (verify_x509_name);@@ -4086,7 +4091,7 @@ usage(void) o.verbosity, o.authname, o.ciphername, o.replay_window, o.replay_time, - o.tls_timeout, o.renegotiate_seconds, + o.tls_cert_profile, o.tls_timeout, o.renegotiate_seconds, o.handshake_window, o.transition_window);#else /* ifdef ENABLE_CRYPTO */ fprintf(fp, usage_message,@@ -7831,6 +7836,15 @@ add_option(struct options *options,VERIFY_PERMISSION (OPT_P_GENERAL );src/openvpn/options.c add_option(struct options *options, · line 7846
Quoted 10 lines
src/openvpn/options.c +8
-0options->cipher_list = p[1 ]; } +else if (streq (p[0 ],"tls-cert-profile" ) && p[1 ] && !p[2 ]) + { +VERIFY_PERMISSION (OPT_P_GENERAL ); +#ifdef ENABLE_CRYPTO_MBEDTLS + options->tls_cert_profile = p[1 ]; +#else +msg (M_WARN ,"WARNING: --tls-cert-profile is not yet implemented for OpenSSL, ignoring option." ); +#endif rather than polluting this code with a new ifdef, wouldn't it be meaningful to print this message in the openssl routine doing the SSL context setup?
Quoted 5 lines
This way we get rid of the ifdef and the "openssl" specific code (which is just the
msg()) would reside in the openssl code.after all this is not an exception on the parsing of the option, but it's an exception on how the value is used.
Gooid point. Though it was a bit more tricky than you might have expected, because the cryptolib-specific code didn't know whether the user specified the option or we were using the default (and I didn't want to print warning when the uses didn't specify the option).
To work around that, I decided to implement the OpenSSL version too, using the approximation based on security levels that was discussed with Gert and David during the hackathon.
Quoted 94 lines
Quoted 94 lines
src/openvpn/options.c +1
-0+ }else if (streq (p[0 ],"crl-verify" ) && p[1 ] && ((p[2 ] &&streq (p[2 ],"dir" )) || (p[2 ] &&streq (p[1 ],INLINE_FILE_TAG ) ) || !p[2 ]) && !p[3 ]) {src/openvpn/options.h +1
-0@@ -502,6 +502,7 @@ struct optionsconst char *priv_key_file;const char *pkcs12_file;const char *cipher_list; +const char *tls_cert_profile;const char *ecdh_curve;const char *tls_verify;int verify_x509_type;src/openvpn/ssl.c +3
-0@@ -621,6 +621,9 @@ init_ssl(const struct options *options, struct tls_root_ctx *new_ctx)* cipher restrictions before loading certificates */ tls_ctx_restrict_ciphers (new_ctx, options->cipher_list); +/* Restrict allowed certificate crypto algorithms */ +tls_ctx_set_cert_profile (new_ctx, options->tls_cert_profile); +tls_ctx_set_options (new_ctx, options->ssl_flags);if (options->pkcs12_file)src/openvpn/ssl_backend.h +10
-0@@ -176,6 +176,16 @@ void tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags);*/ void tls_ctx_restrict_ciphers (struct tls_root_ctx *ctx,const char *ciphers); +/** +* Set the TLS certificate profile. The profile defines which crypto +* algorithms may be used in the supplied certificate. +* +* @param ctx TLS context to restrict, must be valid. +* @param profile The profile name ('preferred', 'legacy' or 'suiteb'). +* Defaults to 'preferred' if NULL. +*/ +void tls_ctx_set_cert_profile (struct tls_root_ctx *ctx,const char *profile); +/** * Check our certificate notBefore and notAfter fields, and warn if the cert is * either not yet valid or has expired. Note that this is a non-fatal error, src/openvpn/ssl_mbedtls.c +28
-0@@ -62,6 +62,34 @@#include <mbedtls/pem.h> #include <mbedtls/sha256.h> +static const mbedtls_x509_crt_profile openvpn_x509_crt_profile_legacy = +{ +/* Hashes from SHA-1 and above */ +MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA1 ) | +MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_RIPEMD160 ) | +MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA224 ) | +MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA256 ) | +MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA384 ) | +MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA512 ), +0xFFFFFFF ,/* Any PK alg */ +0xFFFFFFF ,/* Any curve */ +1024 ,/* RSA-1024 and larger */ +}; + +static const mbedtls_x509_crt_profile openvpn_x509_crt_profile_preferred = +{ +/* SHA-2 and above */ +MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA224 ) | +MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA256 ) | +MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA384 ) | +MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA512 ), +0xFFFFFFF ,/* Any PK alg */ +0xFFFFFFF ,/* Any curve */ +2048 ,/* RSA-2048 and larger */ +}; + +#define openvpn_x509_crt_profile_suiteb mbedtls_x509_crt_profile_suiteb; +void tls_init_lib (void ) {@@ -250,6 +278,27 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers)free (tmp_ciphers_orig); }
Quoted 8 lines
src/openvpn/ssl_mbedtls.c tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) · line 284
Quoted 4 lines
src/openvpn/ssl_mbedtls.c +4
-0+void +tls_ctx_set_cert_profile (struct tls_root_ctx *ctx,const char *profile) +{ +if (!profile ||0 ==strcmp (profile,"preferred" ))can profile really be null? Given that we are assigning it a default value in
init_options()I think we could rather use anassert()here? so we make sure the developer will always set an explicit default?
Ok, removed the check. In the current code, it indeed can not be NULL. And since this functions are not called in response to untrusted input, I agree that it's not needed.
Quoted 49 lines
Quoted 49 lines
src/openvpn/ssl_mbedtls.c +19
-0+ { + ctx->cert_profile = openvpn_x509_crt_profile_preferred; + } + else if (0 == strcmp(profile, "legacy")) + { + ctx->cert_profile = openvpn_x509_crt_profile_legacy; + } + else if (0 == strcmp(profile, "suiteb")) + { + ctx->cert_profile = openvpn_x509_crt_profile_suiteb; + } + else + { +msg (M_FATAL ,"ERROR: Invalid cert profile: %s" , profile); + } +} +void tls_ctx_check_cert_time (const struct tls_root_ctx *ctx) {@@ -917,6 +966,8 @@ key_state_ssl_init(struct key_state_ssl *ks_ssl,mbedtls_ssl_conf_rng (&ks_ssl->ssl_config, mbedtls_ctr_drbg_random,rand_ctx_get ()); +mbedtls_ssl_conf_cert_profile (&ks_ssl->ssl_config, &ssl_ctx->cert_profile); +if (ssl_ctx->allowed_ciphers) {mbedtls_ssl_conf_ciphersuites (&ks_ssl->ssl_config, ssl_ctx->allowed_ciphers);src/openvpn/ssl_mbedtls.h +1
-0@@ -82,6 +82,7 @@ struct tls_root_ctx {struct external_context *external_key;/**< Management external key */ #endif int *allowed_ciphers;/**< List of allowed ciphers for this connection */ +mbedtls_x509_crt_profile cert_profile;/**< Allowed certificate types */ };struct key_state_ssl {src/openvpn/ssl_openssl.c +0
-0@@ -383,6 +383,12 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) } }
Quoted 11 lines
src/openvpn/ssl_openssl.c tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) · line 394
Quoted 10 lines
src/openvpn/ssl_openssl.c +6
-0+void +tls_ctx_set_cert_profile (struct tls_root_ctx *ctx,const char *profile) +{ +/* TODO --tls-cert-profile not supported for OpenSSL builds */ +} +void tls_ctx_check_cert_time (const struct tls_root_ctx *ctx) {
Thanks for reviewing! v5 coming soon.
-Steffan
PATCH v5 1/1 Add --tls-cert-profile option for mbedtls builds
From: Steffan Karger <[email protected]...>
This allows the user to specify what certificate crypto algorithms to support. The supported profiles are 'preferred', 'legacy' (default) and 'suiteb', as discussed in <[email protected]...>
(https://www.mail-archive.com/[email protected]/msg14214.html).
This fully implements the feature for mbed TLS builds, because for mbed it is both more easy to implement and the most relevant because mbed TLS 2+ is by default somewhat restrictive by requiring 2048-bit+ for RSA keys.
For OpenSSL, this implements an approximation based on security levels, as discussed at the hackathon in Karlsruhe.
This patch uses 'legacy' as the default profile following discussion on the openvpn-devel mailing list. This way this patch can be applied to both the release/2.4 and master branches. I'll send a follow-up patch for the master branch to change the default to 'preferred' later.
---
v2:
- add documentation (manpage, Changes.rst and --help)
- no longer print a warning message on each startup for OpenSSL builds
v3:
- remove format changes in unrelated items (introduced in v2)
- Update Changes.rst text to reflect that the default in 2.4.2 is 'legacy' and the default in 2.5 will be 'preferred' (as discussed on the ML).
- This patch is for the master branch only now (due to the default).
v4:
- Ignore the option for OpenSSL builds, instead of rejecting the option and refusing to start.
- Patch is for master and release/2.4 again. A follow-up patch will change the default for master later on.
v5:
- Add (approximate) OpenSSL implementation.
- Remove null check for argument that couln't be null anyway.
Changes.rst | 12 +++++++++++ doc/openvpn.8 | 31 ++++++++++++++++++++++++++ src/openvpn/init.c | 3 ++- src/openvpn/options.c | 12 ++++++++++- src/openvpn/options.h | 1 + src/openvpn/ssl.c | 3 +++ src/openvpn/ssl_backend.h | 17 +++++++++++++-- src/openvpn/ssl_mbedtls.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++- src/openvpn/ssl_mbedtls.h | 1 + src/openvpn/ssl_openssl.c | 30 +++++++++++++++++++++++++- 10 files changed, 159 insertions(+), 6 deletions(-)
Changes.rst +12 -0
@@ -321,6 +321,18 @@ Maintainer-visible changes i386/i686 builds on RHEL5. +Version 2.4.5 +============= + +New features +------------ +- The new option ``--tls-cert-profile`` can be used to restrict the set of + allowed crypto algorithms in TLS certificates in mbed TLS builds. The + default profile is 'legacy' for now, which allows SHA1+, RSA-1024+ and any + elliptic curve certificates. The default will be changed to the 'preferred' + profile in the future, which requires SHA2+, RSA-2048+ and any curve. + + Version 2.4.3 =============
doc/openvpn.8 +31 -0
@@ -4917,6 +4917,37 @@ when using mbed TLS or OpenSSL. .\"********************************************************* .TP +.B \-\-tls\-cert\-profile profile +Set the allowed cryptographic algorithms for certificates according to +.B profile\fN. + +The following profiles are supported: + +.B legacy +(default): SHA1 and newer, RSA 2048-bit+, any elliptic curve. + +.B preferred +: SHA2 and newer, RSA 2048-bit+, any elliptic curve. + +.B suiteb +: SHA256/SHA384, ECDSA with P-256 or P-384. + +This option is only fully supported for mbed TLS builds. OpenSSL builds use +the following approximation: + +.B legacy +(default): sets "security level 1" + +.B preferred +: sets "security level 2" + +.B suiteb +: sets "security level 3" and \-\-tls\-cipher "SUITEB128". + +OpenVPN will migrate to 'preferred' as default in the future. Please ensure +that your keys already comply. +.\"********************************************************* +.TP .B \-\-tls\-timeout n Packet retransmit timeout on TLS control channel if no acknowledgment from remote within
src/openvpn/init.c +2 -1
@@ -1016,7 +1016,8 @@ print_openssl_info(const struct options *options) }if (options->show_tls_ciphers) { -show_available_tls_ciphers (options->cipher_list); +show_available_tls_ciphers (options->cipher_list, + options->tls_cert_profile); }if (options->show_curves) {
src/openvpn/options.c +11 -1
@@ -599,6 +599,8 @@ static const char usage_message[] =#endif "--tls-cipher l : A list l of allowable TLS ciphers separated by : (optional).\n" " : Use --show-tls to see a list of supported TLS ciphers.\n" +"--tls-cert-profile p : Set the allowed certificate crypto algorithm profile\n" +" (default=%s).\n" "--tls-timeout n : Packet retransmit timeout on TLS control channel\n" " if no ACK from remote within n seconds (default=%d).\n" "--reneg-bytes n : Renegotiate data chan. key after n bytes sent and recvd.\n"
@@ -872,6 +874,7 @@ init_options(struct options *o, const bool init_gc) o->renegotiate_seconds =3600 ; o->handshake_window =60 ; o->transition_window =3600 ; + o->tls_cert_profile ="legacy" ; o->ecdh_curve =NULL ;#ifdef ENABLE_X509ALTUSERNAME o->x509_username_field =X509_USERNAME_FIELD_DEFAULT ;
@@ -1750,6 +1753,7 @@ show_settings(const struct options *o)SHOW_STR (cryptoapi_cert);#endif SHOW_STR (cipher_list); +SHOW_STR (tls_cert_profile);SHOW_STR (tls_verify);SHOW_STR (tls_export_cert);SHOW_INT (verify_x509_type);
@@ -2729,6 +2733,7 @@ options_postprocess_verify_ce(const struct options *options, const struct connecMUST_BE_UNDEF (pkcs12_file);#endif MUST_BE_UNDEF (cipher_list); +MUST_BE_UNDEF (tls_cert_profile);MUST_BE_UNDEF (tls_verify);MUST_BE_UNDEF (tls_export_cert);MUST_BE_UNDEF (verify_x509_name);
@@ -4086,7 +4091,7 @@ usage(void) o.verbosity, o.authname, o.ciphername, o.replay_window, o.replay_time, - o.tls_timeout, o.renegotiate_seconds, + o.tls_cert_profile, o.tls_timeout, o.renegotiate_seconds, o.handshake_window, o.transition_window);#else /* ifdef ENABLE_CRYPTO */ fprintf(fp, usage_message,
@@ -7831,6 +7836,11 @@ add_option(struct options *options,VERIFY_PERMISSION (OPT_P_GENERAL ); options->cipher_list = p[1 ]; } +else if (streq (p[0 ],"tls-cert-profile" ) && p[1 ] && !p[2 ]) + { +VERIFY_PERMISSION (OPT_P_GENERAL ); + options->tls_cert_profile = p[1 ]; + }else if (streq (p[0 ],"crl-verify" ) && p[1 ] && ((p[2 ] &&streq (p[2 ],"dir" )) || (p[2 ] &&streq (p[1 ],INLINE_FILE_TAG ) ) || !p[2 ]) && !p[3 ]) {
src/openvpn/options.h +1 -0
@@ -502,6 +502,7 @@ struct optionsconst char *priv_key_file;const char *pkcs12_file;const char *cipher_list; +const char *tls_cert_profile;const char *ecdh_curve;const char *tls_verify;int verify_x509_type;
src/openvpn/ssl.c +3 -0
@@ -616,6 +616,9 @@ init_ssl(const struct options *options, struct tls_root_ctx *new_ctx)tls_ctx_client_new (new_ctx); } +/* Restrict allowed certificate crypto algorithms */ +tls_ctx_set_cert_profile (new_ctx, options->tls_cert_profile); +/* Allowable ciphers */ /* Since @SECLEVEL also influces loading of certificates, set the * cipher restrictions before loading certificates */
src/openvpn/ssl_backend.h +15 -2
@@ -176,6 +176,16 @@ void tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags);*/ void tls_ctx_restrict_ciphers (struct tls_root_ctx *ctx,const char *ciphers); +/** +* Set the TLS certificate profile. The profile defines which crypto +* algorithms may be used in the supplied certificate. +* +* @param ctx TLS context to restrict, must be valid. +* @param profile The profile name ('preferred', 'legacy' or 'suiteb'). +* Defaults to 'preferred' if NULL. +*/ +void tls_ctx_set_cert_profile (struct tls_root_ctx *ctx,const char *profile); +/** * Check our certificate notBefore and notAfter fields, and warn if the cert is * either not yet valid or has expired. Note that this is a non-fatal error,
@@ -505,9 +515,12 @@ void print_details(struct key_state_ssl *ks_ssl, const char *prefix);* Show the TLS ciphers that are available for us to use in the OpenSSL * library. * -* @param - list of allowed TLS cipher, or NULL. +* @param cipher_list list of allowed TLS cipher, or NULL. +* @param tls_cert_profile TLS certificate crypto profile name. */ -void show_available_tls_ciphers (const char *tls_ciphers); +void +show_available_tls_ciphers (const char *cipher_list, +const char *tls_cert_profile);/* * Show the available elliptic curves in the crypto library
src/openvpn/ssl_mbedtls.c +54 -1
84 lines not on this page · raw message
src/openvpn/ssl_mbedtls.h +1 -0
@@ -82,6 +82,7 @@ struct tls_root_ctx {struct external_context *external_key;/**< Management external key */ #endif int *allowed_ciphers;/**< List of allowed ciphers for this connection */ +mbedtls_x509_crt_profile cert_profile;/**< Allowed certificate types */ };struct key_state_ssl {
src/openvpn/ssl_openssl.c +29 -1
@@ -383,6 +383,32 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) } } +void +tls_ctx_set_cert_profile (struct tls_root_ctx *ctx,const char *profile) +{ +/* OpenSSL does not have certificate profiles, but a complex set of +* callbacks that we could try to implement to achieve something similar. +* For now, use OpenSSL's security levels to achieve similar (but not equal) +* behaviour. */ +if (0 ==strcmp (profile,"preferred" )) + { +SSL_CTX_set_security_level (ctx->ctx,2 ); + } +else if (0 ==strcmp (profile,"legacy" )) + { +SSL_CTX_set_security_level (ctx->ctx,1 ); + } +else if (0 ==strcmp (profile,"suiteb" )) + { +SSL_CTX_set_security_level (ctx->ctx,3 ); +SSL_CTX_set_cipher_list (ctx->ctx,"SUITEB128" ); + } +else + { +msg (M_FATAL ,"ERROR: Invalid cert profile: %s" , profile); + } +} +void tls_ctx_check_cert_time (const struct tls_root_ctx *ctx) {
@@ -1722,7 +1748,8 @@ print_details(struct key_state_ssl *ks_ssl, const char *prefix) }void -show_available_tls_ciphers (const char *cipher_list) +show_available_tls_ciphers (const char *cipher_list, +const char *tls_cert_profile) {struct tls_root_ctx tls_ctx;SSL *ssl;
@@ -1742,6 +1769,7 @@ show_available_tls_ciphers(const char *cipher_list)crypto_msg (M_FATAL ,"Cannot create SSL object" ); } +tls_ctx_set_cert_profile (&tls_ctx, tls_cert_profile);tls_ctx_restrict_ciphers (&tls_ctx, cipher_list);printf ("Available TLS Ciphers,\n" );
Signature · 1 line
2.14.1
Hi,
On 12/11/17 18:37, Steffan Karger wrote:
[CUT]
src/openvpn/ssl_openssl.c tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) · line 395
Quoted 10 lines
src/openvpn/ssl_openssl.c +10
-0+void +tls_ctx_set_cert_profile (struct tls_root_ctx *ctx,const char *profile) +{ +/* OpenSSL does not have certificate profiles, but a complex set of +* callbacks that we could try to implement to achieve something similar. +* For now, use OpenSSL's security levels to achieve similar (but not equal) +* behaviour. */ +if (0 ==strcmp (profile,"preferred" )) + { +SSL_CTX_set_security_level (ctx->ctx,2 );
unfortunately this function does not exist in OpenSSL 1.0.x and openvpn does not compile.
However, we don't need anything equivalent for openssl-1.0.x because the legacy profile is implicitly supported there.
Cheers,
Signature · 1 line
Antonio Quartulli
PATCH v6 1/1 Add --tls-cert-profile option for mbedtls builds
From: Steffan Karger <[email protected]...>
This allows the user to specify what certificate crypto algorithms to support. The supported profiles are 'preferred', 'legacy' (default) and 'suiteb', as discussed in <[email protected]...>
(https://www.mail-archive.com/[email protected]/msg14214.html).
This fully implements the feature for mbed TLS builds, because for mbed it is both more easy to implement and the most relevant because mbed TLS 2+ is by default somewhat restrictive by requiring 2048-bit+ for RSA keys.
For OpenSSL, this implements an approximation based on security levels, as discussed at the hackathon in Karlsruhe.
This patch uses 'legacy' as the default profile following discussion on the openvpn-devel mailing list. This way this patch can be applied to both the release/2.4 and master branches. I'll send a follow-up patch for the master branch to change the default to 'preferred' later.
---
v2:
- add documentation (manpage, Changes.rst and --help)
- no longer print a warning message on each startup for OpenSSL builds
v3:
- remove format changes in unrelated items (introduced in v2)
- Update Changes.rst text to reflect that the default in 2.4.2 is 'legacy' and the default in 2.5 will be 'preferred' (as discussed on the ML).
- This patch is for the master branch only now (due to the default).
v4:
- Ignore the option for OpenSSL builds, instead of rejecting the option and refusing to start.
- Patch is for master and release/2.4 again. A follow-up patch will change the default for master later on.
v5:
- Add (approximate) OpenSSL implementation.
- Remove null check for argument that couln't be null anyway.
v6:
- Fix compilation with OpenSSL 1.0.x
Changes.rst | 12 +++++++++++ doc/openvpn.8 | 31 ++++++++++++++++++++++++++ src/openvpn/init.c | 3 ++- src/openvpn/options.c | 10 +++++++++ src/openvpn/options.h | 1 + src/openvpn/ssl.c | 3 +++ src/openvpn/ssl_backend.h | 17 +++++++++++++-- src/openvpn/ssl_mbedtls.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++- src/openvpn/ssl_mbedtls.h | 1 + src/openvpn/ssl_openssl.c | 38 +++++++++++++++++++++++++++++++- 10 files changed, 166 insertions(+), 5 deletions(-)
Changes.rst +12 -0
@@ -321,6 +321,18 @@ Maintainer-visible changes i386/i686 builds on RHEL5. +Version 2.4.5 +============= + +New features +------------ +- The new option ``--tls-cert-profile`` can be used to restrict the set of + allowed crypto algorithms in TLS certificates in mbed TLS builds. The + default profile is 'legacy' for now, which allows SHA1+, RSA-1024+ and any + elliptic curve certificates. The default will be changed to the 'preferred' + profile in the future, which requires SHA2+, RSA-2048+ and any curve. + + Version 2.4.3 =============
doc/openvpn.8 +31 -0
@@ -4917,6 +4917,37 @@ when using mbed TLS or OpenSSL. .\"********************************************************* .TP +.B \-\-tls\-cert\-profile profile +Set the allowed cryptographic algorithms for certificates according to +.B profile\fN. + +The following profiles are supported: + +.B legacy +(default): SHA1 and newer, RSA 2048-bit+, any elliptic curve. + +.B preferred +: SHA2 and newer, RSA 2048-bit+, any elliptic curve. + +.B suiteb +: SHA256/SHA384, ECDSA with P-256 or P-384. + +This option is only fully supported for mbed TLS builds. OpenSSL builds use +the following approximation: + +.B legacy +(default): sets "security level 1" + +.B preferred +: sets "security level 2" + +.B suiteb +: sets "security level 3" and \-\-tls\-cipher "SUITEB128". + +OpenVPN will migrate to 'preferred' as default in the future. Please ensure +that your keys already comply. +.\"********************************************************* +.TP .B \-\-tls\-timeout n Packet retransmit timeout on TLS control channel if no acknowledgment from remote within
src/openvpn/init.c +2 -1
@@ -1016,7 +1016,8 @@ print_openssl_info(const struct options *options) }if (options->show_tls_ciphers) { -show_available_tls_ciphers (options->cipher_list); +show_available_tls_ciphers (options->cipher_list, + options->tls_cert_profile); }if (options->show_curves) {
src/openvpn/options.c +10 -0
@@ -599,6 +599,8 @@ static const char usage_message[] =#endif "--tls-cipher l : A list l of allowable TLS ciphers separated by : (optional).\n" " : Use --show-tls to see a list of supported TLS ciphers.\n" +"--tls-cert-profile p : Set the allowed certificate crypto algorithm profile\n" +" (default=legacy).\n" "--tls-timeout n : Packet retransmit timeout on TLS control channel\n" " if no ACK from remote within n seconds (default=%d).\n" "--reneg-bytes n : Renegotiate data chan. key after n bytes sent and recvd.\n"
@@ -872,6 +874,7 @@ init_options(struct options *o, const bool init_gc) o->renegotiate_seconds =3600 ; o->handshake_window =60 ; o->transition_window =3600 ; + o->tls_cert_profile =NULL ; o->ecdh_curve =NULL ;#ifdef ENABLE_X509ALTUSERNAME o->x509_username_field =X509_USERNAME_FIELD_DEFAULT ;
@@ -1750,6 +1753,7 @@ show_settings(const struct options *o)SHOW_STR (cryptoapi_cert);#endif SHOW_STR (cipher_list); +SHOW_STR (tls_cert_profile);SHOW_STR (tls_verify);SHOW_STR (tls_export_cert);SHOW_INT (verify_x509_type);
@@ -2729,6 +2733,7 @@ options_postprocess_verify_ce(const struct options *options, const struct connecMUST_BE_UNDEF (pkcs12_file);#endif MUST_BE_UNDEF (cipher_list); +MUST_BE_UNDEF (tls_cert_profile);MUST_BE_UNDEF (tls_verify);MUST_BE_UNDEF (tls_export_cert);MUST_BE_UNDEF (verify_x509_name);
@@ -7831,6 +7836,11 @@ add_option(struct options *options,VERIFY_PERMISSION (OPT_P_GENERAL ); options->cipher_list = p[1 ]; } +else if (streq (p[0 ],"tls-cert-profile" ) && p[1 ] && !p[2 ]) + { +VERIFY_PERMISSION (OPT_P_GENERAL ); + options->tls_cert_profile = p[1 ]; + }else if (streq (p[0 ],"crl-verify" ) && p[1 ] && ((p[2 ] &&streq (p[2 ],"dir" )) || (p[2 ] &&streq (p[1 ],INLINE_FILE_TAG ) ) || !p[2 ]) && !p[3 ]) {
src/openvpn/options.h +1 -0
@@ -502,6 +502,7 @@ struct optionsconst char *priv_key_file;const char *pkcs12_file;const char *cipher_list; +const char *tls_cert_profile;const char *ecdh_curve;const char *tls_verify;int verify_x509_type;
src/openvpn/ssl.c +3 -0
@@ -616,6 +616,9 @@ init_ssl(const struct options *options, struct tls_root_ctx *new_ctx)tls_ctx_client_new (new_ctx); } +/* Restrict allowed certificate crypto algorithms */ +tls_ctx_set_cert_profile (new_ctx, options->tls_cert_profile); +/* Allowable ciphers */ /* Since @SECLEVEL also influces loading of certificates, set the * cipher restrictions before loading certificates */
src/openvpn/ssl_backend.h +15 -2
@@ -176,6 +176,16 @@ void tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags);*/ void tls_ctx_restrict_ciphers (struct tls_root_ctx *ctx,const char *ciphers); +/** +* Set the TLS certificate profile. The profile defines which crypto +* algorithms may be used in the supplied certificate. +* +* @param ctx TLS context to restrict, must be valid. +* @param profile The profile name ('preferred', 'legacy' or 'suiteb'). +* Defaults to 'preferred' if NULL. +*/ +void tls_ctx_set_cert_profile (struct tls_root_ctx *ctx,const char *profile); +/** * Check our certificate notBefore and notAfter fields, and warn if the cert is * either not yet valid or has expired. Note that this is a non-fatal error,
@@ -505,9 +515,12 @@ void print_details(struct key_state_ssl *ks_ssl, const char *prefix);* Show the TLS ciphers that are available for us to use in the OpenSSL * library. * -* @param - list of allowed TLS cipher, or NULL. +* @param cipher_list list of allowed TLS cipher, or NULL. +* @param tls_cert_profile TLS certificate crypto profile name. */ -void show_available_tls_ciphers (const char *tls_ciphers); +void +show_available_tls_ciphers (const char *cipher_list, +const char *tls_cert_profile);/* * Show the available elliptic curves in the crypto library
src/openvpn/ssl_mbedtls.c +54 -1
84 lines not on this page · raw message
src/openvpn/ssl_mbedtls.h +1 -0
@@ -82,6 +82,7 @@ struct tls_root_ctx {struct external_context *external_key;/**< Management external key */ #endif int *allowed_ciphers;/**< List of allowed ciphers for this connection */ +mbedtls_x509_crt_profile cert_profile;/**< Allowed certificate types */ };struct key_state_ssl {
src/openvpn/ssl_openssl.c +37 -1
@@ -383,6 +383,40 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) } } +void +tls_ctx_set_cert_profile (struct tls_root_ctx *ctx,const char *profile) +{ +#if (OPENSSL_VERSION_NUMBER >=0x10100000 ) +/* OpenSSL does not have certificate profiles, but a complex set of +* callbacks that we could try to implement to achieve something similar. +* For now, use OpenSSL's security levels to achieve similar (but not equal) +* behaviour. */ +if (!profile ||0 ==strcmp (profile,"legacy" )) + { +SSL_CTX_set_security_level (ctx->ctx,1 ); + } +else if (0 ==strcmp (profile,"preferred" )) + { +SSL_CTX_set_security_level (ctx->ctx,2 ); + } +else if (0 ==strcmp (profile,"suiteb" )) + { +SSL_CTX_set_security_level (ctx->ctx,3 ); +SSL_CTX_set_cipher_list (ctx->ctx,"SUITEB128" ); + } +else + { +msg (M_FATAL ,"ERROR: Invalid cert profile: %s" , profile); + } +#else +if (profile) + { +msg (M_WARN ,"WARNING: OpenSSL 1.0.1 does not support --tls-cert-profile" +", ignoring user-set profile: '%s'" , profile); + } +#endif +} +void tls_ctx_check_cert_time (const struct tls_root_ctx *ctx) {
@@ -1722,7 +1756,8 @@ print_details(struct key_state_ssl *ks_ssl, const char *prefix) }void -show_available_tls_ciphers (const char *cipher_list) +show_available_tls_ciphers (const char *cipher_list, +const char *tls_cert_profile) {struct tls_root_ctx tls_ctx;SSL *ssl;
@@ -1742,6 +1777,7 @@ show_available_tls_ciphers(const char *cipher_list)crypto_msg (M_FATAL ,"Cannot create SSL object" ); } +tls_ctx_set_cert_profile (&tls_ctx, tls_cert_profile);tls_ctx_restrict_ciphers (&tls_ctx, cipher_list);printf ("Available TLS Ciphers,\n" );
Signature · 1 line
2.14.1
Hi,
Quoted 14 lines · Steffan Karger
From: Steffan Karger <[email protected]...>
This allows the user to specify what certificate crypto algorithms to support. The supported profiles are 'preferred', 'legacy' (default) and 'suiteb', as discussed in <[email protected]....>
(https://www.mail-archive.com/[email protected]/msg14214.html).This fully implements the feature for mbed TLS builds, because for mbed it is both more easy to implement and the most relevant because mbed TLS 2+ is by default somewhat restrictive by requiring 2048-bit+ for RSA keys.
For OpenSSL, this implements an approximation based on security levels, as discussed at the hackathon in Karlsruhe.
Quoted 6 lines
This patch uses 'legacy' as the default profile following discussion on the openvpn-devel mailing list. This way this patch can be applied to both the release/2.4 and master branches. I'll send a follow-up patch for the master branch to change the default to 'preferred' later.
Signed-off-by Steffan Karger <[email protected]...>
Code looks good, but the commit subject is now wrong, because this patch is actually implementing cert profiles for both mbedTLS and OpenSSL.
So I ACK it, but the committer should fix the subject for sake of clarity.
I have tested the patch with mbedTLS and with OpenSSL 1.0, but not with OpenSSL 1.1.
Signature · 1 line
Antonio Quartulli
.. of course this conflicts with o->renegotiate_seconds_min...
Nevertheless, thanks for the patch :-) - it makes my FreeBSD 10.3 (mbedTLS 2.6) buildslave now happy again (on the default settings - with --tls-cert-profile preferred, it refuses the old-hash cert, as it should).
Also tested with openssl 1.0.1, where it warns and does nothing, as expected. Good :-)
Commit subject amended according to Antonio's comment.
Your patch has been applied to the master and release/2.4 branch.
commit aba758740d26224b7b3957df221def7ab80c5802 (master) commit 8bcabf0a1621e6ccc7a44465a73de29fd2d541b3 (release/2.4)
Author: Steffan Karger Date: Sun Nov 12 17:36:36 2017 +0100
Add --tls-cert-profile option.
Signed-off-by: Steffan Karger <[email protected]...>
Acked-by: Antonio Quartulli <[email protected]...>
Message-Id: <[email protected]...>
URL: https://www.mail-archive.com/[email protected]/msg15848.html
Signed-off-by: Gert Doering <[email protected]...>--
kind regards,
Gert Doering
Hi,
Quoted 8 lines · Gert Doering
.. of course this conflicts with
o->renegotiate_seconds_min...Nevertheless, thanks for the patch :-) - it makes my FreeBSD 10.3 (mbedTLS 2.6) buildslave now happy again (on the default settings - with --tls-cert-profile preferred, it refuses the old-hash cert, as it should).
Also tested with openssl 1.0.1, where it warns and does nothing, as expected. Good :-)
I *should* have tested with LibreSSL as well...
ssl_openssl.o: In function tls_ctx_set_cert_profile': /home/buildbot/build-openvpn/build-cron2-openbsd-60-amd64-stable-master--disable -lzo--disable-management/build/src/openvpn/ssl_openssl.c:404: undefined reference to SSL_CTX_set_security_level' /home/buildbot/build-openvpn/build-cron2-openbsd-60-amd64-stable-master--disable-lzo--disable-management/build/src/openvpn/ssl_openssl.c:400: undefined reference to `SSL_CTX_set_security_level'
... *roll eyes*
(Not sure, though, why it only complains about two out of three, but still annoyance... if LibreSSL claims OPENSSL_VERSION_NUMBER >= 0x10100000 it better should provide everything needed)
This is on OpenBSD 6.0, which happens to be something Samuli's vagrant setup can provide nicely if anyone wants to have a look :-)
gert
Signature · 3 lines
now what should I write here... Gert Doering - Munich, Germany [email protected]...
Quoted 19 lines · Gert Doering
Hi,
Quoted 8 lines · Gert Doering
.. of course this conflicts with
o->renegotiate_seconds_min...Nevertheless, thanks for the patch :-) - it makes my FreeBSD 10.3 (mbedTLS 2.6) buildslave now happy again (on the default settings - with --tls-cert-profile preferred, it refuses the old-hash cert, as it should).
Also tested with openssl 1.0.1, where it warns and does nothing, as expected. Good :-)
I *should* have tested with LibreSSL as well...
ssl_openssl.o: In function `tls_ctx_set_cert_profile':
/home/buildbot/build-openvpn/build-cron2-openbsd-60-amd64-stable-master--disable-lzo--disable-management/build/src/openvpn/ssl_openssl.c:404:
undefined reference toSSL_CTX_set_security_level' /home/buildbot/build-openvpn/build-cron2-openbsd-60-amd64-stable-master--disable-lzo--disable-management/build/src/openvpn/ssl_openssl.c:400: undefined reference toSSL_CTX_set_security_level'
Quoted 5 lines
... *roll eyes*
(Not sure, though, why it only complains about two out of three, but still annoyance... if LibreSSL claims
OPENSSL_VERSION_NUMBER>=0x10100000it better should provide everything needed)
LibreSSL defines:
#define OPENSSL_VERSION_NUMBER 0x20000000L
breaking #ifdef checks based on it. Sadly, people tend to prefer adding
&& !defined(LIBRESSL_VERSION_NUMBER)
to fix the build, rather than doing features detection using autoconf or similar. openvpn can easily solve this.
Quoted 2 lines
This is on OpenBSD 6.0, which happens to be something Samuli's vagrant setup can provide nicely if anyone wants to have a look :-)
Here's a diff, master builds and seems to run fine as a client on OpenBSD-current.
I can cook a similar diff for the remaining OPENSSL / LIBRESSL_VERSION_NUMBER #ifdef.
From 15315d3c3b25814a426bfc8184c4dfd262f28768 Mon Sep 17 00:00:00 2001
From: Jeremie Courreges-Anglas <[email protected]...>
Date: Sun, 19 Nov 2017 22:57:56 +0100
Subject: [PATCH] Fix build with LibreSSL
Detect the presence of SSL_CTX_set_security_level(), don't check OPENSSL_VERSION_NUMBER.
--- configure.ac | 1 + src/openvpn/ssl_openssl.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-)
configure.ac +1 -0
@@ -927,6 +927,7 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then EVP_MD_CTX_reset \ SSL_CTX_get_default_passwd_cb \ SSL_CTX_get_default_passwd_cb_userdata \ + SSL_CTX_set_security_level \ X509_get0_pubkey \ X509_STORE_get0_objects \ X509_OBJECT_free \
src/openvpn/ssl_openssl.c +1 -1
@@ -386,7 +386,7 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers)void tls_ctx_set_cert_profile (struct tls_root_ctx *ctx,const char *profile) { -#if (OPENSSL_VERSION_NUMBER >=0x10100000 ) +#ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL /* OpenSSL does not have certificate profiles, but a complex set of * callbacks that we could try to implement to achieve something similar. * For now, use OpenSSL's security levels to achieve similar (but not equal)
Signature · 1 line
2.15.0
Signature · 2 lines
-- jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF DDCC 0DFA 74AE 1524 E7EE
Quoted 37 lines · Jeremie Courreges-Anglas
Quoted 19 lines · Gert Doering
Hi,
Quoted 8 lines · Gert Doering
.. of course this conflicts with
o->renegotiate_seconds_min...Nevertheless, thanks for the patch :-) - it makes my FreeBSD 10.3 (mbedTLS 2.6) buildslave now happy again (on the default settings - with --tls-cert-profile preferred, it refuses the old-hash cert, as it should).
Also tested with openssl 1.0.1, where it warns and does nothing, as expected. Good :-)
I *should* have tested with LibreSSL as well...
ssl_openssl.o: In function `tls_ctx_set_cert_profile':
/home/buildbot/build-openvpn/build-cron2-openbsd-60-amd64-stable-master--disable-lzo--disable-management/build/src/openvpn/ssl_openssl.c:404:
undefined reference toSSL_CTX_set_security_level' /home/buildbot/build-openvpn/build-cron2-openbsd-60-amd64-stable-master--disable-lzo--disable-management/build/src/openvpn/ssl_openssl.c:400: undefined reference toSSL_CTX_set_security_level'Quoted 5 lines
... *roll eyes*
(Not sure, though, why it only complains about two out of three, but still annoyance... if LibreSSL claims
OPENSSL_VERSION_NUMBER>=0x10100000it better should provide everything needed)LibreSSL defines:
#define OPENSSL_VERSION_NUMBER 0x20000000Lbreaking #ifdef checks based on it. Sadly, people tend to prefer adding
&& !defined(LIBRESSL_VERSION_NUMBER)
to fix the build, rather than doing features detection using autoconf or similar. openvpn can easily solve this.
Quoted 8 lines
Quoted 2 lines
This is on OpenBSD 6.0, which happens to be something Samuli's vagrant setup can provide nicely if anyone wants to have a look :-)
Here's a diff, master builds and seems to run fine as a client on OpenBSD-current.
I can cook a similar diff for the remaining OPENSSL /
LIBRESSL_VERSION_NUMBER#ifdef.
Here's another diff to detect SSL_CTX_get0_certificate().
Tested against LibreSSL only; adding
#define HAVE_SSL_CTX_GET0_CERTIFICATE 1
to config.h lets ssl_openssl.c build (with a warning), the link fails as expected.
From 1abd6089a45260e4ce7adfae3fa619f9055edcaf Mon Sep 17 00:00:00 2001
From: Jeremie Courreges-Anglas <[email protected]...>
Date: Sun, 19 Nov 2017 23:12:30 +0100
Subject: [PATCH] Detect if SSL_CTX_get0_certificate is available
Don't rely on #ifdef OPENSSL/LIBRESSL_VERSION_NUMBER checks.
--- configure.ac | 1 + src/openvpn/ssl_openssl.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-)
configure.ac +1 -0
@@ -925,6 +925,7 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then EVP_MD_CTX_new \ EVP_MD_CTX_free \ EVP_MD_CTX_reset \ + SSL_CTX_get0_certificate \ SSL_CTX_get_default_passwd_cb \ SSL_CTX_get_default_passwd_cb_userdata \ SSL_CTX_set_security_level \
src/openvpn/ssl_openssl.c +2 -2
@@ -425,7 +425,7 @@ tls_ctx_check_cert_time(const struct tls_root_ctx *ctx)ASSERT (ctx); -#if OPENSSL_VERSION_NUMBER >=0x10002000L && !defined(LIBRESSL_VERSION_NUMBER ) +#ifdef HAVE_SSL_CTX_GET0_CERTIFICATE /* OpenSSL 1.0.2 and up */ cert =SSL_CTX_get0_certificate (ctx->ctx);#else
@@ -460,7 +460,7 @@ tls_ctx_check_cert_time(const struct tls_root_ctx *ctx) } cleanup: -#if OPENSSL_VERSION_NUMBER <0x10002000L || defined(LIBRESSL_VERSION_NUMBER ) +#ifndef HAVE_SSL_CTX_GET0_CERTIFICATESSL_free (ssl );#endif return ;
Signature · 1 line
2.15.0
Signature · 2 lines
-- jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF DDCC 0DFA 74AE 1524 E7EE
Steffan Karger
NAKHi,
Quoted 58 lines · Jeremie Courreges-Anglas
Here's another diff to detect
SSL_CTX_get0_certificate().Tested against LibreSSL only; adding
#define HAVE_SSL_CTX_GET0_CERTIFICATE 1to
config.hletsssl_openssl.cbuild (with a warning), the link fails as expected.From
1abd6089a45260e4ce7adfae3fa619f9055edcafMon Sep 17 00:00:00 2001
From: Jeremie Courreges-Anglas <[email protected]...>
Date: Sun, 19 Nov 2017 23:12:30 +0100
Subject: [PATCH] Detect ifSSL_CTX_get0_certificateis availableDon't rely on #ifdef OPENSSL/LIBRESSL_VERSION_NUMBER checks.
Signed-off-by Jeremie Courreges-Anglas <[email protected]...>--- configure.ac | 1 + src/openvpn/ssl_openssl.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-)configure.ac +1
-0@@ -925,6 +925,7 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then EVP_MD_CTX_new \ EVP_MD_CTX_free \ EVP_MD_CTX_reset \ + SSL_CTX_get0_certificate \ SSL_CTX_get_default_passwd_cb \ SSL_CTX_get_default_passwd_cb_userdata \ SSL_CTX_set_security_level \src/openvpn/ssl_openssl.c +2
-2@@ -425,7 +425,7 @@ tls_ctx_check_cert_time(const struct tls_root_ctx *ctx)ASSERT (ctx); -#if OPENSSL_VERSION_NUMBER >=0x10002000L && !defined(LIBRESSL_VERSION_NUMBER ) +#ifdef HAVE_SSL_CTX_GET0_CERTIFICATE /* OpenSSL 1.0.2 and up */ cert =SSL_CTX_get0_certificate (ctx->ctx);#else @@ -460,7 +460,7 @@ tls_ctx_check_cert_time(const struct tls_root_ctx *ctx) } cleanup: -#if OPENSSL_VERSION_NUMBER <0x10002000L || defined(LIBRESSL_VERSION_NUMBER ) +#ifndef HAVE_SSL_CTX_GET0_CERTIFICATESSL_free (ssl );#endif return ;Signature · 1 line
2.15.0
NAK.
Looking at this patch again I realize I have misunderstood the intentions when first looking at it. I thought LibreSSL *did* have an SSL_CTX_get0_certificate() and this patch would make us use it (instead of the workaround in the #else). But this is just about replacing the version check with a configure check. I oppose that change because it hides information I want to have: "what code can be purged when we drop support for openssl 1.0 and libressl?".
-Steffan
On Thu, Dec 14 2017, Steffan Karger <[email protected]...> wrote:
[...]
Quoted 7 lines
NAK.
Looking at this patch again I realize I have misunderstood the intentions when first looking at it. I thought LibreSSL *did* have an
SSL_CTX_get0_certificate()and this patch would make us use it (instead of the workaround in the #else). But this is just about replacing the version check with a configure check.
Are you still opposed to such a diff (updated version attached), now that LibreSSL HEAD provides SSL_CTX_get0_certificate?
Quoted 3 lines
I oppose that change because it
hides information I want to have: "what code can be purged when we drop support for openssl 1.0 and libressl?".
Maybe there's another way to encode that information? Like, consistently formatted comments describing the first OpenSSL (and LibreSSL) releases that provided a function?
Signature · 1 line
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF DDCC 0DFA 74AE 1524 E7EE
From e6d80207bf7f1323670d0bc1102fa51309b1aa14 Mon Sep 17 00:00:00 2001
From: Jeremie Courreges-Anglas <[email protected]...>
Date: Sun, 4 Mar 2018 19:24:36 +0100
Subject: [PATCH] Detect availability of SSL_CTX_get0_certificate
instead of relying on simpler version checks. This allows using SSL_CTX_get0_certificate with LibreSSL.
--- configure.ac | 1 + src/openvpn/ssl_openssl.c | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-)
configure.ac +1 -0
@@ -918,6 +918,7 @@ if test "${with_crypto_library}" = "openssl"; then EVP_MD_CTX_new \ EVP_MD_CTX_free \ EVP_MD_CTX_reset \ + SSL_CTX_get0_certificate \ SSL_CTX_get_default_passwd_cb \ SSL_CTX_get_default_passwd_cb_userdata \ SSL_CTX_set_security_level \
src/openvpn/ssl_openssl.c +3 -3
@@ -459,8 +459,8 @@ tls_ctx_check_cert_time(const struct tls_root_ctx *ctx)ASSERT (ctx); -#if OPENSSL_VERSION_NUMBER >=0x10002000L && !defined(LIBRESSL_VERSION_NUMBER ) -/* OpenSSL 1.0.2 and up */ +#ifdef HAVE_SSL_CTX_GET0_CERTIFICATE +/* OpenSSL 1.0.2 and up, LibreSSL 2.7.0 and up */ cert =SSL_CTX_get0_certificate (ctx->ctx);#else /* OpenSSL 1.0.1 and earlier need an SSL object to get at the certificate */
@@ -494,7 +494,7 @@ tls_ctx_check_cert_time(const struct tls_root_ctx *ctx) } cleanup: -#if OPENSSL_VERSION_NUMBER <0x10002000L || defined(LIBRESSL_VERSION_NUMBER ) +#ifndef HAVE_SSL_CTX_GET0_CERTIFICATESSL_free (ssl );#endif return ;
Signature · 1 line
2.16.0
Hi,
Quoted 6 lines · Jeremie Courreges-Anglas
On Thu, Dec 14 2017, Steffan Karger <[email protected]...> wrote:
[...]
Quoted 2 lines
NAK.
Quoted 8 lines
Quoted 5 lines
Looking at this patch again I realize I have misunderstood the intentions when first looking at it. I thought LibreSSL *did* have an
SSL_CTX_get0_certificate()and this patch would make us use it (instead of the workaround in the #else). But this is just about replacing the version check with a configure check.Are you still opposed to such a diff (updated version attached), now that LibreSSL HEAD provides
SSL_CTX_get0_certificate?
Yes, I'd rather not use the workaround if not needed. Still not very happy about the approach though. Why not simply add || LIBRESSL_VERSION
Quoted 9 lines
x.y.z ?
Quoted 3 lines
I oppose that change because it
hides information I want to have: "what code can be purged when we drop support for openssl 1.0 and libressl?".Maybe there's another way to encode that information? Like, consistently formatted comments describing the first OpenSSL (and LibreSSL) releases that provided a function?
Yes, we could do that. But if we're going to put that info into the code anyway, why not just use the define?
-Steffan
Quoted 1 line · Steffan Karger
Yes, I'd rather not use the workaround if not needed.
Bad wording. Read that as "I'm no longer opposed to a patch".
-Steffan
Hi,
Quoted 9 lines · Jeremie Courreges-Anglas
Quoted 3 lines
(Not sure, though, why it only complains about two out of three, but still annoyance... if LibreSSL claims
OPENSSL_VERSION_NUMBER>=0x10100000it better should provide everything needed)LibreSSL defines:
#define OPENSSL_VERSION_NUMBER 0x20000000Lbreaking #ifdef checks based on it.
Indeed. I find this a curious and not useful setting - "if it's not compatible with OPENSSL, why define such a version number"? But that's slightly out of scope here...
Quoted 6 lines
Sadly, people tend to prefer adding
&& !defined(LIBRESSL_VERSION_NUMBER)
to fix the build, rather than doing features detection using autoconf or similar. openvpn can easily solve this.
... and I'm thankful for your patch, because this is exactly what I considered doing here. We already check for all the 1.0/1.1 openssl differences (accessor functions), so adding this one is logical.
Quoted 5 lines
Quoted 2 lines
This is on OpenBSD 6.0, which happens to be something Samuli's vagrant setup can provide nicely if anyone wants to have a look :-)
Here's a diff, master builds and seems to run fine as a client on OpenBSD-current.
Thanks. Patch looks good to me, but I leave the final word to Steffan (maybe he wants to amend the non-support message to include LibreSSL, or whatever)
Quoted 2 lines
I can cook a similar diff for the remaining OPENSSL /
LIBRESSL_VERSION_NUMBER#ifdef.
This would be appreciated.
gert
Signature · 3 lines
now what should I write here... Gert Doering - Munich, Germany [email protected]...
Hi,
On 20-11-17 09:06, Gert Doering wrote:> On Sun, Nov 19, 2017 at 11:01:39PM +0100, Jeremie Courreges-Anglas
Quoted 8 lines
Quoted 7 lines · wrote:
Quoted 4 lines
(Not sure, though, why it only complains about two out of three, but still annoyance... if LibreSSL claims
OPENSSL_VERSION_NUMBER>=0x10100000it better should provide everything needed)LibreSSL defines:
Quoted 7 lines
Quoted 3 lines
#define
OPENSSL_VERSION_NUMBER0x20000000Lbreaking #ifdef checks based on it.
Indeed. I find this a curious and not useful setting - "if it's not compatible with OPENSSL, why define such a version number"? But that's slightly out of scope here...
+1, highly frustrating. LibreSSL should really just make up their mind whether they want to be OpenSSL-compatible or not, and act accordingly.
Quoted 11 lines
Quoted 6 lines
Sadly, people tend to prefer adding
&& !defined(LIBRESSL_VERSION_NUMBER)
to fix the build, rather than doing features detection using autoconf or similar. openvpn can easily solve this.
... and I'm thankful for your patch, because this is exactly what I
considered doing here. We already check for all the 1.0/1.1
openssl differences (accessor functions), so adding this one is logical.
*If* we want to keep LibreSSL working, I agree this is the way to go.
But I'm kind of annoyed that we are including more and more #ifdefs
to keep LibreSSL happy. The version checks are much simpler and make it easy to see what code can be purged when we drop support for e.g openssl 1.0.1. I don't want to keep these 'backwards compatibility' ifdefs forever. At some point we'll have to decide to either completely stop supporting LibreSSL, or add it as a true abstraction (which I will *not* maintain). We're getting closer and closer to that point.
Quoted 10 lines
Quoted 6 lines
Quoted 3 lines
This is on OpenBSD 6.0, which happens to be something Samuli's vagrant setup can provide nicely if anyone wants to have a look :-)
Here's a diff, master builds and seems to run fine as a client on OpenBSD-current.
Thanks. Patch looks good to me, but I leave the final word to Steffan (maybe he wants to amend the non-support message to include LibreSSL, or whatever)
They look good at first sight, but I'll check these properly later this week - when I have some spare cycles available.
Quoted 4 lines
Quoted 2 lines
I can cook a similar diff for the remaining OPENSSL /
LIBRESSL_VERSION_NUMBER#ifdef.This would be appreciated.
Same reservations as above.
To reiterate: our policy towards LibreSSL is currently that we do *not* support it, but we won't break it on purpose and accept trivial patches to keep it working. Where 'trivial' is - of course - fuzzy.
-Steffan
Hi,
Quoted 44 lines · Jeremie Courreges-Anglas
Here's a diff, master builds and seems to run fine as a client on OpenBSD-current.
From: Jeremie Courreges-Anglas <[email protected]...>
Date: Sun, 19 Nov 2017 22:57:56 +0100
Subject: [PATCH] Fix build with LibreSSLDetect the presence of
SSL_CTX_set_security_level(), don't checkOPENSSL_VERSION_NUMBER.Signed-off-by Jeremie Courreges-Anglas <[email protected]...>--- configure.ac | 1 + src/openvpn/ssl_openssl.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-)configure.ac +1
-0@@ -927,6 +927,7 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then EVP_MD_CTX_reset \ SSL_CTX_get_default_passwd_cb \ SSL_CTX_get_default_passwd_cb_userdata \ + SSL_CTX_set_security_level \ X509_get0_pubkey \ X509_STORE_get0_objects \ X509_OBJECT_free \src/openvpn/ssl_openssl.c +1
-1@@ -386,7 +386,7 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers)void tls_ctx_set_cert_profile (struct tls_root_ctx *ctx,const char *profile) { -#if (OPENSSL_VERSION_NUMBER >=0x10100000 ) +#ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL /* OpenSSL does not have certificate profiles, but a complex set of * callbacks that we could try to implement to achieve something similar. * For now, use OpenSSL's security levels to achieve similar (but not equal) Signature · 1 line
2.15.0
Patch looks good and clean enough to restore compatibilty with libressl.
Tested that this doesn't break --tls-cert-profile with OpenSSL 1.1, and
doesn't break builds with OpenSSL 1.0.
-Steffan
[Openvpn-devel] [PATCH applied] Re: Fix build with LibreSSL
In reply to Jeremie Courreges-AnglasThanks. Tested on OpenBSD 6.0, fixes compilation again.
Your patch has been applied to the master and release/2.4 branch.
commit 88a827f25cb4a79f06597ca438f8f04d37a03d4e (master) commit eac1e089239999a161d81e0222d461c8b580a776 (release/2.4)
Author: Jeremie Courreges-Anglas Date: Sun Nov 19 22:57:56 2017 +0100
Fix build with LibreSSL
Signed-off-by: Jeremie Courreges-Anglas <[email protected]...>
Acked-by: Steffan Karger <[email protected]...>
Message-Id: <[email protected]...>
URL: https://www.mail-archive.com/[email protected]/msg15902.html
Signed-off-by: Gert Doering <[email protected]...>--
kind regards,
Gert Doering