How to view the OCSP TLS response CertificateStatus? - ssl

I'm currently trying to find out how a server handles OCSP stapling and want to view how often it is getting it's certificate signed. According to RFC 6066 (if I'm reading it right), the certificate and a time stamp should be signed and returned under status_request, if a CertificateStatus message is present. How can I view the timestamped certificate and it's corresponding signature? So far I've used Wireshark which does not seem to show this response as far as I can see. I've used curl which I think is verifying the certificate however I can't actually see the time stamped certificate (* SSL certificate status: good (0) ).
As a side question how recent does a timestamped certificate need to be for it to be valid?
Thanks in advance

You can use the openssl s_client command with the -status flag to send a certificate status request to the server. If the server supports OCSP stapling, you'll see the details of the OCSP response in the data, including the signature over it.
For example, if we try it with stackoverflow.com:
crow#mac:api$ openssl s_client -connect stackoverflow.com:443 -status
CONNECTED(00000006)
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify return:1
depth=0 CN = *.stackexchange.com
verify return:1
OCSP response:
======================================
OCSP Response Data:
OCSP Response Status: successful (0x0)
Response Type: Basic OCSP Response
Version: 1 (0x0)
Responder Id: C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
Produced At: Dec 10 14:03:00 2020 GMT
Responses:
Certificate ID:
Hash Algorithm: sha1
Issuer Name Hash: 7EE66AE7729AB3FCF8A220646C16A12D6071085D
Issuer Key Hash: A84A6A63047DDDBAE6D139B7A64565EFF3A8ECA1
Serial Number: 03F73CD163AB052D41D18294D569DB388C2E
Cert Status: good
This Update: Dec 10 14:00:00 2020 GMT
Next Update: Dec 17 14:00:00 2020 GMT
Signature Algorithm: sha256WithRSAEncryption
9a:d6:32:9d:61:74:9a:d7:e0:46:a4:f8:e6:52:29:da:ce:b0:
...
In terms of how recent the response needs to be, you'll see that there's a "This Update" time which is the most recent time at which the responder (i.e. the party signing the OCSP response) knew the status to be correct, and a "Next Update" time which is the time at which newer information will be available. As long as the current time is between those two times, you can consider the response to be valid. Of course, it's always possible a newer (and different) response was created before that "Next Update" time, and the only way to know for sure is to make a live check to the OCSP server, but the general intent is that the window of time in the response should be sufficiently short that for most purposes you shouldn't need to worry about this.

Related

Understanding openssl. Where is the cert file?

I am using the command ...
openssl s_client -showcerts -connect reds-cluster-01:443
And I get the output:
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
verify return:1
depth=1 C = US, O = DigiCert Inc, CN = RapidSSL TLS DV RSA Mixed SHA256 2020 CA-1
verify return:1
depth=0 CN = *.my-co-example.com
verify return:1
CONNECTED(00000003)
---
Certificate chain
0 s:/CN=*.my-co-example.com
i:/C=US/O=DigiCert Inc/CN=RapidSSL TLS DV RSA Mixed SHA256 2020 CA-1
-----BEGIN CERTIFICATE-----
MIIGnxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgkqhkiG9w0BAQsFADBZ
...
I assume that means somewhere on the filesystem of my server there would be a file somewhere that has the string ...
MIIGnxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgkqhkiG9w0BAQsFADBZ
... in it. How can I find that file without having to execute something like?
sudo grep -sr MIIGnxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgkqhkiG9w0BAQsFADBZ /
I assume that means somewhere on the filesystem of my server there would be a file somewhere that has the string ...
This assumption is wrong. What you see is part of the server certificate, which need to be checked against a CA certificate located in the local trust store. The server certificate is typically not in the local trust store. See SSL Certificate framework 101: How does the browser actually verify the validity of a given server certificate? for more on certificates are checked.
You can see more with "CURL -W CERTS" from Daniel Stenberg (also on Stack Overflow), which works on curl for the past 25+ years.
When a client connects to a TLS server it gets sent one or more certificates during the handshake.
Those certificates are verified by the client, to make sure that the server is indeed the right one: the server the client expects it to be; no impostor and no man in the middle etc.
When such a server certificate is signed by a Certificate Authority (CA), that CA’s certificate is normally not sent by the server but the client is expected to have it already in its CA store.
(So no file to check on the filesystem)
Ever since the day SSL and TLS first showed up in the 1990s user have occasionally wanted to be able to save the certificates provided by the server in a TLS handshake.
The openssl tool has offered this ability since along time and is actually one of my higher ranked stackoverflow answers.
Now (for curl 7.88.0,to be shipped in February 2023), Daniel proposes:
Using the –write-out (-w) option and the new variables %{certs} and %{num_certs}, curl can now do what you want.
Get the certificates from a server in PEM format:
$ curl https://curl.se -w "%{certs}" -o /dev/null > cacert.pem
$ curl --cacert cacert.pem https://curl.se/
That is easier to parse than the openssl s_client -showcerts -connect current alternative.

What is sct list in SSL certificate?

What is sct list in SSL certificate? I had seen it in Google's SSL certificate.
And how to add it in a certificate using openssl?
e712f2b0377e1a62fb8ec90c6184f1ea7b37cb561d11265bf3e0f34bf241546e
‎Wednesday, ‎15 ‎July, ‎2020 5:29:23 PM
SHA256
ECDSA
304602210096c52ed8da6b4d3babfca5fdd1f75837fdd1a7e52eb9921ae5427cc33a9151ba022100e02b680bf63fd773b280c1f10c35de25bc6ba09423f8057819b40e9708a9dbd2
v1
07b75c1be57d68fff1b0c61d2315c7bae6577c5794b76aeebc613a1a69d3a21c
‎Wednesday, ‎15 ‎July, ‎2020 5:29:23 PM
SHA256
ECDSA
30440220412487d8eeda1cd592dcf550fd1d6b924007d91dfa1f10c521d224b2855e08fa0220528761cab1a239ae56d9ff841259f81a8039cfd78e0bb461ab8a496519431743
This is a list of Signed Certificate Timestamps. These are part of certificate transparency, as defined in RFC 6962.
The data contained in a SCT is as follows (using one of yours for an example):
Log ID: e712f2b0377e1a62fb8ec90c6184f1ea7b37cb561d11265bf3e0f34bf241546e (this happens to be the Let's Encrypt Oak2020 log)
Issue Date: ‎Wednesday, ‎15 ‎July, ‎2020 5:29:23 PM
Hash algorithm: SHA256
Signature algorithm: ECDSA
Signature data: 304602210096c52ed8da6b4d3babfca5fdd1f75837fdd1a7e52eb9921ae5427cc33a9151ba022100e02b680bf63fd773b280c1f10c35de25bc6ba09423f8057819b40e9708a9dbd2
When a CA issues a certificate, it records the certificate issuance with one or more CT log (publicly run servers that provably record certificate issuance).
The SCT indicates when the issuance occurred, which log it was recorded in, and how to find it (using the signature data). To verify that the information is correct, the client is supposed to verify that the certificate in the log matches the one you are verifying.
This is not something you should include in certificates you issue unless you happen to be running a public certificate authority. Self-signed certificates are not submitted to CT logs.

CN field is missing in SSL certificate from subject

I have SSL certificate, and I want to know the domain name associated with the certificate, for that I am using openssl to get the text of the .crt file.
The sample output is as follows:
Certificate:
Data:
Version: 1 (0x0)
Serial Number: 87778 (22)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=IN, ST=Maharastra, L=Mumbai, O=Tests Pvt Ltd, OU=test/emailAddress=all#test.com
Validity
Not Before: Jan 2 02:09:10 2014 GMT
Not After : Dec 31 02:09:10 2023 GMT
Subject: C=IN, ST=Maharastra, L=Mumbai, O=Tests Pvt Ltd, OU=test/emailAddress=all#test.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
As we can see there is not CN field in the above certificate, let me know if the certificate is wrong, or we can expect certificate files without CN.
With HTTPS a server certificate is expected to contain the name of the server and this name should match the expected name, otherwise the TLS handshake will fail. The name is specified today using the Subject Alternative Names (SAN) extension and before that was given using the CN of the subject. But the CN is considered obsolete for years and browsers like Chrome will not consider it anymore, i.e. make the SAN mandatory.
The certificate in your case contains neither CN nor SAN and thus will not be usable for HTTPS. There are other use cases of SSL/TLS apart from HTTPS though where this certificate might be acceptable. But it is unclear what specific use case you have.

how do I unblock self-signed SSL certificates?

Issue: users can't log into mobile app due to "unable to contact server"
debugging message: "TypeError: Network request failed"
Attempted fixes: restarted server, verified that db is running and nothing has changed, restarted VM that server is running on, I checked the api using postman. When I ran a simple POST request I got the following message:
There was an error connecting to
https://app.something.com/api/Accounts/5076/sometest?filter%5Bwhere%5D%xxxxx%5D=null&access_token=mwVfUBNxxxxxxx5x4A4Y5DktKnTZXeL6CB34MoP.
One of the suggestions I was given was:
Self-signed SSL certificates are being blocked: Fix this by turning
off 'SSL certificate verification' in Settings > General
As soon as I followed this step, I was able to make the POST request and everything seemed to work fine. I'm completely new to this type of error. Allso, I did not set up this app/db/certificates. So, other than unblocking self-signed SSL certificates(which seems like a really bad idea), I'm not sure how to proceed. What are my options?
here's what the result of examining the certificate:
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify error:num=20:unable to get local issuer certificate
verify return:0 poll
errornotBefore=Jan 28 11:54:38 2019 GMT
notAfter=Apr 28 11:54:38 2019 GMT
Either, purchase a signed certificate from a CA if you plan to expose this to the public.
Or the free option is to use Let's Encrypt, with this service, you are issues free certificates, however they expire in a relatively short period of time; most of the time however you can run an agent which will automatically rotate the certificates before they expire.
The third option is to install the CA certificate that was used to self sign this, into to your browser. i.e., like a large company might do.
edit
Seems like it might instead be an expired certificate? Check when it expires with this:
openssl s_client -showcerts -servername www.stackoverflow.com -connect www.stackoverflow.com:443 </dev/null | openssl x509 -noout -dates
change both instances of stackoverflow you your domain

Get complete certificate chain including the root certificate

How do I get complete certificate chain for a server? Though some claim one should be able to do just that with openssl s_client -showcerts, it turns not always to be the case.
echo | openssl s_client -CApath /etc/ssl/certs -connect www.ssllabs.com:443 \
-showcerts | grep -B2 BEGIN
depth=3 C = SE, O = AddTrust AB, OU = AddTrust External TTP Network, CN = AddTrust External CA Root
verify return:1
depth=2 C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Certification Authority
verify return:1
depth=1 C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Domain Validation Secure Server CA
verify return:1
depth=0 OU = Domain Control Validated, OU = PositiveSSL, CN = www.ssllabs.com
verify return:1
0 s:/OU=Domain Control Validated/OU=PositiveSSL/CN=www.ssllabs.com
i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
-----BEGIN CERTIFICATE-----
--
1 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
-----BEGIN CERTIFICATE-----
--
2 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
-----BEGIN CERTIFICATE-----
DONE
Here we have three certificates our of four. All except of the AddTrust External CA Root certificate. (Possibly because it is not included into the certificate bundle. And not like this is required. And yes, I can find the missing one at /etc/ssl/certs)
How do I get all certificates for a server in a fully automatic fashion?
Meta: I tried to answer this in superuser but you deleted it. Fortunately when I found this copy most of my work was still sitting in a scratch notepad I hadn't closed, otherwise I wouldn't have been willing to do the research work twice.
s_client -showcerts shows the certs sent by the server; according to the RFCs, this should be a valid chain in upward order except that the root MAY (in RFC2119 definition i.e. allowed but not particularly recommended) be omitted. However, not all servers are configured correctly, and some may send extra, missing, and/or out-of-order certs. Also depending on the CA used there may be more than one valid chain but the server can only send one. openssl currently will use only the chain sent, but this will change soon in 1.0.2, and other reliers already sometimes find a different chain than the one sent.
openssl: if the received chain is complete up to and maybe including a root which is in the truststore used (whose default location depends on system or build, and in any case can always be overridden) then openssl client will validate it as okay -- unless it is expired, or revoked and that info is available which usually it isn't. In that case you can write a client program that connects after setting a cert-verify callback function that outputs the full certs as processed by the validation loop, or other info from them you want, as opposed to s_client which uses a callback that logs (only) the subject name in the depth=n lines, which you can see in your example includes all 4 certs in the chain here. openssl is opensource, so a client program that does things mostly like s_client could be a modified copy of s_client (in this case specifically s_cb.c).
Java can also do this and is a good bit shorter to write, but requires Java be installed. If the received chain validates against an anchor in the truststore used (which defaults to a set of public roots but can be modified or overridden, and can have non-root anchors) you similarly can write a program (maybe 20 lines) to connect using a HandshakeCompletedListener which dumps the info from event.getPeerCertificates(). However if the chain doesn't validate, Java aborts the handshake with an exception and you get no certs at all, unlike the openssl case where you might get partial information before the error occurs -- plus openssl's checking, at least by default, isn't quite as strict anyway.
UPDATE: for completeness, in Java 7+, commandline keytool -printcert -sslserver displays the chain sent, in a rather cluttered format.
Among the browsers I can easily check, Firefox and Chrome on Windows (at least) can write out the chain they found and validated. ISTR but can't easily retest the Firefox error/exception dialog can also do this for a chain that fails to validate and may be incomplete. These are not automatic as-is, but I've seen ads for numerous "simulate GUI user input" tools that apparently could drive them as desired.
You get the chain including the builtin trusted root certificate inside the verify_callback (see SSL_CTX_set_verify. With a small Perl program you can dump the chain like this:
#!/usr/bin/perl
use strict;
use warnings;
use IO::Socket::SSL;
IO::Socket::SSL->new(
PeerHost => 'www.google.com:443',
SSL_verify_callback => sub {
my $cert = $_[4];
my $subject = Net::SSLeay::X509_NAME_oneline(Net::SSLeay::X509_get_subject_name($cert));
my $issuer = Net::SSLeay::X509_NAME_oneline(Net::SSLeay::X509_get_issuer_name($cert));
print "# $subject (issuer=$issuer)\n";
print Net::SSLeay::PEM_get_string_X509($cert),"\n";
return 1;
}
) or die $SSL_ERROR||$!;