Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/nodejs/src/crypto/crypto_util.h
1 #ifndef SRC_CRYPTO_CRYPTO_UTIL_H_ 2 #define SRC_CRYPTO_CRYPTO_UTIL_H_ 3 4 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 5 6 #include "async_wrap.h" 7 #include "env.h" 8 #include "node_errors.h" 9 #include "node_external_reference.h" 10 #include "node_internals.h" 11 #include "string_bytes.h" 12 #include "util.h" 13 #include "v8.h" 14 15 #include "ncrypto.h" 16 17 #include <openssl/dsa.h> 18 #include <openssl/ec.h> 19 #include <openssl/err.h> 20 #include <openssl/evp.h> 21 #include <openssl/hmac.h> 22 #include <openssl/kdf.h> 23 #include <openssl/rsa.h> 24 #include <openssl/ssl.h> 25 26 // The FIPS-related functions are only available 27 // when the OpenSSL itself was compiled with FIPS support. 28 #if defined(OPENSSL_FIPS) && OPENSSL_VERSION_MAJOR < 3 29 # include <openssl/fips.h> 30 #endif // OPENSSL_FIPS 31 32 #include <algorithm> 33 #include <climits> 34 #include <cstdio> 35 #include <memory> 36 #include <optional> 37 #include <string> 38 #include <vector> 39 40 namespace node { 41 42 namespace crypto { 43 // Currently known sizes of commonly used OpenSSL struct sizes. 44 // OpenSSL considers it's various structs to be opaque and the 45 // sizes may change from one version of OpenSSL to another, so 46 // these values should not be trusted to remain static. These 47 // are provided to allow for some close to reasonable memory 48 // tracking. 49 constexpr size_t kSizeOf_DH = 144; 50 constexpr size_t kSizeOf_EC_KEY = 80; 51 constexpr size_t kSizeOf_EVP_CIPHER_CTX = 168; 52 constexpr size_t kSizeOf_EVP_MD_CTX = 48; 53 constexpr size_t kSizeOf_EVP_PKEY = 72; 54 constexpr size_t kSizeOf_EVP_PKEY_CTX = 80; 55 constexpr size_t kSizeOf_HMAC_CTX = 32; 56 57 bool ProcessFipsOptions(); 58 59 bool InitCryptoOnce(v8::Isolate* isolate); 60 void InitCryptoOnce(); 61 62 void InitCrypto(v8::Local<v8::Object> target); 63 64 extern void UseExtraCaCerts(const std::string& file); 65 void CleanupCachedRootCertificates(); 66 67 int PasswordCallback(char* buf, int size, int rwflag, void* u); 68 69 int NoPasswordCallback(char* buf, int size, int rwflag, void* u); 70 71 // Decode is used by the various stream-based crypto utilities to decode 72 // string input. 73 template <typename T> 74 void Decode(const v8::FunctionCallbackInfo<v8::Value>& args, 75 void (*callback)(T*, const v8::FunctionCallbackInfo<v8::Value>&, 76 const char*, size_t)) { 77 T* ctx; 78 ASSIGN_OR_RETURN_UNWRAP(&ctx, args.This()); 79 80 if (args[0]->IsString()) { 81 StringBytes::InlineDecoder decoder; 82 Environment* env = Environment::GetCurrent(args); 83 enum encoding enc = ParseEncoding(env->isolate(), args[1], UTF8); 84 if (decoder.Decode(env, args[0].As<v8::String>(), enc).IsNothing()) 85 return; 86 callback(ctx, args, decoder.out(), decoder.size()); 87 } else { 88 ArrayBufferViewContents<char> buf(args[0]); 89 callback(ctx, args, buf.data(), buf.length()); 90 } 91 } 92 93 #define NODE_CRYPTO_ERROR_CODES_MAP(V) \ 94 V(CIPHER_JOB_FAILED, "Cipher job failed") \ 95 V(DERIVING_BITS_FAILED, "Deriving bits failed") \ 96 V(ENGINE_NOT_FOUND, "Engine \"%s\" was not found") \ 97 V(INVALID_KEY_TYPE, "Invalid key type") \ 98 V(KEY_GENERATION_JOB_FAILED, "Key generation job failed") \ 99 V(OK, "Ok") \ 100 101 enum class NodeCryptoError { 102 #define V(CODE, DESCRIPTION) CODE, 103 NODE_CRYPTO_ERROR_CODES_MAP(V) 104 #undef V 105 }; 106 107 template <typename... Args> 108 std::string getNodeCryptoErrorString(const NodeCryptoError error, 109 Args&&... args) { 110 const char* error_string = nullptr; 111 switch (error) { 112 #define V(CODE, DESCRIPTION) \ 113 case NodeCryptoError::CODE: \ 114 error_string = DESCRIPTION; \ 115 break; 116 NODE_CRYPTO_ERROR_CODES_MAP(V) 117 #undef V 118 } 119 return SPrintF(error_string, std::forward<Args>(args)...); 120 } 121 122 // Utility struct used to harvest error information from openssl's error stack 123 struct CryptoErrorStore final : public MemoryRetainer { 124 public: 125 void Capture(); 126 127 bool Empty() const; 128 129 template <typename... Args> 130 void Insert(const NodeCryptoError error, Args&&... args); 131 132 v8::MaybeLocal<v8::Value> ToException( 133 Environment* env, 134 v8::Local<v8::String> exception_string = v8::Local<v8::String>()) const; 135 136 SET_NO_MEMORY_INFO() 137 SET_MEMORY_INFO_NAME(CryptoErrorStore) 138 SET_SELF_SIZE(CryptoErrorStore) 139 140 private: 141 std::vector<std::string> errors_; 142 }; 143 144 template <typename... Args> 145 void CryptoErrorStore::Insert(const NodeCryptoError error, Args&&... args) { 146 const char* error_string = nullptr; 147 switch (error) { 148 #define V(CODE, DESCRIPTION) \ 149 case NodeCryptoError::CODE: error_string = DESCRIPTION; break; 150 NODE_CRYPTO_ERROR_CODES_MAP(V) 151 #undef V 152 } 153 errors_.emplace_back(SPrintF(error_string, 154 std::forward<Args>(args)...)); 155 } 156 157 v8::MaybeLocal<v8::Value> cryptoErrorListToException( 158 Environment* env, const ncrypto::CryptoErrorList& errors); 159 160 template <typename T> 161 T* MallocOpenSSL(size_t count) { 162 void* mem = OPENSSL_malloc(MultiplyWithOverflowCheck(count, sizeof(T))); 163 CHECK_IMPLIES(mem == nullptr, count == 0); 164 return static_cast<T*>(mem); 165 } 166 167 // A helper class representing a read-only byte array. When deallocated, its 168 // contents are zeroed. 169 class ByteSource { 170 public: 171 class Builder { 172 public: 173 // Allocates memory using OpenSSL's memory allocator. 174 explicit Builder(size_t size) 175 : data_(MallocOpenSSL<char>(size)), size_(size) {} 176 177 Builder(Builder&& other) = delete; 178 Builder& operator=(Builder&& other) = delete; 179 Builder(const Builder&) = delete; 180 Builder& operator=(const Builder&) = delete; 181 182 ~Builder() { OPENSSL_clear_free(data_, size_); } 183 184 // Returns the underlying non-const pointer. 185 template <typename T> 186 T* data() { 187 return reinterpret_cast<T*>(data_); 188 } 189 190 // Returns the (allocated) size in bytes. 191 size_t size() const { return size_; } 192 193 // Returns if (allocated) size is zero. 194 bool empty() const { return size_ == 0; } 195 196 // Finalizes the Builder and returns a read-only view that is optionally 197 // truncated. 198 ByteSource release(std::optional<size_t> resize = std::nullopt) && { 199 if (resize) { 200 CHECK_LE(*resize, size_); 201 if (*resize == 0) { 202 OPENSSL_clear_free(data_, size_); 203 data_ = nullptr; 204 } 205 size_ = *resize; 206 } 207 ByteSource out = ByteSource::Allocated(data_, size_); 208 data_ = nullptr; 209 size_ = 0; 210 return out; 211 } 212 213 private: 214 void* data_; 215 size_t size_; 216 }; 217 218 ByteSource() = default; 219 ByteSource(ByteSource&& other) noexcept; 220 ~ByteSource(); 221 222 ByteSource& operator=(ByteSource&& other) noexcept; 223 224 ByteSource(const ByteSource&) = delete; 225 ByteSource& operator=(const ByteSource&) = delete; 226 227 template <typename T = void> 228 const T* data() const { 229 return reinterpret_cast<const T*>(data_); 230 } 231 232 size_t size() const { return size_; } 233 234 bool empty() const { return size_ == 0; } 235 236 operator bool() const { return data_ != nullptr; } 237 238 ncrypto::BignumPointer ToBN() const { 239 return ncrypto::BignumPointer(data<unsigned char>(), size()); 240 } 241 242 // Creates a v8::BackingStore that takes over responsibility for 243 // any allocated data. The ByteSource will be reset with size = 0 244 // after being called. 245 std::unique_ptr<v8::BackingStore> ReleaseToBackingStore(); 246 247 v8::Local<v8::ArrayBuffer> ToArrayBuffer(Environment* env); 248 249 v8::MaybeLocal<v8::Uint8Array> ToBuffer(Environment* env); 250 251 static ByteSource Allocated(void* data, size_t size); 252 253 template <typename T> 254 static ByteSource Allocated(const ncrypto::Buffer<T>& buffer) { 255 return Allocated(buffer.data, buffer.len); 256 } 257 258 static ByteSource Foreign(const void* data, size_t size); 259 260 static ByteSource FromEncodedString(Environment* env, 261 v8::Local<v8::String> value, 262 enum encoding enc = BASE64); 263 264 static ByteSource FromStringOrBuffer(Environment* env, 265 v8::Local<v8::Value> value); 266 267 static ByteSource FromString(Environment* env, 268 v8::Local<v8::String> str, 269 bool ntc = false); 270 271 static ByteSource FromBuffer(v8::Local<v8::Value> buffer, 272 bool ntc = false); 273 274 static ByteSource FromBIO(const ncrypto::BIOPointer& bio); 275 276 static ByteSource NullTerminatedCopy(Environment* env, 277 v8::Local<v8::Value> value); 278 279 static ByteSource FromSymmetricKeyObjectHandle(v8::Local<v8::Value> handle); 280 281 static ByteSource FromSecretKeyBytes( 282 Environment* env, v8::Local<v8::Value> value); 283 284 private: 285 const void* data_ = nullptr; 286 void* allocated_data_ = nullptr; 287 size_t size_ = 0; 288 289 ByteSource(const void* data, void* allocated_data, size_t size) 290 : data_(data), allocated_data_(allocated_data), size_(size) {} 291 }; 292 293 enum CryptoJobMode { 294 kCryptoJobAsync, 295 kCryptoJobSync 296 }; 297 298 CryptoJobMode GetCryptoJobMode(v8::Local<v8::Value> args); 299 300 template <typename CryptoJobTraits> 301 class CryptoJob : public AsyncWrap, public ThreadPoolWork { 302 public: 303 using AdditionalParams = typename CryptoJobTraits::AdditionalParameters; 304 305 explicit CryptoJob(Environment* env, 306 v8::Local<v8::Object> object, 307 AsyncWrap::ProviderType type, 308 CryptoJobMode mode, 309 AdditionalParams&& params) 310 : AsyncWrap(env, object, type), 311 ThreadPoolWork(env, "crypto"), 312 mode_(mode), 313 params_(std::move(params)) { 314 // If the CryptoJob is async, then the instance will be 315 // cleaned up when AfterThreadPoolWork is called. 316 if (mode == kCryptoJobSync) MakeWeak(); 317 } 318 319 bool IsNotIndicativeOfMemoryLeakAtExit() const override { 320 // CryptoJobs run a work in the libuv thread pool and may still 321 // exist when the event loop empties and starts to exit. 322 return true; 323 } 324 325 void AfterThreadPoolWork(int status) override { 326 Environment* env = AsyncWrap::env(); 327 CHECK_EQ(mode_, kCryptoJobAsync); 328 CHECK(status == 0 || status == UV_ECANCELED); 329 std::unique_ptr<CryptoJob> ptr(this); 330 // If the job was canceled do not execute the callback. 331 // TODO(@jasnell): We should likely revisit skipping the 332 // callback on cancel as that could leave the JS in a pending 333 // state (e.g. unresolved promises...) 334 if (status == UV_ECANCELED) return; 335 v8::HandleScope handle_scope(env->isolate()); 336 v8::Context::Scope context_scope(env->context()); 337 338 v8::Local<v8::Value> exception; 339 v8::Local<v8::Value> args[2]; 340 { 341 node::errors::TryCatchScope try_catch(env); 342 // If ToResult returns Nothing, then an exception should have been 343 // thrown and we should have caught it. Otherwise, args[0] and args[1] 344 // both should have been set to a value, even if the value is undefined. 345 if (ptr->ToResult(&args[0], &args[1]).IsNothing()) { 346 CHECK(try_catch.HasCaught()); 347 CHECK(try_catch.CanContinue()); 348 exception = try_catch.Exception(); 349 } 350 } 351 352 if (!exception.IsEmpty()) { 353 ptr->MakeCallback(env->ondone_string(), 1, &exception); 354 } else { 355 CHECK(!args[0].IsEmpty()); 356 CHECK(!args[1].IsEmpty()); 357 ptr->MakeCallback(env->ondone_string(), arraysize(args), args); 358 } 359 } 360 361 virtual v8::Maybe<void> ToResult(v8::Local<v8::Value>* err, 362 v8::Local<v8::Value>* result) = 0; 363 364 CryptoJobMode mode() const { return mode_; } 365 366 CryptoErrorStore* errors() { return &errors_; } 367 368 AdditionalParams* params() { return ¶ms_; } 369 370 const char* MemoryInfoName() const override { 371 return CryptoJobTraits::JobName; 372 } 373 374 void MemoryInfo(MemoryTracker* tracker) const override { 375 tracker->TrackField("params", params_); 376 tracker->TrackField("errors", errors_); 377 } 378 379 static void Run(const v8::FunctionCallbackInfo<v8::Value>& args) { 380 Environment* env = Environment::GetCurrent(args); 381 382 CryptoJob<CryptoJobTraits>* job; 383 ASSIGN_OR_RETURN_UNWRAP(&job, args.This()); 384 if (job->mode() == kCryptoJobAsync) 385 return job->ScheduleWork(); 386 387 v8::Local<v8::Value> ret[2]; 388 env->PrintSyncTrace(); 389 job->DoThreadPoolWork(); 390 if (job->ToResult(&ret[0], &ret[1]).IsJust()) { 391 CHECK(!ret[0].IsEmpty()); 392 CHECK(!ret[1].IsEmpty()); 393 args.GetReturnValue().Set( 394 v8::Array::New(env->isolate(), ret, arraysize(ret))); 395 } 396 } 397 398 static void Initialize( 399 v8::FunctionCallback new_fn, 400 Environment* env, 401 v8::Local<v8::Object> target) { 402 v8::Isolate* isolate = env->isolate(); 403 v8::HandleScope scope(isolate); 404 v8::Local<v8::Context> context = env->context(); 405 v8::Local<v8::FunctionTemplate> job = NewFunctionTemplate(isolate, new_fn); 406 job->Inherit(AsyncWrap::GetConstructorTemplate(env)); 407 job->InstanceTemplate()->SetInternalFieldCount( 408 AsyncWrap::kInternalFieldCount); 409 SetProtoMethod(isolate, job, "run", Run); 410 SetConstructorFunction(context, target, CryptoJobTraits::JobName, job); 411 } 412 413 static void RegisterExternalReferences(v8::FunctionCallback new_fn, 414 ExternalReferenceRegistry* registry) { 415 registry->Register(new_fn); 416 registry->Register(Run); 417 } 418 419 private: 420 const CryptoJobMode mode_; 421 CryptoErrorStore errors_; 422 AdditionalParams params_; 423 }; 424 425 template <typename DeriveBitsTraits> 426 class DeriveBitsJob final : public CryptoJob<DeriveBitsTraits> { 427 public: 428 using AdditionalParams = typename DeriveBitsTraits::AdditionalParameters; 429 430 static void New(const v8::FunctionCallbackInfo<v8::Value>& args) { 431 Environment* env = Environment::GetCurrent(args); 432 433 CryptoJobMode mode = GetCryptoJobMode(args[0]); 434 435 AdditionalParams params; 436 if (DeriveBitsTraits::AdditionalConfig(mode, args, 1, ¶ms) 437 .IsNothing()) { 438 // The DeriveBitsTraits::AdditionalConfig is responsible for 439 // calling an appropriate THROW_CRYPTO_* variant reporting 440 // whatever error caused initialization to fail. 441 return; 442 } 443 444 new DeriveBitsJob(env, args.This(), mode, std::move(params)); 445 } 446 447 static void Initialize( 448 Environment* env, 449 v8::Local<v8::Object> target) { 450 CryptoJob<DeriveBitsTraits>::Initialize(New, env, target); 451 } 452 453 static void RegisterExternalReferences(ExternalReferenceRegistry* registry) { 454 CryptoJob<DeriveBitsTraits>::RegisterExternalReferences(New, registry); 455 } 456 457 DeriveBitsJob( 458 Environment* env, 459 v8::Local<v8::Object> object, 460 CryptoJobMode mode, 461 AdditionalParams&& params) 462 : CryptoJob<DeriveBitsTraits>( 463 env, 464 object, 465 DeriveBitsTraits::Provider, 466 mode, 467 std::move(params)) {} 468 469 void DoThreadPoolWork() override { 470 ncrypto::ClearErrorOnReturn clear_error_on_return; 471 if (!DeriveBitsTraits::DeriveBits(AsyncWrap::env(), 472 *CryptoJob<DeriveBitsTraits>::params(), 473 &out_, 474 this->mode())) { 475 CryptoErrorStore* errors = CryptoJob<DeriveBitsTraits>::errors(); 476 errors->Capture(); 477 if (errors->Empty()) 478 errors->Insert(NodeCryptoError::DERIVING_BITS_FAILED); 479 return; 480 } 481 success_ = true; 482 } 483 484 v8::Maybe<void> ToResult(v8::Local<v8::Value>* err, 485 v8::Local<v8::Value>* result) override { 486 Environment* env = AsyncWrap::env(); 487 CryptoErrorStore* errors = CryptoJob<DeriveBitsTraits>::errors(); 488 if (success_) { 489 CHECK(errors->Empty()); 490 *err = v8::Undefined(env->isolate()); 491 if (!DeriveBitsTraits::EncodeOutput( 492 env, *CryptoJob<DeriveBitsTraits>::params(), &out_) 493 .ToLocal(result)) { 494 return v8::Nothing<void>(); 495 } 496 } else { 497 if (errors->Empty()) errors->Capture(); 498 CHECK(!errors->Empty()); 499 *result = v8::Undefined(env->isolate()); 500 if (!errors->ToException(env).ToLocal(err)) { 501 return v8::Nothing<void>(); 502 } 503 } 504 CHECK(!result->IsEmpty()); 505 CHECK(!err->IsEmpty()); 506 return v8::JustVoid(); 507 } 508 509 SET_SELF_SIZE(DeriveBitsJob) 510 void MemoryInfo(MemoryTracker* tracker) const override { 511 tracker->TrackFieldWithSize("out", out_.size()); 512 CryptoJob<DeriveBitsTraits>::MemoryInfo(tracker); 513 } 514 515 private: 516 ByteSource out_; 517 bool success_ = false; 518 }; 519 520 void ThrowCryptoError(Environment* env, 521 unsigned long err, // NOLINT(runtime/int) 522 const char* message = nullptr); 523 524 class CipherPushContext { 525 public: 526 inline explicit CipherPushContext(Environment* env) 527 : list_(env->isolate()), env_(env) {} 528 529 inline void push_back(const char* str) { 530 list_.emplace_back(OneByteString(env_->isolate(), str)); 531 } 532 533 inline v8::Local<v8::Array> ToJSArray() { 534 return v8::Array::New(env_->isolate(), list_.data(), list_.size()); 535 } 536 537 private: 538 v8::LocalVector<v8::Value> list_; 539 Environment* env_; 540 }; 541 542 #if OPENSSL_VERSION_MAJOR >= 3 543 template <class TypeName, 544 TypeName* fetch_type(OSSL_LIB_CTX*, const char*, const char*), 545 void free_type(TypeName*), 546 const TypeName* getbyname(const char*), 547 const char* getname(const TypeName*)> 548 void array_push_back(const TypeName* evp_ref, 549 const char* from, 550 const char* to, 551 void* arg) { 552 if (!from) 553 return; 554 555 const TypeName* real_instance = getbyname(from); 556 if (!real_instance) 557 return; 558 559 const char* real_name = getname(real_instance); 560 if (!real_name) 561 return; 562 563 // EVP_*_fetch() does not support alias names, so we need to pass it the 564 // real/original algorithm name. 565 // We use EVP_*_fetch() as a filter here because it will only return an 566 // instance if the algorithm is supported by the public OpenSSL APIs (some 567 // algorithms are used internally by OpenSSL and are also passed to this 568 // callback). 569 TypeName* fetched = fetch_type(nullptr, real_name, nullptr); 570 if (!fetched) 571 return; 572 573 free_type(fetched); 574 static_cast<CipherPushContext*>(arg)->push_back(from); 575 } 576 #else 577 template <class TypeName> 578 void array_push_back(const TypeName* evp_ref, 579 const char* from, 580 const char* to, 581 void* arg) { 582 if (!from) 583 return; 584 static_cast<CipherPushContext*>(arg)->push_back(from); 585 } 586 #endif 587 588 // WebIDL AllowSharedBufferSource. 589 inline bool IsAnyBufferSource(v8::Local<v8::Value> arg) { 590 return arg->IsArrayBufferView() || 591 arg->IsArrayBuffer() || 592 arg->IsSharedArrayBuffer(); 593 } 594 595 template <typename T> 596 class ArrayBufferOrViewContents { 597 public: 598 ArrayBufferOrViewContents() = default; 599 ArrayBufferOrViewContents(const ArrayBufferOrViewContents&) = delete; 600 void operator=(const ArrayBufferOrViewContents&) = delete; 601 602 inline explicit ArrayBufferOrViewContents(v8::Local<v8::Value> buf) { 603 if (buf.IsEmpty()) { 604 return; 605 } 606 607 CHECK(IsAnyBufferSource(buf)); 608 if (buf->IsArrayBufferView()) { 609 auto view = buf.As<v8::ArrayBufferView>(); 610 offset_ = view->ByteOffset(); 611 length_ = view->ByteLength(); 612 data_ = view->Buffer()->Data(); 613 } else if (buf->IsArrayBuffer()) { 614 auto ab = buf.As<v8::ArrayBuffer>(); 615 offset_ = 0; 616 length_ = ab->ByteLength(); 617 data_ = ab->Data(); 618 } else { 619 auto sab = buf.As<v8::SharedArrayBuffer>(); 620 offset_ = 0; 621 length_ = sab->ByteLength(); 622 data_ = sab->Data(); 623 } 624 } 625 626 inline const T* data() const { 627 // Ideally, these would return nullptr if IsEmpty() or length_ is zero, 628 // but some of the openssl API react badly if given a nullptr even when 629 // length is zero, so we have to return something. 630 if (empty()) return &buf; 631 return reinterpret_cast<T*>(data_) + offset_; 632 } 633 634 inline T* data() { 635 // Ideally, these would return nullptr if IsEmpty() or length_ is zero, 636 // but some of the openssl API react badly if given a nullptr even when 637 // length is zero, so we have to return something. 638 if (empty()) return &buf; 639 return reinterpret_cast<T*>(data_) + offset_; 640 } 641 642 inline size_t size() const { return length_; } 643 644 inline bool empty() const { return length_ == 0; } 645 646 // In most cases, input buffer sizes passed in to openssl need to 647 // be limited to <= INT_MAX. This utility method helps us check. 648 inline bool CheckSizeInt32() { return size() <= INT_MAX; } 649 650 inline ByteSource ToByteSource() const { 651 return ByteSource::Foreign(data(), size()); 652 } 653 654 inline ByteSource ToCopy() const { 655 if (empty()) return ByteSource(); 656 ByteSource::Builder buf(size()); 657 memcpy(buf.data<void>(), data(), size()); 658 return std::move(buf).release(); 659 } 660 661 inline ByteSource ToNullTerminatedCopy() const { 662 if (empty()) return ByteSource(); 663 ByteSource::Builder buf(size() + 1); 664 memcpy(buf.data<void>(), data(), size()); 665 buf.data<char>()[size()] = 0; 666 return std::move(buf).release(size()); 667 } 668 669 inline ncrypto::DataPointer ToDataPointer() const { 670 if (empty()) return {}; 671 if (auto dp = ncrypto::DataPointer::Alloc(size())) { 672 memcpy(dp.get(), data(), size()); 673 return dp; 674 } 675 return {}; 676 } 677 678 template <typename M> 679 void CopyTo(M* dest, size_t len) const { 680 static_assert(sizeof(M) == 1, "sizeof(M) must equal 1"); 681 len = std::min(len, size()); 682 if (len > 0 && data() != nullptr) { 683 memcpy(dest, data(), len); 684 } 685 } 686 687 private: 688 T buf = 0; 689 size_t offset_ = 0; 690 size_t length_ = 0; 691 void* data_ = nullptr; 692 693 // Declaring operator new and delete as deleted is not spec compliant. 694 // Therefore declare them private instead to disable dynamic alloc 695 void* operator new(size_t); 696 void* operator new[](size_t); 697 void operator delete(void*); 698 void operator delete[](void*); 699 }; 700 701 v8::MaybeLocal<v8::Value> EncodeBignum( 702 Environment* env, 703 const BIGNUM* bn, 704 int size, 705 v8::Local<v8::Value>* error); 706 707 v8::Maybe<void> SetEncodedValue(Environment* env, 708 v8::Local<v8::Object> target, 709 v8::Local<v8::String> name, 710 const BIGNUM* bn, 711 int size = 0); 712 713 bool SetRsaOaepLabel(const ncrypto::EVPKeyCtxPointer& rsa, 714 const ByteSource& label); 715 716 namespace Util { 717 void Initialize(Environment* env, v8::Local<v8::Object> target); 718 void RegisterExternalReferences(ExternalReferenceRegistry* registry); 719 } // namespace Util 720 721 } // namespace crypto 722 } // namespace node 723 724 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 725 #endif // SRC_CRYPTO_CRYPTO_UTIL_H_