Skip to content

Conversation

@gla5001
Copy link
Contributor

@gla5001 gla5001 commented Aug 10, 2017

Feature request to add openSSL error stack to the exception object
thrown from crypto. New exception property only added to object
if the error stack has not cleared out prior to calling
ThrowCryptoError.

Refs: #5444

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines
Affected core subsystem(s)

Feature request to add openSSL error stack to the exception object
thrown from crypto. New exception property only added to object
if the error stack has not cleared out prior to calling
ThrowCryptoError.

Refs: nodejs#5444
@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. crypto Issues and PRs related to the crypto subsystem. labels Aug 10, 2017
@gla5001
Copy link
Contributor Author

gla5001 commented Aug 10, 2017

Decided to open up this PR with my initial commit to get some general feedback to see if this is what was expected and if i'm on the right track. I didn't include any tests at this time since im just making sure what I have right now is correct. Once I know if this is correct or not, i'll add some tests.

void ThrowCryptoError(Environment* env,
unsigned long err, // NOLINT(runtime/int)
const char* default_message = nullptr) {
HandleScope scope(env->isolate());
Copy link
Contributor Author

@gla5001 gla5001 Aug 10, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Below is the bulk of the change. Updated ThrowCryptoError to get the current error state and add the stack to a new property on the exception object. I figured it would be a good idea to include the errorStack regardless if the error passed in is a default_message or openSSL error.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also. Do i need to change any documentation on this? if so, where is it located?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docs would be somewhere in here: https://github.com/nodejs/node/blob/master/doc/api/errors.md#class-error

There is no specific class for crypto errors, so docs will just have to go with generic Error but described as "only for crypto"


ClearErrorOnReturn clear_error_on_return;
// ClearErrorOnReturn clear_error_on_return;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so i comment out this line for now. Maybe i'm wrong, but it feels like this was in the wrong spot. This is not the binding function and I thought the openssl's error stack needs to be balanced upon entry and exit of the VerifyFinal bound function. So i moved it there. Please let me know if im wrong and I'll uncomment this and remove the line from the bound function, but I might need a little guidance on what I need to move around to not clear out the error stack when exiting this function. Maybe we just throw the error from this function instead of the bound function?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You make a compelling case, but I would have to look more closely and don't have time right now. I think there was a bug recently where sign failure was causing subsequent operations to fail because stack wasn't cleared, but that just means its important to do, not that its important to do here, so this needs careful thought.


ERR_set_mark();

bp = BIO_new_mem_buf(const_cast<char*>(key_pem), key_pem_len);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setting the err mark. #5444 (comment). Im not sure where else we might need to do this in this file.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I admit I don't understand why that is necessary when you have a ClearErrorOnReturn in the binding function.


ClearErrorOnReturn clear_error_on_return;

Verify* verify;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here is adding the clear_error_on_return in the function thats bound


Verify* verify;
ASSIGN_OR_RETURN_UNWRAP(&verify, args.Holder());

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will add tests once I know if this is correct route to handle this or what I need to change


exception->Set(env->context(), key, errorStack).FromJust();
env->isolate()->ThrowException(exception);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new property looks like this

openSSLErrorStack:
[ 'error:0906700D:PEM routines:PEM_ASN1_read_bio:ASN1 lib',
  'error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error' ]

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Useful comment, please put it in the source code

@Trott
Copy link
Member

Trott commented Aug 10, 2017

@nodejs/crypto

ERR_error_string_n(err, errmsg, sizeof(errmsg));
env->ThrowError(errmsg);
message = String::NewFromUtf8(env->isolate(), errmsg,
v8::NewStringType::kInternalized)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe the performance diff isn't observable, but I wonder if errors are thrown enough for it to be worth internalizing the string

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll change this to normal and the one below in the else


Local<Value> exception_v = Exception::Error(message);
CHECK(!exception_v.IsEmpty());
// add the openSSLErrorStack property
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

node comment style is to have capitalized and punctuated sentences, pls take a look at all the comments


// get the error state
// will only add to errorStack if state has not been cleared out
ERR_STATE *es;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merge this line with next, so declaration and initialization is done in one line


// add content to the openssl error stack
unsigned int i = 0;
while (es->bottom != es->top
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

given that this while loop has an initialization before it, and increments its state at the end, should it be a for loop?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup. Will do

unsigned long err_buf = es->err_buffer[es->top]; // NOLINT(runtime/int)
// only add if there is valid err_buffer
if (err_buf) {
char tmpStr[128] = { 0 };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd choose 256, it is what ERR_error_string() uses. I think it doesn't need zero initialization, ERR_error_string_n() terminates.


exception->Set(env->context(), key, errorStack).FromJust();
env->isolate()->ThrowException(exception);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Useful comment, please put it in the source code


ClearErrorOnReturn clear_error_on_return;
// ClearErrorOnReturn clear_error_on_return;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You make a compelling case, but I would have to look more closely and don't have time right now. I think there was a bug recently where sign failure was causing subsequent operations to fail because stack wasn't cleared, but that just means its important to do, not that its important to do here, so this needs careful thought.

void ThrowCryptoError(Environment* env,
unsigned long err, // NOLINT(runtime/int)
const char* default_message = nullptr) {
HandleScope scope(env->isolate());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docs would be somewhere in here: https://github.com/nodejs/node/blob/master/doc/api/errors.md#class-error

There is no specific class for crypto errors, so docs will just have to go with generic Error but described as "only for crypto"

@gla5001
Copy link
Contributor Author

gla5001 commented Aug 11, 2017

Added some updates from previous review and tests

const credentials = tls.createSecureContext(options);
const context = credentials.context;
const notcontext = { setOptions: context.setOptions, setKey: context.setKey };
tls.createSecureContext({ secureOptions: 1 }, notcontext);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated tests below to check for existence of new openSSLErrorStack property for when it should and should not be there

@addaleax
Copy link
Member

ping @sam-github, most of your comments have been addressed

provide a text description of the error.
provide a text description of the error. For crypto only, `Error` objects will
include the OpenSSL error stack, if it's available when the error is thrown, in
a separate property.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tiny nits: use long forms (it'sit is) and I’d put the sentence in a new paragraph.

env->ThrowError(errmsg);
message = String::NewFromUtf8(env->isolate(), errmsg,
v8::NewStringType::kNormal)
.ToLocalChecked();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tiny style nit: 4 spaces indentation for statement continuations (applies elsewhere too)

Local<Object> exception = exception_v.As<Object>();
Local<String> key = String::NewFromUtf8(env->isolate(), "openSSLErrorStack",
v8::NewStringType::kInternalized)
.ToLocalChecked();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can feel free to add this to the list in env.h. (Also, using FIXED_ONE_BYTE_STRING should be okay here too.)

Copy link
Contributor Author

@gla5001 gla5001 Aug 14, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@addaleax thanks for reviewing this. Just to clarify, you're saying that I could add the property to list in env.h or use FIXED_ONE_BYTE_STRING, correct?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes – either one is fine, and I’d have a slight preference for the former :)

// The openSSL stack should have content.
if ((err instanceof Error) &&
/asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag/.test(err) &&
err.openSSLErrorStack !== undefined &&
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe be more specific here and check Array.isArray(err.openSSLErrorStack)?

v8::NewStringType::kNormal)
.ToLocalChecked();
.ToLocalChecked();
} else {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added additional space to these since its a continuation of line

Local<Object> exception = exception_v.As<Object>();
Local<Array> errorStack = Array::New(env->isolate());

ERR_STATE *es = ERR_get_state();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to allocate memory, where does that get freed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought that the openssl lib would take care of this, but maybe my assumption is incorrect?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m not sure myself. 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My thinking is that we should probably just let the openssl lib free the memory. ERR_get_state will return a pointer to the err state struct that was allocated by openssl. If we try to free that memory here, wont that cause potential issues down the line if other functions need to access it/try to read the reference it has to it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can't (shouldn't) free the memory, openssl takes care of it internally.

if (err_buf) {
char tmpStr[256] = { };
ERR_error_string_n(err_buf, tmpStr, sizeof(tmpStr));
errorStack->Set(i, String::NewFromUtf8(env->isolate(), tmpStr,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you always use the overload of Set() that takes a context argument/returns a Maybe? The other one is deprecated.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And its ok that I get a compiler warning warning: ignoring return value of function declared with 'warn_unused_result' attribute?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You’d call .FromJust()on the result, just like .ToLocalChecked() for MaybeLocals :)

Local<Object> exception = exception_v.As<Object>();
Local<Array> errorStack = Array::New(env->isolate());

ERR_STATE *es = ERR_get_state();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can't (shouldn't) free the memory, openssl takes care of it internally.

Local<Value> exception_v = Exception::Error(message);
CHECK(!exception_v.IsEmpty());
Local<Object> exception = exception_v.As<Object>();
Local<Array> errorStack = Array::New(env->isolate());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style issue: use snake_case for locals, not camelCase.

@gla5001
Copy link
Contributor Author

gla5001 commented Aug 18, 2017

So i believe i have addressed everyones review comments. The only thing left outstanding is the comment about moving ClearErrorOnReturn clear_error_on_return; in the first commit. Any additional inout would be great.

@gla5001
Copy link
Contributor Author

gla5001 commented Aug 24, 2017

There has not been any activity on this for several days now. @addaleax @bnoordhuis is there anything else that should be done on this?

@addaleax
Copy link
Member

@gla5001 Thanks for the ping – as far as I am concerned, the code looks good, but I’m not familiar enough with OpenSSL’s APIs to give this an approval.

ping @nodejs/crypto

TimothyGu and others added 3 commits September 12, 2017 08:25
When ESM support was added it created a regression in the test runner
that broke the ability to run individual tests. This commit
re-introduces the use of `NormalizePath` which fixes the regression
in the test runner

Refs: nodejs#15300
PR-URL: nodejs#15329
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Gibson Fahnestock <gibfahn@gmail.com>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Update AUTHORS list using tools/update-authors.sh.
Update .mailmap to handle duplicates.

PR-URL: nodejs#15181
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Timothy Gu <timothygu99@gmail.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Reviewed-By: Khaidi Chu <i@2333.moe>
Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Roman Reiss <me@silverwind.io>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
PR-URL: nodejs#15002
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
gergelyke and others added 6 commits September 20, 2017 10:42
PR-URL: nodejs#15235
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Daijiro Wachi <daijiro.wachi@gmail.com>
`domain.dispose()` is generally considered an anti-pattern, has been
runtime-deprecated for over 4 years, and is a part of the `domain`
module that can not be emulated by `async_hooks`; so remove it.

Ref: https://nodejs.org/en/docs/guides/domain-postmortem/
Ref: 4a74fc9

PR-URL: nodejs#15412
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
Currently the following compiler warning is generated:
1 warning generated.
../src/udp_wrap.cc:238:12: warning: comparison of integers of different
signs: 'int' and 'uint32_t' (aka 'unsigned int') [-Wsign-compare]
  if (size != args[0].As<Uint32>()->Value()) {
      ~~~~ ^  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.

This commit changes the check to see that the Uint32 value does not
exceed the max int size instead of first casting and then comparing.

PR-URL: nodejs#15402
Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
The list is defunct at this point.
I believe this to be in effect a minor defect from
3eecdf9

PR-URL: nodejs#8422
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Julien Gilli <jgilli@nodejs.org>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Refs: nodejs#14985
PR-URL: nodejs#15461
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Fixes: nodejs#14577
PR-URL: nodejs#14581
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: James M Snell <jasnell@gmail.com>
@sam-github
Copy link
Contributor

All my comments addressed, so LGTM

I haven't had time to review for #14725 (comment), though, and still don't, so someone else will have to sign off on that.

@gla5001
Copy link
Contributor Author

gla5001 commented Sep 20, 2017

thanks @sam-github

@sam-github
Copy link
Contributor

btw, looks like it needs rebasing.

@gla5001
Copy link
Contributor Author

gla5001 commented Sep 20, 2017

yeah, i'll take care of that once I get a few more approvals.

@sam-github
Copy link
Contributor

ping @nodejs/crypto

Copy link
Member

@bnoordhuis bnoordhuis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bikeshed: anyone have opinions on the .openSSLErrorStack property name?

Performance: creating an array and setting a property for every exception might not be cheap.

provide a text description of the error.

For crypto only, `Error` objects will include the OpenSSL error stack in a
separate property if it is available when the error is thrown.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you name the property here?

Local<Object> exception = exception_v.As<Object>();
Local<Array> error_stack = Array::New(env->isolate());

ERR_STATE *es = ERR_get_state();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style: star leans left.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup. will fix

ERR_STATE *es = ERR_get_state();
// Build the error_stack array to be added to openSSLErrorStack property.
for (unsigned int i = 0; es->bottom != es->top
&& (es->err_flags[es->top] & ERR_FLAG_MARK) == 0; i++) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't look correct to me. For starters, es->top and es->bottom should be restored after you're done. Second, this assumes es->bottom <= es->top but that isn't necessarily true because it's a ring buffer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok. i think i understand. I'll fix this

unsigned long err_buf = es->err_buffer[es->top]; // NOLINT(runtime/int)
// Only add error string if there is valid err_buffer.
if (err_buf) {
char tmpStr[256] = { };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style: snake_case and no init necessary.

// 'error:0906700D:PEM routines:PEM_ASN1_read_bio:ASN1 lib',
// 'error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error'
// ]
exception->Set(env->openssl_error_stack(), error_stack);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you use the Set() that takes a Local<Context>?


ERR_set_mark();

bp = BIO_new_mem_buf(const_cast<char*>(key_pem), key_pem_len);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I admit I don't understand why that is necessary when you have a ClearErrorOnReturn in the binding function.

vsemozhetbyt and others added 11 commits September 20, 2017 22:39
PR-URL: nodejs#15463
Fixes: nodejs#15462
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
PR-URL: nodejs#15481
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Bryan English <bryan@bryanenglish.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
PR-URL: nodejs#13003
Fixes: nodejs#12951
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
V8 platform tasks may schedule other tasks (both background and
foreground), and may perform asynchronous operations like
resolving Promises.

To address that:

- Run the task queue drain call inside a callback scope.
  This makes sure asynchronous operations inside it, like
  resolving promises, lead to the microtask queue and any
  subsequent operations not being silently forgotten.
- Move the task queue drain call before `EmitBeforeExit()`
  and only run `EmitBeforeExit()` if there is no new event
  loop work.
- Account for possible new foreground tasks scheduled by
  background tasks in `DrainBackgroundTasks()`.

PR-URL: nodejs#15428
Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Matthew Loring <mattloring@google.com>
Feature request to add openSSL error stack to the exception object
thrown from crypto. New exception property only added to object
if the error stack has not cleared out prior to calling
ThrowCryptoError.

Refs: nodejs#5444
@gla5001
Copy link
Contributor Author

gla5001 commented Sep 21, 2017

having some git issues. will resolve them

@gla5001 gla5001 mentioned this pull request Sep 21, 2017
4 tasks
@gla5001
Copy link
Contributor Author

gla5001 commented Sep 21, 2017

I did something terribly wrong git wise here. i opened a new PR #15518 with all the updated changes. Please review that. I am closing this PR.

@gla5001 gla5001 closed this Sep 21, 2017
@sam-github
Copy link
Contributor

FYI, for next time, you can force push a branch to replace it's contents without closing a PR.

@gla5001
Copy link
Contributor Author

gla5001 commented Sep 21, 2017

cool. thanks for the tip.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c++ Issues and PRs that require attention from people who are familiar with C++. crypto Issues and PRs related to the crypto subsystem.

Projects

None yet

Development

Successfully merging this pull request may close these issues.