0

I've created a private root CA and issued some SSL certificate for some https websites,

(I am not sure whether this should be called as self-signed certificate, in my case, the root ca certificate is self signed, but the SSL certificate for websites issued from the root CA is not self-signed. This makes me confused about how to choose google search keyword).

These https website works well in Chrome, Firefox, but not Safari. (Of course, Chrome and Firefox will show security warning but give me opportunity to continue viewing, but Safari does not completely).

The point is: my website provided a certificate chain file which is

The website certificate... +
The root CA certificate...

, Chrome and Firefox can smartly find root CA from the certificate chain file, but Safari does not.

Safari reports error:

Safari Can't Open the Page – Safari can't open the page because Safari can't establish a secure connection to the server 'servername'.

  • Of course, I can in advance import the Root CA certificate to Mac's keychain, then Safari works without even warnings. But this is not what I want, I can not demand users to do such manual things.

  • If I generate a real self signed SSL certificate (without upper level CA), Safari will give me an opportunity to view the website. But this is also not what I want, because I have some Java application which call multiple https websites and should not ignore certificate check, I want to register just one common root CA certificate to Java cacerts keystore so that all relative https websites will be trusted automatically.

Can anyone tell me how to solve this issue? I mean without manually import Root CA in advance, yet let user have the opportunity to view the website anyway. Note, Chrome and Firefox works well.

I am going to specify some certificate extension to tell the browser where to find the root CA certificate, not sure if there is any other better way.

