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.
Related
This question already has answers here:
Invalid self signed SSL cert - "Subject Alternative Name Missing"
(11 answers)
Getting net::ERR_CERT_COMMON_NAME_INVALID
(2 answers)
NET::ERR_CERT_COMMON_NAME_INVALID - Error Message
(3 answers)
Closed 11 months ago.
I have a certificate for a Synology NAS (Common Name: nas1.contoso.local) signed by a Windows 2016 CA server. Unfortunately, I am getting a NET::ERR_CERT_COMMON_NAME_INVALID error when I open the site (https://nas1.contoso.local) in Google Chrome.
However, the URL is exactly the same as the certificate common name, so I'm not sure the issue would be?
The root certificate for the CA server is already trusted by my computer and there is a "This certificate is valid" message in the certificate details. I've also tried opening the site in Safari, and the certificate details has the error "nas1.contoso.local certificate name does not match input".
Common Name: nas1.contoso.local
Site URL (with the error): https://nas1.contoso.local
Certificate Expires: March 20, 2024 11:52:02AM PST
Encryption: 2056
I've also tried creating and using certificates for *.contoso.local, as well as another nas1.contoso.local certificate with an IP address SAN. The wildcard certificate failed the same way, but oddly enough, the direct IP address SAN worked without any certificate errors when going directly to the IP address (e.g. https://10.0.0.2), but going directly to nas1.contoso.local still threw an error.
I'm not sure what could be causing this problem? Any help would be appreciated.
Edit: Here's the output from echo | openssl s_client -connect nas1.contoso.local:443 | openssl x509 -text -noout (removed the modulus and exponent output)
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
1e:00:00:00:4b:5f:ad:53:57:8f:69:f5:c1:00:00:00:00:00:4b
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=contoso-WIN-T2A-CA
Validity
Not Before: Mar 21 18:52:02 2022 GMT
Not After : Mar 20 18:52:02 2024 GMT
Subject: C=US, ST=CA, O=contoso, OU=IT, CN=nas1.contoso.local/emailAddress=admin#contoso.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
X509v3 extensions:
1.3.6.1.4.1.311.20.2:
...W.e.b.S.e.r.v.e.r
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Subject Key Identifier:
66:2F:78:AC:17:69:25:8F:68:7A:BD:4B:CF:6A:C8:95:FE:8C:26:E1
X509v3 Authority Key Identifier:
keyid:58:66:30:49:C8:5C:A2:9B:E9:BE:B5:DE:7C:7B:ED:F7:3E:8F:43:48
X509v3 CRL Distribution Points:
Full Name:
URI:http://WIN-T2A/CertEnroll/contoso-WIN-T2A-CA.crl
Authority Information Access:
CA Issuers - URI:ldap:///CN=contoso-WIN-T2A-CA,CN=AIA,CN=Public%20Key%20Services,CN=Services,CN=Configuration,DC=contoso,DC=local?cACertificate?base?objectClass=certificationAuthority
Signature Algorithm: sha256WithRSAEncryption
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.
I have a custom CAroot.crt (generated by me) and all my clients certificates are signed with this CAroot.crt. I have a TrustStore.jks where I put only clients certificates and not CAroot.crt, because I would like to have the possibility to remove a client from my truststore any time.
When I try to start my application I got the following:
*** Certificate chain
<Empty>
***
main, fatal error: 42: null cert chain
This is my trustStore.jks:
Keystore type: jks
Keystore provider: SUN
Your keystore contains 1 entry
Alias name: localhost
Creation date: Nov 23, 2019
Entry type: trustedCertEntry
Owner: CN=localhost, OU=IT, O=QUEROBUY, L=SAO CAETANO DO SUL, ST=SAO PAULO, C=BR
Issuer: CN=localhost, OU=IT, O=LANHELLAS XYZ, L=SAO CAETANO DO SUL, ST=SAO PAULO, C=BR
Serial number: 5416c04e360f9d50323c52d8a5b04be2969c9b86
Valid from: Sat Nov 23 16:39:54 BRT 2019 until: Tue Apr 06 16:39:54 BRT 2021
Certificate fingerprints:
MD5: 8F:29:1C:1F:05:89:0B:E6:A0:57:84:FE:B0:78:68:2D
SHA1: 95:C8:EA:0E:C8:7C:4E:99:E4:73:85:49:57:D6:BB:88:AF:52:52:12
SHA256: 7E:ED:19:AF:02:DB:CC:88:98:D0:10:4E:39:67:AA:4D:3F:70:DA:76:03:1B:CB:41:06:DC:3B:51:38:16:78:5F
Signature algorithm name: SHA256withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 1
*******************************************
*******************************************
If I add "CARoot.crt" to my trustStore.jks everything works fine, but I lose the chance to invalidate some specific client certificate. Imagine, I have 10 clients, each one with your own certificate (.crt) assigned by "CARoot.crt" but Client 001 for some reason should be invalidated immediately, I will just remove your public key from trustStore.jks in server, without that I should wait for certificate expiration date.
WHY: if you look slightly earlier in the debuglog you will see the CertificateRequest message, which specifies (among other things) the Cert[ificate] Authorities the server asks for; see rfc5246. Java defines this as the Subject names of the certs in the truststore, because the certs in the truststore are normally expected to be CA certs (and usually CA root certs, as the predefined ones are). Most client software obeys this instruction, though there are exceptions. Thus if your truststore contains certs like
Subject=Client1 Issuer=MyCA
Subject=Client2 Issuer=MyCA
Subject=Client3 Issuer=MyCA
then your server will ask for certs issued by any of Client1 Client2 Client3 but not MyCA. If the client actually has only one cert and it is for e.g. Client2 but is issued by MyCA -- not by any Clientn -- most client software will consider that cert unacceptable for this server/handshake.
THE PKI WAY. It is not true that a certificate can't be invalidated before expiration. PKI in general is explicitly designed to deal with such cases, which are generically termed revocation. There are various reasons a certificate can be revoked before expiring; for the particular PKI scheme used for SSL/TLS (and by Java for other things as well, like code signing), namely PKIX (or the effectively equivalent X.509) see rfc5280 5.3.1 as well as the rest of section 5 for Certificate Revocation Lists (CRLs), the older and traditional way of handling revocation, and rfc6960 for Online Certificate Status Protocol (OCSP), the newer way.
For the 'real' (public) PKI this mostly just works. Java implements PKIX revocation checking, but for SSL/TLS (JSSE) it is disabled by default; you must set sysprop com.sun.net.ssl.checkRevocation to use it. You may also need to set com.sun.security.enableCRLDP for CRLs and AFAICT always need to set security property (not sysprop) ocsp.enable for OCSP. See e.g.:
Check X509 certificate revocation status in Spring-Security before authenticating
Checking a X509 Certificate Revocation
Java SSL Certificate Revocation Checking
But running CRL distribution point(s) and/or OCSP responder(s) so that they are correct and available when needed -- which can be any time -- is non-trivial; this is one of the things real CAs charge money for (or get subsidized). Doing this for your own personal CA can vary from a pain in the butt to effectively impossible, but if you want to, be much more specific about your CA.
Your situation is in principle simpler; you have only one CA and you operate it, so you know when revocations occur. You could trivially provide the CRL(s) to the server when it(they) change. But AFAICS the builtin code has no way to use that information, so you'll have to use the hook that allows writing your own TrustManager in place of the builtin one, and modify it to use a validator with a CertStore that uses the CRLs. This is probably also a fair bit of work, but only once.
WORKAROUNDS. Instead of doing it 'right' in PKI terms, you could continue with your approach of trusting the leaf certs individually by modifying the server or the clients.
You could change the (X509)TrustManager hook in the server to validate certs as usual, but override getAcceptedIssuers to return a different (and correct for your case) list of 'requested' CAs, causing JSSE to send a CertificateRequest that causes the client(s) to use their correct cert(s).
Depending on the clients you might be able to change them to ignore the 'requested' CAs and send their cert anyway -- which the server's default TrustManager will validate if it is in the truststore (or the CA is). For OpenSSL this is easy; OpenSSL already ignores the requested CA list and just sends whatever is configured. For Java you could hook the client KeyManager and override chooseClientAliases method to not check against the list of desired issuers as it normally does. For other clients add to your Q or ask a new one.
TrustStore.jks is how java will determine whether or not it trusts a certificate. Its essentially a keystore file of root certificates. You will have to add your root certificate to this store if you want to avoid "not trustes messages."
In your scenario, since you used that root to issue 10 client certificates, removing the client_certificate.crt from your trust or key stores wont distrust it. Because, by design, java is looking at the TrustStore and finding the root certificate and thus trusting client_certificate.crt still. You are going to need a redesign of your CA.
When deploying any sort of PKI infrastructure, you will need to also set up CRL and/or OCSP servers. These are the two protocols used to revoke a certificate.
I also recommend you do not issue "end user certificates" directly from the root. Its best issue intermediate certificates off the root, and then use intermediate_certificate.crt to issue your actual server or client certs.
For a reason why, see here: https://security.stackexchange.com/questions/128779/why-is-it-more-secure-to-use-intermediate-ca-certificates#128800
And here is a great and easy way to deploy your own CA using OpenSSL. It will show you how to set up the root, intermediate, and revocation servers. https://jamielinux.com/docs/openssl-certificate-authority/
I am using a certificate with subject alternative names in the "Subject" field instead of x509 extensions.
A java client that I use still fails connecting to https url complaining that hostname in certificate didn't match. My understanding is as long as the hostname is listed in Subject Alt Names it should work.
Here is the format of the Subject field in the certificate
C=US,ST=.......CN=x.yz.com/emailAddress=a#b.com/subjectAltName=DNS.1=x2.y.com,DNS.2=x3.y.com
Is it necessary to define SAN as X509 extensions
The subjectAltName is expected to be an X509v3 extension of the certificate, not a part of the Subject field. Therefore, if you listed the SAN names into the Subject, your certificate is invalid.
Here's an example of a certificate that defines an SAN. This answer contains the list of allowed fields for a subject.
In SSL how does it check whether there is a matching certificate in the trust-store? Is it by matching the fingerprint or the serial number?
I always thought it's by matching the fingerprint, but when I ran a java SSL debug following is what I got, and I couldn't see any fingerprint there.
*** Certificate chain
chain [0] = [
[
Version: V3
Subject: CN=XXXX
Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11
Key: Sun RSA public key, 1024 bits
modulus: XXXX
public exponent: XXXX
Validity: [From: Mon Mar 16 22:48:10 UTC 2015,
To: Sun Jun 14 22:48:10 UTC 2015]
Issuer: CN=XXXX
SerialNumber: [ XXXXXXX]
Certificate Extensions: 1
[1]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
...
]
]
]
Algorithm: [SHA256withRSA]
Signature:
...
]
***
I hope this is not a duplicate question (I checked the suggested questions before posting).
It doesn't check whether there is a matching certificate. It checks whether there is a certificate whose subject equals the issuer of this certificate, and whose public key verifies the signature of this certificate.
Quite often, the Certificate Authority Key Identifier is marked as non-critical when present in the certificate to verify, and it's not even always present. You couldn't really rely on that as a fingerprint reference to use.
The verification is done by building a certification path, by chaining the Issuer DN (Distinguished Name) of the certificate to verify to the Subject DN of a CA certificate you trust.
This is described in the CertPathBuilder/CertPathValidator sections of the Java PKI Programmer's Guide. (More generally, this follows RFC 3820, since there are other attributes to check too.)
Alternatively, you can also have an exact End Entity Certificate (not a CA certificate) directly in the truststore. In this case, an exact match with the certificate can be used.