@@ -300,9 +300,23 @@ void SecureContext::Initialize(Environment* env, Handle<Object> target) {
300
300
env->SetProtoMethod (t, " getTicketKeys" , SecureContext::GetTicketKeys);
301
301
env->SetProtoMethod (t, " setTicketKeys" , SecureContext::SetTicketKeys);
302
302
env->SetProtoMethod (t, " setFreeListLength" , SecureContext::SetFreeListLength);
303
+ env->SetProtoMethod (t,
304
+ " enableTicketKeyCallback" ,
305
+ SecureContext::EnableTicketKeyCallback);
303
306
env->SetProtoMethod (t, " getCertificate" , SecureContext::GetCertificate<true >);
304
307
env->SetProtoMethod (t, " getIssuer" , SecureContext::GetCertificate<false >);
305
308
309
+ t->Set (FIXED_ONE_BYTE_STRING (env->isolate (), " kTicketKeyReturnIndex" ),
310
+ Integer::NewFromUnsigned (env->isolate (), kTicketKeyReturnIndex ));
311
+ t->Set (FIXED_ONE_BYTE_STRING (env->isolate (), " kTicketKeyHMACIndex" ),
312
+ Integer::NewFromUnsigned (env->isolate (), kTicketKeyHMACIndex ));
313
+ t->Set (FIXED_ONE_BYTE_STRING (env->isolate (), " kTicketKeyAESIndex" ),
314
+ Integer::NewFromUnsigned (env->isolate (), kTicketKeyAESIndex ));
315
+ t->Set (FIXED_ONE_BYTE_STRING (env->isolate (), " kTicketKeyNameIndex" ),
316
+ Integer::NewFromUnsigned (env->isolate (), kTicketKeyNameIndex ));
317
+ t->Set (FIXED_ONE_BYTE_STRING (env->isolate (), " kTicketKeyIVIndex" ),
318
+ Integer::NewFromUnsigned (env->isolate (), kTicketKeyIVIndex ));
319
+
306
320
t->PrototypeTemplate ()->SetAccessor (
307
321
FIXED_ONE_BYTE_STRING (env->isolate (), " _external" ),
308
322
CtxGetter,
@@ -378,6 +392,7 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
378
392
}
379
393
380
394
sc->ctx_ = SSL_CTX_new (method);
395
+ SSL_CTX_set_app_data (sc->ctx_ , sc);
381
396
382
397
// Disable SSLv2 in the case when method == SSLv23_method() and the
383
398
// cipher list contains SSLv2 ciphers (not the default, should be rare.)
@@ -982,6 +997,95 @@ void SecureContext::SetFreeListLength(const FunctionCallbackInfo<Value>& args) {
982
997
}
983
998
984
999
1000
+ void SecureContext::EnableTicketKeyCallback (
1001
+ const FunctionCallbackInfo<Value>& args) {
1002
+ SecureContext* wrap = Unwrap<SecureContext>(args.Holder ());
1003
+
1004
+ SSL_CTX_set_tlsext_ticket_key_cb (wrap->ctx_ , TicketKeyCallback);
1005
+ }
1006
+
1007
+
1008
+ int SecureContext::TicketKeyCallback (SSL* ssl,
1009
+ unsigned char * name,
1010
+ unsigned char * iv,
1011
+ EVP_CIPHER_CTX* ectx,
1012
+ HMAC_CTX* hctx,
1013
+ int enc) {
1014
+ static const int kTicketPartSize = 16 ;
1015
+
1016
+ SecureContext* sc = static_cast <SecureContext*>(
1017
+ SSL_CTX_get_app_data (ssl->ctx ));
1018
+
1019
+ Environment* env = sc->env ();
1020
+ HandleScope handle_scope (env->isolate ());
1021
+ Context::Scope context_scope (env->context ());
1022
+
1023
+ Local<Value> argv[] = {
1024
+ Buffer::New (env,
1025
+ reinterpret_cast <char *>(name),
1026
+ kTicketPartSize ).ToLocalChecked (),
1027
+ Buffer::New (env,
1028
+ reinterpret_cast <char *>(iv),
1029
+ kTicketPartSize ).ToLocalChecked (),
1030
+ Boolean::New (env->isolate (), enc != 0 )
1031
+ };
1032
+ Local<Value> ret = node::MakeCallback (env,
1033
+ sc->object (),
1034
+ env->ticketkeycallback_string (),
1035
+ ARRAY_SIZE (argv),
1036
+ argv);
1037
+ Local<Array> arr = ret.As <Array>();
1038
+
1039
+ int r = arr->Get (kTicketKeyReturnIndex )->Int32Value ();
1040
+ if (r < 0 )
1041
+ return r;
1042
+
1043
+ Local<Value> hmac = arr->Get (kTicketKeyHMACIndex );
1044
+ Local<Value> aes = arr->Get (kTicketKeyAESIndex );
1045
+ if (Buffer::Length (aes) != kTicketPartSize )
1046
+ return -1 ;
1047
+
1048
+ if (enc) {
1049
+ Local<Value> name_val = arr->Get (kTicketKeyNameIndex );
1050
+ Local<Value> iv_val = arr->Get (kTicketKeyIVIndex );
1051
+
1052
+ if (Buffer::Length (name_val) != kTicketPartSize ||
1053
+ Buffer::Length (iv_val) != kTicketPartSize ) {
1054
+ return -1 ;
1055
+ }
1056
+
1057
+ memcpy (name, Buffer::Data (name_val), kTicketPartSize );
1058
+ memcpy (iv, Buffer::Data (iv_val), kTicketPartSize );
1059
+ }
1060
+
1061
+ HMAC_Init_ex (hctx,
1062
+ Buffer::Data (hmac),
1063
+ Buffer::Length (hmac),
1064
+ EVP_sha256 (),
1065
+ nullptr );
1066
+
1067
+ const unsigned char * aes_key =
1068
+ reinterpret_cast <unsigned char *>(Buffer::Data (aes));
1069
+ if (enc) {
1070
+ EVP_EncryptInit_ex (ectx,
1071
+ EVP_aes_128_cbc (),
1072
+ nullptr ,
1073
+ aes_key,
1074
+ iv);
1075
+ } else {
1076
+ EVP_DecryptInit_ex (ectx,
1077
+ EVP_aes_128_cbc (),
1078
+ nullptr ,
1079
+ aes_key,
1080
+ iv);
1081
+ }
1082
+
1083
+ return r;
1084
+ }
1085
+
1086
+
1087
+
1088
+
985
1089
void SecureContext::CtxGetter (Local<String> property,
986
1090
const PropertyCallbackInfo<Value>& info) {
987
1091
HandleScope scope (info.GetIsolate ());
0 commit comments