Exclamations:

  • I don't mean "just send a new CA certificate (in a chain or otherwise) and your browser "smartly" accept it", I don mean let browser "accept it", but just let it pass the chain validation and ask user if they accept the risk of unknown root CA.

  • About "Chain files are not CAs": I know it much, chain file does not even include the root CA certificate, browser have some means to find root CA certificate, such as from preinstalled root CAs, or probably by a "Authority Info Access" field in the certificate, there is a URL point to root CA. This is a not-well-known area, also depends on browser implementation: How does browser get root CA(I don't mean trust or accept) from the website's certificate itself.

  • I have followed Apple's guideline https://support.apple.com/en-us/HT210176

EDIT 2021/02/12: things get more and more interesting for Safari:

  • https://ip_address works. (of course with security warning)
  • https://dns_name does not works (not even a security warning)
  • https://dns_name works in private browsing mode (of course with security warning).

Let me append some tech detail, here is the certificate chain returned by the website: (Note that I replaced some sensitive names with word such as my-host...)

$ echo Q | openssl s_client -showcerts -verify 5 -connect my-host.my-domain:443
verify depth is 5
CONNECTED(00000005)
depth=1 CN = My Root CA Name
verify error:num=19:self signed certificate in certificate chain
verify return:1
depth=1 CN = My Root CA Name
verify return:1
depth=0 CN = my-host.my-domain
verify return:1
---
Certificate chain
 0 s:CN = my-host.my-domain
   i:CN = My Root CA Name
-----BEGIN CERTIFICATE-----
MIIDqjCCApKgAwIBAgIJAIh7Dn2n363zMA0GCSqGSIb3DQEBCwUAMBoxGDAWBgNV
BAMMD1RyaWRlbnQgUm9vdCBDQTAeFw0yMTAyMDkwNDU4MzZaFw0yMjAzMTMwNDU4
......
+bnUvHgMmMukXgMLo3e6tnF/Za9z/BCv0KESoFEIg7uWo+IUZv8wXYI8YQEaeeGt
s2et3Js1eBqN1zle8ejoFuInQNS5wkalx0D+zTcCcXVvnUJm2womcKBxFAHJeZDg
vvbsua6FH0JTVjeprdmx1mKkj+MP4N664vP8kAj6
-----END CERTIFICATE-----
 1 s:CN = My Root CA Name
   i:CN = My Root CA Name
-----BEGIN CERTIFICATE-----
MIIDFzCCAf+gAwIBAgIJAIafS0ZYzGA4MA0GCSqGSIb3DQEBCwUAMBoxGDAWBgNV
BAMMD1RyaWRlbnQgUm9vdCBDQTAeFw0yMTAyMDkwNDU0MTdaFw0zMTAyMDcwNDU0
......
+b4lJl9fUHd01xqGbBGmp/BL8EI+IveSRTKr/Boi+klqvlgOi5TgUF/0R9gmwPRO
OXIL5hdA7CTsgaURWJ897p5JVYsPtofjnL10
-----END CERTIFICATE-----
---
Server certificate
subject=CN = my-host.my-domain

issuer=CN = My Root CA Name

---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 2449 bytes and written 432 bytes
Verification error: self signed certificate in certificate chain
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: F6FF34026A5B10EE149D442FA4035916330AE09AC2B771369EA0B94754501892
    Session-ID-ctx:
    Master-Key: BF444224C15CEDC3309F01E4C5DE8F8331AF9B82F0613601FE5D1B677F6526DD3FF97BB00DB3DC5BB0E35EA489861FF6
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 300 (seconds)
    TLS session ticket:
    0000 - d6 5f 48 e0 90 10 48 22-46 83 7f 82 d1 a4 17 da   ._H...H"F.......
    0010 - 17 10 e8 1e e1 dc 17 58-9c 36 e8 d1 36 f5 d7 f6   .......X.6..6...
    ......
    00d0 - 85 63 2a 3c 0e 6c 18 f3-27 fb 21 7d bd 3d 8b 33   .c*<.l..'.!}.=.3
    00e0 - bf 3c 60 da 06 2e 23 3b-a0 f2 f6 88 5e 0c 2b f2   .<`...#;....^.+.

    Start Time: 1612937133
    Timeout   : 7200 (sec)
    Verify return code: 19 (self signed certificate in certificate chain)
    Extended master secret: yes
---
DONE

The apache2(2.4.29 Ubuntu) config:

<IfModule mod_ssl.c>
    <VirtualHost *:443>
        SSLEngine On
        SSLCertificateFile    /etc/apache2/certs/web_cert.pem
        SSLCertificateKeyFile /etc/apache2/certs/web_key.pem
        DocumentRoot /var/www
        LimitRequestFieldSize 32768
    </VirtualHost>
</IfModule>

Note that the /etc/apache2/certs/web_cert.pem is actually a concatenation of the website's certificate and the root CA certificate, i.e., a certificate chain file.

Other info:

The root CA certificate:

# openssl x509 -text -noout < /etc/apache2/certs/root_ca_cert.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            86:9f:4b:46:58:cc:60:38
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN = My Root CA Name
        Validity
            Not Before: Feb  9 04:54:17 2021 GMT
            Not After : Feb  7 04:54:17 2031 GMT
        Subject: CN = My Root CA Name
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    ......
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: critical
                CA:TRUE
            X509v3 Subject Key Identifier:
                EE:BF:15:0D:35:BC:4C:92:88:4F:9B:21:FC:B6:C4:29:C4:35:9E:D3
            X509v3 Authority Key Identifier:
                keyid:EE:BF:15:0D:35:BC:4C:92:88:4F:9B:21:FC:B6:C4:29:C4:35:9E:D3

            X509v3 Key Usage:
                Certificate Sign, CRL Sign
    Signature Algorithm: sha256WithRSAEncryption
         ......

The root CA key

# openssl rsa -text -noout < /etc/apache2/certs/root_ca_key.pem
Private-Key: (2048 bit)
modulus:
    ......
publicExponent: 65537 (0x10001)
privateExponent:
    ......
prime1:
    ......
prime2:
    ......
exponent1:
    ......
exponent2:
    ......
coefficient:
    ......

The website certificate:

# openssl x509 -text -noout < /etc/apache2/certs/web_cert.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            88:7b:0e:7d:a7:df:ad:f3
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN = My Root CA Name
        Validity
            Not Before: Feb  9 04:58:36 2021 GMT
            Not After : Mar 13 04:58:36 2022 GMT
        Subject: CN = my-host.my-domain
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    ......
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Subject Key Identifier:
                E2:83:31:54:D3:49:D1:5E:78:6C:29:84:15:C9:80:48:26:AF:7A:EF
            X509v3 Authority Key Identifier:
                keyid:EE:BF:15:0D:35:BC:4C:92:88:4F:9B:21:FC:B6:C4:29:C4:35:9E:D3
                DirName:/CN=My Root CA Name
                serial:86:9F:4B:46:58:CC:60:38

            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage: critical
                TLS Web Server Authentication
            X509v3 Subject Alternative Name:
                DNS:my-host.my-domain, IP Address:100.100.100.100
    Signature Algorithm: sha256WithRSAEncryption
         ......

The website's certificate key:

# openssl rsa -text -noout < /etc/apache2/certs/web_key.pem
Private-Key: (2048 bit)
modulus:
    ......
publicExponent: 65537 (0x10001)
privateExponent:
    ......
prime1:
    ......
prime2:
    ......
exponent1:
    ......
exponent2:
    ......
coefficient:
    ......

Keychain verification result:

s# openssl verify -CAfile /etc/apache2/certs/root_ca_cert.pem < /etc/apache2/certs/web_cert.pem
stdin: OK
1
  • Comments are not for extended discussion; this conversation has been moved to chat.
    – Kusalananda
    Feb 13, 2021 at 11:20

1 Answer 1

0

Sorry for troubling you all, not sure which part finally made it works, after clearing HSTS plist and browser history and reboot, now it works. I have also confirmed that two users with same MacOS version works, only my Macbook and another colleague's Macbook had the issue. Seams because of we manually registered other Root CA which has same name.

Summary: when the issue happens, https via IP works, Private browsing mode works for both dnsname and ip, and some users works, and now mine also works, of course, all shows security warning, I think the issue is NOT because "Apple have consciously decided not to offer this option if there is a CA certificate in-play and it's not in your trust store" , but because of browser cache or HSTS settings etc, after all some local things.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.