diff options
Diffstat (limited to 'src/nxt_openssl.c')
-rw-r--r-- | src/nxt_openssl.c | 179 |
1 files changed, 54 insertions, 125 deletions
diff --git a/src/nxt_openssl.c b/src/nxt_openssl.c index 273ca7f4..1e08015e 100644 --- a/src/nxt_openssl.c +++ b/src/nxt_openssl.c @@ -16,18 +16,32 @@ typedef struct { - SSL *session; - nxt_conn_t *conn; + SSL *session; + nxt_conn_t *conn; - int ssl_error; - uint8_t times; /* 2 bits */ - uint8_t handshake; /* 1 bit */ + int ssl_error; + uint8_t times; /* 2 bits */ + uint8_t handshake; /* 1 bit */ - nxt_tls_conf_t *conf; - nxt_buf_mem_t buffer; + nxt_tls_conf_t *conf; + nxt_buf_mem_t buffer; } nxt_openssl_conn_t; +struct nxt_tls_ticket_s { + u_char name[16]; + u_char hmac_key[32]; + u_char aes_key[32]; + uint8_t size; +}; + + +struct nxt_tls_tickets_s { + nxt_uint_t count; + nxt_tls_ticket_t tickets[]; +}; + + typedef enum { NXT_OPENSSL_HANDSHAKE = 0, NXT_OPENSSL_READ, @@ -607,8 +621,8 @@ static nxt_int_t nxt_tls_ticket_keys(nxt_task_t *task, SSL_CTX *ctx, nxt_tls_init_t *tls_init, nxt_mp_t *mp) { + size_t len; uint32_t i; - nxt_int_t ret; nxt_str_t value; nxt_uint_t count; nxt_conf_value_t *member, *tickets_conf; @@ -672,23 +686,21 @@ nxt_tls_ticket_keys(nxt_task_t *task, SSL_CTX *ctx, nxt_tls_init_t *tls_init, nxt_conf_get_string(member, &value); - ret = nxt_openssl_base64_decode(buf, 80, value.start, value.length); - if (nxt_slow_path(ret == NXT_ERROR)) { - return NXT_ERROR; - } + len = nxt_base64_decode(buf, value.start, value.length); - if (ret == 48) { - ticket->aes128 = 1; + nxt_memcpy(ticket->name, buf, 16); + + if (len == 48) { nxt_memcpy(ticket->aes_key, buf + 16, 16); nxt_memcpy(ticket->hmac_key, buf + 32, 16); + ticket->size = 16; } else { - ticket->aes128 = 0; nxt_memcpy(ticket->hmac_key, buf + 16, 32); nxt_memcpy(ticket->aes_key, buf + 48, 32); + ticket->size = 32; } - nxt_memcpy(ticket->name, buf, 16); } while (i < count); if (SSL_CTX_set_tlsext_ticket_key_cb(ctx, nxt_tls_ticket_key_callback) @@ -727,7 +739,6 @@ static int nxt_tls_ticket_key_callback(SSL *s, unsigned char *name, unsigned char *iv, EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx, int enc) { - size_t size; nxt_uint_t i; nxt_conn_t *c; const EVP_MD *digest; @@ -745,25 +756,14 @@ nxt_tls_ticket_key_callback(SSL *s, unsigned char *name, unsigned char *iv, tls = c->u.tls; ticket = tls->conf->tickets->tickets; -#ifdef OPENSSL_NO_SHA256 - digest = EVP_sha1(); -#else - digest = EVP_sha256(); -#endif + i = 0; if (enc == 1) { /* encrypt session ticket */ nxt_debug(c->socket.task, "TLS session ticket encrypt"); - if (ticket[0].aes128 == 1) { - cipher = EVP_aes_128_cbc(); - size = 16; - - } else { - cipher = EVP_aes_256_cbc(); - size = 32; - } + cipher = (ticket[0].size == 16) ? EVP_aes_128_cbc() : EVP_aes_256_cbc(); if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) != 1) { nxt_openssl_log_error(c->socket.task, NXT_LOG_ALERT, @@ -771,32 +771,24 @@ nxt_tls_ticket_key_callback(SSL *s, unsigned char *name, unsigned char *iv, return -1; } - if (EVP_EncryptInit_ex(ectx, cipher, NULL, ticket[0].aes_key, iv) - != 1) + nxt_memcpy(name, ticket[0].name, 16); + + if (EVP_EncryptInit_ex(ectx, cipher, NULL, ticket[0].aes_key, iv) != 1) { nxt_openssl_log_error(c->socket.task, NXT_LOG_ALERT, "EVP_EncryptInit_ex() failed"); return -1; } - if (HMAC_Init_ex(hctx, ticket[0].hmac_key, size, digest, NULL) != 1) { - nxt_openssl_log_error(c->socket.task, NXT_LOG_ALERT, - "HMAC_Init_ex() failed"); - return -1; - } - - nxt_memcpy(name, ticket[0].name, 16); - - return 1; - } else { /* decrypt session ticket */ - for (i = 0; i < tls->conf->tickets->count; i++) { + do { if (nxt_memcmp(name, ticket[i].name, 16) == 0) { goto found; } - } + + } while (++i < tls->conf->tickets->count); nxt_debug(c->socket.task, "TLS session ticket decrypt, key not found"); @@ -807,29 +799,33 @@ nxt_tls_ticket_key_callback(SSL *s, unsigned char *name, unsigned char *iv, nxt_debug(c->socket.task, "TLS session ticket decrypt, key number: \"%d\"", i); - if (ticket[i].aes128 == 1) { - cipher = EVP_aes_128_cbc(); - size = 16; + enc = (i == 0) ? 1 : 2 /* renew */; - } else { - cipher = EVP_aes_256_cbc(); - size = 32; - } + cipher = (ticket[i].size == 16) ? EVP_aes_128_cbc() : EVP_aes_256_cbc(); - if (EVP_DecryptInit_ex(ectx, cipher, NULL, ticket[i].aes_key, iv) != 1) { + if (EVP_DecryptInit_ex(ectx, cipher, NULL, ticket[i].aes_key, iv) != 1) + { nxt_openssl_log_error(c->socket.task, NXT_LOG_ALERT, "EVP_DecryptInit_ex() failed"); return -1; } + } - if (HMAC_Init_ex(hctx, ticket[i].hmac_key, size, digest, NULL) != 1) { - nxt_openssl_log_error(c->socket.task, NXT_LOG_ALERT, - "HMAC_Init_ex() failed"); - return -1; - } +#ifdef OPENSSL_NO_SHA256 + digest = EVP_sha1(); +#else + digest = EVP_sha256(); +#endif - return (i == 0) ? 1 : 2 /* renew */; + if (HMAC_Init_ex(hctx, ticket[i].hmac_key, ticket[i].size, digest, NULL) + != 1) + { + nxt_openssl_log_error(c->socket.task, NXT_LOG_ALERT, + "HMAC_Init_ex() failed"); + return -1; } + + return enc; } #endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */ @@ -1819,70 +1815,3 @@ nxt_openssl_copy_error(u_char *p, u_char *end) return p; } - - -nxt_int_t -nxt_openssl_base64_decode(u_char *d, size_t dlen, const u_char *s, size_t slen) -{ - BIO *bio, *b64; - nxt_int_t count, ret; - u_char buf[128]; - - b64 = BIO_new(BIO_f_base64()); - if (nxt_slow_path(b64 == NULL)) { - goto error; - } - - bio = BIO_new_mem_buf(s, slen); - if (nxt_slow_path(bio == NULL)) { - goto error; - } - - bio = BIO_push(b64, bio); - - BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); - - count = 0; - - if (d == NULL) { - - for ( ;; ) { - ret = BIO_read(bio, buf, 128); - - if (ret < 0) { - goto invalid; - } - - count += ret; - - if (ret != 128) { - break; - } - } - - } else { - count = BIO_read(bio, d, dlen); - - if (count < 0) { - goto invalid; - } - } - - BIO_free_all(bio); - - return count; - -error: - - BIO_vfree(b64); - ERR_clear_error(); - - return NXT_ERROR; - -invalid: - - BIO_free_all(bio); - ERR_clear_error(); - - return NXT_DECLINED; -} |