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