|
26 | 26 | #include <openssl/decoder.h> |
27 | 27 | #include <openssl/provider.h> |
28 | 28 | #endif |
| 29 | +#include <openssl/x509v3.h> |
29 | 30 | #include <sys/types.h> |
30 | 31 | #include <sys/stat.h> |
31 | 32 | #include <stdint.h> |
@@ -262,6 +263,19 @@ static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) { |
262 | 263 | return 1; |
263 | 264 | } |
264 | 265 |
|
| 266 | +/* |
| 267 | + * Override cert purpose, to accept certificates that have only |
| 268 | + * server purpose flag as client certificate (needed for s2s authentication). |
| 269 | + */ |
| 270 | +static int cert_verify_callback(X509_STORE_CTX *x509, void *ptr) { |
| 271 | + X509_VERIFY_PARAM *param = X509_STORE_CTX_get0_param(x509); |
| 272 | + if (param) { |
| 273 | + X509_VERIFY_PARAM_set_purpose(param, X509_PURPOSE_SSL_SERVER); |
| 274 | + X509_VERIFY_PARAM_set_trust(param, X509_TRUST_SSL_SERVER); |
| 275 | + } |
| 276 | + return X509_verify_cert(x509); |
| 277 | +} |
| 278 | + |
265 | 279 | /* |
266 | 280 | * ECDHE is enabled only on OpenSSL 1.0.0e and later. |
267 | 281 | * See http://www.openssl.org/news/secadv_20110906.txt |
@@ -549,6 +563,7 @@ static int ssl_sni_callback(const SSL *s, int *foo, void *data) { |
549 | 563 | #define SET_CERTIFICATE_FILE_CONNECT 2 |
550 | 564 | #define VERIFY_NONE 0x10000 |
551 | 565 | #define COMPRESSION_NONE 0x100000 |
| 566 | +#define OVERRIDE_CERT_PURPOSE 0x200000 |
552 | 567 |
|
553 | 568 | static ERL_NIF_TERM ssl_error(ErlNifEnv *env, const char *errstr) { |
554 | 569 | size_t rlen; |
@@ -579,6 +594,7 @@ static SSL_CTX *create_new_ctx(char *cert_file, char *key_file, |
579 | 594 | char *ciphers, unsigned char *dh, size_t dh_size, |
580 | 595 | char *dh_file, char *ca_file, |
581 | 596 | unsigned int command, |
| 597 | + unsigned long flags, |
582 | 598 | char **err_str) { |
583 | 599 | long verifyopts; |
584 | 600 | int res = 0; |
@@ -650,6 +666,8 @@ static SSL_CTX *create_new_ctx(char *cert_file, char *key_file, |
650 | 666 | SSL_CTX_set_mode(ctx, SSL_MODE_RELEASE_BUFFERS); |
651 | 667 | #endif |
652 | 668 | SSL_CTX_set_verify(ctx, verifyopts, verify_callback); |
| 669 | + if (flags & OVERRIDE_CERT_PURPOSE) |
| 670 | + SSL_CTX_set_cert_verify_callback(ctx, cert_verify_callback, NULL); |
653 | 671 |
|
654 | 672 | #ifndef SSL_OP_NO_RENEGOTIATION |
655 | 673 | SSL_CTX_set_info_callback(ctx, &ssl_info_callback); |
@@ -721,7 +739,7 @@ static char *create_ssl_for_cert(char *cert_file, state_t *state) { |
721 | 739 |
|
722 | 740 | enif_rwlock_rwlock(certs_map_lock); |
723 | 741 | SSL_CTX *ctx = create_new_ctx(cert_file, key_file, ciphers, dh, dh_size, |
724 | | - dh_file, ca_file, command, &ret); |
| 742 | + dh_file, ca_file, command,options & OVERRIDE_CERT_PURPOSE, &ret); |
725 | 743 | if (ret == NULL) { |
726 | 744 | new_info = enif_alloc(sizeof(cert_info_t)); |
727 | 745 | if (new_info) { |
@@ -839,7 +857,7 @@ static ERL_NIF_TERM open_nif(ErlNifEnv *env, int argc, |
839 | 857 | state->dh_file = (char*)(state->dh + dh_bin.size + 1); |
840 | 858 | state->ca_file = state->dh_file + dhfile_bin.size + 1; |
841 | 859 | sni = state->ca_file + cafile_bin.size + 1; |
842 | | - state->options = options; |
| 860 | + state->options = options | (flags & OVERRIDE_CERT_PURPOSE); |
843 | 861 | state->command = command; |
844 | 862 |
|
845 | 863 | memcpy(state->cert_file, certfile_bin.data, certfile_bin.size); |
|
0 commit comments