27 #include <openssl/x509_vfy.h> 28 #include <openssl/dh.h> 29 #include <openssl/bn.h> 39 err_cert = X509_STORE_CTX_get_current_cert(ctx);
40 err = X509_STORE_CTX_get_error(ctx);
41 depth = X509_STORE_CTX_get_error_depth(ctx);
46 if (!preverify_ok && err == X509_V_ERR_UNABLE_TO_GET_CRL) {
47 _sx_debug(
ZONE,
"ignoring verify error:num=%d:%s:depth=%d:%s\n", err,
48 X509_verify_cert_error_string(err), depth, buf);
56 X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256);
60 X509_verify_cert_error_string(err), depth, buf);
71 if (!preverify_ok && (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT))
73 X509_NAME_oneline(X509_get_issuer_name(err_cert), buf, 256);
82 strncpy(buf, (
char *)(password), size);
87 #define DECLARE_sx_ssl_getparams(name, type) \ 88 static type *sx_ssl_get_##name(const char *file) { \ 91 if ((bio = BIO_new_file(file, "r")) == NULL) \ 93 ret = PEM_read_bio_##name(bio, NULL, NULL, NULL); \ 101 BIGNUM *(*
const get_prime)(BIGNUM *);
103 const unsigned minlen;
105 { get_rfc3526_prime_8192, NULL, 6145 },
106 { get_rfc3526_prime_6144, NULL, 4097 },
107 { get_rfc3526_prime_4096, NULL, 3073 },
108 { get_rfc3526_prime_3072, NULL, 2049 },
109 { get_rfc3526_prime_2048, NULL, 1025 },
110 { get_rfc2409_prime_1024, NULL, 0 }
118 #if OPENSSL_VERSION_NUMBER < 0x10100005L 119 dh->p = get_prime(NULL);
120 BN_dec2bn(&dh->g, gen);
121 if (!dh->p || !dh->g) {
127 BIGNUM *p, *g = NULL;
131 if (p == NULL || g == NULL || !DH_set0_pqg(dh, p, NULL, g)) {
151 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
152 int type = pkey ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE;
155 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA)
156 keylen = EVP_PKEY_bits(pkey);
190 char *ns = NULL, *to = NULL, *from = NULL, *version = NULL;
208 _sx_debug(
ZONE,
"starttls requested on already encrypted channel, dropping packet");
214 _sx_debug(
ZONE,
"starttls requested on already compressed channel, dropping packet");
237 if(s->
ns != NULL) ns = strdup(s->
ns);
252 if(ns != NULL) free(ns);
253 if(to != NULL) free(to);
254 if(from != NULL) free(from);
255 if(version != NULL) free(version);
268 if( ((_sx_ssl_conn_t)s->
plugin_data[p->
index])->private_key_password != NULL )
274 _sx_debug(
ZONE,
"server can't handle ssl, business as usual");
309 X509_NAME_ENTRY *entry;
311 X509_EXTENSION *extension;
312 STACK_OF(GENERAL_NAME) *altnames;
313 GENERAL_NAME *altname;
314 OTHERNAME *othername;
317 int id_on_xmppAddr_nid;
318 ASN1_OBJECT *id_on_xmppAddr_obj;
320 int i, j, count,
id = 0, len;
323 if ((cert = SSL_get_peer_certificate(sc->ssl) ) == NULL)
328 id_on_xmppAddr_nid = OBJ_create(
"1.3.6.1.5.5.7.8.5",
"id-on-xmppAddr",
"XMPP Address Identity");
329 id_on_xmppAddr_obj = OBJ_nid2obj(id_on_xmppAddr_nid);
330 _sx_debug(
ZONE,
"external_id: Created id-on-xmppAddr SSL object");
333 for (i = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1);
335 i = X509_get_ext_by_NID(cert, NID_subject_alt_name, i)) {
337 if ((extension = X509_get_ext(cert, i)) == NULL) {
338 _sx_debug(
ZONE,
"external_id: Can't get subjectAltName. Possibly malformed cert.");
342 if ((altnames = X509V3_EXT_d2i(extension)) == NULL) {
343 _sx_debug(
ZONE,
"external_id: Can't get all AltNames. Possibly malformed cert.");
347 count = sk_GENERAL_NAME_num(altnames);
348 for (j = 0; j < count; j++) {
349 if ((altname = sk_GENERAL_NAME_value(altnames, j)) == NULL) {
350 _sx_debug(
ZONE,
"external_id: Can't get AltName. Possibly malformed cert.");
354 if (altname->type == GEN_OTHERNAME &&
355 OBJ_cmp(altname->d.otherName->type_id, id_on_xmppAddr_obj) == 0) {
356 othername = altname->d.otherName;
357 len = ASN1_STRING_to_UTF8((
unsigned char **) &buff, othername->value->value.utf8string);
360 sc->external_id[id] = (
char *) malloc(
sizeof(
char) * (len + 1));
361 memcpy(sc->external_id[
id], buff, len);
362 sc->external_id[id][len] =
'\0';
363 _sx_debug(
ZONE,
"external_id: Found(%d) subjectAltName/id-on-xmppAddr: '%s'",
id, sc->external_id[
id]);
366 }
else if (altname->type == GEN_DNS) {
367 len = ASN1_STRING_length(altname->d.dNSName);
368 sc->external_id[id] = (
char *) malloc(
sizeof(
char) * (len + 1));
369 #if OPENSSL_VERSION_NUMBER < 0x10100005L 370 memcpy(sc->external_id[
id], ASN1_STRING_data(altname->d.dNSName), len);
372 memcpy(sc->external_id[
id], ASN1_STRING_get0_data(altname->d.dNSName), len);
374 sc->external_id[id][len] =
'\0';
375 _sx_debug(
ZONE,
"external_id: Found(%d) subjectAltName/dNSName: '%s'",
id, sc->external_id[
id]);
380 sk_GENERAL_NAME_pop_free(altnames, GENERAL_NAME_free);
385 sk_GENERAL_NAME_pop_free(altnames, GENERAL_NAME_free);
388 name = X509_get_subject_name(cert);
389 for (i = X509_NAME_get_index_by_NID(name, NID_commonName, -1);
391 i = X509_NAME_get_index_by_NID(name, NID_commonName, i)) {
393 if ((entry = X509_NAME_get_entry(name, i)) == NULL) {
394 _sx_debug(
ZONE,
"external_id: Can't get commonName(%d). Possibly malformed cert. Continuing.", i);
398 len = ASN1_STRING_to_UTF8((
unsigned char **) &buff, X509_NAME_ENTRY_get_data(entry));
402 sc->external_id[id] = (
char *) malloc(
sizeof(
char) * (len + 1));
403 memcpy(sc->external_id[
id], buff, len);
404 sc->external_id[id][len] =
'\0';
405 _sx_debug(
ZONE,
"external_id: Found(%d) commonName: '%s'",
id, sc->external_id[
id]);
424 while(!SSL_is_init_finished(sc->ssl)) {
425 _sx_debug(
ZONE,
"secure channel not established, handshake in progress");
428 if(sc->last_state == SX_SSL_STATE_WANT_READ && BIO_pending(sc->rbio) == 0)
433 ret = SSL_connect(sc->ssl);
435 ret = SSL_accept(sc->ssl);
440 sc->last_state = SX_SSL_STATE_NONE;
442 s->
ssf = SSL_get_cipher_bits(sc->ssl, NULL);
444 _sx_debug(
ZONE,
"using cipher %s (%d bits)", SSL_get_cipher_name(sc->ssl), s->
ssf);
452 err = SSL_get_error(sc->ssl, ret);
454 if(err == SSL_ERROR_WANT_READ)
455 sc->last_state = SX_SSL_STATE_WANT_READ;
456 else if(err == SSL_ERROR_WANT_WRITE)
457 sc->last_state = SX_SSL_STATE_WANT_WRITE;
461 sc->last_state = SX_SSL_STATE_ERROR;
463 errstring = ERR_error_string(ERR_get_error(), NULL);
493 if(sc->last_state == SX_SSL_STATE_ERROR)
520 ret = SSL_write(sc->ssl, wbuf->data, wbuf->len);
526 jqueue_push(sc->wq, wbuf, (sc->wq->front != NULL) ? sc->wq->front->priority + 1 : 0);
529 err = SSL_get_error(sc->ssl, ret);
531 if(err == SSL_ERROR_ZERO_RETURN) {
536 if(err == SSL_ERROR_WANT_READ) {
539 sc->last_state = SX_SSL_STATE_WANT_READ;
543 sc->last_state = SX_SSL_STATE_ERROR;
546 errstring = ERR_error_string(ERR_get_error(), NULL);
566 if(BIO_pending(sc->wbio) > 0) {
567 int bytes_pending = BIO_pending(sc->wbio);
568 assert(buf->
len == 0);
570 BIO_read(sc->wbio, buf->
data, bytes_pending);
571 buf->
len += bytes_pending;
575 buf->
notify = wbuf->notify;
584 if(sc->last_state == SX_SSL_STATE_WANT_READ || sc->last_state == SX_SSL_STATE_NONE)
592 int est, ret, err, pending;
597 if(sc->last_state == SX_SSL_STATE_ERROR)
606 BIO_write(sc->rbio, buf->
data, buf->
len);
619 pending = SSL_pending(sc->ssl);
621 pending = BIO_pending(sc->rbio);
624 while((pending = SSL_pending(sc->ssl)) > 0 || (pending = BIO_pending(sc->rbio)) > 0) {
627 ret = SSL_read(sc->ssl, &(buf->
data[buf->
len]), pending);
637 if (SSL_get_shutdown(sc->ssl) == SSL_RECEIVED_SHUTDOWN)
648 err = SSL_get_error(sc->ssl, ret);
653 if(err == SSL_ERROR_ZERO_RETURN) {
664 err = SSL_get_error(sc->ssl, ret);
667 if(err == SSL_ERROR_WANT_READ) {
668 sc->last_state = SX_SSL_STATE_WANT_READ;
679 sc->last_state = SX_SSL_STATE_ERROR;
681 errstring = ERR_error_string(ERR_get_error(), NULL);
703 if(BIO_pending(sc->wbio) > 0 || (est > 0 &&
jqueue_size(sc->wq) > 0))
707 if(sc->last_state == SX_SSL_STATE_WANT_READ || sc->last_state == SX_SSL_STATE_NONE)
719 char *pemfile = NULL;
721 char *pemfile_password = NULL;
737 assert((
int) (ctx != NULL));
739 sc = (_sx_ssl_conn_t) calloc(1,
sizeof(
struct _sx_ssl_conn_st));
742 sc->rbio = BIO_new(BIO_s_mem());
743 sc->wbio = BIO_new(BIO_s_mem());
746 sc->ssl = SSL_new(ctx);
747 SSL_set_bio(sc->ssl, sc->rbio, sc->wbio);
748 SSL_set_connect_state(sc->ssl);
750 #if OPENSSL_VERSION_NUMBER < 0x10100005L 751 #ifdef ENABLE_EXPERIMENTAL 752 SSL_set_ssl_method(sc->ssl, TLSv1_2_client_method());
754 SSL_set_ssl_method(sc->ssl, TLSv1_client_method());
757 SSL_set_ssl_method(sc->ssl, TLS_client_method());
762 sc->external_id[i] = NULL;
771 pemfile_password = ((_sx_ssl_conn_t)s->
plugin_data[p->
index])->private_key_password;
775 if(pemfile != NULL) {
777 ret = SSL_use_certificate_file(sc->ssl, pemfile, SSL_FILETYPE_PEM);
779 _sx_debug(
ZONE,
"couldn't load alternate certificate from %s", pemfile);
787 SSL_CTX_set_default_passwd_cb_userdata(ctx, (
void *)pemfile_password);
791 ret = SSL_use_PrivateKey_file(sc->ssl, pemfile, SSL_FILETYPE_PEM);
793 _sx_debug(
ZONE,
"couldn't load alternate private key from %s", pemfile);
801 ret = SSL_check_private_key(sc->ssl);
803 _sx_debug(
ZONE,
"private key does not match certificate public key");
843 assert((
int) (ctx != NULL));
845 sc = (_sx_ssl_conn_t) calloc(1,
sizeof(
struct _sx_ssl_conn_st));
848 sc->rbio = BIO_new(BIO_s_mem());
849 sc->wbio = BIO_new(BIO_s_mem());
852 sc->ssl = SSL_new(ctx);
853 SSL_set_bio(sc->ssl, sc->rbio, sc->wbio);
854 SSL_set_accept_state(sc->ssl);
855 SSL_set_options(sc->ssl, SSL_OP_NO_SSLv3);
859 sc->external_id[i] = NULL;
887 if(sc->external_id[i] != NULL)
888 free(sc->external_id[i]);
892 if(sc->pemfile != NULL) free(sc->pemfile);
894 if(sc->private_key_password != NULL) free(sc->private_key_password);
896 if(sc->ssl != NULL) SSL_free(sc->ssl);
917 SSL_CTX_free((SSL_CTX *) ctx);
929 const char *name, *pemfile, *cachain, *password, *ciphers;
935 name = va_arg(args,
const char *);
936 pemfile = va_arg(args,
const char *);
943 cachain = va_arg(args,
const char *);
944 mode = va_arg(args,
int);
945 password = va_arg(args,
char *);
946 ciphers = va_arg(args,
char *);
953 SSL_load_error_strings();
981 STACK_OF(X509_NAME) *cert_names;
985 EC_KEY *eckey = NULL;
1003 #if OPENSSL_VERSION_NUMBER < 0x10100005L 1004 #ifdef ENABLE_EXPERIMENTAL 1005 ctx = SSL_CTX_new(TLSv1_2_method());
1007 ctx = SSL_CTX_new(SSLv23_method());
1010 ctx = SSL_CTX_new(TLS_method());
1013 _sx_debug(
ZONE,
"ssl context creation failed; %s", ERR_error_string(ERR_get_error(), NULL));
1019 ciphers =
"!aNULL:!eNULL:!EXP:" SSL_DEFAULT_CIPHER_LIST;
1021 if (SSL_CTX_set_cipher_list(ctx, ciphers) != 1) {
1022 _sx_debug(
ZONE,
"Can't set cipher list for SSL context: %s", ERR_error_string(ERR_get_error(), NULL));
1028 if (cachain != NULL) {
1029 ret = SSL_CTX_load_verify_locations (ctx, cachain, NULL);
1031 _sx_debug(
ZONE,
"WARNING: couldn't load CA chain: %s; %s", cachain, ERR_error_string(ERR_get_error(), NULL));
1033 _sx_debug(
ZONE,
"Loaded CA verify location chain: %s", cachain);
1035 cert_names = SSL_load_client_CA_file(cachain);
1036 if (cert_names != NULL) {
1037 SSL_CTX_set_client_CA_list(ctx, cert_names);
1040 _sx_debug(
ZONE,
"WARNING: couldn't load client CA chain: %s", cachain);
1048 SSL_CTX_set_default_verify_paths(ctx);
1049 _sx_debug(
ZONE,
"No CA chain specified. Loading SSL default CA certs: /etc/ssl/certs");
1052 store = SSL_CTX_get_cert_store(ctx);
1055 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK);
1058 ret = SSL_CTX_use_certificate_chain_file(ctx, pemfile);
1060 _sx_debug(
ZONE,
"couldn't load certificate from %s; %s", pemfile, ERR_error_string(ERR_get_error(), NULL));
1066 SSL_CTX_set_default_passwd_cb_userdata(ctx, (
void *)password);
1070 ret = SSL_CTX_use_PrivateKey_file(ctx, pemfile, SSL_FILETYPE_PEM);
1072 _sx_debug(
ZONE,
"couldn't load private key from %s; %s", pemfile, ERR_error_string(ERR_get_error(), NULL));
1078 ret = SSL_CTX_check_private_key(ctx);
1080 _sx_debug(
ZONE,
"private key does not match certificate public key; %s", ERR_error_string(ERR_get_error(), NULL));
1085 _sx_debug(
ZONE,
"setting ssl context '%s' verify mode to %02x", name, mode);
1091 if((
dhparams = sx_ssl_get_DHparams(pemfile))) {
1093 #if OPENSSL_VERSION_NUMBER < 0x10100005L 1101 if((ecparams = sx_ssl_get_ECPKParameters(pemfile)) && (nid = EC_GROUP_get_curve_name(ecparams)) && (eckey = EC_KEY_new_by_curve_name(nid))) {
1102 SSL_CTX_set_tmp_ecdh(ctx, eckey);
1103 _sx_debug(
ZONE,
"custom ECDH curve %s loaded from certificate", OBJ_nid2sn(nid));
1106 #if defined(SSL_set_ecdh_auto) 1108 SSL_CTX_set_ecdh_auto(ctx, 1);
1112 eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
1113 SSL_CTX_set_tmp_ecdh(ctx, eckey);
1119 if(contexts == NULL) {
1121 p->
private = (
void *) contexts;
1124 if(!(name[0] ==
'*' && name[1] == 0)) {
1136 _sx_debug(
ZONE,
"ssl context '%s' initialised; certificate and key loaded from %s", name, pemfile);
1141 SSL_CTX_free((SSL_CTX *) tmp);
1149 assert((
int) (p != NULL));
1150 assert((
int) (s != NULL));
1154 _sx_debug(
ZONE,
"wrong conn type or state for client starttls");
1167 if(pemfile != NULL) {
1168 s->
plugin_data[p->
index] = (_sx_ssl_conn_t) calloc(1,
sizeof(
struct _sx_ssl_conn_st));
1172 if(private_key_password != NULL)
1173 ((_sx_ssl_conn_t)s->
plugin_data[p->
index])->private_key_password = strdup(private_key_password);
#define stream_err_UNDEFINED_CONDITION
void(* free)(sx_t s, sx_plugin_t p)
#define _sx_event(s, e, data)
void(* server)(sx_t s, sx_plugin_t p)
static DH * _sx_ssl_tmp_dh_callback(SSL *ssl, int export, int keylen)
static int _sx_pem_passwd_callback(char *buf, int size, int rwflag, void *password)
void(* unload)(sx_plugin_t p)
int jqueue_size(jqueue_t q)
void(* features)(sx_t s, sx_plugin_t p, nad_t nad)
error info for event_ERROR
int sx_ssl_server_addcert(sx_plugin_t p, const char *name, const char *pemfile, const char *cachain, int mode, const char *password, const char *ciphers)
args: name, pemfile, cachain, mode
int nad_add_namespace(nad_t nad, const char *uri, const char *prefix)
bring a new namespace into scope
void sx_server_init(sx_t s, unsigned int flags)
static int _sx_ssl_process(sx_t s, sx_plugin_t p, nad_t nad)
void _sx_chain_io_plugin(sx_t s, sx_plugin_t p)
int nad_append_elem(nad_t nad, int ns, const char *name, int depth)
create a new elem on the list
void nad_free(nad_t nad)
free that nad
int xhash_iter_next(xht h)
static void _sx_ssl_starttls_notify_proceed(sx_t s, void *arg)
#define SX_ERR_SSL
error codes
static void _sx_ssl_features(sx_t s, sx_plugin_t p, nad_t nad)
void jqueue_free(jqueue_t q)
void _sx_buffer_alloc_margin(sx_buf_t buf, int before, int after)
utility: ensure a certain amount of allocated space adjacent to buf->data
static DH * sx_ssl_make_dh_params(BIGNUM *(*const get_prime)(BIGNUM *), const char *gen)
holds the state for a single stream
#define SX_SSL_MAGIC
magic numbers, so plugins can find each other
void sx_client_init(sx_t s, unsigned int flags, const char *ns, const char *to, const char *from, const char *version)
#define NAD_ENAME_L(N, E)
void jqueue_push(jqueue_t q, void *data, int priority)
#define NAD_NURI_L(N, NS)
static int _sx_ssl_wio(sx_t s, sx_plugin_t p, sx_buf_t buf)
void xhash_put(xht h, const char *key, void *val)
static void _sx_ssl_server(sx_t s, sx_plugin_t p)
#define SX_SSL_STARTTLS_OFFER
void _sx_buffer_free(sx_buf_t buf)
utility: kill a buffer
sx_buf_t _sx_buffer_new(const char *data, int len, _sx_notify_t notify, void *notify_arg)
utility: make a new buffer if len>0 but data is NULL, the buffer will contain that many bytes of garb...
static void sx_ssl_free_dh_params(void)
int xhash_iter_get(xht h, const char **key, int *keylen, void **val)
static void _sx_ssl_unload(sx_plugin_t p)
#define SX_ERR_STARTTLS_FAILURE
static int _sx_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
this plugin implements the traditional SSL "wrappermode" streams and STARTTLS extension documented in...
static void _sx_ssl_client(sx_t s, sx_plugin_t p)
#define SX_SSL_STARTTLS_REQUIRE
static void _sx_ssl_get_external_id(sx_t s, _sx_ssl_conn_t sc)
void sx_error(sx_t s, int err, const char *text)
void _sx_reset(sx_t s)
utility; reset stream state
int sx_openssl_initialized
void _sx_close(sx_t s)
close a stream
void * jqueue_pull(jqueue_t q)
int xhash_iter_first(xht h)
iteration
jqueue_t jqueue_new(void)
int sx_ssl_init(sx_env_t env, sx_plugin_t p, va_list args)
args: name, pemfile, cachain, mode
int(* wio)(sx_t s, sx_plugin_t p, sx_buf_t buf)
void _sx_buffer_clear(sx_buf_t buf)
utility: clear out a buffer, but don't deallocate it
#define DECLARE_sx_ssl_getparams(name, type)
void * xhash_get(xht h, const char *key)
#define SX_SSL_WRAPPER
sx stream flags
#define _sx_gen_error(e, c, g, s)
helper macro to populate this struct
int(* process)(sx_t s, sx_plugin_t p, nad_t nad)
int(* rio)(sx_t s, sx_plugin_t p, sx_buf_t buf)
static int _sx_ssl_handshake(sx_t s, _sx_ssl_conn_t sc)
#define SX_CONN_EXTERNAL_ID_MAX_COUNT
int sx_ssl_client_starttls(sx_plugin_t p, sx_t s, const char *pemfile, const char *private_key_password)
void(* client)(sx_t s, sx_plugin_t p)
static void _sx_ssl_free(sx_t s, sx_plugin_t p)
cleanup
static int _sx_ssl_rio(sx_t s, sx_plugin_t p, sx_buf_t buf)
#define SX_COMPRESS_WRAPPER