@@ -608,6 +608,19 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
608608 SSL_SESS_CACHE_NO_AUTO_CLEAR);
609609 SSL_CTX_sess_set_get_cb (sc->ctx_ , SSLWrap<Connection>::GetSessionCallback);
610610 SSL_CTX_sess_set_new_cb (sc->ctx_ , SSLWrap<Connection>::NewSessionCallback);
611+
612+ #if OPENSSL_VERSION_NUMBER >= 0x10100000L
613+ // OpenSSL 1.1.0 changed the ticket key size, but the OpenSSL 1.0.x size was
614+ // exposed in the public API. To retain compatibility, install a callback
615+ // which restores the old algorithm.
616+ if (RAND_bytes (sc->ticket_key_name_ , sizeof (sc->ticket_key_name_ )) <= 0 ||
617+ RAND_bytes (sc->ticket_key_hmac_ , sizeof (sc->ticket_key_hmac_ )) <= 0 ||
618+ RAND_bytes (sc->ticket_key_aes_ , sizeof (sc->ticket_key_aes_ )) <= 0 ) {
619+ return env->ThrowError (" Error generating ticket keys" );
620+ }
621+ SSL_CTX_set_tlsext_ticket_key_cb (sc->ctx_ ,
622+ SecureContext::TicketCompatibilityCallback);
623+ #endif
611624}
612625
613626
@@ -1285,11 +1298,17 @@ void SecureContext::GetTicketKeys(const FunctionCallbackInfo<Value>& args) {
12851298 ASSIGN_OR_RETURN_UNWRAP (&wrap, args.Holder ());
12861299
12871300 Local<Object> buff = Buffer::New (wrap->env (), 48 ).ToLocalChecked ();
1301+ #if OPENSSL_VERSION_NUMBER >= 0x10100000L
1302+ memcpy (Buffer::Data (buff), wrap->ticket_key_name_ , 16 );
1303+ memcpy (Buffer::Data (buff) + 16 , wrap->ticket_key_hmac_ , 16 );
1304+ memcpy (Buffer::Data (buff) + 32 , wrap->ticket_key_aes_ , 16 );
1305+ #else
12881306 if (SSL_CTX_get_tlsext_ticket_keys (wrap->ctx_ ,
12891307 Buffer::Data (buff),
12901308 Buffer::Length (buff)) != 1 ) {
12911309 return wrap->env ()->ThrowError (" Failed to fetch tls ticket keys" );
12921310 }
1311+ #endif
12931312
12941313 args.GetReturnValue ().Set (buff);
12951314#endif // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
@@ -1312,11 +1331,17 @@ void SecureContext::SetTicketKeys(const FunctionCallbackInfo<Value>& args) {
13121331 return env->ThrowTypeError (" Ticket keys length must be 48 bytes" );
13131332 }
13141333
1334+ #if OPENSSL_VERSION_NUMBER >= 0x10100000L
1335+ memcpy (wrap->ticket_key_name_ , Buffer::Data (args[0 ]), 16 );
1336+ memcpy (wrap->ticket_key_hmac_ , Buffer::Data (args[0 ]) + 16 , 16 );
1337+ memcpy (wrap->ticket_key_aes_ , Buffer::Data (args[0 ]) + 32 , 16 );
1338+ #else
13151339 if (SSL_CTX_set_tlsext_ticket_keys (wrap->ctx_ ,
13161340 Buffer::Data (args[0 ]),
13171341 Buffer::Length (args[0 ])) != 1 ) {
13181342 return env->ThrowError (" Failed to fetch tls ticket keys" );
13191343 }
1344+ #endif
13201345
13211346 args.GetReturnValue ().Set (true );
13221347#endif // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
@@ -1427,6 +1452,42 @@ int SecureContext::TicketKeyCallback(SSL* ssl,
14271452}
14281453
14291454
1455+ #if OPENSSL_VERSION_NUMBER >= 0x10100000L
1456+ int SecureContext::TicketCompatibilityCallback (SSL* ssl,
1457+ unsigned char * name,
1458+ unsigned char * iv,
1459+ EVP_CIPHER_CTX* ectx,
1460+ HMAC_CTX* hctx,
1461+ int enc) {
1462+ SecureContext* sc = static_cast <SecureContext*>(
1463+ SSL_CTX_get_app_data (SSL_get_SSL_CTX (ssl)));
1464+
1465+ if (enc) {
1466+ memcpy (name, sc->ticket_key_name_ , sizeof (sc->ticket_key_name_ ));
1467+ if (RAND_bytes (iv, 16 ) <= 0 ||
1468+ EVP_EncryptInit_ex (ectx, EVP_aes_128_cbc (), nullptr ,
1469+ sc->ticket_key_aes_ , iv) <= 0 ||
1470+ HMAC_Init_ex (hctx, sc->ticket_key_hmac_ , sizeof (sc->ticket_key_hmac_ ),
1471+ EVP_sha256 (), nullptr ) <= 0 ) {
1472+ return -1 ;
1473+ }
1474+ return 1 ;
1475+ }
1476+
1477+ if (memcmp (name, sc->ticket_key_name_ , sizeof (sc->ticket_key_name_ )) != 0 ) {
1478+ // The ticket key name does not match. Discard the ticket.
1479+ return 0 ;
1480+ }
1481+
1482+ if (EVP_DecryptInit_ex (ectx, EVP_aes_128_cbc (), nullptr , sc->ticket_key_aes_ ,
1483+ iv) <= 0 ||
1484+ HMAC_Init_ex (hctx, sc->ticket_key_hmac_ , sizeof (sc->ticket_key_hmac_ ),
1485+ EVP_sha256 (), nullptr ) <= 0 ) {
1486+ return -1 ;
1487+ }
1488+ return 1 ;
1489+ }
1490+ #endif
14301491
14311492
14321493void SecureContext::CtxGetter (Local<String> property,
0 commit comments