@@ -615,6 +615,19 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
615615 SSL_SESS_CACHE_NO_AUTO_CLEAR);
616616 SSL_CTX_sess_set_get_cb (sc->ctx_ , SSLWrap<Connection>::GetSessionCallback);
617617 SSL_CTX_sess_set_new_cb (sc->ctx_ , SSLWrap<Connection>::NewSessionCallback);
618+
619+ #if OPENSSL_VERSION_NUMBER >= 0x10100000L
620+ // OpenSSL 1.1.0 changed the ticket key size, but the OpenSSL 1.0.x size was
621+ // exposed in the public API. To retain compatibility, install a callback
622+ // which restores the old algorithm.
623+ if (RAND_bytes (sc->ticket_key_name_ , sizeof (sc->ticket_key_name_ )) <= 0 ||
624+ RAND_bytes (sc->ticket_key_hmac_ , sizeof (sc->ticket_key_hmac_ )) <= 0 ||
625+ RAND_bytes (sc->ticket_key_aes_ , sizeof (sc->ticket_key_aes_ )) <= 0 ) {
626+ return env->ThrowError (" Error generating ticket keys" );
627+ }
628+ SSL_CTX_set_tlsext_ticket_key_cb (sc->ctx_ ,
629+ SecureContext::TicketCompatibilityCallback);
630+ #endif
618631}
619632
620633
@@ -1292,11 +1305,17 @@ void SecureContext::GetTicketKeys(const FunctionCallbackInfo<Value>& args) {
12921305 ASSIGN_OR_RETURN_UNWRAP (&wrap, args.Holder ());
12931306
12941307 Local<Object> buff = Buffer::New (wrap->env (), 48 ).ToLocalChecked ();
1308+ #if OPENSSL_VERSION_NUMBER >= 0x10100000L
1309+ memcpy (Buffer::Data (buff), wrap->ticket_key_name_ , 16 );
1310+ memcpy (Buffer::Data (buff) + 16 , wrap->ticket_key_hmac_ , 16 );
1311+ memcpy (Buffer::Data (buff) + 32 , wrap->ticket_key_aes_ , 16 );
1312+ #else
12951313 if (SSL_CTX_get_tlsext_ticket_keys (wrap->ctx_ ,
12961314 Buffer::Data (buff),
12971315 Buffer::Length (buff)) != 1 ) {
12981316 return wrap->env ()->ThrowError (" Failed to fetch tls ticket keys" );
12991317 }
1318+ #endif
13001319
13011320 args.GetReturnValue ().Set (buff);
13021321#endif // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
@@ -1319,11 +1338,17 @@ void SecureContext::SetTicketKeys(const FunctionCallbackInfo<Value>& args) {
13191338 return env->ThrowTypeError (" Ticket keys length must be 48 bytes" );
13201339 }
13211340
1341+ #if OPENSSL_VERSION_NUMBER >= 0x10100000L
1342+ memcpy (wrap->ticket_key_name_ , Buffer::Data (args[0 ]), 16 );
1343+ memcpy (wrap->ticket_key_hmac_ , Buffer::Data (args[0 ]) + 16 , 16 );
1344+ memcpy (wrap->ticket_key_aes_ , Buffer::Data (args[0 ]) + 32 , 16 );
1345+ #else
13221346 if (SSL_CTX_set_tlsext_ticket_keys (wrap->ctx_ ,
13231347 Buffer::Data (args[0 ]),
13241348 Buffer::Length (args[0 ])) != 1 ) {
13251349 return env->ThrowError (" Failed to fetch tls ticket keys" );
13261350 }
1351+ #endif
13271352
13281353 args.GetReturnValue ().Set (true );
13291354#endif // !def(OPENSSL_NO_TLSEXT) && def(SSL_CTX_get_tlsext_ticket_keys)
@@ -1434,6 +1459,42 @@ int SecureContext::TicketKeyCallback(SSL* ssl,
14341459}
14351460
14361461
1462+ #if OPENSSL_VERSION_NUMBER >= 0x10100000L
1463+ int SecureContext::TicketCompatibilityCallback (SSL* ssl,
1464+ unsigned char * name,
1465+ unsigned char * iv,
1466+ EVP_CIPHER_CTX* ectx,
1467+ HMAC_CTX* hctx,
1468+ int enc) {
1469+ SecureContext* sc = static_cast <SecureContext*>(
1470+ SSL_CTX_get_app_data (SSL_get_SSL_CTX (ssl)));
1471+
1472+ if (enc) {
1473+ memcpy (name, sc->ticket_key_name_ , sizeof (sc->ticket_key_name_ ));
1474+ if (RAND_bytes (iv, 16 ) <= 0 ||
1475+ EVP_EncryptInit_ex (ectx, EVP_aes_128_cbc (), nullptr ,
1476+ sc->ticket_key_aes_ , iv) <= 0 ||
1477+ HMAC_Init_ex (hctx, sc->ticket_key_hmac_ , sizeof (sc->ticket_key_hmac_ ),
1478+ EVP_sha256 (), nullptr ) <= 0 ) {
1479+ return -1 ;
1480+ }
1481+ return 1 ;
1482+ }
1483+
1484+ if (memcmp (name, sc->ticket_key_name_ , sizeof (sc->ticket_key_name_ )) != 0 ) {
1485+ // The ticket key name does not match. Discard the ticket.
1486+ return 0 ;
1487+ }
1488+
1489+ if (EVP_DecryptInit_ex (ectx, EVP_aes_128_cbc (), nullptr , sc->ticket_key_aes_ ,
1490+ iv) <= 0 ||
1491+ HMAC_Init_ex (hctx, sc->ticket_key_hmac_ , sizeof (sc->ticket_key_hmac_ ),
1492+ EVP_sha256 (), nullptr ) <= 0 ) {
1493+ return -1 ;
1494+ }
1495+ return 1 ;
1496+ }
1497+ #endif
14371498
14381499
14391500void SecureContext::CtxGetter (Local<String> property,
0 commit comments