GnuTLS implementation for TLS listening ports and client connections#81
GnuTLS implementation for TLS listening ports and client connections#81yadij merged 29 commits intosquid-cache:masterfrom
Conversation
1ab5953 to
f832ff1
Compare
rousskov
left a comment
There was a problem hiding this comment.
I agree that it would be good for @chtsanti to review this, but I know he has a lot on his plate right now. I am submitting this review in hope to help you make progress with this PR while you are waiting for Christos.
Also fixes the definitions for the CertPointer and PrivateKeyPointer.
Thank you! I hope this fix works well with all important compilers.
Enable most of the http(s)_port listening socket logic to always build except where OpenSSL-specific dependency still exists.
"Always build" sounds like a good thing, but after reading the proposed code, I fear that a more accurate description would be closer to "make more non-OpenSSL TLS code compile even though it does not really work yet". I did my best to give specific/constructive code comments, but I fear a deeper problem/conflict here.
IMO, added code must work (correctly) when reached. It must not ignore or hide errors. It should do something useful (other than producing errors). It should be reachable. Naturally, there are exceptions to this rule of thumb, but those exceptions should be backed by some very convincing arguments. This PR appears to add code that compiles but, for every HTTPS connections produces the following runtime ERRORs:
- "HTTPS not supported by this Squid" (when built without OpenSSL and without GnuTLS support) or
- "clientNegotiateSSL session logics not implemented" (when built with GnuTLS support)
If the above is happening in PR code, then I have to question the value of supporting such totally broken/unusable configurations (at the expense of making the code a lot more complex). If the above is not happening because the corresponding tryTlsHandshake() (or its caller) code is never reached in those two cases, then I have to question the value of adding so much unreachable (and complex!) code.
GnuTLS implementation is added for the basic https_port logic pathway and TLS handshake.
Does this PR add working, production-ready support for any Squid features when Squid is built with GnuTLS? If yes, what are they? I cannot tell whether the current "basic https_port logic pathway" and "TLS handshake" descriptions mean something like "some parts of some TLS-related features are working with GnuTLS now (but nothing new fully works)" or "Squid features X and Y can now be used in production with GnuTLS". IMO, the difference between the two cases is critical for admins and reviewers alike, but the PR description does not have enough information for me to understand support for which Squid features (if any) was actually added to GnuTLS builds.
src/cf.data.pre
Outdated
| TLS / SSL Options: | ||
|
|
||
| cert= Path to SSL certificate (PEM format). | ||
| tls-cert= Path to TLS server certificate (PEM format). |
There was a problem hiding this comment.
AFAICT, technically, there is no such thing as a "server certificate" in this context. A server may use a certificate, of course, but that use does not change the certificate itself. There is also a TLS Server Certificate message (containing X509 certificates), but this option is not about that message, of course.
Similarly, there is no "TLS certificate" or "SSL certificate". Most certificates we deal with are X509 certificates that have nothing to do with SSL or TLS. SSL and TLS use X509 format of public key certificates, of course, but that does not make the certificate they use a "TLS certificate".
I suggest leaving this option as is, but if you have to change it, describe it as "Public key certificate in PEM format. Used to ..." or something like that.
Essentially the same can be said about tls-key.
There was a problem hiding this comment.
There have been a few issues in squid-users already from people working with that idea that all certs are equivalent and encountering "invalid certificate" errors as a result.
Certificates containing TLS extension fields cannot always be used by SSL protocol. Likewise minimal certificates for SSL lack fields TLS is increasingly making mandatory at the higher protocol level. That small but critical detail is making the idea that there is no distinction between the protocols and server vs client certs be false.
Certificates loaded here are increasingly generated for TLS use and contain the KeyUsage extension field. When that is used only certificates marked as being for servers can be added to a server context. Admin configuring a cert= with a X509 cert marked for client-only usage will get errors from the library on each client connection attempt. It needs to be not marked at all ("SSL certificate") or marked with TLS extensions for server usage ("TLS server certificate").
There was a problem hiding this comment.
Yes, many certificates are unusable in a given context. IMHO, that fact does not justify using misleading/inaccurate (for this context) terminology such as "server certificate", "TLS certificate", or "SSL certificate".
If you think that cert= documentation should describe required (or even desirable) certificate properties, I do not think anybody would object to such a change. My complaint was not about adding such descriptions.
There was a problem hiding this comment.
Fair enough. I've applied a change to call the server port certificates just 'X.509 certificate' and describe the requirements in separate paragraphs.
src/cf.data.pre
Outdated
| if not specified, the certificate file is | ||
| assumed to be a combined certificate and | ||
| key file. | ||
| When OpenSSL or LibreSSL is used this file may also |
There was a problem hiding this comment.
I do not think we should mention LibreSSL in squid.conf because I do not think we should imply any support for that library (until we have the resources to properly support it).
There was a problem hiding this comment.
This is one of the few things that have been tested with LibreSSL. Removed anyway.
There was a problem hiding this comment.
Thank you for addressing this request.
The admin does not know what has been tested, and the boundaries of the tested "it" are always vague. Once they see "LibreSSL" mentioned like this, many admins naturally expect LibreSSL to be supported and work in general.
src/client_side.cc
Outdated
| static int | ||
| Squid_SSL_accept(ConnStateData *conn, PF *callback) | ||
| static bool | ||
| tryTlsHandshake(ConnStateData *conn, PF *callback) |
There was a problem hiding this comment.
Please remove "try" from the function name. We sometimes use the "try" prefix for throwing routines that have a try/catch wrapper around them, but the use case is (currently) different here (and even the original try/catch use case is rather questionable as far as naming is concerned -- fooOrThrow() is often a better name in those cases).
There was a problem hiding this comment.
Please use "accept" instead of "handshake" in the function name. There are several kinds of handshakes in this context. Saying "accept" here clarifies things a lot!
There was a problem hiding this comment.
Overall, it seems like the proposed monolith tryTlsHandshake() function should be replaced with:
- one
TlsAcceptOrThrow()function per OpenSSL/GnuTLS/none library plus - a generic try/catch TlsAccept() wrapper that closes the connection on failures.
There was a problem hiding this comment.
This function is where the "TLS connection" concept using handshakes as a pseudo-accept() starts to fall down. It is the callback run after TCP accept(). It attempts to perform a TLS handshake, but may result in 0-N handshakes happening - in that 0 case there is "anonymous TLS", aka TLS with no session / "connection".
It just happens that OpenSSL API is not capable of the latter TLS/1.2+ feature so it uses the badly named function "SSL_accept()" and dies if no handshake occurs.
I'm using 'attempt' instead of 'try', but not adding 'accept' into the naming.
There was a problem hiding this comment.
This function is where the "TLS connection" concept using handshakes as a pseudo-accept() starts to fall down
I see no evidence of that. Yes, accepts may happen at different layers (e.g., TCP, TLS, and application). There is nothing wrong or even confusing about that IMO.
It attempts to perform a TLS handshake, but may result in 0-N handshakes happening
Counting the number of handshakes sounds like splitting hairs to me. I doubt the concept of a handshake (if it is formally defined) allows for such counting and even if it is, there seems to be no point in counting individual "shakes" when we are talking about naming a function that does them.
that 0 case there is "anonymous TLS", aka TLS with no session / "connection".
My quick search for these terms failed to find any relevant matches. If you are sure this is something we should be discussing, please provide pointers defining the relevant "anonymous TLS" concept.
I'm using 'attempt' instead of 'try', but not adding 'accept' into the naming.
I am considering this problem as unresolved. I am not married to the word "accept" (even though the term fits the bill very well), but we should (continue to) distinguish client-Squid handshakes from Squid-server handshakes.
src/client_side.cc
Outdated
| * \retval -1 on error | ||
| * \retval true on success | ||
| * \retval false when needs more data | ||
| * \retval false when an error occured and closes the TCP connection |
There was a problem hiding this comment.
To fix spelling and improve grammar, please s/occured and closes the TCP connection/occurred (also closes the TCP connection)/
There was a problem hiding this comment.
AFAICT, the correct way to fix this API is throw an exception on errors instead of overloading a false result with two very different outcomes.
There was a problem hiding this comment.
In this case the caller was closing the TCP connection based on numeric result, so in order not to change OpenSSL build behaviour I just moved that particular action into the function. The callers only needs to handle the boolean result with no new side effects or code being skipped by a throw.
Adding a TODO note about this future fix though. The behaviour change should be done in dedicated fix without other code changes adding possible confusion.
There was a problem hiding this comment.
The end result of your changes is an introduction of bad API. It does not really matter whether the changes were well-intentioned, small, moving-only, etc.
The original API was not ideal, but it was acceptable. The new API is not. I see two reasonable choices:
- Keep the old API: You can still close the connection inside the function, before returning
-1of course. I am not asking you to undo that "just moved that particular action" change. - Fix the API.
I agree that fixing the API by throwing on errors is not a trivial change, and I do not insist on that change to be done inside this PR. However, the first alternative does not seem to complicate this PR at all. If that is true, please undo the API change (i.e., follow the first bullet) or implement any better option that I have missed instead.
| int fd = conn->clientConnection->fd; | ||
| auto ssl = fd_table[fd].ssl.get(); | ||
| int ret; | ||
| auto session = fd_table[fd].ssl.get(); |
There was a problem hiding this comment.
I do not see a reason to rename this variable in this PR, but if you do, please s/session/tls/ to avoid introducing a TLS session concept where none exists (yet).
There was a problem hiding this comment.
This is not "a TLS". It is a pointer used to access session data which is being initialized by the handshake - if it succeeds. We cannot help that OpenSSL uses "SSL" to name its API object.
There was a problem hiding this comment.
You seem to reopen the TLS connection-vs-session discussions that, I thought, were already resolved on squid-dev. The object in question is not a session. It is a connection. I do not insist on calling it "ssl" or "tls". I insist on not calling it "session". If you prefer "tlsConnection" or "tlsConn", I am fine with that.
| } | ||
| } | ||
| gnutls_free(data.data); | ||
| #endif |
There was a problem hiding this comment.
Seems like we are missing an #else case here.
There was a problem hiding this comment.
Aye, added extra debugging and all ifdef in this file now have an else. Even if only to state what is not implemented or unreachable.
There was a problem hiding this comment.
I am worried about sweeping the "nobody cares about #else" problem under the rug. If we do not think this through now, we may significantly increase the cost of supporting TLS-free builds, not to mention adding support for another TLS library. Just adding debugs() lines now will hide any non-TLS and 3rd-library support problems from users and developers when Squid is built without TLS support or we start adding 3rd library support.
Is it possible to raise the bar by making Security code fail to compile if it is used when it should not be? We did a similar thing with several Security pointer types already -- they cannot be dereferences without a compilation problem. Can we do the same with KeyData and such? I think it should be possible without significant changes. For example, how about using the following sketch in KeyData.h?
#if HAVE_TLS_SUPPORT
class KeyData ...
#else
class KeyData {};
#endif
The HAVE_TLS_SUPPORT (or a similar macro) will be auto-computed based on USE_OPENSSL and USE_GNUTLS macros, of course. When adding support for a 3rd TLS library API, the developer will only need to adjust that (trivial) macro computation code to trigger all the compiler errors they must fix.
The whole KeyData.cc body can be surrounded by the HAVE_TLS_SUPPORT guard while all #if switches with look something like this:
#if USE_OPENSSL
...
#elsif USE_GNUTLS
...
#else
#error missing code for your current TLS library
#endif
src/security/KeyData.cc
Outdated
| #if USE_OPENSSL | ||
| return X509_check_private_key(cert.get(), pkey.get()); | ||
| #elif USE_GNUTLS | ||
| return true; // TODO find GnuTLS equivalent check |
There was a problem hiding this comment.
Feels like an XXX to me, not a TODO.
There was a problem hiding this comment.
I thought so too until I read what that OpenSSL function actually does - which is purely to check that parameters like KeyUsage if any on the key are also on the cert .... there can apparently be additional ones on the cert not in the key, and the two cert/key items can be completely unrelated while still passing this check.
The GnuTLS API does most of this kind of check automatically when you add that cert+key pair to the context instead of being explicitly done by us. So I think we are safe enough leaving it to do that for now.
The check this call seemed to be doing (verify the cert and key were actually a matching pair) is something we probably should implement for nicer squid.conf error messages. But that is also missing for OpenSSL so out of scope in this PR. I have an XXX in the caller about doing something better than this function can provide right now to verify the config details.
There was a problem hiding this comment.
that OpenSSL function [...] is purely to check that parameters like KeyUsage if any on the key are also on the cert
AFAICT, comparing parameters is not the only check that X509_check_private_key() performs in OpenSSL v1.1.0f. The function also checks that the public key of the given certificate matches the given private key (via an EVP_PKEY_cmp() call). For example, for RSA keys, EVP_PKEY_cmp() uses rsa_pub_cmp() to compare the two "raw" key values:
static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
{
if (BN_cmp(b->pkey.rsa->n, a->pkey.rsa->n) != 0
|| BN_cmp(b->pkey.rsa->e, a->pkey.rsa->e) != 0)
return 0;
return 1;
}
Why is OpenSSL comparing public and private keys? According to EVP_PKEY_cmp() manual page, "Since OpenSSL private keys contain public key components too the function
EVP_PKEY_cmp() can also be used to determine if a private key matches
a public key".
My code interpretation seems to match X509_check_private_key() documentation which says that the function returns success "if the keys match each other". There is a separate function for comparing just the parameters.
Did I misinterpret what X509_check_private_key() does?
There was a problem hiding this comment.
The section "BUGS" in that documentation you referenced explicitly mentions that passing it two public keys (x and k) generated with the same parameters will return success.
There was a problem hiding this comment.
With the new structure of KeyData.cc members I have inlined this check to the applicable USE_OPENSSL code block.
src/security/KeyData.cc
Outdated
|
|
||
| /// verify that a private key and cert match | ||
| static bool | ||
| checkPrivateKey(Security::CertPointer &cert, Security::PrivateKeyPointer &pkey) |
There was a problem hiding this comment.
If possible, please make this into a private constant KeyData method and avoid passing these parameters.
src/security/KeyData.cc
Outdated
| gnutls_x509_crt_t certificate; | ||
| x = gnutls_pcert_export_x509(&pcrt, &certificate); | ||
| if (x != GNUTLS_E_SUCCESS) { | ||
| certificate = nullptr; // paranoid: just in case the *_t ptr is undefined after deinit. |
There was a problem hiding this comment.
Missing error reporting? Why is this error handling should be any different from all the other errors before it?
There was a problem hiding this comment.
AFAIK this function call is just a data copy from one structure to another. So it fails only if the input was loaded with non-X509 types (ie. incompatible with X.509). We are loading the data immediately prior with explicit GNUTLS_X509_FMT_PEM flag to ensure that only X.509 succeeds in the earlier call.
The remaining edge case is a non-existing certificate. The error for that is in the else clause of the next if-statement block shared by both GnuTLS and OpenSSL, all we need do to trigger that is set the pointer to nil (as done for the paranoid case)
There was a problem hiding this comment.
I am surprised that you are trying to justify the lack of error reporting by speculating that the function usually does not fail. Looking at GnuTLS sources, I quickly lost count of the different error conditions gnutls_pcert_export_x509() and its callees detect! The function is a lot more complex than a simple copy and even if it were that simple, the simplicity is not a valid excuse to avoid error reporting, especially in code that already detects the error condition and that already reports other similar errors.
src/security/KeyData.cc
Outdated
| certificate = nullptr; // paranoid: just in case the *_t ptr is undefined after deinit. | ||
| } | ||
| #else | ||
| // to simplify and prevent 'undefined variable errors' in the next code block |
There was a problem hiding this comment.
IMO, this method's layout makes things mode complex/confusing than they actually are. Please give each of the three library cases (OpenSSL/GnutTLS/other) its own method implementation. They share nothing worth preserving AFAICT!
There was a problem hiding this comment.
The design for libsecurity code is to have each behavioural action be presented by a single generic function/method with internal ifdef split for how that behaviour is implemented by the supported libraries. Using library-specific methods is what we are trying to move away from.
I would like to move the load-key and load-chain into separate functions. But right now the BIO object used by OpenSSL implementation currently gets in the way of splitting off the chain load as it would have to be passed around between the cert and chain methods when no other library API does so.
If you like I can split off the key loading into a generic method whose OpenSSL implementation is just a call to ReadPrivateKeyFromFile(). I was thinking of leaving that until the ReadPrivateKeyFromFile() code could be cleanly moved into KeyData as the OpenSSL implementation of that method.
There was a problem hiding this comment.
The design for libsecurity code is to have each behavioural action be presented by a single generic function/method with internal ifdef split for how that behaviour is implemented by the supported libraries. Using library-specific methods is what we are trying to move away from.
We should not mechanically apply Security API principles to that API implementation. Yes, there should be one Security::foo() API for all. However, how that Security::foo() is implemented is a different story. If it makes sense to use library-specific implementations for some good reason, then we should use library-specific implementations.
When there is virtually no shared code or overlap between library-specific code implementing Security::foo(), it is better to #ifdef whole method bodies rather than force readers to navigate a complicated maze of #ifdef code blocks that depend on each other.
If you like I can split off the key loading into a generic method whose OpenSSL implementation is just a call to ReadPrivateKeyFromFile().
To address this particular change request, please refactor loadX509CertFromFile() to follow this pattern:
Security::KeyData::loadX509CertFromFile()
{
... optional shared code ...
#if USE_OPENSSL
... OpenSSL-specific code ...
#elif USE_GNUTLS
... GnuTLS-specific code ...
#else
... code specific to disabled SSL support ...
#endif
... optional shared code ...
}
The insides of each of those #ifdef sections is outside this change request scope.
There was a problem hiding this comment.
Refactored.
Notice that layout currently results in public certs being sent twice in TLS handshakes. Because of the required multiple BIO objects. I have left a few XXX in the OpenSSL code for that and a few other checks that seem to be worthwhile, but out of scope for this PR.
cdde7d8 to
af2c1b2
Compare
|
In reply to your overview questions:
While location and symbol naming has changed the code is intended to be the same as the previously existing OpenSSL-only logic which has been in production use. Each piece of GnuTLS code has been tested as equivalent to the matching OpenSSL code to the best of my abilities.
I mean the code which performs the below (and no more) is made to be working for GnuTLS builds by this PR:
All options documented with tls-* prefix work with either OpenSSL or GnuTLS as of the commit where they were renamed, and have the documented behaviour. Most of which is unchanged from OpenSSL-only behaviour. Any TLS/SSL related feature involving options not yet documented in such manner should be considered "not yet implemented" and should produce an error if used in GnuTLS builds. There is one brand new behaviour added in this PR because the GnuTLS API makes it trivial to implement. That is configuring multiple cert=/key= parameters for the https_port. When configured in this manner Squid should be able to present ServerHello for any of those cert's domains based on the client request. |
abe7545 to
dd3ddb4
Compare
dd3ddb4 to
82188ed
Compare
4381371 to
4965572
Compare
f3f0d2e to
1e807cd
Compare
chtsanti
left a comment
There was a problem hiding this comment.
Looks that the code is equivalent for openSSL, so I am not expecting any problem.
My I ask, from the code I am understanding that the gnutls supports multiple certificates per port tls context. What does it mean? Does the gnutls selects the correct certificate for the SNI name? Or they are just chained when sent to the client?
Move the logic for loading cert/key from PEM file from libsslsquid to libsecurity. Also, fix CertPointer and PrivateKeyPointer definitions for non-OpenSSL builds.
For the record, this PR was committed without addressing my concerns. @yadij, please do not dismiss others' reviews without even discussing your intent to do so and allowing the reviewer to update their review. |
|
This commit breaks running with existing certs. My cert is not accepted w/o explaining why. |
|
@badfiles, are you sure it is this commit and this commit alone? In other words, does reversing this commit and only this commit resolve the problem in your environment? Did you adjust your configuration in any way?
Please detail whether it is Squid or the client/browser that does not "accept" your certificate. Providing error details and/or posting an ALL,9 log while reproducing the problem (with no other traffic) may also help. |
|
This commit only. I changed cert= to tls-cert= in config. Rolling back po previously built version (before this commit)) solves the issue (with cert=). |
|
hmm, what OS are you using? |
|
Also, you should not have had to change it to tls-cert= to load the config. If you have built with the OpenSSL support needed to do cert generation the old config settings for OpenSSL-only builds should still work just fine. |
|
w/o changing config same error |
|
I am confirming the problem. I am getting the following errors: |
|
@yadij, please fix or revert ASAP. |
|
I applied the patch in PR #144 and run 1-2 tests. Still there are problems. The problem in this patch looks that it is the tlsAttemptHandshake method, which return a true/false value where the old Squid_SSL_accept returned tri-state value, -1,0,1. But I did not run more tests and checks to see the exact problem. Moreover maybe there are other problems too. I must apologize for my previous positive vote, but when I am reviewing a PR even if I am trying to check for bugs, and I am not running tests. I am mostly just checking how the patch affects the design, or causes problems difficult to be detected and solved in the future. But I am expecting that the author has run 1-2 tests. |
|
@christos, In the case of the SSL/TLS and libsecurity changes specifically, please do run tests as well. I am pretty sure yours will be different from mine and catch different things. In general it is not a requirement, but these changes are a bit special being security+privacy+crypto. (I am testing what I can, but there are govt restrictions on crypto MITM that I have to work around.) I am suspecting the latest issues are with the call in client_side.cc line 3310. The behaviour there is a bit weird. Given that you have written a handshake parser do we actually need to pass this to the library anymore? |
The parser just do simple parsing. OpenSSL api does more tests than just parsing, checks the openSSL versions, the used algorithms, possible attacks and many other. It is a long discussion if you want to disable these checks... |
|
Okay, I'm reverting that particular API change for now in the PR #144 fixes. We can have the longer discussion about fixing it at some future time, there is a TODO about that already. Can you review & test the PR 144 changes please to see if there is anything else you can find. Thanks. |
I do not think reviewers should apologize for not running tests. Testing is the responsibility of the PR author, not a reviewer. You simply do not have enough resources to properly review and test most SSL-related PRs in addition to your own work!
Government restrictions cannot justify posting and committing complex untested modifications of highly popular TLS-related features while essentially relying on others to test those modifications. We need to change the current status quo. I have sent you an email with specific suggestions to avoid airing dirty laundry here. Meanwhile, please consider reverting this broken PR commit. |
|
After this "GnuTLS implementation" improvement, ssl_bump function has stopped working. root@frw:/# service squid start How now to make self-signed certificates?! ERROR: Ignoring https_port 127.0.0.1:3129 due to TLS context initialization failure. |
|
@michaeladm, the fixes for those issues are in PR 144 which is currently stuck awaiting review and confirmation from people affected as to whether the issue is fully fixed for them. If you have any other issues related to this commit which can be replicated after applying the PR 144 patch please mention it in that PR. |
|
PR #144 is stuck awaiting tests (it also lacks a review but that is a minor secondary issue in this case). @michaeladm, if you can thoroughly test the changes in PR #144 in your SslBump setup, please do so and report your results (there). |
…squid-cache#81) Move the http_port cert= and key= options logic to libsecurity and add GnuTLS implementation for PEM file loading. Also adds some extra debugging to clarify listening port initialization problems with the PEM files. Enable most of the http(s)_port listening socket logic to always build except where OpenSSL-specific dependency still exists. It may seem reasonable to leave it optionally excluded for minimal builds, however a minimal proxy that does not support HTTPS in any way is increasingly useless in the modern web so preference is given to building the generic TLS related code. This also simplifies the required testing to detect code portability issues. GnuTLS implementation is added for https_port configured with static cert=/key= parameters and the resulting TLS handshake behaviour. Squid built with GnuTLS can now act as useful parent proxies behind a SSL-Bump'ing frontend or for other clients which require a TLS explicit proxy. Also fixes the definitions for the CertPointer and PrivateKeyPointer.
…#81) (#152) Move the http_port cert= and key= options logic to libsecurity and add GnuTLS implementation for PEM file loading. Also adds some extra debugging to clarify listening port initialization problems with the PEM files. Enable most of the http(s)_port listening socket logic to always build except where OpenSSL-specific dependency still exists. It may seem reasonable to leave it optionally excluded for minimal builds, however a minimal proxy that does not support HTTPS in any way is increasingly useless in the modern web so preference is given to building the generic TLS related code. This also simplifies the required testing to detect code portability issues. GnuTLS implementation is added for https_port configured with static cert=/key= parameters and the resulting TLS handshake behaviour. Squid built with GnuTLS can now act as useful parent proxies behind a SSL-Bump'ing frontend or for other clients which require a TLS explicit proxy. Also fixes the definitions for the CertPointer and PrivateKeyPointer.
PR squid-cache#81 adding GnuTLS support required splitting the way certificate chains were loaded. This resulted in the leaf certificate being added twice at the prefix of a chain in te servreHello. It turns out that some recipients validate strictly that the chain delivered by a serverHello does not contain extra certificates and reject the handshake if they do. This patch implements the XXX about filtering certificates for chain sequence order and self-sign properties added in the initial PR. Resolving the bug 4831 regression and also reporting failures at startup/reconfigure for admins. Also, add debug display of certificate names for simpler detection and administratve fix when loaded files fail these tests.
PR squid-cache#81 adding GnuTLS support required splitting the way certificate chains were loaded. This resulted in the leaf certificate being added twice at the prefix of a chain in te servreHello. It turns out that some recipients validate strictly that the chain delivered by a serverHello does not contain extra certificates and reject the handshake if they do. This patch implements the XXX about filtering certificates for chain sequence order and self-sign properties added in the initial PR. Resolving the bug 4831 regression and also reporting failures at startup/reconfigure for admins. Also, add debug display of certificate names for simpler detection and administratve fix when loaded files fail these tests.
PR squid-cache#81 adding GnuTLS support required splitting the way certificate chains were loaded. This resulted in the leaf certificate being added twice at the prefix of a chain in te servreHello. It turns out that some recipients validate strictly that the chain delivered by a serverHello does not contain extra certificates and reject the handshake if they do. This patch implements the XXX about filtering certificates for chain sequence order and self-sign properties added in the initial PR. Resolving the bug 4831 regression and also reporting failures at startup/reconfigure for admins. Also, add debug display of certificate names for simpler detection and administratve fix when loaded files fail these tests.
PR squid-cache#81 adding GnuTLS support required splitting the way certificate chains were loaded. This resulted in the leaf certificate being added twice at the prefix of a chain in te servreHello. It turns out that some recipients validate strictly that the chain delivered by a serverHello does not contain extra certificates and reject the handshake if they do. This patch implements the XXX about filtering certificates for chain sequence order and self-sign properties added in the initial PR. Resolving the bug 4831 regression and also reporting failures at startup/reconfigure for admins. Also, add debug display of certificate names for simpler detection and administratve fix when loaded files fail these tests.
Move the http_port cert= and key= options logic to libsecurity and add GnuTLS implementation for PEM file loading. Also adds some extra debugging to clarify listening port initialization problems with the PEM files.
Enable most of the http(s)_port listening socket logic to always build except where OpenSSL-specific dependency still exists. It may seem reasonable to leave it optionally excluded for minimal builds, however a minimal proxy that does not support HTTPS in any way is increasingly useless in the modern web so preference is given to building the generic TLS related code. This also simplifies the required testing to detect code portability issues.
GnuTLS implementation is added for https_port configured with static cert=/key= parameters and the resulting TLS handshake behaviour. Squid built with GnuTLS can now act as useful parent proxies behind a SSL-Bump'ing frontend or for other clients which require a TLS explicit proxy.
Also fixes the definitions for the CertPointer and PrivateKeyPointer.