I am trying to figure out how to tell Boost Beast to use a client authentication certificate during the SSL handshake.
I have looked at the Boost Beast documentation, but have been unable to find any hint on client side certificates. The examples also do not cover this case.
Related
I'm currently testing an mTLS scenario server and client using boost asio. Each party has its own certificate and key, using self signed CA root (OpenSSL).
It works as expected, however there is a major issue which after searching quite a lot, came to a dead end. I need to be able to revoke client side certificates at any point in time.
So the question is, how to revoke certificates from clients? (make asio server refuse them)
I tried several options in the boost asio context without success, I could not find a way to revoke the client side certificate.
I need a snippet of code for a program i am writing with Boost Asio SSL.
I have a system of two clients, that connect with each other. I require them to do a mutual authentication, so, that at the end of the handshake() command, both clients can be certain that the other client has the private key to the certificate they supplied.
Both clients have a context object, lets call them ctx1and ctx2 and each client has a public certificate and a private key.
Is it possible to set up the context objects so, that when i call socket.handshake() the clients will do a two-way authentication. If not, what would be the correct way to go about to achieve my goal ?
It looks like boost just uses the OpenSSL interface.
I don't know boost much but I've implemented lots of OpenSSL internals for Perl and came to the following conclusions after reading the relevant parts of the boost source code:
To have mutual authentication with OpenSSL you have to use SSL_VERIFY_PEER on the client side and SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT on the server side. If you use only SSL_VERIFY_PEER on the server side it will only send the certificate request to the client, but silently accept if the client sends no certificate back.
With boost this would probably be:
ctx.set_verify_mode(ssl::verify_peer); // client side
ctx.set_verify_mode(ssl::verify_peer|ssl::verify_fail_if_no_peer_cert); // server side
If you set verify_mode this way it will verify the certificates against the configured trusted CAs (set with ctx.load_verify_file or ctx.load_verify_path).
If you have full control over the CA which signed the certificates (i.e. its your own CA) it might be enough for you to accept any certificates signed by this CA. But if you use a CA which also signed certificates you don't want to accept, like typically the case with public CAs, you also need to verify the contents of the certificate. Details how to do this depends on your protocol, but for the usual internet protocols like HTTP or SMTP this involves checking commonName and/or subjectAltNames of the certificate. Details like wildcard handling vary between the protocols.
Boost provides rfc2818_verification to help you with HTTP-style validation, although from reading the code I think the implementation is slightly wrong (multiple wildcards accepted, IDN wildcards allowed - see RFC6125 for requirements).
I don't know of any standards for verifying client certificates. Often just any certificate signed by a specific (private) CA will be accepted. Other times certificates from a public CA matching a specific e-mail pattern. It looks like boost does not help you much in this case, so you probably have to get OpenSSL SSL* handle with sock.native_handle() and then use OpenSSL functions to extract certificate (SSL_get_peer_certificate) and to check the contents of the certificate (various X509_* functions).
At least if public CAs are involved you should also check the revocation status of the certificates. It looks like boost does not provide a direct interface to CRL (certificate revocation list) so you have to use ctx.native_handle() with the appropriate OpenSSL functions (X509_STORE_add_crl etc). Using OCSP (online status revocation protocol) is way more complex and relevant OpenSSL functions are mostly undocumented, which means you have to read the OpenSSL source code to use them :(
One cant force other side to authenticate against you, it is up to protocol, Ieach side autenticate only against other side. Just follow manuals as http://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/overview/ssl.html
ssl::context ctx(ssl::context::sslv23);
ctx.set_verify_mode(ssl::verify_peer);
ctx.load_verify_file("ca.pem");
I'm working on a C++ client app that needs to read from a secure websocket. After looking into some websocket libraries I would like to use easywsclient but it does not support TLS. I tried adding support for URLs that start with wss using OpenSSL by following this article but would like to avoid loading certificates and private keys from files (if possible). I looked into how this is done in boost asio and they recommend using certify to access a platform's TLS keystore. I also researched chrome browser and found that it uses BoringSSL which lead me to Tink. However, I can not find an example of how to use Tink/BoringSSL to secure a websocket and deal with client side certificates and keys. Can someone point me in the right direction?
Clients that want to read from a websocket do not have to setup cerificates and private keys, this is only relevant for a web socket server that must suport tls/ssl.
As I do not know much about C++ , I can only give you an example in PHP for a client connecting to a websocket server using TLS/SSL. Here the client prepares a $context in order to use TLS/SSL vai a stream.
$context = stream_context_create();
stream_context_set_option($context, 'ssl', 'allow_self_signed', true);
stream_context_set_option($context, 'ssl', 'verify_peer', false);
stream_context_set_option($context, 'ssl', 'verify_peer_name', false);
Later on the connection is made using this context,
$this->socketMaster = stream_socket_client(
"$prot$Address$Port", $errno, $errstr, 30,
STREAM_CLIENT_CONNECT, $context
);
For the full source go to:
https://github.com/napengam/phpWebSocketServer/blob/master/phpClient/websocketCore.php
I have a problem.
I am using openssl for validate my cert - x509_verify_cert(). But this function doesn't use ocsp. So it can be a problem if there is no crl.
In openssl errors i found this define - x509_err_ocsp_verify_needed, but i don't understand how it uses.
It seems that may be exists some kind of callback for my connecting to ocsp server function or something like that.
Also i found it which i can use, as i understand, for my own validate function, but i want only ocsp check.
So my question is: is it possible ask openssl use ocsp for validation and how?
It is possible :
openssl ocsp -issuer certchain.pem -cert cert.pem -text -url <the ocsp responder URL>
Some links to articles with more details:
https://raymii.org/s/articles/OpenSSL_Manually_Verify_a_certificate_against_an_OCSP.html
https://akshayranganath.github.io/OCSP-Validation-With-Openssl/
OpenSSL API does not provide a single API to do OCSP validation. The OpenSSL API provides the primitives so that you can implement your own validation. There are details you need to fill to the implementation which may depend on your situation you are trying to solve.
I would suggest that you get to know the openssl ocsp command as a basis of your understanding. Reading the links from Sanjeev's answer gives you examples of using this command as well.
To implement OCSP validation you will need to:
Extract server and issuer certificates from somewhere (SSL connection most likely)
Extract the OCSP server list from the server certificate
Generate a OCSP request using the server and issuer certificates
Send the request to the OCSP server and get a response back
Optionally validate the response
Extract the certificate status
Optionally you can also cache the result with the response update date range so that you can shortcut the above procedure if you see the certificate again.
You can also group a bunch of server certificates to the same OCSP server into a single request as well.
Of note is that the OCSP server link may not be HTTP and you may need to support whatever link type the certificate may have. For example in windows AD enterprise setups, the server OCSP may only have LDAP OCSP server links.
You may also like to see my answer to a question where I go into code examples of OCSP request and response handling.
UPDATE:
If you want to check the whole chain, you will have to do the above one certificate at a time (although the certificates operations can be overlapped). As far as I know, there is no way to check a whole chain at once. Also, you may find that a lot of intermediate certificates don't provide OCSP links anyway so there is no way to check. If you need to do this then it would be a good idea to cache the results as you will come across the same intermediate certificates all the time. In fact you could schedule to do this ahead of time for "known" intermediate certificates that you come across all this time.
You also keep pointing to "x509_verify_cert" check I quote:
Applications rarely call this function directly but it is used by
OpenSSL internally for certificate validation, in both the S/MIME and
SSL/TLS code.
So you shouldn't be calling this yourself anyway.
It seems that may be exists some kind of callback for my connecting to ocsp server function or something like that.
X509_STORE_CTX_set_verify_cb - used to set a callback to do your own custom verification - used a lot in server SSL setups
X509_STORE_CTX_set_ex_data - used to add custom argument values used by the callback
X509_VERIFY_PARAM_set_flags - used to setup flags (e.g. X509_V_FLAG_CRL_CHECK or X509_V_FLAG_CRL_CHECK_ALL)
In openssl errors i found this define - x509_err_ocsp_verify_needed
X509_V_ERR_OCSP_VERIFY_NEEDED is defined and never used in the openssl codebase. It is meant to returned from a verify callback function that the user provides (i.e. X509_STORE_CTX_set_verify_cb) to indicate that verification should fail with that error. What you do with that information is up to you. If you supply a callback and return that error from a openssl SSL connection that the SSL connection will terminate.
Also of note, if you do add a custom verification callback that does do full OCSP checking, it will slow down the SSL connection setup a lot. This is why most browsers don't do this by default as it slows down the user experience to much.
I want to know the functions which establish the SSL connection from windows.. I am writing a code to know whether the SMTP uses SSL of TLS ..i am able to find get TLS because encryption happens after handshake... i want to know about SSl .. please help me.
Thank you in advance
OpenSSL is the most common library used for SSL.