@@ -24,51 +24,71 @@ using v8::ArrayBuffer;
24
24
using v8::BackingStore;
25
25
using v8::BackingStoreInitializationMode;
26
26
using v8::Context;
27
+ using v8::DictionaryTemplate;
27
28
using v8::FunctionCallbackInfo;
28
29
using v8::FunctionTemplate;
29
30
using v8::HandleScope;
30
31
using v8::Int32;
31
32
using v8::Isolate;
32
33
using v8::Local;
33
34
using v8::LocalVector;
35
+ using v8::MaybeLocal;
34
36
using v8::Object;
35
37
using v8::Uint32;
38
+ using v8::Undefined;
36
39
using v8::Value;
37
40
38
41
namespace crypto {
39
42
namespace {
40
43
// Collects and returns information on the given cipher
41
44
void GetCipherInfo (const FunctionCallbackInfo<Value>& args) {
42
45
Environment* env = Environment::GetCurrent (args);
43
- CHECK (args[0 ]->IsObject ());
44
- Local<Object> info = args[0 ].As <Object>();
45
46
46
- CHECK (args[1 ]->IsString () || args[1 ]->IsInt32 ());
47
+ auto tmpl = env->cipherinfo_detail_template ();
48
+ if (tmpl.IsEmpty ()) {
49
+ static constexpr std::string_view names[] = {
50
+ " mode" ,
51
+ " name" ,
52
+ " nid" ,
53
+ " keyLength" ,
54
+ " blockSize" ,
55
+ " ivLength" ,
56
+ };
57
+ tmpl = DictionaryTemplate::New (env->isolate (), names);
58
+ env->set_cipherinfo_detail_template (tmpl);
59
+ }
60
+ MaybeLocal<Value> values[] = {
61
+ Undefined (env->isolate ()), // mode
62
+ Undefined (env->isolate ()), // name
63
+ Undefined (env->isolate ()), // nid
64
+ Undefined (env->isolate ()), // keyLength
65
+ Undefined (env->isolate ()), // blockSize
66
+ Undefined (env->isolate ()), // ivLength
67
+ };
68
+
69
+ CHECK (args[0 ]->IsString () || args[0 ]->IsInt32 ());
47
70
48
71
const auto cipher = ([&] {
49
- if (args[1 ]->IsString ()) {
50
- Utf8Value name (env->isolate (), args[1 ]);
72
+ if (args[0 ]->IsString ()) {
73
+ Utf8Value name (env->isolate (), args[0 ]);
51
74
return Cipher::FromName (*name);
52
75
} else {
53
- int nid = args[1 ].As <Int32>()->Value ();
76
+ int nid = args[0 ].As <Int32>()->Value ();
54
77
return Cipher::FromNid (nid);
55
78
}
56
79
})();
57
80
58
81
if (!cipher) return ;
59
82
60
- int iv_length = cipher.getIvLength ();
61
- int key_length = cipher.getKeyLength ();
62
- int block_length = cipher.getBlockSize ();
63
- auto mode_label = cipher.getModeLabel ();
64
- auto name = cipher.getName ();
83
+ size_t iv_length = cipher.getIvLength ();
84
+ size_t key_length = cipher.getKeyLength ();
65
85
66
86
// If the testKeyLen and testIvLen arguments are specified,
67
87
// then we will make an attempt to see if they are usable for
68
88
// the cipher in question, returning undefined if they are not.
69
89
// If they are, the info object will be returned with the values
70
90
// given.
71
- if (args[2 ]->IsInt32 () || args[3 ]->IsInt32 ()) {
91
+ if (args[1 ]->IsUint32 () || args[2 ]->IsUint32 ()) {
72
92
// Test and input IV or key length to determine if it's acceptable.
73
93
// If it is, then the getCipherInfo will succeed with the given
74
94
// values.
@@ -77,16 +97,16 @@ void GetCipherInfo(const FunctionCallbackInfo<Value>& args) {
77
97
return ;
78
98
}
79
99
80
- if (args[2 ]->IsInt32 ()) {
81
- int check_len = args[2 ].As <Int32 >()->Value ();
100
+ if (args[1 ]->IsUint32 ()) {
101
+ size_t check_len = args[1 ].As <Uint32 >()->Value ();
82
102
if (!ctx.setKeyLength (check_len)) {
83
103
return ;
84
104
}
85
105
key_length = check_len;
86
106
}
87
107
88
- if (args[3 ]->IsInt32 ()) {
89
- int check_len = args[3 ].As <Int32 >()->Value ();
108
+ if (args[2 ]->IsUint32 ()) {
109
+ size_t check_len = args[2 ].As <Uint32 >()->Value ();
90
110
// For CCM modes, the IV may be between 7 and 13 bytes.
91
111
// For GCM and OCB modes, we'll check by attempting to
92
112
// set the value. For everything else, just check that
@@ -106,55 +126,30 @@ void GetCipherInfo(const FunctionCallbackInfo<Value>& args) {
106
126
}
107
127
}
108
128
109
- if (mode_label.length () &&
110
- info->Set (env->context (),
111
- FIXED_ONE_BYTE_STRING (env->isolate (), " mode" ),
112
- OneByteString (
113
- env->isolate (), mode_label.data (), mode_label.length ()))
114
- .IsNothing ()) {
115
- return ;
116
- }
117
-
118
- if (info->Set (env->context (),
119
- env->name_string (),
120
- OneByteString (env->isolate (), name))
121
- .IsNothing ()) {
122
- return ;
123
- }
129
+ // Lowercase the name in place before we create the JS string from it.
130
+ std::string name_str (cipher.getName ());
131
+ name_str = ToLower (name_str);
124
132
125
- if (info->Set (env->context (),
126
- FIXED_ONE_BYTE_STRING (env->isolate (), " nid" ),
127
- Int32::New (env->isolate (), cipher.getNid ()))
128
- .IsNothing ()) {
129
- return ;
130
- }
133
+ values[0 ] = ToV8Value (env->context (), cipher.getModeLabel (), env->isolate ());
134
+ values[1 ] = ToV8Value (env->context (), name_str, env->isolate ());
135
+ values[2 ] = Uint32::NewFromUnsigned (env->isolate (), cipher.getNid ());
136
+ values[3 ] = Uint32::NewFromUnsigned (env->isolate (), key_length);
131
137
132
138
// Stream ciphers do not have a meaningful block size
133
- if (!cipher.isStreamMode () &&
134
- info->Set (env->context (),
135
- FIXED_ONE_BYTE_STRING (env->isolate (), " blockSize" ),
136
- Int32::New (env->isolate (), block_length))
137
- .IsNothing ()) {
138
- return ;
139
+ if (!cipher.isStreamMode ()) {
140
+ values[4 ] = Uint32::NewFromUnsigned (env->isolate (), cipher.getBlockSize ());
139
141
}
140
142
141
143
// Ciphers that do not use an IV shouldn't report a length
142
- if (iv_length != 0 &&
143
- info->Set (
144
- env->context (),
145
- FIXED_ONE_BYTE_STRING (env->isolate (), " ivLength" ),
146
- Int32::New (env->isolate (), iv_length)).IsNothing ()) {
147
- return ;
144
+ if (iv_length != 0 ) {
145
+ values[5 ] = Uint32::NewFromUnsigned (env->isolate (), iv_length);
148
146
}
149
147
150
- if (info->Set (
151
- env->context (),
152
- FIXED_ONE_BYTE_STRING (env->isolate (), " keyLength" ),
153
- Int32::New (env->isolate (), key_length)).IsNothing ()) {
154
- return ;
148
+ Local<Object> info;
149
+ if (NewDictionaryInstanceNullProto (env->context (), tmpl, values)
150
+ .ToLocal (&info)) {
151
+ args.GetReturnValue ().Set (info);
155
152
}
156
-
157
- args.GetReturnValue ().Set (info);
158
153
}
159
154
} // namespace
160
155
0 commit comments