GithubHelp home page GithubHelp logo

aws / s2n-tls Goto Github PK

View Code? Open in Web Editor NEW
4.4K 172.0 692.0 27.97 MB

An implementation of the TLS/SSL protocols

Home Page: https://aws.github.io/s2n-tls/usage-guide/

License: Apache License 2.0

Makefile 3.29% C 84.79% Shell 2.20% Python 4.22% Coq 0.32% Perl 0.05% CMake 0.35% C++ 0.37% Ruby 0.07% Dockerfile 0.03% Java 0.03% Rust 4.10% HTML 0.01% Nix 0.17%
tls ssl s2n encryption c c99 cryptography crypto

s2n-tls's Introduction

s2n

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

Build Status Apache 2 License C99 Github forks Github stars

Quickstart for Ubuntu

# clone s2n-tls
git clone https://github.com/aws/s2n-tls.git
cd s2n-tls

# install build dependencies
sudo apt update
sudo apt install cmake

# install a libcrypto
sudo apt install libssl-dev

# build s2n-tls
cmake . -Bbuild \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_INSTALL_PREFIX=./s2n-tls-install
cmake --build build -j $(nproc)
CTEST_PARALLEL_LEVEL=$(nproc) ctest --test-dir build
cmake --install build

See the s2n-tls build documentation for further guidance on building s2n-tls for your platform.

Have a Question?

If you think you might have found a security impacting issue, please follow our Security Notification Process.

If you have any questions about submitting PRs, s2n-tls API usage, or something similar, please open an issue.

Documentation

s2n-tls uses Doxygen to document its public API. The latest s2n-tls documentation can be found on GitHub pages. The Usage Guide explains how different TLS features can be configured and used.

Documentation for older versions or branches of s2n-tls can be generated locally. To generate the documentation, install doxygen and run doxygen docs/doxygen/Doxyfile. The doxygen documentation can now be found at docs/doxygen/output/html/index.html.

Doxygen installation instructions are available at the Doxygen webpage.

Using s2n-tls

The s2n-tls I/O APIs are designed to be intuitive to developers familiar with the widely-used POSIX I/O APIs, and s2n-tls supports blocking, non-blocking, and full-duplex I/O. Additionally there are no locks or mutexes within s2n-tls.

/* Create a server mode connection handle */
struct s2n_connection *conn = s2n_connection_new(S2N_SERVER);
if (conn == NULL) {
    ... error ...
}

/* Associate a connection with a file descriptor */
if (s2n_connection_set_fd(conn, fd) < 0) {
    ... error ...
}

/* Negotiate the TLS handshake */
s2n_blocked_status blocked;
if (s2n_negotiate(conn, &blocked) < 0) {
    ... error ...
}

/* Write data to the connection */
int bytes_written;
bytes_written = s2n_send(conn, "Hello World", sizeof("Hello World"), &blocked);

For details on building the s2n-tls library and how to use s2n-tls in an application you are developing, see the Usage Guide.

s2n-tls features

s2n-tls implements SSLv3, TLS1.0, TLS1.1, TLS1.2, and TLS1.3. For encryption, s2n-tls supports 128-bit and 256-bit AES in the CBC and GCM modes, ChaCha20, 3DES, and RC4. For forward secrecy, s2n-tls supports both DHE and ECDHE. s2n-tls also supports the Server Name Indicator (SNI), Application-Layer Protocol Negotiation (ALPN), and Online Certificate Status Protocol (OCSP) TLS extensions. SSLv3, RC4, 3DES, and DHE are each disabled by default for security reasons.

As it can be difficult to keep track of which encryption algorithms and protocols are best to use, s2n-tls features a simple API to use the latest "default" set of preferences. If you prefer to remain on a specific version for backwards compatibility, that is also supported.

/* Use the latest s2n-tls "default" set of ciphersuite and protocol preferences */
s2n_config_set_cipher_preferences(config, "default");

/* Use a specific set of preferences, update when you're ready */
s2n_config_set_cipher_preferences(config, "20150306")

s2n-tls safety mechanisms

Internally s2n-tls takes a systematic approach to data protection and includes several mechanisms designed to improve safety.

Small and auditable code base

Ignoring tests, blank lines and comments, s2n-tls is about 6,000 lines of code. s2n's code is also structured and written with a focus on reviewability. All s2n-tls code is subject to code review, and we plan to complete security evaluations of s2n-tls on an annual basis.

To date there have been two external code-level reviews of s2n-tls, including one by a commercial security vendor. s2n-tls has also been shared with some trusted members of the broader cryptography, security, and Open Source communities. Any issues discovered are always recorded in the s2n-tls issue tracker.

Static analysis, fuzz-testing and penetration testing

In addition to code reviews, s2n-tls is subject to regular static analysis, fuzz-testing, and penetration testing. Several penetration tests have occurred, including two by commercial vendors.

Unit tests and end-to-end testing

s2n-tls includes positive and negative unit tests and end-to-end test cases.

Unit test coverage can be viewed here. Note that this represents unit coverage for a particular build. Since that build won't necessarily support all s2n-tls features, test coverage may be artificially lowered.

Erase on read

s2n-tls encrypts or erases plaintext data as quickly as possible. For example, decrypted data buffers are erased as they are read by the application.

Built-in memory protection

s2n-tls uses operating system features to protect data from being swapped to disk or appearing in core dumps.

Minimalist feature adoption

s2n-tls avoids implementing rarely used options and extensions, as well as features with a history of triggering protocol-level vulnerabilities. For example there is no support for session renegotiation or DTLS.

Compartmentalized random number generation

The security of TLS and its associated encryption algorithms depends upon secure random number generation. s2n-tls provides every thread with two separate random number generators. One for "public" randomly generated data that may appear in the clear, and one for "private" data that should remain secret. This approach lessens the risk of potential predictability weaknesses in random number generation algorithms from leaking information across contexts.

Modularized encryption

s2n-tls has been structured so that different encryption libraries may be used. Today s2n-tls supports OpenSSL (versions 1.0.2, 1.1.1 and 3.0.x), LibreSSL, BoringSSL, AWS-LC, and the Apple Common Crypto framework to perform the underlying cryptographic operations.

