@ -300,9 +300,23 @@ void SecureContext::Initialize(Environment* env, Handle<Object> target) {
env - > SetProtoMethod ( t , " getTicketKeys " , SecureContext : : GetTicketKeys ) ;
env - > SetProtoMethod ( t , " setTicketKeys " , SecureContext : : SetTicketKeys ) ;
env - > SetProtoMethod ( t , " setFreeListLength " , SecureContext : : SetFreeListLength ) ;
env - > SetProtoMethod ( t ,
" enableTicketKeyCallback " ,
SecureContext : : EnableTicketKeyCallback ) ;
env - > SetProtoMethod ( t , " getCertificate " , SecureContext : : GetCertificate < true > ) ;
env - > SetProtoMethod ( t , " getIssuer " , SecureContext : : GetCertificate < false > ) ;
t - > Set ( FIXED_ONE_BYTE_STRING ( env - > isolate ( ) , " kTicketKeyReturnIndex " ) ,
Integer : : NewFromUnsigned ( env - > isolate ( ) , kTicketKeyReturnIndex ) ) ;
t - > Set ( FIXED_ONE_BYTE_STRING ( env - > isolate ( ) , " kTicketKeyHMACIndex " ) ,
Integer : : NewFromUnsigned ( env - > isolate ( ) , kTicketKeyHMACIndex ) ) ;
t - > Set ( FIXED_ONE_BYTE_STRING ( env - > isolate ( ) , " kTicketKeyAESIndex " ) ,
Integer : : NewFromUnsigned ( env - > isolate ( ) , kTicketKeyAESIndex ) ) ;
t - > Set ( FIXED_ONE_BYTE_STRING ( env - > isolate ( ) , " kTicketKeyNameIndex " ) ,
Integer : : NewFromUnsigned ( env - > isolate ( ) , kTicketKeyNameIndex ) ) ;
t - > Set ( FIXED_ONE_BYTE_STRING ( env - > isolate ( ) , " kTicketKeyIVIndex " ) ,
Integer : : NewFromUnsigned ( env - > isolate ( ) , kTicketKeyIVIndex ) ) ;
t - > PrototypeTemplate ( ) - > SetAccessor (
FIXED_ONE_BYTE_STRING ( env - > isolate ( ) , " _external " ) ,
CtxGetter ,
@ -378,6 +392,7 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
}
sc - > ctx_ = SSL_CTX_new ( method ) ;
SSL_CTX_set_app_data ( sc - > ctx_ , sc ) ;
// Disable SSLv2 in the case when method == SSLv23_method() and the
// cipher list contains SSLv2 ciphers (not the default, should be rare.)
@ -982,6 +997,95 @@ void SecureContext::SetFreeListLength(const FunctionCallbackInfo<Value>& args) {
}
void SecureContext : : EnableTicketKeyCallback (
const FunctionCallbackInfo < Value > & args ) {
SecureContext * wrap = Unwrap < SecureContext > ( args . Holder ( ) ) ;
SSL_CTX_set_tlsext_ticket_key_cb ( wrap - > ctx_ , TicketKeyCallback ) ;
}
int SecureContext : : TicketKeyCallback ( SSL * ssl ,
unsigned char * name ,
unsigned char * iv ,
EVP_CIPHER_CTX * ectx ,
HMAC_CTX * hctx ,
int enc ) {
static const int kTicketPartSize = 16 ;
SecureContext * sc = static_cast < SecureContext * > (
SSL_CTX_get_app_data ( ssl - > ctx ) ) ;
Environment * env = sc - > env ( ) ;
HandleScope handle_scope ( env - > isolate ( ) ) ;
Context : : Scope context_scope ( env - > context ( ) ) ;
Local < Value > argv [ ] = {
Buffer : : New ( env ,
reinterpret_cast < char * > ( name ) ,
kTicketPartSize ) . ToLocalChecked ( ) ,
Buffer : : New ( env ,
reinterpret_cast < char * > ( iv ) ,
kTicketPartSize ) . ToLocalChecked ( ) ,
Boolean : : New ( env - > isolate ( ) , enc ! = 0 )
} ;
Local < Value > ret = node : : MakeCallback ( env ,
sc - > object ( ) ,
env - > ticketkeycallback_string ( ) ,
ARRAY_SIZE ( argv ) ,
argv ) ;
Local < Array > arr = ret . As < Array > ( ) ;
int r = arr - > Get ( kTicketKeyReturnIndex ) - > Int32Value ( ) ;
if ( r < 0 )
return r ;
Local < Value > hmac = arr - > Get ( kTicketKeyHMACIndex ) ;
Local < Value > aes = arr - > Get ( kTicketKeyAESIndex ) ;
if ( Buffer : : Length ( aes ) ! = kTicketPartSize )
return - 1 ;
if ( enc ) {
Local < Value > name_val = arr - > Get ( kTicketKeyNameIndex ) ;
Local < Value > iv_val = arr - > Get ( kTicketKeyIVIndex ) ;
if ( Buffer : : Length ( name_val ) ! = kTicketPartSize | |
Buffer : : Length ( iv_val ) ! = kTicketPartSize ) {
return - 1 ;
}
memcpy ( name , Buffer : : Data ( name_val ) , kTicketPartSize ) ;
memcpy ( iv , Buffer : : Data ( iv_val ) , kTicketPartSize ) ;
}
HMAC_Init_ex ( hctx ,
Buffer : : Data ( hmac ) ,
Buffer : : Length ( hmac ) ,
EVP_sha256 ( ) ,
nullptr ) ;
const unsigned char * aes_key =
reinterpret_cast < unsigned char * > ( Buffer : : Data ( aes ) ) ;
if ( enc ) {
EVP_EncryptInit_ex ( ectx ,
EVP_aes_128_cbc ( ) ,
nullptr ,
aes_key ,
iv ) ;
} else {
EVP_DecryptInit_ex ( ectx ,
EVP_aes_128_cbc ( ) ,
nullptr ,
aes_key ,
iv ) ;
}
return r ;
}
void SecureContext : : CtxGetter ( Local < String > property ,
const PropertyCallbackInfo < Value > & info ) {
HandleScope scope ( info . GetIsolate ( ) ) ;