%PDF- <> %âãÏÓ endobj 2 0 obj <> endobj 3 0 obj <>/ExtGState<>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI] >>/Annots[ 28 0 R 29 0 R] /MediaBox[ 0 0 595.5 842.25] /Contents 4 0 R/Group<>/Tabs/S>> endobj ºaâÚÎΞ-ÌE1ÍØÄ÷{òò2ÿ ÛÖ^ÔÀá TÎ{¦?§®¥kuµùÕ5sLOšuY>endobj 2 0 obj<>endobj 2 0 obj<>endobj 2 0 obj<>endobj 2 0 obj<> endobj 2 0 obj<>endobj 2 0 obj<>es 3 0 R>> endobj 2 0 obj<> ox[ 0.000000 0.000000 609.600000 935.600000]/Fi endobj 3 0 obj<> endobj 7 1 obj<>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI]>>/Subtype/Form>> stream
#include "crypto/crypto_scrypt.h" #include "async_wrap-inl.h" #include "crypto/crypto_util.h" #include "env-inl.h" #include "memory_tracker-inl.h" #include "node_buffer.h" #include "threadpoolwork-inl.h" #include "v8.h" namespace node { using v8::FunctionCallbackInfo; using v8::Int32; using v8::Just; using v8::Maybe; using v8::Nothing; using v8::Uint32; using v8::Value; namespace crypto { #ifndef OPENSSL_NO_SCRYPT ScryptConfig::ScryptConfig(ScryptConfig&& other) noexcept : mode(other.mode), pass(std::move(other.pass)), salt(std::move(other.salt)), N(other.N), r(other.r), p(other.p), maxmem(other.maxmem), length(other.length) {} ScryptConfig& ScryptConfig::operator=(ScryptConfig&& other) noexcept { if (&other == this) return *this; this->~ScryptConfig(); return *new (this) ScryptConfig(std::move(other)); } void ScryptConfig::MemoryInfo(MemoryTracker* tracker) const { if (mode == kCryptoJobAsync) { tracker->TrackFieldWithSize("pass", pass.size()); tracker->TrackFieldWithSize("salt", salt.size()); } } Maybe<bool> ScryptTraits::EncodeOutput( Environment* env, const ScryptConfig& params, ByteSource* out, v8::Local<v8::Value>* result) { *result = out->ToArrayBuffer(env); return Just(!result->IsEmpty()); } Maybe<bool> ScryptTraits::AdditionalConfig( CryptoJobMode mode, const FunctionCallbackInfo<Value>& args, unsigned int offset, ScryptConfig* params) { Environment* env = Environment::GetCurrent(args); params->mode = mode; ArrayBufferOrViewContents<char> pass(args[offset]); ArrayBufferOrViewContents<char> salt(args[offset + 1]); if (UNLIKELY(!pass.CheckSizeInt32())) { THROW_ERR_OUT_OF_RANGE(env, "pass is too large"); return Nothing<bool>(); } if (UNLIKELY(!salt.CheckSizeInt32())) { THROW_ERR_OUT_OF_RANGE(env, "salt is too large"); return Nothing<bool>(); } params->pass = mode == kCryptoJobAsync ? pass.ToCopy() : pass.ToByteSource(); params->salt = mode == kCryptoJobAsync ? salt.ToCopy() : salt.ToByteSource(); CHECK(args[offset + 2]->IsUint32()); // N CHECK(args[offset + 3]->IsUint32()); // r CHECK(args[offset + 4]->IsUint32()); // p CHECK(args[offset + 5]->IsNumber()); // maxmem CHECK(args[offset + 6]->IsInt32()); // length params->N = args[offset + 2].As<Uint32>()->Value(); params->r = args[offset + 3].As<Uint32>()->Value(); params->p = args[offset + 4].As<Uint32>()->Value(); params->maxmem = args[offset + 5]->IntegerValue(env->context()).ToChecked(); if (EVP_PBE_scrypt( nullptr, 0, nullptr, 0, params->N, params->r, params->p, params->maxmem, nullptr, 0) != 1) { THROW_ERR_CRYPTO_INVALID_SCRYPT_PARAMS(env); return Nothing<bool>(); } params->length = args[offset + 6].As<Int32>()->Value(); if (params->length < 0) { THROW_ERR_OUT_OF_RANGE(env, "length must be <= %d", INT_MAX); return Nothing<bool>(); } return Just(true); } bool ScryptTraits::DeriveBits( Environment* env, const ScryptConfig& params, ByteSource* out) { char* data = MallocOpenSSL<char>(params.length); ByteSource buf = ByteSource::Allocated(data, params.length); unsigned char* ptr = reinterpret_cast<unsigned char*>(data); // Both the pass and salt may be zero-length at this point if (!EVP_PBE_scrypt( params.pass.get(), params.pass.size(), params.salt.data<unsigned char>(), params.salt.size(), params.N, params.r, params.p, params.maxmem, ptr, params.length)) { return false; } *out = std::move(buf); return true; } #endif // !OPENSSL_NO_SCRYPT } // namespace crypto } // namespace node