I am trying to do CRL check on macos catalina. I am doing exactly same as what is mentioned in
https://developer.apple.com/forums/thread/97740
SecPolicyRef revPolicy = nil;
revPolicy = SecPolicyCreateRevocation(kSecRevocationCRLMethod | kSecRevocationRequirePositiveResponse);
except for the setting the trust anchor part. I have created a self signed root CA using openssl and created a server certificate signed by the root CA.
I have a CRL distribution point mentioned in server certificate
X509v3 CRL Distribution Points:
Full Name:
URI:http://www.test.com/crl.pem
OSX is completely ignoring the CRL distribution point. There is no attempt to contact the CRL server during handshake.
What could be wrong here? Don't CRL checks work in OSX? Does it require some additional information in the certificate?
Related
I am using mkcert to generate a self signed certificate for localhost.
mkcert -install
mkcert localhost
This works fine for the browser but if I try and and do a fetch from node, I get this error:
FetchError: request to https://localhost:52882/ failed, reason: unable to verify the first certificate
I think this is because mkcert is not creating the full chain.
I have hacked around this by using the NODE_EXTRA_CA_CERTS environment variable.
NODE_EXTRA_CA_CERTS="$(mkcert -CAROOT)/rootCA.pem"
and I know there is the process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; nuclear approach but I am curious to know how this can be fixed without these.
It is working perfectly. You have own certificate authority (CA) and that one issues localhost certificate directly. There is no intermediate certificate authority used, so assumption mkcert is not creating the full chain is not correct.
CA cert must be available on your machine and you need to define, which CA certs are trustworthy. NODE_EXTRA_CA_CERTS is exactly that config, where you can allow particular CA cert file.
Of course you can add this custom CA cert to system CA cert stores. Their locations depend on used OS, e.g.:
"/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo etc.
"/etc/pki/tls/certs/ca-bundle.crt", // Fedora/RHEL 6
"/etc/ssl/ca-bundle.pem", // OpenSUSE
"/etc/pki/tls/cacert.pem", // OpenELEC
"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", // CentOS/RHEL 7
"/etc/ssl/cert.pem", // Alpine Linux
That should be done by mkcert -install.
My guess is that your node is not using system CA store (env variable NODE_OPTIONS=--use-openssl-ca), so only node's own CA certs (e.g. https://github.com/nodejs/node/blob/v14.0.0/src/node_root_certs.h) are trustworthy for the node.
You have option to use system CA cert store (env variable NODE_OPTIONS=--use-openssl-ca or node CLI parameter --use-openssl-ca) or you can allow your custom CA with env variable NODE_EXTRA_CA_CERTS as you did.
I am curious as to whether invocation of a single line of openssl command line interface has the ability to perform complete OCSP verification protocol, e.g. query all the OCSP responder servers in a chain to confirm the current validity of certificates.
To see if this might be so, I specified the -CAfile option as /dev/null, hoping that would avoid any cached certificates being used in lieu of lookup: As explained in #pepo 's answer, the server certificate chain is sent a part of the basic TLS1.2 handshake specified in RFC 5246 (more details in update below)
# openssl s_client -CAfile /dev/null -connect www.equifaxsecurity2017.com:443
which gave the output:
CONNECTED(00000003)
depth=3 C = US, O = Equifax, OU = Equifax Secure Certificate Authority
verify return:1
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify return:1
depth=1 C = US, O = GeoTrust Inc., OU = Domain Validated SSL, CN = GeoTrust DV SSL CA - G3
verify return:1
depth=0 CN = www.equifaxsecurity2017.com
verify return:1
---
Certificate chain
0 s:/CN=www.equifaxsecurity2017.com
i:/C=US/O=GeoTrust Inc./OU=Domain Validated SSL/CN=GeoTrust DV SSL CA - G3
1 s:/C=US/O=GeoTrust Inc./OU=Domain Validated SSL/CN=GeoTrust DV SSL CA - G3
i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
---
Server certificate
-----BEGIN CERTIFICATE-----
<omitted>
-----END CERTIFICATE-----
subject=/CN=www.equifaxsecurity2017.com
issuer=/C=US/O=GeoTrust Inc./OU=Domain Validated SSL/CN=GeoTrust DV SSL CA - G3
---
No client certificate CA names sent
....
It looks as though openssl has found all three links in the chain without any help from cached files, and so must have communicated over the internet with agents (1) GeoTrust DV SSL CA - G3, and (2) GeoTrust Global CA, to build the chain. Is that correct?
No! It's not correct!
Has openssl also verified the chain by making the appropriate OCSP request to each of the three OCSP responders?
(My guess is "no". I am also aware that openssl ocsp ... can be used in conjunction with manual text operations on certificates to perform OSCP verification one link at a time. However, it does seem plausible, even preferable, that openssl would have been written to perform full OCSP verification, and that is why I am asking.)
UPDATE 9-14-2017:
Thanks to #pepo 's answer "SSL server (if configured correctly) will send certificate chain (except root CA certificate)", I looked up RFC 5246 and found section "7.4.2 Server Certificate" which explains the content of the "Server Certificate" part of the TLS1.2 handshake:
This is a sequence (chain) of certificates. The sender's
certificate MUST come first in the list. Each following certificate
MUST directly certify the one preceding it. Because certificate
validation requires that root keys be distributed independently, the
self-signed certificate that specifies the root certificate
authority MAY be omitted from the chain, under the assumption that
the remote end must already possess it in order to validate it in
any case.
Furthermore, thanks to #pepo's answer about the -crl_check_all option, I tried that and got the following output:
CONNECTED(00000003)
depth=0 CN = www.equifaxsecurity2017.com
verify error:num=3:unable to get certificate CRL
verify return:1
depth=1 C = US, O = GeoTrust Inc., OU = Domain Validated SSL, CN = GeoTrust DV SSL CA - G3
verify error:num=3:unable to get certificate CRL
It failed with error unable to get certificate CRL. It turns out not be critical, because the chosen website has OCSP stapling enabled.
If instead of -crl_check_all to perform CRL checking, we instead
add the option -status
which requests OCSP stapling, then the following output is received:
CONNECTED(00000003)
<stuff omitted omitted>
OCSP response:
======================================
OCSP Response Data:
OCSP Response Status: successful (0x0)
Response Type: Basic OCSP Response
Version: 1 (0x0)
Responder Id: CE2C8B1E8BD2300FD1B15446E9B594254949321B
Produced At: Sep 10 11:12:45 2017 GMT
Responses:
Certificate ID: ...
Cert Status: good
This Update: Sep 10 11:12:45 2017 GMT
Next Update: Sep 17 11:12:45 2017 GMT
Signature Algorithm: sha1WithRSAEncryption
<stuff omitted>
This shows OCSP stapling is enabled on the server side, but it appears to only be enabled for the first (the leaf) certificate, and not for the second certificate. (The self-signed third certificate must be validated independently anyway). So, to verify the second certificate, either CRL-checking or OCSP-request-response must be used. Since CRL-checking is not enabled by this particular authorization chain, that leaves only OCSP-request-response.
Thanks to #pepo 's reply, I understand much better the relationship between openssl, the TLS1.2 protocol, and these methods for verifying authorization (listed in historical order):
CRL (certificate revocation list) checking
OSCP request and response
OCSP stapling
However, a new question has also been raised:
Regarding the OCSP-stapling response sent by the server along with the certificates in the chain during the "Server Certificate" message step - this has signature information (from the next level up) that needs to be verified. Is this signature information actually verified during the processing of openssl ... -status?
UPDATE: 9-15-2017
The safe answer to the question "Is this signature information actually verified during the processing of openssl ... -status? " seems to be NO, according to this
answer
and also #dave_thompson_085 's comment below (he has looked through the source code).
Is it confusing? Yes! Oddly,
the "OpenSSL Cookbook (feistyduck, Ivan Ristić)"
is
unusually unclear about this question,
showing no explicit way to verify the signature, while also not explicitly saying the whether or not the signature has been verified. In contrast, for both of the other types revocation checking:
CRL-checking
and
OCSP-request-response (find "submit OCSP request")
the "OpenSSL Cookbook" shows explicit methods (recipes) to go the extra distance and complete the verification manually using the information already yielded by openssl. It would be a very human mistake to infer that reason "OpenSSL Cookbok" does not include the recipe for full validation of a stapled OCSP-reponse is because it is not necessary.
IMHO, it would be very responsible of OpenSSL (or any similar library) to include top level documentation, in the following order of priority
(1) explanation that OpenSSL does NOT offer a black box solution to TLS+authorization,
(2) explanation about what limited part of that solution it DOES offer (e.g., TLS handshake without authorization checking),
(3) documentation on recipes for assembling OpenSSL components to complete
the authorization checking solution.
Misunderstanding spreads very easily. Just a few days ago I was trying to write a simple program to send notification mail from my Linux Ubuntu PC. The standard Python releases (both ver 2 and 3) include an SMTP and an SSL library "implementing" TLS1.2. In 10 minutes I could write the program and walk through it in the debugger. I could see the call from the python SSL library to OpenSSL's handshake() function and assumed that handshake() must be handling all the authorization checking, based on the assumption that the SSL library and the SMTP library would not be released without including authorization checking. Strangely, the calling code in the SSL library included a post-handshake() check to make sure the received certificate name matched that of the called server. "Why would such a primitive check be necessary if handshake() already handled all the signature verifications, etc.?", I thought. That doubt started a journey peeling back layers of the TLS security onion and I haven't been able to stop crying since.
I don't want to try to re-invent the wheel, which would probably be wobbly anyway. Yet, I can't seem to find any available wheels. Where to go from here?
SSL server (if configured correctly) will send certificate chain (except root CA certificate). You can verify it here.
Openssl did not fetch these certificate but it got them served when initiating ssl connection. You can read more about s_client behavior in openssl documentation
I don't know if it performs OCSP verification but I doubt it. IMHO (based on The s_client utility is a test tool and is designed to continue the handshake after any certificate verification errors.) it does not perform any validation by default at all but you can at least enable CRL checking by specifying argument -crl_check_all
openssl s_client -connect www.equifaxsecurity2017.com:443 -crl_check_all
I'm trying to use a free ssl certificate(s?) I got from wosign in node.js, but I'm having some issues.
I'm creating my server with:
var server = https.createServer({key: serviceKey, cert: certificate}, httpHandler).listen(port)
which works fine with my self-signed certificate. To allow wosign to generate a certificate, I gave them the CSR that was generated alongside my self-signed certificate. They gave me the following files:
root.crt
3_user_my.domain.crt
2_issuer_Intermediate.crt
1_cross_Intermediate.crt
I've also read through the following couple sources to help me along:
https://www.ohling.org/blog/2015/02/wosign-free-2y-ssl-certificate.html
http://www.lowendtalk.com/discussion/41289/free-chinese-2-year-ssl-certificate-dv-kuaissl-by-wosign-com
Both mention that the "order" of the certificates is important, but I don't know what they mean there. I assumed that there would be a single certificate I could replace my self-signed certificate with. If there's an order, I assume it goes 1->2->3 as those numbers are in the filenames.
I replaced my certificate with the 3_user_my.domain.crt contents, and it works like my self-signed one - chrome says it should only work on localhost.
So how do I "order" these certs and ultimately how do I use the files given to me so that browsers will recognize it correctly?
Ok, I got it working.
A. I learned that the "certificate" used actually can be multiple certificates (crt files that only have one -----BEGIN CERTIFICATE----- and one -----END CERTIFICATE-----. So in order to make it work right, I needed to create one certificate file/string that contained 3 of the 4 certificates I got in the right order (apparently the root.crt isn't useful)
B1. The English set of certificate wosign gave me didn't match my private key, which I verified using the following:
openssl x509 -noout -modulus -in yourcertificate.crt | openssl md5
openssl rsa -noout -modulus -in private.key | openssl md5
# If both outputs match, the cert matches the key, otherwise they don't
B2. So I chose the chinese certificate option, and there was a much different set of certs in the archive I got from that. I used the bundled cert for NGINX. And that works!
My immediate certificate on https://paper-shape.com got a weak signature algorithm SHA1: https://www.ssllabs.com/ssltest/analyze.html?d=paper-shape.com
I followed theses instructions. I created my pfx file both per OpenSSL and per certificate export wizard.
The CRT and pem (immediate certificate from startcom) seem to be ok, because the following command shows "Signature Algorithm: sha256WithRSAEncryption" on both (CRT and PEM):
$ openssl x509 -text -in paper-shape.com.crt
Either something went wrong during my pfx creation process or azure website overrules my immediate certificate.
Has anybody an idea?
Check your locally-installed certificates (on Windows, 'certmgr.msc'). You may have an old SHA-1-signed copy of the StartCom intermediate certificate which is still valid (say, to 2017) and being used in preference to that provided by the server.
You can find (and chain) the SHA-256 intermediate certificate for Class-1 in PEM format, here: https://www.startssl.com/certs/class1/sha2/pem/sub.class1.server.sha2.ca.pem
I have been facing this same problem, I was about to pull my hair out when the certificate seemed to be right in some browsers and OS and in others it claimed I was using SHA-1 and even https://shaaaaaaaaaaaaa.com was telling me that I had a SHA-2 signed crt.
So! Here is a huge thread in StartCom forum about this issue: https://forum.startcom.org/viewtopic.php?f=15&t=15929&st=0&sk=t&sd=a
The thing is that the browser is using an Intermediate crt that is SHA-1 signed.
The solution: you need to configurate the Intermadiate crt in your server!
You can see more details here:
https://sslmate.com/blog/post/chrome_cached_sha1_chains
I think i messed up a little with my SSL certificates.
We are using SSL Certificates for all OpenVPN clients (witch works perfectly), generated using the easy-rsa toolkit.
And now i want to use the same certificates for Web servers on the OpenVPN hosts
All Keys are 4096 bit long.
My idea is that mybe the Usage purpose is wrong for apache, but i am not quite sure.
root#howard~# openssl x509 -in howard.example.com.crt -text -noout
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 15 (0xf)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=AT, ST=STMK, L=Graz, O=Bee Company, OU=Root CA, CN=example.com/name=rootca/emailAddress=root#bee.example.com
Validity
Not Before: Aug 13 12:36:41 2013 GMT
Not After : Aug 11 12:36:41 2023 GMT
Subject: C=AT, ST=STMK, L=Graz, O=example.com.at, OU=changeme, CN=howard.example.com/name=howard.example.com/emailAddress=root#example.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (4096 bit)
Modulus:
NOTHING_TO_READ_HERE :)
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Comment:
Easy-RSA Generated Certificate
X509v3 Subject Key Identifier:
NOTHING_TO_READ_HERE :)
X509v3 Authority Key Identifier:
keyid:NOTHING_TO_READ_HERE :)
DirName:/C=AT/ST=STMK/L=Graz/O=Bee Company/OU=Root CA/CN=example.com/name=rootca/emailAddress=root#bee.example.com
serial:NOTHING_TO_READ_HERE :)
X509v3 Extended Key Usage:
TLS Web Client Authentication
X509v3 Key Usage:
Digital Signature
Signature Algorithm: sha1WithRSAEncryption
I have no idea how to change/add the purpose of a key when i am generating it with the easy-rsa toolkit.
All i do when generating a new OpenVPN certificate:
cd /usr/share/doc/openvpn/examples/easy-rsa/2.0/
vi vars
. ./vars
./build-key CLIENTNAME
And inside the vars file i couldn't find anything.
But Firefox is returning an
sec_error_inadequate_cert_type
Microsoft's IE just prompts me over and over again if I really trust this certificate...
Any ideas on what i did wrong, or what i need to do?
My idea would be that apache cant handle 4096 bit Keys...
Your key usage and extended key usages are clearly not for a TLS server:
X509v3 Extended Key Usage:
TLS Web Client Authentication
X509v3 Key Usage:
Digital Signature
For a web server you'd obviously want the "TLS Web Server Authentication" extended key usage.
For the key usage, it's less obvious, but you'd want the Key Encipherment too.
More details:
NSS Tech Note 3
These questions on Security.SE: Extensions for SSL server certificate and Which key usages are required by each key exchange method?
Actually, you can do this with easy-rsa - just use build-key-server rather than build-key
I have run into the same issue but by fooling around with the openssl.config included in OpenVPN easyrsa I have found that you can use the ./build-key-server script (sorry If I am not accurate but I am using OpenVPN over Windows) works like a charm :)