Timing blinding

s2n-tls includes structured support for blinding time-based side-channels that may leak sensitive data. For example, if s2n-tls fails to parse a TLS record or handshake message, s2n-tls will add a randomized delay of between 10 and 30 seconds, granular to nanoseconds, before responding. This raises the complexity of real-world timing side-channel attacks by a factor of at least tens of trillions.

Table based state-machines

s2n-tls uses simple tables to drive the TLS/SSL state machines, making it difficult for invalid out-of-order states to arise.

C safety

s2n-tls is written in C, but makes light use of standard C library functions and wraps all memory handling, string handling, and serialization in systematic boundary-enforcing checks.

Security issue notifications

If you discover a potential security issue in s2n-tls we ask that you notify AWS Security via our vulnerability reporting page. Please do not create a public github issue.

If you package or distribute s2n-tls, or use s2n-tls as part of a large multi-user service, you may be eligible for pre-notification of future s2n-tls releases. Please contact [email protected].

Contributing to s2n-tls

If you are interested in contributing to s2n-tls, please see our development guide.

Language Bindings for s2n-tls

See our language bindings list for language bindings for s2n-tls that we're aware of.

s2n-tls's People

Contributors

achudnov avatar alexeblee avatar alexw91 avatar andrewhop avatar baekkyok avatar baldwinmatt avatar bbutch avatar bpdavidson avatar camshaft avatar colmmacc avatar danielsn avatar dougch avatar fatrat1117 avatar feliperodri avatar goatgoose avatar harrisonkaiser avatar jldodds avatar jmayclin avatar jonathanhenson avatar lrstewart avatar maddeleine avatar ntc2 avatar raycoll avatar rday avatar tawdry-audrey avatar toidiu avatar ttjsu-aws avatar wesleyrosenblum avatar xonatius avatar zz85 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

s2n-tls's Issues

Missing Apache source headers

I noticed the following files were missing Apache headers.

./error/s2n_errno.c
./error/s2n_errno.h
./tls/s2n_cbc.c

Happy to add them. I don't have private repos setup for my account, so didn't do a PR.

I've got the change done and 'make' succeeded. Didn't want to commit without your okay.

s2nc fails to link on arm

Attempting to build on a Debian stable armhf system. I was building against libssl1.0.2c

cc -pedantic -Wall -Werror -Wimplicit -Wunused -Wcomment -Wchar-subscripts -Wuninitialized -Wshadow -Wcast-qual -Wcast-align -Wwrite-strings -Wstack-protector -fPIC -std=c99 -D_POSIX_C_SOURCE=200112L -fstack-protector-all -O2 -I../libcrypto-root/include/ -I../api/ -I../ -Wno-deprecated-declarations -Wno-unknown-pragmas -Wformat-security -D_FORTIFY_SOURCE=2 s2nc.c echo.c  -o s2nc -L../lib/ -ls2n -ldl -lrt -lpthread
/usr/bin/ld: s2nc: hidden symbol `pthread_atfork' in /usr/lib/arm-linux-gnueabihf/libpthread_nonshared.a(pthread_atfork.oS) is referenced by DSO
/usr/bin/ld: final link failed: Bad value
gcc (Debian 4.9.2-10) 4.9.2
4:4.9.2-2
GNU ld (GNU Binutils for Debian) 2.25
2.25-5

Support ECDSA signatures

At present s2n supports RSA signatures from certificates, it would be great to also support ECDSA. Realistically this issue depends on implementing #3 (support for multiple certificates) first.

Note: some versions of safari claim to support ECDSA, but do not.

Issues around including a PRNG

Right now s2n uses /dev/urandom for all entropy, per the example of the excellent NaCL library, best summarized by Thomas Ptacek: http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/ .

The performance problem with urandom

The problem with using /dev/urandom though is that it is slow; at present it is the main (and really only) performance bottleneck in s2n. Reading from /dev/urandom involves kernel level locks and context switching. A quick benchmark shows that it's about a hundred times slower than using an in-process PRNG.

Will a PRNG work?

A modern PRNG should be safe to generate unpredictable and randomly distributed data once it has been seeded with about 256 bits of meaningful entropy, an in-process PRNG can be secure in that sense.

Unfortunately PRNGs are also inherently stateful and it is very difficult to guarantee that the internal state won't be replicated between processes. C99 does offer strong guarantees around thread local storage and it's relatively easy to ensure that two threads are seeded independently, but so far I've found no ironclad way to ensure that a fork() , or worse ... syscall(SYS_fork...) won't result in two processes having identically seeded PRNGs. This is particularly bad with TLS, because randomly-distributed data can sometimes be public (explicit IVs) and sometimes be very sensitive and private (PFS key generation).

One initially promising solution is to guard access to the PRNG with a getpid() call, and to detect changes in PID and reseed when needed. Unfortunately this also turns out not to be reliable: http://yarchive.net/comp/linux/getpid_caching.html libc can cache the PID value and get it wrong in some circumstances.

Why this matters

Since it's feasible that s2n will be used inside language runtimes (e.g. the JVM, Ruby, Python ..), it's not unrealistic to expect the calling application to call fork(), vfork() or even syscall(SYS_fork) , it's best to protect against this in a robust way.

Potential solutions

If getentropy()/getrandom() have better locking/performance semantics, using them may help, but these are not widely available. Another solution maybe to use the RDRAND instruction directly where available, but this comes with its own challenges. See also djb's write up at: http://blog.cr.yp.to/20140205-entropy.html.

Support for privilege seperation

There is no real need for RSA/ECDSA keys to reside in the same process as the user-application, or for that matter for the ephemeral keys used to encrypt data. TLS permits at least three process model;

  • Process 1: Use RSA/ECDSA keys to sign/decrypt when needed
  • Process 2: Use AES/3DES/RC4 keys to encrypt/decrypt the actual data on the wire
  • Process 3: The calling application

While good for security, this kind of model might be tough to make performant; especially to privsep the 2nd process. Can we use vmsplice() to help here? are Unix pipes the way to go? or some kind of lockless ring structure using shared memory? is the additional complexity worth it?

Include regression tests for ABI stability

It should be possible with various invokations of nm/objdumb/elf-utils to ensure that s2n is remaining ABI stable (at least within reason). Adding systematic regression tests would guard against developer error.

Add an s2n_finalize()

s2n_init() opens /dev/urandom and overrides OpenSSL's entropy gathering routines, but there is no corresponding s2n_finalize() call to undo this operation.

make results in "../lib//libs2n.so: undefined reference to `EVP_DecryptFinal_ex'"

