How do I find out if a certificate is self-signed or authorized by CA? Somewhere I read that self-signed subject and issuer will be same, is it correct?
Self-signed certificate will have identical subject and issuer fields, but a) this is not guaranteed, and b) the inverse is not true. Just because the fields have the same value that does not mean the certificate is self-signed.
Here are the outputs from one of our internal root (root-ca.crt) and intermediate certificates (ca.crt):
$ openssl x509 -subject -issuer -noout -in root-ca.crt subject= /C=DE/ST=Berlin/L=Berlin/O=classmarkets GmbH/CN=classmarkets CA issuer= /C=DE/ST=Berlin/L=Berlin/O=classmarkets GmbH/CN=classmarkets CA $ openssl x509 -subject -issuer -noout -in ca.crt subject= /CN=classmarkets CA/C=DE/L=Berlin/O=classmarkets GmbH/ST=Berlin issuer= /C=DE/ST=Berlin/L=Berlin/O=classmarkets GmbH/CN=classmarkets CA
You can see that the fields are the same for both certificates, even though ca.crt has been signed by root-ca.crt:
$ openssl x509 -noout -text -in ca.crt | grep -A1 'Key Identifier' X509v3 Authority Key Identifier: keyid:A2:2D:AF:A0:D2:64:DF:30:F1:72:39:AC:21:AF:45:D6:D4:12:19:94 -- X509v3 Subject Key Identifier: 30:B0:6B:B5:56:9A:95:7C:31:4B:B2:65:95:0D:F9:EE:E8:3D:3A:C9 $ openssl x509 -noout -text -in root-ca.crt | grep -A1 'Key Identifier' X509v3 Subject Key Identifier: A2:2D:AF:A0:D2:64:DF:30:F1:72:39:AC:21:AF:45:D6:D4:12:19:94
Note the absence of the
Authority Key Identifier in root-ca.crt.
RFC3280 states in section 188.8.131.52 (emphasis mine):
The keyIdentifier field of the authorityKeyIdentifier extension MUST be included in all certificates generated by conforming CAs to facilitate certification path construction. There is one exception; where a CA distributes its public key in the form of a "self-signed" certificate, the authority key identifier MAY be omitted. The signature on a self-signed certificate is generated with the private key associated with the certificate's subject public key. (This proves that the issuer possesses both the public and private keys.) In this case, the subject and authority key identifiers would be identical, but only the subject key identifier is needed for certification path building.
So it seems to me that the
Subject Key Identifiers are a much better indicator for self-signed certs than the
Subject fields. For a self-signed certificate the
Authority Key Identifier will either be absent or have the same value as the
Subject Key Identifier.
@Vilican answer is technically correct and should do the job most of the time. But I wanted to find out if a certificate I was examining (not some particular web site) was used as a self-signed certificate or was a CA cert.
What I found out is that valid Root CA certificates have same issuer and subject. Also
Certificate Basic Constraints indicates this is a CA as well number of allowed intermediate CAs to be signed by this one.
While self-signed certs used to secure a web site usually are not marked as CAs as well have a DNS name as
Subject. And/or have a list of allowed DNS names/IPaddresses under
Certificate subject alt name.
I suppose it's not correctly to check only match of subject and issuer of a certificate. There are plenty of options where different certificates with different start/end date or other metadata to have same subject and issuer. I'm using following method to check certificate is self-signed:
openssl verify -CAfile /cert/to/check.pem -CApath /cert/to/check.pem /cert/to/check.pem
Then if this check failed it's possible to check if certificate is signed with another certificate:
openssl verify -CAfile /cert/of/issuer.pem -CApath /cert/of/issuer.pem /cert/to/check.pem
Specifying same certificate as
CApath prevents successful verification against default trusted certificates of OpenSSL.
Sometimes not self-signed certificate have same subject and issuer.
openssl s_client - can check certificate
Test real certificate
DOMAIN="google.com"; PORT="443" echo | openssl s_client -servername "$DOMAIN" -connect "$DOMAIN:$PORT" > /dev/null --- depth=3 C = BE, O = GlobalSign nv-sa, OU = Root CA, CN = GlobalSign Root CA verify return:1 depth=2 C = US, O = Google Trust Services LLC, CN = GTS Root R1 verify return:1 depth=1 C = US, O = Google Trust Services LLC, CN = GTS CA 1C3 verify return:1 depth=0 CN = *.google.com verify return:1 DONE
Test self-signed certificate
DOMAIN="lan.local"; PORT="443" echo | openssl s_client -servername "$DOMAIN" -connect "$DOMAIN:$PORT" > /dev/null --- depth=1 C = US, O = xxx LLC, OU = rootCA, CN = Local xxx LLC Root CA, emailAddress = [email protected] verify error:num=19:self signed certificate in certificate chain DONE
I have normal certificate
SUBJECT="US, ST" ISSUER="US, ST"
openssl s_client output
depth=2 C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust RSA Certification Authority verify return:1 depth=1 C = US, ST = MI, L = Ann Arbor, O = Internet2, OU = InCommon, CN = InCommon RSA Server CA verify return:1 depth=0 C = US, ST = North Carolina, O = xxx, CN = xxx.xxx verify return:1 DONE