| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "tls.h" | ||
| 2 | #include <openssl/ssl.h> | ||
| 3 | #include <openssl/err.h> | ||
| 4 | #include <stdio.h> | ||
| 5 | #include <stdlib.h> | ||
| 6 | #include "log.h" | ||
| 7 | |||
| 8 | static const unsigned char protos[] = "\x02h2\x08http/1.1"; | ||
| 9 | static const unsigned int protos_len = 12; | ||
| 10 | |||
| 11 | static int alpn_select_cb(SSL *ssl, | ||
| 12 | const unsigned char **out, | ||
| 13 | unsigned char *outlen, | ||
| 14 | const unsigned char *in, | ||
| 15 | unsigned int inlen, | ||
| 16 | void *arg); | ||
| 17 | |||
| 18 | ✗ | SSL_CTX *create_ssl_context(const char *cert_path, const char *key_path) | |
| 19 | { | ||
| 20 | ✗ | SSL_CTX *ctx = SSL_CTX_new(TLS_server_method()); | |
| 21 | ✗ | if (!ctx) | |
| 22 | { | ||
| 23 | ✗ | log_message(LOG_LEVEL_ERROR, "Unable to create SSL context"); | |
| 24 | ✗ | return NULL; | |
| 25 | } | ||
| 26 | ✗ | SSL_CTX_set_options(ctx, | |
| 27 | SSL_OP_NO_SSLv2 | | ||
| 28 | SSL_OP_NO_SSLv3 | | ||
| 29 | SSL_OP_NO_TLSv1 | | ||
| 30 | SSL_OP_NO_TLSv1_1); | ||
| 31 | ✗ | SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); | |
| 32 | |||
| 33 | ✗ | if (SSL_CTX_set_alpn_protos(ctx, protos, protos_len) != 0) | |
| 34 | { | ||
| 35 | ✗ | log_message(LOG_LEVEL_ERROR, "Failed to set ALPN protocols"); | |
| 36 | ✗ | SSL_CTX_free(ctx); | |
| 37 | ✗ | return NULL; | |
| 38 | } | ||
| 39 | ✗ | SSL_CTX_set_alpn_select_cb(ctx, alpn_select_cb, NULL); | |
| 40 | |||
| 41 | ✗ | if (SSL_CTX_use_certificate_file(ctx, cert_path, SSL_FILETYPE_PEM) <= 0) | |
| 42 | { | ||
| 43 | ✗ | log_message(LOG_LEVEL_ERROR, "Failed to load certificate file: %s", | |
| 44 | ERR_error_string(ERR_get_error(), NULL)); | ||
| 45 | ✗ | SSL_CTX_free(ctx); | |
| 46 | ✗ | return NULL; | |
| 47 | } | ||
| 48 | ✗ | if (SSL_CTX_use_PrivateKey_file(ctx, key_path, SSL_FILETYPE_PEM) <= 0) | |
| 49 | { | ||
| 50 | ✗ | log_message(LOG_LEVEL_ERROR, "Failed to load private key file: %s", | |
| 51 | ERR_error_string(ERR_get_error(), NULL)); | ||
| 52 | ✗ | SSL_CTX_free(ctx); | |
| 53 | ✗ | return NULL; | |
| 54 | } | ||
| 55 | /* Enable session caching/resumption for faster handshakes */ | ||
| 56 | ✗ | SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER); | |
| 57 | { | ||
| 58 | ✗ | unsigned char sess_id_ctx[] = "emme"; | |
| 59 | ✗ | if (SSL_CTX_set_session_id_context(ctx, sess_id_ctx, sizeof(sess_id_ctx)) != 1) | |
| 60 | { | ||
| 61 | ✗ | log_message(LOG_LEVEL_ERROR, "Failed to set session id context"); | |
| 62 | ✗ | SSL_CTX_free(ctx); | |
| 63 | ✗ | return NULL; | |
| 64 | } | ||
| 65 | } | ||
| 66 | ✗ | return ctx; | |
| 67 | } | ||
| 68 | |||
| 69 | ✗ | static int alpn_select_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen, | |
| 70 | const unsigned char *in, unsigned int inlen, void *arg) | ||
| 71 | { | ||
| 72 | (void)ssl; | ||
| 73 | (void)arg; | ||
| 74 | ✗ | if (SSL_select_next_proto((unsigned char **)out, outlen, protos, protos_len, in, inlen) | |
| 75 | != OPENSSL_NPN_NEGOTIATED) | ||
| 76 | { | ||
| 77 | ✗ | return SSL_TLSEXT_ERR_NOACK; | |
| 78 | } | ||
| 79 | ✗ | return SSL_TLSEXT_ERR_OK; | |
| 80 | } | ||
| 81 | |||
| 82 | ✗ | void cleanup_ssl_context(SSL_CTX *ctx) | |
| 83 | { | ||
| 84 | ✗ | SSL_CTX_free(ctx); | |
| 85 | ✗ | EVP_cleanup(); | |
| 86 | ✗ | } | |
| 87 |