-
Notifications
You must be signed in to change notification settings - Fork 610
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
added parallel certificate verification #47
Conversation
|
||
} | ||
|
||
fn parallel_verify_common_cert<'a>(roots: &RootCertStore, |
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.
Am I missing something or is this an exact copy of verify_common_cert
?
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.
there's a minute change--I'm using par_iter instead.
When I was looking at performance, parallelizing wasn't improving the code at all, so parallel_verify_common_cert uses rayon to convert from rustls to webpki structures. After that, performance improved. I didn't necessarily want to make permanent changes to the serial code (but I can).
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.
Well, it's just my two cents -- I am also just a curious wanna-be contributer:
I think it's probably better not to duplicate such a critical part of the code, so we might be better off find solution that is flexible in whether processing it in parallel or not.
I have no idea how @ctz thinks about adding new dependencies.
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.
Is maybe possible to make verify_common_cert()
take a presented_certs
of some Iter
trait? (I am not familiar with the details of rayon and its compatibility to std)
Hey @avadacatavra, good performance catch! |
@manuels I can make my performance results readable and post them in a few hours :) |
I think the performance you're seeing is likely explained by briansmith/ring#431 But doing cert checks in parallel against all the roots is a very interesting idea. @briansmith how would you feel about that at the webpki level? |
pub fn parallel_verify_server_cert(roots: &RootCertStore, | ||
presented_certs: &Vec<ASN1Cert>, | ||
dns_name: &str) -> Result<(), TLSError> { | ||
crossbeam::scope(|scope| { |
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.
How would the Rustls user control the level of parallelism (how many threads are used)?
I suspect that you don't want to parallelize the entire certificate chain verification, for efficiency (battery use) reasons. Many certificate will have multiple chains that are valid, and each chain requires verifying a bunch of signatures, so if you do the whole path building in parallel, you'll end up doing a bunch of extra signature verifications, which are very expensive. I will explain the multiple ways you already parallelize certificate verification without increasing CPU consumption:
|
Regarding sending CertificateVerify before we've verified the server's identity: If we're not doing client auth then it is clearly OK. If we're doing client auth (signing with our own private key and sending our own certificate) then it is debatable whether we should send a proof of our identity without having verified the server's identity first. In Firefox/NSS, I decided to not send the CertificateVerify message until the server's identity has been validated (all signatures verified). |
Could you please list the 13 sites? And also which version of OpenSSL? |
@briansmith Those results used OpenSSL 1.0.2i. I've also run my tests with OpenSSL OpenSSL 1.0.2k, which was slightly faster (71ms vs 77ms for total connection time) The sites are:
Servo is currently using rust-openssl v0.7.14. Part of the Servo PR is a bump to v.0.9.6. There's an OpensslClient in hyper-openssl, but that doesn't allow us to customize the verification method. |
@avadacatavra Great, thanks for the list. Looking over that list, I see there is a mix of algorithms (RSA and ECDSA) and key sizes (P-256 and P-384, RSA 2048 and larger). Given TLS is complex and the crypto primitives used are also complex, there could be multiple performance issues, so we need to find a way to isolate the performance issues. I filed briansmith/crypto-bench#24 and briansmith/crypto-bench#25 for investigating the performance of signature verification between ring and OpenSSL. I also filed briansmith/webpki#38 for isolating the certificate chain verification from anything in Rustls. |
@briansmith there's more numbers here: https://avadacatavra.github.io/servo/2016/02/07/webpkiresults.html |
What's the status on this? |
@nox status is that I had to finish the hyper bump and XOW before returning to this :) |
This needs a rebase. |
I think there are lower hanging fruit for making the performance competitive here. Not that I dislike the idea of parallelising this; and if rustls had a (perhaps optional) dependency on rayon or something I would also use it in the record layer too. |
Hey @avadacatavra I'm adding benchmarks for cert verification for all these sites, and can't find a CNN site with a valid certificate (they do TLS, but present a certificate for 'a.ssl.fastly.net'). What hostname were you using? edit: missed the bit in your blog post about cnn being non-TLS. Sorry for the noise! |
@ctz thanks for working on the benchmarks--I'm wrapping up some other projects that took priority over the past few weeks, then hoping to get back to this and related projects |
As discussed above, I think there are opportunities to do some operations in parallel but the approach in this PR is really inefficient. The performance issue with RSA signature verification in ring was fixed a while back, and I think this PR was basically a workaround for that issue. So I think this should be closed. |
I'm working on using webpki and rustls in Servo. This PR will allow that.
When evaluating performance, I found that verify_server_cert was slower than using openssl, so I created two parallel functions to improve performance.
Performance evaluation: I connected to 13 https sites using verify_server_cert, parallel_verify_server_cert, and the openssl code currently used in servo.
Average time to establish a connection using:
I plan to continue to look for improvements.