From 199b0f4be17b779ea41e10cf337fbcb2435be47a Mon Sep 17 00:00:00 2001 From: James Mayclin Date: Fri, 14 Apr 2023 17:07:53 -0700 Subject: [PATCH] update security policy and rust binding documentation (#3906) --- README.md | 4 ++ bindings/rust/s2n-tls-sys/README.md | 3 ++ bindings/rust/s2n-tls-tokio/README.md | 1 + bindings/rust/s2n-tls/README.md | 2 + docs/USAGE-GUIDE.md | 74 ++++++++++++++------------- tls/s2n_security_policies.h | 37 ++++++++++++++ tls/s2n_x509_validator.c | 24 +++++++++ 7 files changed, 109 insertions(+), 36 deletions(-) create mode 100644 bindings/rust/s2n-tls-sys/README.md create mode 100644 bindings/rust/s2n-tls-tokio/README.md create mode 100644 bindings/rust/s2n-tls/README.md diff --git a/README.md b/README.md index e3e9b080578..64baa0db5c3 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,10 @@ s2n-tls is a C99 implementation of the TLS/SSL protocols that is designed to be simple, small, fast, and with security as a priority. It is released and licensed under the Apache License 2.0. +> s2n-tls is short for "signal to noise" and is a nod to the almost magical act of encryption — disguising meaningful signals, like your critical data, as seemingly random noise. +> +> -- [s2n-tls announcement](https://aws.amazon.com/blogs/security/introducing-s2n-a-new-open-source-tls-implementation/) + [![Build Status](https://codebuild.us-west-2.amazonaws.com/badges?uuid=eyJlbmNyeXB0ZWREYXRhIjoiMndlTzJNbHVxWEo3Nm82alp4eGdGNm4rTWdxZDVYU2VTbitIR0ZLbHVtcFFGOW5majk5QnhqaUp3ZEkydG1ueWg0NGlhRE43a1ZnUzZaQTVnSm91TzFFPSIsIml2UGFyYW1ldGVyU3BlYyI6IlJLbW42NENlYXhJNy80QnYiLCJtYXRlcmlhbFNldFNlcmlhbCI6MX0%3D&branch=main)](https://github.com/aws/s2n-tls/) [![Apache 2 License](https://img.shields.io/github/license/aws/s2n-tls.svg)](http://aws.amazon.com/apache-2-0/) [![C99](https://img.shields.io/badge/language-C99-blue.svg)](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf) diff --git a/bindings/rust/s2n-tls-sys/README.md b/bindings/rust/s2n-tls-sys/README.md new file mode 100644 index 00000000000..e9931479489 --- /dev/null +++ b/bindings/rust/s2n-tls-sys/README.md @@ -0,0 +1,3 @@ +This crates provides low level rust bindings for [s2n-tls](https://github.com/aws/s2n-tls) which are autogenerated with [bindgen](https://github.com/rust-lang/rust-bindgen) + +This crate is not intended for direct consumption by end consumers. Interested developers should instead look at the [s2n-tls](https://crates.io/crates/s2n-tls) or [s2n-tls-tokio](https://crates.io/crates/s2n-tls-tokio) crates. These provide higher-level, more ergonomic bindings than the `s2n-tls-sys` crate. \ No newline at end of file diff --git a/bindings/rust/s2n-tls-tokio/README.md b/bindings/rust/s2n-tls-tokio/README.md new file mode 100644 index 00000000000..25af6b21920 --- /dev/null +++ b/bindings/rust/s2n-tls-tokio/README.md @@ -0,0 +1 @@ +`s2n-tls-tokio` provides async bindings that allow consumers to use [s2n-tls](https://github.com/aws/s2n-tls) within the tokio runtime. To consume `s2n-tls` outside of an async context consider using the [s2n-tls](https://crates.io/crates/s2n-tls) crate. \ No newline at end of file diff --git a/bindings/rust/s2n-tls/README.md b/bindings/rust/s2n-tls/README.md new file mode 100644 index 00000000000..0bf29c8a8ce --- /dev/null +++ b/bindings/rust/s2n-tls/README.md @@ -0,0 +1,2 @@ +This crate provides ergonomic, idiomatic Rust bindings for [s2n-tls](https://github.com/aws/s2n-tls). From the s2n-tls readme: +> s2n-tls is a C99 implementation of the TLS/SSL protocols that is designed to be simple, small, fast, and with security as a priority. It is released and licensed under the Apache License 2.0. \ No newline at end of file diff --git a/docs/USAGE-GUIDE.md b/docs/USAGE-GUIDE.md index 6d84cdf6dfd..a0d3939c3d1 100644 --- a/docs/USAGE-GUIDE.md +++ b/docs/USAGE-GUIDE.md @@ -386,39 +386,39 @@ s2n-tls uses pre-made security policies to help avoid common misconfiguration mi `s2n_config_set_cipher_preferences()` sets a security policy, which includes the cipher/kem/signature/ecc preferences and protocol version. -### Chart: Security Policy Version To Protocol Version And Ciphersuites +### Chart: Security Policy Version To Protocol Version And Ciphersuites The following chart maps the security policy version to protocol version and ciphersuites supported. -| version | SSLv3 | TLS1.0 | TLS1.1 | TLS1.2 | TLS1.3 | AES-CBC | ChaCha20-Poly1305 | ECDSA | AES-GCM | 3DES | RC4 | DHE | ECDHE | ChaCha20-Boosted | -|----------------------------------------------|-------|--------|--------|--------|---------|---------|-------------------|-------|---------|------|-----|-----|-------|------------------| -| "default" | | X | X | X | | X | X | | X | | | | X | | -| "20190214" | | X | X | X | | X | | X | X | X | | X | X | | -| "20170718" | | X | X | X | | X | | | X | | | | X | | -| "20170405" | | X | X | X | | X | | | X | X | | | X | | -| "20170328" | | X | X | X | | X | | | X | X | | X | X | | -| "20170210" | | X | X | X | | X | X | | X | | | | X | | -| "20160824" | | X | X | X | | X | | | X | | | | X | | -| "20160804" | | X | X | X | | X | | | X | X | | | X | | -| "20160411" | | X | X | X | | X | | | X | X | | | X | | -| "20150306" | | X | X | X | | X | | | X | X | | | X | | -| "20150214" | | X | X | X | | X | | | X | X | | X | | | -| "20150202" | | X | X | X | | X | | | | X | | X | | | -| "20141001" | | X | X | X | | X | | | | X | X | X | | | -| "20140601" | X | X | X | X | | X | | | | X | X | X | | | -| "20190120" | | X | X | X | | X | | | X | X | | | X | | -| "20190121" | | X | X | X | | X | | | X | X | | | X | | -| "20190122" | | X | X | X | | X | | X | X | X | | X | X | | -| "default_tls13" | | X | X | X | X | X | X | X | X | | | | X | | -| "20190801" | | X | X | X | X | X | X | | X | | | | X | | -| "20190802" | | X | X | X | X | X | X | | X | | | | X | | -| "20200207" | | X | X | X | X | X | X | | X | | | | | | -| "20230317" | | | | X | X | X | | X | X | | | | X | | -| "rfc9151" | | | | X | X | | | X | X | | | X | X | | -| "CloudFront-TLS-1-2-2021" | | | | X | X | | X | X | X | | | | X | | -| "CloudFront-TLS-1-2-2021-ChaCha20-Boosted" | | | | X | X | | X | X | X | | | | X | X | - -The "default" and "default_tls13" versions are special in that they will be updated with future s2n-tls changes and ciphersuites and protocol versions may be added and removed, or their internal order of preference might change. Numbered versions are fixed and will never change. +| version | SSLv3 | TLS1.0 | TLS1.1 | TLS1.2 | TLS1.3 | AES-CBC | AES-GCM | ChaCha20-Poly1305 | 3DES | RC4 | DHE | ECDHE | +|---------------------------|-------|--------|--------|--------|---------|---------|---------|-------------------|------|-----|-----|-------| +| "default" | | X | X | X | | X | X | | | | | X | +| "default_tls13" | | X | X | X | X | X | X | X | | | | X | +| "default_fips" | | | | X | | X | X | | | | X | X | +| "20190214" | | X | X | X | | X | X | | X | | X | X | +| "20170718" | | X | X | X | | X | X | | | | | X | +| "20170405" | | X | X | X | | X | X | | X | | | X | +| "20170328" | | X | X | X | | X | X | | X | | X | X | +| "20170210" | | X | X | X | | X | X | X | | | | X | +| "20160824" | | X | X | X | | X | X | | | | | X | +| "20160804" | | X | X | X | | X | X | | X | | | X | +| "20160411" | | X | X | X | | X | X | | X | | | X | +| "20150306" | | X | X | X | | X | X | | X | | | X | +| "20150214" | | X | X | X | | X | X | | X | | X | | +| "20150202" | | X | X | X | | X | | | X | | X | | +| "20141001" | | X | X | X | | X | | | X | X | X | | +| "20140601" | X | X | X | X | | X | | | X | X | X | | +| "20190120" | | X | X | X | | X | X | | X | | | X | +| "20190121" | | X | X | X | | X | X | | X | | | X | +| "20190122" | | X | X | X | | X | X | | X | | X | X | +| "20190801" | | X | X | X | X | X | X | X | | | | X | +| "20190802" | | X | X | X | X | X | X | X | | | | X | +| "20200207" | | X | X | X | X | X | X | X | | | | | +| "20230317" | | | | X | X | X | X | | | | | X | +| "rfc9151" | | | | X | X | | X | | | | X | X | +| "CloudFront-TLS-1-2-2021" | | | | X | X | | X | X | | | | X | + +The "default", "default_tls13", and "default_fips" versions are special in that they will be updated with future s2n-tls changes and ciphersuites and protocol versions may be added and removed, or their internal order of preference might change. Numbered versions are fixed and will never change. In general, customers prefer to use numbered versions for production use cases to prevent impact from library updates. "20230317" offers more limited but more secure options than "default". It only supports TLS1.2 and TLS1.3 and is FIPS compliant. Choose this policy if you don't need or want to support less secure legacy options like TLS1.1 or SHA1. @@ -440,13 +440,15 @@ s2n-tls does not expose an API to control the order of preference for each ciphe #### ChaCha20 Boosting -s2n-tls usually prefers AES over ChaCha20. However, some clients-- particularly mobile or IOT devices-- do not support AES hardware acceleration, making AES less efficient and performant than ChaCha20. In this case, clients will indicate their preference for ChaCha20 by listing it first during cipher suite negotiation. Usually s2n-tls servers ignore client preferences, but s2n-tls offers "ChaCha20 boosted" security policies that will choose ChaCha20 over AES if the client indicates a preference for ChaCha20. +s2n-tls usually prefers AES over ChaCha20. However, some clients-- particularly mobile or IOT devices-- do not support AES hardware acceleration, making AES less efficient and performant than ChaCha20. In this case, clients will indicate their preference for ChaCha20 by listing it first during cipher suite negotiation. Usually s2n-tls servers ignore client preferences, but s2n-tls offers "ChaCha20 boosted" security policies that will choose ChaCha20 over AES if the client indicates a preference for ChaCha20. This is available in the "CloudFront-TLS-1-2-2021-ChaCha20-Boosted" policy, which is identical to the "CloudFront-TLS-1-2-2021" policy listed above but with ChaCha20 Boosting enabled. ### Chart: Security Policy Version To Supported Signature Schemes | version | RSA PKCS1 | ECDSA | SHA-1 Legacy | RSA PSS | |----------------|--------------|----------|---------------|----------| | "default" | X | X | X | | +| "default_tls13"| X | X | X | X | +| "default_fips" | X | X | | | | "20190214" | X | X | X | | | "20170718" | X | X | X | | | "20170405" | X | X | X | | @@ -463,7 +465,6 @@ s2n-tls usually prefers AES over ChaCha20. However, some clients-- particularly | "20190120" | X | X | X | | | "20190121" | X | X | X | | | "20190122" | X | X | X | | -| "default_tls13"| X | X | X | X | | "20190801" | X | X | X | X | | "20190802" | X | X | X | X | | "20200207" | X | X | X | X | @@ -478,6 +479,8 @@ legacy SHA-1 algorithms in CertificateVerify messages if TLS1.2 has been negotia | version | secp256r1 | secp384r1 | x25519 | |----------------|--------------|------------|--------| | "default" | X | X | | +| "default_tls13"| X | X | X | +| "default_fips" | X | X | | | "20190214" | X | X | | | "20170718" | X | X | | | "20170405" | X | X | | @@ -494,7 +497,6 @@ legacy SHA-1 algorithms in CertificateVerify messages if TLS1.2 has been negotia | "20190120" | X | X | | | "20190121" | X | X | | | "20190122" | X | X | | -| "default_tls13"| X | X | X | | "20190801" | X | X | X | | "20190802" | X | X | | | "20200207" | X | X | X | @@ -567,7 +569,7 @@ The OCSP stapling information will be automatically validated if the underlying Certificate Revocation Lists (CRLs) are lists of issued, unexpired certificates that have been revoked by the CA. CAs publish updated versions of these lists periodically. A validator wishing to verify a certificate obtains a CRL from the CA, validates the CRL, and checks to ensure the certificate is not contained in the list, and therefore has not been revoked by the CA. -The s2n CRL lookup callback must be implemented and set via `s2n_config_set_crl_lookup_cb()` to enable CRL validation in s2n-tls. This callback will be triggered once for each certificate in the certificate chain. +The s2n CRL lookup callback must be implemented and set via `s2n_config_set_crl_lookup_cb()` to enable CRL validation in s2n-tls. This callback will be triggered once for each certificate in the certificate chain. The CRLs for all certificates received in the handshake must be obtained in advance of the CRL lookup callback, outside of s2n-tls. It is not possible in s2n-tls to obtain CRLs in real-time. Applications should load these CRLs into memory, by creating `s2n_crl`s via `s2n_crl_new()`, and adding the obtained CRL data via `s2n_crl_load_pem()`. The `s2n_crl` should be freed via `s2n_crl_free()` when no longer needed. @@ -664,7 +666,7 @@ for details about proper SSLv2 ClientHello parsing. ### Client Hello Callback -Users can access the Client Hello during the handshake by setting the callback `s2n_config_set_client_hello_cb()`. A possible use-case for this is to modify the `s2n_connection` based on information in the Client Hello. This should be done carefully, as modifying the connection in response to untrusted input can be dangerous. In particular, switching from an `s2n_config` that supports TLS1.3 to one that does not opens the server up to a possible version downgrade attack. +Users can access the Client Hello during the handshake by setting the callback `s2n_config_set_client_hello_cb()`. A possible use-case for this is to modify the `s2n_connection` based on information in the Client Hello. This should be done carefully, as modifying the connection in response to untrusted input can be dangerous. In particular, switching from an `s2n_config` that supports TLS1.3 to one that does not opens the server up to a possible version downgrade attack. `s2n_connection_server_name_extension_used()` MUST be invoked before exiting the callback if any of the connection properties were changed on the basis of the Server Name extension. If desired, the callback can return a negative value to make s2n-tls terminate the handshake early with a fatal handshake failure alert. @@ -673,7 +675,7 @@ Users can access the Client Hello during the handshake by setting the callback ` The callback can be invoked in two modes: **S2N_CLIENT_HELLO_CB_BLOCKING** or **S2N_CLIENT_HELLO_CB_NONBLOCKING**. Use `s2n_config_set_client_hello_cb_mode()` to set the desired mode. The default mode, "blocking mode", will wait for the Client Hello callback to succeed and then continue the handshake. Use this mode for light-weight callbacks that won't slow down the handshake or block the main thread, like logging or simple configuration changes. - + In contrast, "non-blocking mode" will wait for the ClientHello callback to succeed and then pause the handshake, immediately returning from s2n_negotiate with an error indicating that the handshake is blocked on application input. This allows the application to do expensive or time-consuming work like network calls outside of the callback without blocking the main thread. Only when the application calls `s2n_client_hello_cb_done()` will the handshake be able to resume. ## Record sizes diff --git a/tls/s2n_security_policies.h b/tls/s2n_security_policies.h index d0f883cc461..367aeeb8c18 100644 --- a/tls/s2n_security_policies.h +++ b/tls/s2n_security_policies.h @@ -25,12 +25,49 @@ /* Kept up-to-date by s2n_security_policies_test */ #define NUM_RSA_PSS_SCHEMES 6 +/* The s2n_security_policy struct is used to define acceptable and available + * algorithms for use in the TLS protocol. Note that the behavior of each field + * likely differs between different TLS versions, as the mechanics of cipher + * negotiation often have significant differences between TLS versions. + * + * In s2n-tls, the signature_algorithms extension only applies to signatures in + * CertificateVerify messages. To specify acceptable signature algorithms for + * certificates the certificate_signature_preferences field should be set in the + * security policy. + */ struct s2n_security_policy { uint8_t minimum_protocol_version; + /* TLS 1.0 - 1.2 - cipher preference includes multiple elements such + * as signature algorithms, record algorithms, and key exchange algorithms + * TLS 1.3 - cipher preference only determines record encryption + */ const struct s2n_cipher_preferences *cipher_preferences; + /* kem_preferences is only used for Post-Quantum cryptography */ const struct s2n_kem_preferences *kem_preferences; + /* This field roughly corresponds to the "signature_algorithms" extension. + * The client serializes this field of the security_policy to populate the + * extension, and it is also used by the server to choose an appropriate + * entry from the options supplied by the client. + * TLS 1.2 - optional extension to specify signature algorithms other than + * default: https://www.rfc-editor.org/rfc/rfc5246#section-7.4.1.4.1 + * TLS 1.3 - required extension specifying signature algorithms + */ const struct s2n_signature_preferences *signature_preferences; + /* When this field is set, the endpoint will ensure that the signatures on + * the certificates in the peer's certificate chain are in the specified + * list. Note that s2n-tls does not support the signature_algorithms_cert + * extension. Unlike the signature_preferences field, this information is + * never transmitted to a peer. + */ const struct s2n_signature_preferences *certificate_signature_preferences; + /* This field roughly corresponds to the information in the + * "supported_groups" extension. + * TLS 1.0 - 1.2 - "elliptic_curves" extension indicates supported groups + * for both key exchange and signature algorithms. + * TLS 1.3 - the "supported_groups" extension indicates the named groups + * which the client supports for key exchange + * https://www.rfc-editor.org/rfc/rfc8446#section-4.2.7 + */ const struct s2n_ecc_preferences *ecc_preferences; }; diff --git a/tls/s2n_x509_validator.c b/tls/s2n_x509_validator.c index 4aeb6a868e8..78fdb3fbb25 100644 --- a/tls/s2n_x509_validator.c +++ b/tls/s2n_x509_validator.c @@ -732,6 +732,30 @@ S2N_RESULT s2n_validate_certificate_signature(struct s2n_connection *conn, X509 const struct s2n_security_policy *security_policy; RESULT_GUARD_POSIX(s2n_connection_get_security_policy(conn, &security_policy)); + /** + * We only restrict the signature algorithm on the certificates in the + * peer's certificate chain if the certificate_signature_preferences field + * is set in the security policy. This is contrary to the RFC, which + * specifies that the signatures in the "signature_algorithms" extension + * apply to signatures in the certificate chain in certain scenarios, so RFC + * compliance would imply validating that the certificate chain signature + * algorithm matches one of the algorithms specified in the + * "signature_algorithms" extension. + * + *= https://www.rfc-editor.org/rfc/rfc5246#section-7.4.2 + *= type=exception + *= reason=not implemented due to lack of utility + *# If the client provided a "signature_algorithms" extension, then all + *# certificates provided by the server MUST be signed by a + *# hash/signature algorithm pair that appears in that extension. + * + *= https://www.rfc-editor.org/rfc/rfc8446#section-4.2.3 + *= type=exception + *= reason=not implemented due to lack of utility + *# If no "signature_algorithms_cert" extension is present, then the + *# "signature_algorithms" extension also applies to signatures appearing in + *# certificates. + */ if (security_policy->certificate_signature_preferences == NULL) { return S2N_RESULT_OK; }