On a clean Ubuntu 14.04, with a uptodate git version of s2n, the commands

apt-get update
apt-get upgrade
apt-get install git build-essential openssl libssl-dev
git clone https://github.com/awslabs/s2n.git
cd s2n/
make clean
make

result in the errors below. Tips how to solve this are welcome.

<snip>
make -C bin
make[1]: Entering directory `/git/s2n/bin'
cc -pedantic -Wall -Werror -Wimplicit -Wunused -Wcomment -Wchar-subscripts -Wuninitialized -Wshadow -Wcast-qual -Wcast-align -Wwrite-strings -Wstack-protector -fPIC -std=c99 -D_POSIX_C_SOURCE=200112L -fstack-protector-all -O2 -I../libcrypto-root/include/ -I../api/ -I../ -Wno-deprecated-declarations -Wno-unknown-pragmas -Wformat-security -D_FORTIFY_SOURCE=2 s2nc.c echo.c  -o s2nc -L../lib/ -ls2n -ldl -lrt -lpthread
../lib//libs2n.so: undefined reference to `EVP_DecryptFinal_ex'
../lib//libs2n.so: undefined reference to `SHA224_Update'
../lib//libs2n.so: undefined reference to `ENGINE_free'
../lib//libs2n.so: undefined reference to `EC_KEY_set_public_key'
../lib//libs2n.so: undefined reference to `DHparams_dup'
../lib//libs2n.so: undefined reference to `SHA384_Init'
../lib//libs2n.so: undefined reference to `RSA_public_encrypt'
../lib//libs2n.so: undefined reference to `ENGINE_set_default'
../lib//libs2n.so: undefined reference to `EVP_aes_128_gcm'
../lib//libs2n.so: undefined reference to `ENGINE_set_init_function'
../lib//libs2n.so: undefined reference to `MD5_Final'
../lib//libs2n.so: undefined reference to `ENGINE_init'
../lib//libs2n.so: undefined reference to `RSA_size'
../lib//libs2n.so: undefined reference to `EVP_aes_256_cbc'
../lib//libs2n.so: undefined reference to `ENGINE_set_flags'
../lib//libs2n.so: undefined reference to `EC_KEY_get0_public_key'
../lib//libs2n.so: undefined reference to `ENGINE_add'
../lib//libs2n.so: undefined reference to `BN_num_bits'
../lib//libs2n.so: undefined reference to `RC4'
../lib//libs2n.so: undefined reference to `BN_bin2bn'
../lib//libs2n.so: undefined reference to `RSA_free'
../lib//libs2n.so: undefined reference to `EVP_PKEY_free'
../lib//libs2n.so: undefined reference to `EC_POINT_oct2point'
../lib//libs2n.so: undefined reference to `SHA384_Update'
../lib//libs2n.so: undefined reference to `ENGINE_new'
../lib//libs2n.so: undefined reference to `SHA224_Init'
../lib//libs2n.so: undefined reference to `SHA256_Init'
../lib//libs2n.so: undefined reference to `SHA512_Update'
../lib//libs2n.so: undefined reference to `d2i_RSAPrivateKey'
../lib//libs2n.so: undefined reference to `EVP_CIPHER_CTX_init'
../lib//libs2n.so: undefined reference to `DH_new'
../lib//libs2n.so: undefined reference to `BN_free'
../lib//libs2n.so: undefined reference to `EC_KEY_generate_key'
../lib//libs2n.so: undefined reference to `EVP_EncryptUpdate'
../lib//libs2n.so: undefined reference to `X509_get_pubkey'
../lib//libs2n.so: undefined reference to `DH_free'
../lib//libs2n.so: undefined reference to `EC_KEY_get0_group'
../lib//libs2n.so: undefined reference to `EVP_aes_128_ecb'
../lib//libs2n.so: undefined reference to `EVP_CIPHER_CTX_set_padding'
../lib//libs2n.so: undefined reference to `EVP_PKEY_get1_RSA'
../lib//libs2n.so: undefined reference to `SHA1_Update'
../lib//libs2n.so: undefined reference to `RSA_verify'
../lib//libs2n.so: undefined reference to `ENGINE_set_name'
../lib//libs2n.so: undefined reference to `EVP_DecryptInit_ex'
../lib//libs2n.so: undefined reference to `RC4_set_key'
../lib//libs2n.so: undefined reference to `EVP_EncryptFinal_ex'
../lib//libs2n.so: undefined reference to `d2i_DHparams'
../lib//libs2n.so: undefined reference to `DH_compute_key'
../lib//libs2n.so: undefined reference to `DH_generate_key'
../lib//libs2n.so: undefined reference to `BN_bn2bin'
../lib//libs2n.so: undefined reference to `SHA512_Final'
../lib//libs2n.so: undefined reference to `EVP_EncryptInit_ex'
../lib//libs2n.so: undefined reference to `EC_POINT_point2oct'
../lib//libs2n.so: undefined reference to `EVP_CIPHER_CTX_ctrl'
../lib//libs2n.so: undefined reference to `ENGINE_set_id'
../lib//libs2n.so: undefined reference to `EVP_aes_256_gcm'
../lib//libs2n.so: undefined reference to `DH_size'
../lib//libs2n.so: undefined reference to `EVP_aes_128_cbc'
../lib//libs2n.so: undefined reference to `SHA256_Final'
../lib//libs2n.so: undefined reference to `SHA1_Init'
../lib//libs2n.so: undefined reference to `SHA224_Final'
../lib//libs2n.so: undefined reference to `EC_KEY_free'
../lib//libs2n.so: undefined reference to `X509_free'
../lib//libs2n.so: undefined reference to `EVP_des_ede3_cbc'
../lib//libs2n.so: undefined reference to `d2i_X509'
../lib//libs2n.so: undefined reference to `SHA256_Update'
../lib//libs2n.so: undefined reference to `RSA_sign'
../lib//libs2n.so: undefined reference to `EC_GROUP_get_degree'
../lib//libs2n.so: undefined reference to `EVP_DecryptUpdate'
../lib//libs2n.so: undefined reference to `MD5_Init'
../lib//libs2n.so: undefined reference to `ENGINE_set_RAND'
../lib//libs2n.so: undefined reference to `MD5_Update'
../lib//libs2n.so: undefined reference to `EC_POINT_free'
../lib//libs2n.so: undefined reference to `EC_POINT_new'
../lib//libs2n.so: undefined reference to `RSA_private_decrypt'
../lib//libs2n.so: undefined reference to `ECDH_compute_key'
../lib//libs2n.so: undefined reference to `SHA1_Final'
../lib//libs2n.so: undefined reference to `EC_KEY_new_by_curve_name'
../lib//libs2n.so: undefined reference to `ENGINE_by_id'
../lib//libs2n.so: undefined reference to `EVP_CIPHER_CTX_cleanup'
../lib//libs2n.so: undefined reference to `SHA512_Init'
collect2: error: ld returned 1 exit status
make[1]: *** [s2nc] Error 1
make[1]: Leaving directory `/git/s2n/bin'
make: *** [bin] Error 2

The file /usr/include/openssl/evp.h is there:

# grep -irn EVP_DecryptFinal_ex *
crypto/s2n_aead_cipher_aes_gcm.c:103:    if (EVP_DecryptFinal_ex(&key->native_format.evp_cipher_ctx, out_data, &out_len) != 1) {

# grep -irn EVP_DecryptFinal_ex /usr/include/
/usr/include/openssl/evp.h:596:int      EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
/usr/include/openssl/evp.h:1274:#define EVP_F_EVP_DECRYPTFINAL_EX                        101

Out of memory due to mlock

s2n_realloc call mlock. s2n_free does not call munlock. This can lead to an out of memory condition.

According to https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_MRG/1.3/html/Realtime_Reference_Guide/sect-Realtime_Reference_Guide-Memory_allocation-Using_mlock_to_avoid_memory_faults.html munlock is necessary when freeing the locked memory.

According to http://www.freebsd.org/cgi/man.cgi?query=mlock "Unlocking is performed explicitly by munlock() or implicitly by a call to munmap()"

Testing on Ubuntu 14.04.2 LTS continued use of mlock without a corresponding munlock after (can also be done before but I don't think it should) free will not allow the memory to be reused.

PIC build error ubuntu, libressl

Building commit 748ed6 of s2n on Ubuntu 14.04 x86_64 with gcc 4.8.4 and the (default) bfd linker.

I've tried libressl versions 2.2.0, 2.1.7, 2.0.5 and all produce similar errors when I try to make s2n:

gcc -shared -lc -lpthread -lrt -o libs2n.so ../utils/s2n_blob.o ../utils/s2n_mem.o ../utils/s2n_random.o ../utils/s2n_safety.o ../utils/s2n_timer.o ../stuffer/s2n_stuffer_base64.o ../stuffer/s2n_stuffer_file.o ../stuffer/s2n_stuffer.o ../stuffer/s2n_stuffer_pem.o ../stuffer/s2n_stuffer_text.o ../tls/s2n_aead.o ../tls/s2n_alerts.o ../tls/s2n_cbc.o ../tls/s2n_cipher_suites.o ../tls/s2n_client_ccs.o ../tls/s2n_client_extensions.o ../tls/s2n_client_finished.o ../tls/s2n_client_hello.o ../tls/s2n_client_key_exchange.o ../tls/s2n_config.o ../tls/s2n_connection.o ../tls/s2n_handshake_io.o ../tls/s2n_handshake.o ../tls/s2n_ocsp_stapling.o ../tls/s2n_prf.o ../tls/s2n_record_read.o ../tls/s2n_record_write.o ../tls/s2n_recv.o ../tls/s2n_send.o ../tls/s2n_server_ccs.o ../tls/s2n_server_cert.o ../tls/s2n_server_done.o ../tls/s2n_server_extensions.o ../tls/s2n_server_finished.o ../tls/s2n_server_hello.o ../tls/s2n_server_key_exchange.o ../tls/s2n_tls.o ../crypto/s2n_aead_cipher_aes_gcm.o ../crypto/s2n_cbc_cipher_3des.o ../crypto/s2n_cbc_cipher_aes.o ../crypto/s2n_dhe.o ../crypto/s2n_drbg.o ../crypto/s2n_ecc.o ../crypto/s2n_hash.o ../crypto/s2n_hmac.o ../crypto/s2n_rsa.o ../crypto/s2n_sequence.o ../crypto/s2n_stream_cipher_null.o ../crypto/s2n_stream_cipher_rc4.o ../error/s2n_errno.o ../libcrypto-root/lib/libcrypto.a
/usr/bin/ld: ../libcrypto-root/lib/libcrypto.a(libcrypto_la-cryptlib.o): relocation R_X86_64_32 against `.rodata.str1.8' can not be used when making a shared object; recompile with -fPIC
../libcrypto-root/lib/libcrypto.a: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
make[1]: *** [libs2n.so] Error 1
make[1]: Leaving directory `/home/mcarpenter/s2n/lib'
make: *** [libs] Error 2

Following the hint it's enough to do export CFLAGS=-fPIC before building libressl (2.2.0) and then s2n. (Even then the s2n build doesn't quite complete since tests fail... but one step at a time).

Is this just a doc error ("please set CFLAGS")? Or is there something more fundamentally wrong?

testlib does not include our libcrypto-build headers.

Mikko from codenomicon reported the following build error:

In file included from ../../tls/s2n_config.h:18:0,
                 from ../../tls/s2n_crypto.h:18,
                 from ../../tls/s2n_handshake.h:21,
                 from ../../tls/s2n_connection.h:23,
                 from s2n_print_connection.c:18:
../../crypto/s2n_rsa.h:18:25: fatal error: openssl/rsa.h: No such file or directory #include <openssl/rsa.h>

It looks like the problem is that our testlib/Makefile does not include the right libcrypto-build in its path. I suspect that the following patch fixes it:

diff --git a/tests/testlib/Makefile b/tests/testlib/Makefile
index beaeffa..6c19478 100644
--- a/tests/testlib/Makefile
+++ b/tests/testlib/Makefile
@@ -20,7 +20,7 @@ all: libtests2n.so libtests2n.dylib

 include ../../s2n.mk

-CFLAGS += -I../../ -I../../api/
+CFLAGS += -I../../ -I../../api/ -I../../libcrypto-root/include/
 LDFLAGS += -L../../lib/ -lcrypto -lpthread -ls2n

 libtests2n.so: ${OBJS}:

Add more systematic defenses to the stuffer

  1. It should not be possible to shrink a static stuffer; doing so can leak memory.
  2. It would be useful to add a flag tracking whether a stuffer has ever had a "raw" (direct pointer) access. If so, the stuffer should not be realloc()'d within its life-cycle; otherwise the pointers may become invalid.

Although s2n does not display these patterns, we should add systematic defenses against any future regressions.

Record layer version number is ignored.

s2n appears to be perfectly willing to accept version numbers such as 0x0000 in the record layer, and also artificially high ones such as 0x400 or 0xffff. This will lead to interoperability problems with future TLS versions.

Memory leak on realloc(3) failure.

s2n_realloc() does b->data = realloc(b->data, size) and if b->data is then NULL it returns an error. By then, the reference to the still allocated, still valid, original memory at the original b->data has been lost and the memory leaked. b->data is now NULL yet b->size isn't zero. (This is a very common pattern of error when using realloc(3).) The return value of realloc() needs storing in a temporary and the library needs to decide if b is still intended to be valid on realloc() failure. (I would expect so.)

s2n_override_openssl_random_test, Ubuntu 14.04, LibreSSL 2.2.0

After building LibreSSL with -fPIC (cf. issue #94) the build of s2n itself fails during the unit tests. I have seen two different failures after repeated build attempts.

One of them (s2n_client_extensions_test) is sporadic and mlock() related and I see a note for that in the USAGE docs so I won't consider that further here.

The other failure that I've seen is s2n_override_openssl_random_test. This fails on every invocation at test 20:

$ LD_LIBRARY_PATH=../../lib ./s2n_override_openssl_random_test
Running s2n_override_openssl_random_test.c                 ... FAILED test 20
(mock_called) == (1) is not true  (s2n_override_openssl_random_test.c line 114)
Error Message: 'no error'

Relevant lines from the test:

109     EXPECT_EQUAL(mock_called, 0);
110 
111     EXPECT_TRUE(DH_generate_key(dh_params.dh) == 1);
112 
113     /* Verify that our mock random is called and that over-riding works */
114     EXPECT_EQUAL(mock_called, 1);

from which I gather that mock_openssl_compat_rand() is not being called.

This can happen if it is actually being called but it returns early if the call to s2n_get_urandom_data() fails so this is my primary suspect for now.

 39 static int mock_openssl_compat_rand(unsigned char *buf, int num)
 40 {
 41     struct s2n_blob blob = {.data = buf, .size = num };
 42 
 43     int r = s2n_get_urandom_data(&blob);
 44     if (r < 0) {
 45         return 0;
 46     }
 47 
 48     mock_called = 1;

I'm out of time today! Will try to debug more tomorrow.

Does not handle EINTR appropriately in a few places.

At least in a few places EINTR is not handled appropriately:

  • s2n_init in ./utils/s2n_random.c for the open system call
  • s2n_stuffer_alloc_ro_from_file in ./stuffer/s2n_stuffer_file.c for the open system call
  • ./tls/s2n_recv.c:106: GUARD(usleep(delay % 1000000));
  • ./bin/echo.c:124: bytes_read = read(STDIN_FILENO, buffer, bytes_available);
  • ./bin/echo.c:91: while (poll(readers, 2, -1) > 0) {

echo is a sample application and not too important right?

Also note that the atomicity of reads and writes is weird. Sometimes, reads and writes CANNOT be interrupted and give only partial results but sometimes they can be interrupted in the middle and return less bytes than expected (but not a value of -1.) But I think that you handle that part well enough in most places.

Also, system calls such as read and write return a value of type ssize_t and not int.

Also, some tests may fail due to this stuff but they're tests so they don't matter too much.

There are a few possibilities to handle this cases.

  • Override the system's signal handlers to restart system calls (not recommended)
  • Temporally block all system signals so that system calls can not be interrupted
  • Make system calls nonblocking so that system calls can not be interrupted
  • Simply handle the EINTR error as appropriate (also remember to handle partial reads and writes)

Also note that close is an absolute pain to handle errors for and is completely fucked from a standardization point of view. I use the following hacky workaround for close but you may simply want to ignore errors from it.

my_error fd_close(int fd)
{
    my_error errnum;
    /*
     * The state of a file descriptor after close gives an EINTR
     * error
     * is unspecified by POSIX so this function avoids the problem
     * by
     * simply blocking all signals.
     */

    sigset_t sigset;

    /* First use the signal set for the full set */
    sigfillset(&sigset);

    errnum = pthread_sigmask(SIG_BLOCK, &sigset, &sigset);
    if (errnum != 0)
        return errnum;

    /* Then reuse the signal set for the old set */

    if (-1 == close(fd)) {
        errnum = errno;
        assert(errnum != 0);
    } else {
        errnum = 0;
    }

    my_error mask_errnum =
        pthread_sigmask(SIG_SETMASK, &sigset, 0);
    if (0 == errnum)
        errnum = mask_errnum;

    return errnum;
}

Support multiple certificates

At present s2n supports one certificate chain per configuration which effectively limits it to one certificate per listening IP address. It should be possible to provide s2n multiple certificates and to have s2n negotiate which certificate should be used based on 1) certificate name matching, including wildcards 2) signature algorithm type and 3) key agreement type (e.g. DSA, ECDSA, RSA ...).

TLS Session Tickets

s2n should support TLS tickets for session re-use. We should take care to ensure that TLS tickets may only be re-used when all of the TLS negotiation parameters match (e.g. SNI field ... etc). Perhaps use NaCL for encrypting the ticket.

Support OCSP stapling

s2n should support OCSP stapling. Implementing HTTP and calling an OSCP endpoint is likely overkill, but it should at least be possible for the caller to periodically provide an OCSP token.

Build on OS X failing

The build was previously working for me on OS X, but now is failing with the following error:

s2n_aead_cipher_aes_gcm.c:61:65: error: use of undeclared identifier 'EVP_CTRL_GCM_GET_TAG'
if (EVP_CIPHER_CTX_ctrl(&key->native_format.evp_cipher_ctx, EVP_CTRL_GCM_GET_TAG, S2N_TLS_GCM_TAG_LEN, tag_data) != 1) {
^
s2n_aead_cipher_aes_gcm.c:87:65: error: use of undeclared identifier 'EVP_CTRL_GCM_SET_TAG'
if (EVP_CIPHER_CTX_ctrl(&key->native_format.evp_cipher_ctx, EVP_CTRL_GCM_SET_TAG, S2N_TLS_GCM_TAG_LEN, tag_data) == 0) {
^
s2n_aead_cipher_aes_gcm.c:115:60: error: implicit declaration of function 'EVP_aes_128_gcm' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
EVP_EncryptInit_ex(&key->native_format.evp_cipher_ctx, EVP_aes_128_gcm(), NULL, NULL, NULL);
^
s2n_aead_cipher_aes_gcm.c:115:60: note: did you mean 'EVP_aes_128_ecb'?
/usr/include/openssl/evp.h:758:19: note: 'EVP_aes_128_ecb' declared here
const EVP_CIPHER EVP_aes_128_ecb(void) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
^
s2n_aead_cipher_aes_gcm.c:115:60: error: incompatible integer to pointer conversion passing 'int' to parameter of type 'const EVP_CIPHER *' (aka 'const struct evp_cipher_st *') [-Werror,-Wint-conversion]
EVP_EncryptInit_ex(&key->native_format.evp_cipher_ctx, EVP_aes_128_gcm(), NULL, NULL, NULL);
^~~~~~~~~~~~~~~~~
/usr/include/openssl/evp.h:580:62: note: passing argument to parameter 'cipher' here
int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl,
^
s2n_aead_cipher_aes_gcm.c:116:61: error: use of undeclared identifier 'EVP_CTRL_GCM_SET_IVLEN'
EVP_CIPHER_CTX_ctrl(&key->native_format.evp_cipher_ctx, EVP_CTRL_GCM_SET_IVLEN, S2N_TLS_GCM_IV_LEN, NULL);
^
s2n_aead_cipher_aes_gcm.c:127:60: error: implicit declaration of function 'EVP_aes_256_gcm' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
EVP_EncryptInit_ex(&key->native_format.evp_cipher_ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
^
s2n_aead_cipher_aes_gcm.c:127:60: note: did you mean 'EVP_aes_256_ecb'?
/usr/include/openssl/evp.h:778:19: note: 'EVP_aes_256_ecb' declared here
const EVP_CIPHER *EVP_aes_256_ecb(void) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER;
^
s2n_aead_cipher_aes_gcm.c:127:60: error: incompatible integer to pointer conversion passing 'int' to parameter of type 'const EVP_CIPHER *' (aka 'const struct evp_cipher_st *') [-Werror,-Wint-conversion]
EVP_EncryptInit_ex(&key->native_format.evp_cipher_ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
^~~~~~~~~~~~~~~~~
/usr/include/openssl/evp.h:580:62: note: passing argument to parameter 'cipher' here
int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl,
^
s2n_aead_cipher_aes_gcm.c:128:61: error: use of undeclared identifier 'EVP_CTRL_GCM_SET_IVLEN'
EVP_CIPHER_CTX_ctrl(&key->native_format.evp_cipher_ctx, EVP_CTRL_GCM_SET_IVLEN, S2N_TLS_GCM_IV_LEN, NULL);
^
s2n_aead_cipher_aes_gcm.c:139:60: error: incompatible integer to pointer conversion passing 'int' to parameter of type 'const EVP_CIPHER *' (aka 'const struct evp_cipher_st *') [-Werror,-Wint-conversion]
EVP_DecryptInit_ex(&key->native_format.evp_cipher_ctx, EVP_aes_128_gcm(), NULL, NULL, NULL);
^~~~~~~~~~~~~~~~~
/usr/include/openssl/evp.h:589:62: note: passing argument to parameter 'cipher' here
int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl,
^
s2n_aead_cipher_aes_gcm.c:140:61: error: use of undeclared identifier 'EVP_CTRL_GCM_SET_IVLEN'
EVP_CIPHER_CTX_ctrl(&key->native_format.evp_cipher_ctx, EVP_CTRL_GCM_SET_IVLEN, S2N_TLS_GCM_IV_LEN, NULL);
^
s2n_aead_cipher_aes_gcm.c:151:60: error: incompatible integer to pointer conversion passing 'int' to parameter of type 'const EVP_CIPHER *' (aka 'const struct evp_cipher_st *') [-Werror,-Wint-conversion]
EVP_DecryptInit_ex(&key->native_format.evp_cipher_ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
^~~~~~~~~~~~~~~~~
/usr/include/openssl/evp.h:589:62: note: passing argument to parameter 'cipher' here
int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl,
^
s2n_aead_cipher_aes_gcm.c:152:61: error: use of undeclared identifier 'EVP_CTRL_GCM_SET_IVLEN'
EVP_CIPHER_CTX_ctrl(&key->native_format.evp_cipher_ctx, EVP_CTRL_GCM_SET_IVLEN, S2N_TLS_GCM_IV_LEN, NULL);
^
12 errors generated.
make[1]: *
* [s2n_aead_cipher_aes_gcm.o] Error 1
make: *** [libs] Error 2

Support dynamic record sizes

s2n callers should be able to specify the maximum record size used for outbound TLS records. Some applications prefer large sizes (which optimize for throughput) and others prefer small sizes (for latency and memory conservation). These sizes should be changeable during the lifetime of a TLS session.

Alternatively, s2n could take responsibility for setting adaptive record sizes.

Additionally; for inbound record sizes it is useful to resize our buffers if the peer is sending small records, as this can conserve memory. Perhaps resize buffers to the min() of the last N records, where N ~= 5-10.

Fix memory leak around the libcrypto boundary

Several functions allocate memory through calls into libcrypto and release it upon successful completion. However the memory is not released under some error conditions which cause
the functions to return early resulting in the memory being leaked.

s2n_dh_compute_shared_secret_as_server() is called by TLS servers every time a client negotiates a session key using integer Diffie-Hellman. It makes one allocation using BN_bin2bn() to hold the client's public key. If the public key is invalid (for instance, all zeroes) the call to DH_compute_key will fail resulting in pub_key memory not being freed. With enough invocations, this could lead to memory exhaustion.

The function s2n_asn1der_to_rsa_public_key() decodes a DER-encoded certificate and extracts an RSA public key from it. Two memory allocations are made in this function by the calls to d2i_X509() and X590_get_pubkey(). Both are correctly released when the function returns. However it can return early under a few error conditions, such as if the certificate does not contain an RSA public key. In these cases the allocations are leaked. At the moment this leak affects only TLS clients since this function is only called on clients.

s2n_pkcs3_to_dh_params() is used to load integer Diffie-Hellman parameters on TLS servers. It makes one allocation using d2i_DHparams() which is not cleaned up if the parameters contain extraneous data. This function is only called during server start-up so it does not appear to be remotely exploitable.

Set up autobuilds for the this project

It would nice if pull requests were automatically built and tested to ensure there are no regressions. I'm not entirely sure how this can be done securely, a pull request may contain arbitrary code, but other projects have figured this out.

ALPN / NPN support

Callers should be able to express protocol-level preferences and have these protocols negotiated.

Tentative API:

s2n_config_set_protocol_preferences(config, "SPDY > HTTP", &err);
char *protocol = s2n_connection_get_protocol(conn, &err);

Support enqueue/dequeue or callbacks APIs

At present s2n operates directly on file descriptors. We have some applications that would prefer to handle the actual network I/O themselves and use "raw" buffers of bytes to interact with s2n.

There are two main possibilities here that we're considering:

  1. Provide an enqueue/dequeue API - are these even possible in a non-blocking way?
  2. Allow a caller to specify callbacks to be used in place of send()/recv() whenever a write or read is needed.

Add support for getentropy() and getrandom()

Some platforms have a getentropy() call for retrieving randomly generated data, Linux has recently added getrandom(), an equivalent call. s2n should support these where available and avoid using /dev/urandom.

Sending an empty certificate to s2n causes a client crash

If a server vends a 0-length certificate list, towards s2n as a client, it's possible to crash s2n when used as a client. Important note: in s2n, client mode is disabled and this issue is not trigger-able.

The crash occurs inside OpenSSL's RSA_size:

#0  0xb7e9c397 in RSA_size () from /root/s2n/s2n-master/lib/libs2n.so
#1  0xb7e84df9 in s2n_rsa_public_encrypted_size () from /root/s2n/s2n-master/lib/libs2n.so
#2  0xb7e788ef in s2n_client_key_send () from /root/s2n/s2n-master/lib/libs2n.so
#3  0xb7e7ac9e in s2n_negotiate () from /root/s2n/s2n-master/lib/libs2n.so
#4  0x08049b44 in echo ()
#5  0x080494d2 in main ()

Per https://github.com/openssl/openssl/blob/35a1cc90bc1795e8893c11e442790ee7f659fffb/crypto/rsa/rsa_crpt.c#L69 RSA_size() is referencing rsa->n, a bignum which in this case is empty.

What's happening is that we're never calling s2n_asn1der_to_rsa_public_key(), because size_of_all_certificates is 0, and so the inner while loop is never exercised. See https://github.com/awslabs/s2n/blob/e17fd1a4370ec96830cade867879fa07655130c8/tls/s2n_server_cert.c#L58

Issue reported by Mikko from Codenomicon.

The following patch fixes the issue and adds some additional checks in similar code-paths (though none are similarly vulnerable).

diff --git a/crypto/s2n_rsa.c b/crypto/s2n_rsa.c
index 34e2bd7..373bed1 100644
--- a/crypto/s2n_rsa.c
+++ b/crypto/s2n_rsa.c
@@ -95,11 +95,17 @@ int s2n_rsa_private_key_free(struct s2n_rsa_private_key *key)

 int s2n_rsa_public_encrypted_size(struct s2n_rsa_public_key *key)
 {
+    notnull_check(key->rsa);
+    notnull_check(key->rsa->n);
+
     return RSA_size(key->rsa);
 }

 int s2n_rsa_private_encrypted_size(struct s2n_rsa_private_key *key)
 {
+    notnull_check(key->rsa);
+    notnull_check(key->rsa->n);
+
     return RSA_size(key->rsa);
 }

diff --git a/tls/s2n_client_key_exchange.c b/tls/s2n_client_key_exchange.c
index 6ce1363..a979c51 100644
--- a/tls/s2n_client_key_exchange.c
+++ b/tls/s2n_client_key_exchange.c
@@ -56,6 +56,8 @@ static int s2n_rsa_client_key_recv(struct s2n_connection *conn)
     encrypted.size = s2n_stuffer_data_available(in);
     encrypted.data = s2n_stuffer_raw_read(in, length);

+    gt_check(encrypted.size, 0);
+
     /* Set rsa_failed to 1 if s2n_rsa_decrypt returns anything other than zero */
     conn->handshake.rsa_failed = !!s2n_rsa_decrypt(&conn->config->cert_and_key_pairs->private_key, &encrypted, &pms);

diff --git a/tls/s2n_server_cert.c b/tls/s2n_server_cert.c
index 6d1c3fb..ac14713 100644
--- a/tls/s2n_server_cert.c
+++ b/tls/s2n_server_cert.c
@@ -32,17 +32,17 @@ int s2n_server_cert_recv(struct s2n_connection *conn)

     GUARD(s2n_stuffer_read_uint24(&conn->handshake.io, &size_of_all_certificates));

-    if (size_of_all_certificates > s2n_stuffer_data_available(&conn->handshake.io)) {
+    if (size_of_all_certificates > s2n_stuffer_data_available(&conn->handshake.io) || size_of_all_certificates < 3) {
         S2N_ERROR(S2N_ERR_BAD_MESSAGE);
     }

-    int certificate = 0;
+    int certificate_count = 0;
     while (s2n_stuffer_data_available(&conn->handshake.io)) {
         uint32_t certificate_size;

         GUARD(s2n_stuffer_read_uint24(&conn->handshake.io, &certificate_size));

-        if (certificate_size > s2n_stuffer_data_available(&conn->handshake.io)) {
+        if (certificate_size > s2n_stuffer_data_available(&conn->handshake.io) || certificate_size == 0) {
             S2N_ERROR(S2N_ERR_BAD_MESSAGE);
         }

@@ -52,15 +52,18 @@ int s2n_server_cert_recv(struct s2n_connection *conn)
         notnull_check(asn1cert.data);

         /* TODO: certificate validation goes here */
+        gt_check(certificate_size, 0);

         /* Pull the public key from the first certificate */
-        if (certificate == 0) {
+        if (certificate_count == 0) {
             GUARD(s2n_asn1der_to_rsa_public_key(&conn->pending.server_rsa_public_key, &asn1cert));
         }

-        certificate++;
+        certificate_count++;
     }

+    gte_check(certificate_count, 1);
+
     conn->handshake.next_state = SERVER_HELLO_DONE;

     if (conn->status_type == S2N_STATUS_REQUEST_OCSP) {
diff --git a/tls/s2n_server_key_exchange.c b/tls/s2n_server_key_exchange.c
index 330ab2f..ec25dcd 100644
--- a/tls/s2n_server_key_exchange.c
+++ b/tls/s2n_server_key_exchange.c
@@ -102,6 +102,8 @@ static int s2n_ecdhe_server_key_recv(struct s2n_connection *conn)
     signature.data = s2n_stuffer_raw_read(in, signature.size);
     notnull_check(signature.data);

+    gt_check(signature_length, 0);
+
     if (s2n_rsa_verify(&conn->pending.server_rsa_public_key, &signature_hash, &signature) < 0) {
         S2N_ERROR(S2N_ERR_BAD_MESSAGE);
     }
@@ -191,6 +193,8 @@ static int s2n_dhe_server_key_recv(struct s2n_connection *conn)
     signature.data = s2n_stuffer_raw_read(in, signature.size);
     notnull_check(signature.data);

+    gt_check(signature_length, 0);
+
     if (s2n_rsa_verify(&conn->pending.server_rsa_public_key, &signature_hash, &signature) < 0) {
         S2N_ERROR(S2N_ERR_BAD_MESSAGE);
     }

Handle SIGPIPE in s2nd/s2nc

Mikko from codenomicon reported occasionally seeing SIGPIPE as an unhandled signal in s2nd. SIGPIPE can be generated when we try to write() to the remote end and the remote end has closed. I don't think that libs2n should mask this; our design is to emulate POSIX read()/write(), but we need s2nd and s2nc to be more tolerant of this. Instead of receiving the signal, it would be better to handle the error in the normal ways, with write() or read() returning negative values (or EOF for read()).

Following patch suppresses SIGPIPE:

index b0268c1..0562d53 100644
--- a/bin/s2nd.c
+++ b/bin/s2nd.c
@@ -22,6 +22,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
+#include <signal.h>
 #include <stdio.h>

 #include <errno.h>
@@ -117,6 +118,11 @@ int main(int argc, const char *argv[])
     hints.ai_family = AF_UNSPEC;
     hints.ai_socktype = SOCK_STREAM;

+    if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
+        fprintf(stderr, "Error disabling SIGPIPE\n");
+        exit(1);
+    }
+
     if ((r = getaddrinfo(argv[1], argv[2], &hints, &ai)) < 0) {
         fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(r));
         return -1;

Support cipher / key-agreement preferences

At present s2n has a single fixed ordering for cipher suites. These defaults should suit most users, but some flexibility is probably necessary.

Tentative proposal for an API:

s2n_config_set_cipher_preferences(config, "AES128 > 3DES > RC4", &err);
s2n_config_set_exchange_preferences(config, "DHE > RSA", &err);

Add support for bundling Openssl/LibreSSL/BoringSSL

Now that we're going to depend on Openssl 1.0.2, it would be nice to have clear instructions on how to build OpenSSL, or LibreSSL, or BoringSSL locally and to use those within s2n. I think we should be able to support each, it looks like they all have the APIs we're using. Additionally, we should consider using libcrypto.a - ie statically linking in libcrypto.

Cross-platform constant-time CBC validation

At present, s2n's CBC validation is not constant time. Instead s2n closes down connections on validation errors, which does make it impractical to mount alert-based timing attacks within the same TLS session. However, validating CBC records in constant time is still desirable. A nanosleep-to-deadline approach has been tested and found to work, but nanosleep is not available on older platforms. A constant-time-CPU-operation approach may be better, but will require testing on several architectures.

Make buffer limits configurable

This line makes me sad, because it can cause some hard-to-debug problems if you use larger keys:
https://github.com/awslabs/s2n/blob/4f7d3e65ac3b10518a5718b8ac592969bae7616c/crypto/s2n_rsa.c#L181

I ran into this problem on OS X and iOS (Apple also has a hard-limit of 4096bit for RSA keys) because I'm using larger (=8192bit) keys. It would be great if such things are made configurable from a central point or even made dynamic (with configurable absolute maximum to prevent DoS).

If I find some time, I may search and replace such things myself.

Configure build with existing libs

If I already have a system-wide installation of updated LibreSSL/OpenSSL libs there's no reason why I shouldn't be able to use them instead of building from scratch into libcrypto-root. How can I configure the build to use a system-wide path for those libs?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.