-
Notifications
You must be signed in to change notification settings - Fork 29.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
src: refactor GetPeerCertificate #17372
Conversation
src/node_crypto.cc
Outdated
// Put issuer inside the object | ||
static void AddIssuer(X509** cert, | ||
const STACK_OF(X509)* const peer_certs, | ||
Local<Object>* const info, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this a pointer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason was so that code in GetPeerCertificate depends on the value being pointed to by info
be updated. But I realise that info
does not have to be a pointer and we only need update it's pointer for this to work. Not sure if that made sense but I'll add a commit and hopefully this will become clearer. Thanks for pointing this out.
src/node_crypto.cc
Outdated
continue; | ||
|
||
Local<Object> ca_info = X509ToObject(env, ca); | ||
(*info)->Set(env->issuercert_string(), ca_info); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feel free to switch this over to the non-deprecated overload of Set()
if you like :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah good point, I'll update to use the function taking a context. Thanks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Related: it would be more efficient to move these two lines out of the loop. Likewise in GetLastIssuedCert()
.
src/node_crypto.cc
Outdated
|
||
static X509* GetLastIssuedCert(X509** cert, | ||
const SSL* const ssl, | ||
Local<Object>* const info, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar question here
src/node_crypto.cc
Outdated
// Put issuer inside the object | ||
static void AddIssuer(X509** cert, | ||
const STACK_OF(X509)* const peer_certs, | ||
Local<Object>* const info, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't have to pass a pointer since you don't replace the Object, just add properties to it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I've changed this now (locally).
src/node_crypto.cc
Outdated
@@ -1974,7 +1974,78 @@ static Local<Object> X509ToObject(Environment* env, X509* cert) { | |||
} | |||
|
|||
|
|||
// TODO(indutny): Split it into multiple smaller functions | |||
// Put issuer inside the object |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a hugely useful comment. If you call the function AddIssuerToObject()
, it's self-documenting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like that, I'll rename the function.
src/node_crypto.cc
Outdated
(*info)->Set(env->issuercert_string(), ca_info); | ||
*info = ca_info; | ||
|
||
// NOTE: Intentionally freeing cert that is not used anymore |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since you're here, can you punctuate the comments?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Absolutely.
src/node_crypto.cc
Outdated
Local<Object>* const info, | ||
Environment* const env) { | ||
*cert = sk_X509_delete(peer_certs, 0); | ||
while (sk_X509_num(peer_certs) > 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unrelated observation: I think this could just be for (;;) {
- the same check is effectively done at the end of the loop when i == 0
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, I'll take a closer look at this.
src/node_crypto.cc
Outdated
return false; | ||
} | ||
return true; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be nicer (certainly more Obviously Correct) to move the sk_X509_pop_free()
on error into this function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll take a look and fix this. Thanks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've pushed a few commit but I've not addressed this yet. Will revisit this next week. I was wondering if you meant that I add sk_X509_pop_free() to this function in addition to the one in GetPeerCertificate which I think is needed as peer_cert is used after this function?
src/node_crypto.cc
Outdated
continue; | ||
|
||
Local<Object> ca_info = X509ToObject(env, ca); | ||
(*info)->Set(env->issuercert_string(), ca_info); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Related: it would be more efficient to move these two lines out of the loop. Likewise in GetLastIssuedCert()
.
src/node_crypto.cc
Outdated
if (!sk_X509_push(peer_certs, cert)) | ||
goto done; | ||
if (!CloneSSLCerts(&cert, &peer_certs, ssl_certs)) { | ||
goto done; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you drop the braces for consistency with the surrounding code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I'll remove them
src/node_crypto.cc
Outdated
// TODO(indutny): Split it into multiple smaller functions | ||
// Put issuer inside the object | ||
static void AddIssuer(X509** cert, | ||
const STACK_OF(X509)* const peer_certs, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
peer_certs
can't be const because it's modified inside the function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I've changed that now.
7042685
to
476e116
Compare
I've pushed a few commit but I've not addressed this yet. Will revisit this next week. |
@bnoordhuis I've been looking into moving these lines out of the loop and ran into an issue. My understanding is that this code is creating a link/chain of
Without setting the |
src/node_crypto.cc
Outdated
Local<Object> ca_info = X509ToObject(env, ca); | ||
info->Set(env->issuercert_string(), ca_info); | ||
info = ca_info; | ||
// Clone `ssl_certs`, because we are going to destruct it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: destruct
→ destroy
? :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps this comment could be remove now. Just reading it again perhaps the method signature should be changed to:
if (CloneSSLCerts(&cert, ssl_certs, &peer_certs)) {
What do you think, would that be clear without the comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, self-explanatory now.
src/node_crypto.cc
Outdated
continue; | ||
|
||
Local<Object> ca_info = X509ToObject(env, ca); | ||
object->Set(context, env->issuercert_string(), ca_info).ToChecked(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we've settled on .FromJust()
(232 vs 44 hits for .ToChecked()
at the time of writing.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I'll correct these.
src/node_crypto.cc
Outdated
break; | ||
|
||
Local<Object> ca_info = X509ToObject(env, ca); | ||
issuer_chain->Set(context, env->issuercert_string(), ca_info).ToChecked(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Likewise.
src/node_crypto.cc
Outdated
// NOTE: Intentionally freeing cert that is not used anymore | ||
X509_free(cert); | ||
issuer_chain = AddIssuerToObject(result, &cert, peer_certs, env); | ||
issuer_chain = GetLastIssuedCert(&cert, w->ssl_, issuer_chain, env); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right you can't factor out the .Set()
calls because they build up a linked list but that arguably makes AddIssuerToObject()
a bit of a misnomer.
Can you try to pass arguments in the same order to both functions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps a better name would be AddIssuerChainToObject?
Can you try to pass arguments in the same order to both functions?
Yep, I'll update the order. Thanks
src/node_crypto.cc
Outdated
Local<Object> ca_info = X509ToObject(env, ca); | ||
info->Set(env->issuercert_string(), ca_info); | ||
info = ca_info; | ||
// Clone `ssl_certs`, because we are going to destruct it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, self-explanatory now.
test/windows-fanned failure looks unrelatedERROR: Error fetching remote repo 'jenkins_tmp'
hudson.plugins.git.GitException: Failed to fetch from [email protected]:janeasystems/node_binary_tmp.git
at hudson.plugins.git.GitSCM.fetchFrom(GitSCM.java:825)
at hudson.plugins.git.GitSCM.retrieveChanges(GitSCM.java:1092)
at hudson.plugins.git.GitSCM.checkout(GitSCM.java:1123)
at hudson.scm.SCM.checkout(SCM.java:495)
at hudson.model.AbstractProject.checkout(AbstractProject.java:1202)
at hudson.model.AbstractBuild$AbstractBuildExecution.defaultCheckout(AbstractBuild.java:574)
at jenkins.scm.SCMCheckoutStrategy.checkout(SCMCheckoutStrategy.java:86)
at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:499)
at hudson.model.Run.execute(Run.java:1724)
at hudson.matrix.MatrixRun.run(MatrixRun.java:146)
at hudson.model.ResourceController.execute(ResourceController.java:97)
at hudson.model.Executor.run(Executor.java:421)
Caused by: hudson.plugins.git.GitException: Command "git reset --hard" returned status code 128:
stdout:
stderr: fatal: Unable to create 'c:/workspace/node-test-binary-windows/.git/index.lock': File exists. |
@bnoordhuis When you get a chance would you be able to take a look at the lastest updates and see what you think? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with two requests.
} | ||
} | ||
if (!result) { | ||
sk_X509_pop_free(*peer_certs, X509_free); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In a similar vein, can you add *peer_certs = nullptr;
?
} | ||
sk_X509_pop_free(peer_certs, X509_free); | ||
return object; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a suggestion but it would be better if this function didn't mutate and invalidate peer_certs
.
Failing that, perhaps pass peer_certs
as an indirect pointer and set *peer_certs = nullptr
; here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good, I'll take a look. Thanks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with @bnoordhuis suggestion
@danbev would you be so kind and please update this accordingly to the suggestions? :-) |
@BridgeAR I hope to revisit this next week (though I've got a sick kid here and I might not be working at all next week by the looks of it) |
Ping @danbev |
1 similar comment
Ping @danbev |
@BridgeAR I've just not had time to revisit this yet but intend to. |
9806458
to
d00841b
Compare
@bnoordhuis @jasnell @addaleax PTAL |
I'm setting this to |
PR-URL: nodejs#17372 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]>
#19087 - had 30 minutes to kill. :-) |
Closing in favour of #19087 |
These commits split the GetPeerCertificate function into smaller function as described in the TODO comment:
// TODO(indutny): Split it into multiple smaller functions
I've mostly left the code as it was and want to trigger CI to pick up any issues.
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
src