| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 32851f3 commit ed94bc4
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,16 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + const common = require('../common.js'); | ||
| 4 | + const { getCiphers, getCipherInfo } = require('node:crypto'); | ||
| 5 | + const bench = common.createBenchmark(main, { | ||
| 6 | + cipher: getCiphers(), | ||
| 7 | + n: 50, | ||
| 8 | + }); | ||
| 9 | + | ||
| 10 | + function main({ n, cipher }) { | ||
| 11 | + bench.start(); | ||
| 12 | + for (let i = 0; i < n; i++) { | ||
| 13 | + getCipherInfo(cipher); | ||
| 14 | + } | ||
| 15 | + bench.end(n); | ||
| 16 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,9 +1,9 @@ | |||
| 1 | 1 | 'use strict'; | |
| 2 | 2 | ||
| 3 | 3 | const { | |
| 4 | + NumberIsInteger, | ||
| 4 | 5 | ObjectSetPrototypeOf, | |
| 5 | 6 | ReflectApply, | |
| 6 | - StringPrototypeToLowerCase, | ||
| 7 | 7 | } = primordials; | |
| 8 | 8 | ||
| 9 | 9 | const { | |
@@ -33,7 +33,7 @@ const { | |||
| 33 | 33 | ||
| 34 | 34 | const { | |
| 35 | 35 | validateEncoding, | |
| 36 | - validateInt32, | ||
| 36 | + validateUint32, | ||
| 37 | 37 | validateObject, | |
| 38 | 38 | validateString, | |
| 39 | 39 | } = require('internal/validators'); | |
@@ -251,31 +251,34 @@ ObjectSetPrototypeOf(Decipheriv.prototype, LazyTransform.prototype); | |||
| 251 | 251 | ObjectSetPrototypeOf(Decipheriv, LazyTransform); | |
| 252 | 252 | addCipherPrototypeFunctions(Decipheriv); | |
| 253 | 253 | ||
| 254 | - function getCipherInfo(nameOrNid, options) { | ||
| 255 | - if (typeof nameOrNid !== 'string' && typeof nameOrNid !== 'number') { | ||
| 256 | - throw new ERR_INVALID_ARG_TYPE( | ||
| 257 | - 'nameOrNid', | ||
| 258 | - ['string', 'number'], | ||
| 259 | - nameOrNid); | ||
| 254 | + const kMinNid = 1; | ||
| 255 | + const kMaxNid = 2_147_483_647; | ||
| 256 | + function getCipherInfo(nameOrNid, options = {}) { | ||
| 257 | + validateObject(options, 'options'); | ||
| 258 | + const { keyLength, ivLength } = options; | ||
| 259 | + if (keyLength !== undefined) { | ||
| 260 | + validateUint32(keyLength, 'options.keyLength'); | ||
| 260 | 261 | } | |
| 261 | - if (typeof nameOrNid === 'number') | ||
| 262 | - validateInt32(nameOrNid, 'nameOrNid'); | ||
| 263 | - let keyLength, ivLength; | ||
| 264 | - if (options !== undefined) { | ||
| 265 | - validateObject(options, 'options'); | ||
| 266 | - ({ keyLength, ivLength } = options); | ||
| 267 | - if (keyLength !== undefined) | ||
| 268 | - validateInt32(keyLength, 'options.keyLength'); | ||
| 269 | - if (ivLength !== undefined) | ||
| 270 | - validateInt32(ivLength, 'options.ivLength'); | ||
| 262 | + if (ivLength !== undefined) { | ||
| 263 | + validateUint32(ivLength, 'options.ivLength'); | ||
| 271 | 264 | } | |
| 272 | 265 | ||
| 273 | - const ret = _getCipherInfo({}, nameOrNid, keyLength, ivLength); | ||
| 274 | - if (ret !== undefined) { | ||
| 275 | - ret.name &&= StringPrototypeToLowerCase(ret.name); | ||
| 276 | - ret.type &&= StringPrototypeToLowerCase(ret.type); | ||
| 266 | + const type = typeof nameOrNid; | ||
| 267 | + | ||
| 268 | + if (type === 'string') { | ||
| 269 | + if (nameOrNid.length === 0) return undefined; | ||
| 270 | + return _getCipherInfo(nameOrNid, keyLength, ivLength); | ||
| 271 | + } else if (type === 'number') { | ||
| 272 | + if (!NumberIsInteger(nameOrNid) || nameOrNid < kMinNid || nameOrNid > kMaxNid) { | ||
| 273 | + return undefined; | ||
| 274 | + } | ||
| 275 | + return _getCipherInfo(nameOrNid, keyLength, ivLength); | ||
| 277 | 276 | } | |
| 278 | - return ret; | ||
| 277 | + | ||
| 278 | + throw new ERR_INVALID_ARG_TYPE( | ||
| 279 | + 'nameOrNid', | ||
| 280 | + ['string', 'number'], | ||
| 281 | + nameOrNid); | ||
| 279 | 282 | } | |
| 280 | 283 | ||
| 281 | 284 | module.exports = { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -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 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -386,6 +386,7 @@ | |||
| 386 | 386 | V(blocklist_constructor_template, v8::FunctionTemplate) \ | |
| 387 | 387 | V(caa_record_template, v8::DictionaryTemplate) \ | |
| 388 | 388 | V(callsite_template, v8::DictionaryTemplate) \ | |
| 389 | + V(cipherinfo_detail_template, v8::DictionaryTemplate) \ | ||
| 389 | 390 | V(cipherinfo_template, v8::DictionaryTemplate) \ | |
| 390 | 391 | V(cname_record_template, v8::DictionaryTemplate) \ | |
| 391 | 392 | V(contextify_global_template, v8::ObjectTemplate) \ | |
| Back | FazBrowse Home | New Git URL |
0 commit comments