Download Complete certificate chain for Intermediate CA

Started by jsingh, April 02, 2024, 11:39:07 PM

Previous topic - Next topic
I am trying to create a certificate authority for internal services in opnsense. I created a root CA and then an intermediate CA. When I tried to install the certificates in the windows trust store, intermediate certificate won't authenticate against the root CA.
I noticed that the certificate does not have the complete chain, whereas certs from my pfsense box ca have a full certificate chain. Is this expected behavior or a bug.
If it's a bug how do I download the complete certficate?

Quote from: jsingh on April 02, 2024, 11:39:07 PM
I am trying to create a certificate authority for internal services in opnsense. I created a root CA and then an intermediate CA. When I tried to install the certificates in the windows trust store, intermediate certificate won't authenticate against the root CA.

You probably made a mistake importing the Root CA, in Windows there are different stores (Machine / User) with different subsections. For third party Root CA's you need to pick the right one (see Microsoft docs, not a Windows expert).

_Don't_ import Intermediates and/or Endpoint certificates, the whole idea of a Root Certificate is that you create a Chain-of-Trust, this chain will automagicly be created if the Root CA is in the right store and the endpoint is sending it's Certificate + Intermediate (which OPNsense does by default).
Also keep in mind not all programs / browsers use the Microsoft store, Edge and Chrome by default use the Windows store. Firefox is using it's own, internal, certificate store, it's only since latest release (>12x.x) Firefox _can_ read the Windows store if configured in it's preferences.

I made sure of importing the root ca and intermediate ca in the correct location.PFsense certs have no issues, it's only the opnsense certs. This is what the Certification Path for the final server certificates that I created from the Intermediate CA shows in windows :

Pfsense Cert:

Root-CA
->Intermediate-CA
--->Certificate

OpnSense Cert

Intermediate-CA
->Certificate

Windows always throws an error that the intermediate certificate cannot be validated against the root certificate, since the root-ca is not part of the certification path in the OPNSense cert



Quote from: jsingh on April 03, 2024, 12:32:39 AM
I made sure of importing the root ca and intermediate ca in the correct location.

Again, you don't import Intermediates in a Certificate Trust Store (some very specific corner cases excluded, this isn't one), just the Root CA. The Chain-of-Trust is automagicly created.

Quote
PFsense certs have no issues

OPNsense don't have issues either, so you're doing something wrong

Because I'm using an external PKI, I just double checked an OPNsense 24.1.4 install and created a new full chain internally:

Scenario: OPNsense Root CA -> OPNsense Intermediate CA -> OPNsense Server Certificate (opnsense.domain.tld)

Imported the OPNsense Root CA in my local OpenSSL trust store. I'm not using Windows, but that shouldn't matter, PKI is an universal standard.

openssl s_client -connect opnsense.domain.tld:443


CONNECTED(00000003)
depth=2 C = US, ST = CA, O = OPNsense, CN = OPNsense Root CA
verify return:1
depth=1 C = US, ST = CA, O = OPNsense, CN = OPNsense Intermediate CA
verify return:1
depth=0 C = US, ST = CA, O = OPNsense, CN = opnsense.domain.tld
verify return:1
---
Certificate chain
0 s:C = US, ST = CA, O = OPNsense, CN = opnsense.domain.tld
   i:C = US, ST = CA, O = OPNsense, CN = OPNsense Intermediate CA
   a:PKEY: id-ecPublicKey, 256 (bit); sigalg: ecdsa-with-SHA512
   v:NotBefore: Apr  3 11:05:28 2024 GMT; NotAfter: May  3 11:05:28 2025 GMT
1 s:C = US, ST = CA, O = OPNsense, CN = OPNsense Intermediate CA
   i:C = US, ST = CA, O = OPNsense, CN = OPNsense Root CA
   a:PKEY: id-ecPublicKey, 384 (bit); sigalg: ecdsa-with-SHA512
   v:NotBefore: Apr  3 11:03:41 2024 GMT; NotAfter: Apr  2 11:03:41 2029 GMT
2 s:C = US, ST = CA, O = OPNsense, CN = OPNsense Root CA
   i:C = US, ST = CA, O = OPNsense, CN = OPNsense Root CA
   a:PKEY: id-ecPublicKey, 384 (bit); sigalg: ecdsa-with-SHA512
   v:NotBefore: Apr  3 11:02:36 2024 GMT; NotAfter: Apr  1 11:02:36 2034 GMT
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIC4TCCAmegAwIBAgIBATAKBggqhkjOPQQDBDBQMQswCQYDVQQGEwJVUzELMAkG
A1UECAwCQ0ExETAPBgNVBAoMCE9QTnNlbnNlMSEwHwYDVQQDDBhPUE5zZW5zZSBJ
bnRlcm1lZGlhdGUgQ0EwHhcNMjQwNDAzMTEwNTI4WhcNMjUwNTAzMTEwNTI4WjBL
MQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExETAPBgNVBAoMCE9QTnNlbnNlMRww
GgYDVQQDDBNvcG5zZW5zZS5kb21haW4udGxkMFkwEwYHKoZIzj0CAQYIKoZIzj0D
AQcDQgAEkWMypjTp7zUWncNuG+6Eu7CS1XQcPNMh3AvTVSAxOkmirQ+tQYb0Z2rw
8A6oYnaEnnRMpSLm5yS2RtAEyv49jaOCATUwggExMAkGA1UdEwQCMAAwEQYJYIZI
AYb4QgEBBAQDAgZAMDQGCWCGSAGG+EIBDQQnFiVPUE5zZW5zZSBHZW5lcmF0ZWQg
U2VydmVyIENlcnRpZmljYXRlMB0GA1UdDgQWBBRMmJFwmp0/hu3ky+uarqMDaouh
hjBwBgNVHSMEaTBngBThUCmC2UveWzPhccWCvvYVg4jQZKFMpEowSDELMAkGA1UE
BhMCVVMxCzAJBgNVBAgMAkNBMREwDwYDVQQKDAhPUE5zZW5zZTEZMBcGA1UEAwwQ
T1BOc2Vuc2UgUm9vdCBDQYIBATAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUI
AgIwCwYDVR0PBAQDAgWgMB4GA1UdEQQXMBWCE29wbnNlbnNlLmRvbWFpbi50bGQw
CgYIKoZIzj0EAwQDaAAwZQIwTrrn5w1sqDjEVUtDrqEhR8+6ZEBIYB91R9UXRpZr
oOfNiG6LtbqwXGkg0uYCEmJQAjEAtd7gJLqXMA2oWsipU7yFJ/9nW7a3sNb+MAww
rqd4DfBXQyw9IlRUmxrepPgUmMX9
-----END CERTIFICATE-----
subject=C = US, ST = CA, O = OPNsense, CN = opnsense.domain.tld
issuer=C = US, ST = CA, O = OPNsense, CN = OPNsense Intermediate CA
---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: ECDSA
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 2344 bytes and written 401 bytes
Verification: OK
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 256 bit
This TLS version forbids renegotiation.
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
---
Post-Handshake New Session Ticket arrived:
SSL-Session:
    Protocol  : TLSv1.3
    Cipher    : TLS_AES_256_GCM_SHA384
    Session-ID: 70F34E2A586FDDB18497303AC41864ABB3EEDB28AB085D1376DCD361F6DD5435
    Session-ID-ctx:
    Resumption PSK: 7BDE425C86B48127AD9BF86C2E4334991DB3346EE573D7063FECEC21917C89136D0CCD84942D90D9F99A5A1D973DC0C4
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 7200 (seconds)
    TLS session ticket:
    0000 - c0 d1 1d 44 ab 91 57 91-b8 3e d4 0b f9 d8 ba 03   ...D..W..>......
    0010 - 1d 50 fc d9 41 10 68 57-6f cb 83 38 16 8b 32 b5   .P..A.hWo..8..2.
    0020 - 02 58 97 07 f1 9a 6b 58-72 4c dc 69 4b f6 1f f9   .X....kXrL.iK...
    0030 - c1 e0 9f e2 b4 a4 55 1f-8e b0 e1 88 38 22 8e 56   ......U.....8".V
    0040 - bc 88 8b ed 10 78 35 c6-f2 10 1b 55 3a 00 9d bd   .....x5....U:...
    0050 - f8 b1 99 32 ff ef d5 11-a7 df 36 0f 80 7e 7d 9c   ...2......6..~}.
    0060 - 6d 21 47 4f b4 06 ba 97-aa 31 66 23 f6 4c b9 9a   m!GO.....1f#.L..
    0070 - fd 2c 0a f8 e1 2b bf eb-32 e4 5c 47 e4 33 29 0c   .,...+..2.\G.3).
    0080 - 42 ae 95 3e 42 ce fe f4-01 e4 19 ba 78 c8 21 bc   B..>B.......x.!.
    0090 - 8f 27 a6 e4 c0 f9 e2 e2-eb 2f 2e 76 84 de 2c ae   .'......./.v..,.
    00a0 - e7 90 b9 9d 5d 60 59 02-83 02 38 d9 c8 f7 ce 33   ....]`Y...8....3
    00b0 - 69 ad ec 66 56 70 92 81-9b 63 e5 b1 ef 76 31 ab   i..fVp...c...v1.
    00c0 - c9 e2 31 90 5e b4 fc 1b-8a bd c1 85 50 d3 d7 5e   ..1.^.......P..^

    Start Time: 1712142773
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: no
    Max Early Data: 0
---
read R BLOCK
---
Post-Handshake New Session Ticket arrived:
SSL-Session:
    Protocol  : TLSv1.3
    Cipher    : TLS_AES_256_GCM_SHA384
    Session-ID: 19D66191294B635164BCBF9C869F41B93C56A64ACD84865A21EE7EC63C4B9BA5
    Session-ID-ctx:
    Resumption PSK: 717294B7075A4270CEBBDD3EA6736212666C3AA595DE07B03FC5FFFAC4F984AF23A576267B73688AD5A12861129828D0
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 7200 (seconds)
    TLS session ticket:
    0000 - c0 d1 1d 44 ab 91 57 91-b8 3e d4 0b f9 d8 ba 03   ...D..W..>......
    0010 - 74 5e 6b 46 36 e0 d5 24-4e 09 e8 6e 8a eb a2 db   t^kF6..$N..n....
    0020 - 43 86 20 8d e0 54 5b 8c-81 de 2e 21 fd f7 93 9e   C. ..T[....!....
    0030 - 8a 9e c9 37 0d 3a de 56-43 3c 57 b4 a5 96 cc 3d   ...7.:.VC<W....=
    0040 - 1f 43 52 c0 ce 89 9c 25-f0 aa a4 3a 33 db 05 0a   .CR....%...:3...
    0050 - 3b 12 db 5c ff 3c fc 19-91 91 26 75 dc 11 2a 56   ;..\.<....&u..*V
    0060 - 40 cd 8b d4 93 98 53 71-51 c8 03 d3 1e 00 b1 5a   @.....SqQ......Z
    0070 - 11 88 97 f0 10 ce da 8f-20 f0 f9 f0 c2 85 28 c4   ........ .....(.
    0080 - 2b 59 31 b3 11 a1 4d 7c-1c 87 e4 56 3e b5 06 b8   +Y1...M|...V>...
    0090 - d5 25 0c c6 fa fd 18 c2-dc 16 d1 4e 5d 5a 18 fd   .%.........N]Z..
    00a0 - 9e 3f 69 32 b2 77 f4 d7-83 33 9a 77 9b 37 e2 30   .?i2.w...3.w.7.0
    00b0 - af 28 1d 93 00 2c 79 38-3e 78 d6 ee 28 0c 7e 74   .(...,y8>x..(.~t
    00c0 - 86 fc e6 81 b1 53 8b d7-8a 13 ec 04 01 0a 44 b1   .....S........D.

    Start Time: 1712142773
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: no
    Max Early Data: 0
---
read R BLOCK
closed


As you can see, OPNsense is sending the FULL chain; it even sends the Root CA which is unnecessary (you're manually trust this one by adding it to your Trust Store), but harmless, just a bit more network traffic. All certs using modern EC keys (P-384 for the Root + Intermediate, P-256 for the server). Root CA with 10y, Intermediate with 5y and Server cert with 395d lifetime.

You might want to paste your full chain here (just the certs, DON'T send KEYS!) so your Root, Intermediate and Certificate. Something like this:

openssl x509 -in OPNsense_Root_CA.crt -noout -text

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 0 (0x0)
        Signature Algorithm: ecdsa-with-SHA512
        Issuer: C = US, ST = CA, O = OPNsense, CN = OPNsense Root CA
        Validity
            Not Before: Apr  3 11:02:36 2024 GMT
            Not After : Apr  1 11:02:36 2034 GMT
        Subject: C = US, ST = CA, O = OPNsense, CN = OPNsense Root CA
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (384 bit)
                pub:
                    04:78:57:75:06:5b:92:36:59:ce:68:83:15:f1:c7:
                    1d:47:45:9a:22:00:ec:4f:50:e8:9c:bf:c9:0f:05:
                    33:3f:38:4c:9e:a3:68:1c:16:19:30:9e:0e:45:0e:
                    e5:05:a7:01:b8:16:fc:95:a3:bd:ff:99:7e:68:fb:
                    29:b6:eb:01:1b:fc:43:3d:ad:b9:d3:cc:5a:05:c6:
                    ba:91:d5:10:2c:90:ea:83:c3:bf:5b:3e:56:b3:a6:
                    a4:ba:a8:12:91:b2:b4
                ASN1 OID: secp384r1
                NIST CURVE: P-384
        X509v3 extensions:
            Netscape Comment:
                OPNsense Generated Certificate Authority
            X509v3 Subject Key Identifier:
                E1:50:29:82:D9:4B:DE:5B:33:E1:71:C5:82:BE:F6:15:83:88:D0:64
            X509v3 Authority Key Identifier:
                E1:50:29:82:D9:4B:DE:5B:33:E1:71:C5:82:BE:F6:15:83:88:D0:64
            X509v3 Basic Constraints: critical
                CA:TRUE
            X509v3 Key Usage: critical
                Digital Signature, Certificate Sign, CRL Sign
    Signature Algorithm: ecdsa-with-SHA512
    Signature Value:
        30:65:02:31:00:d6:a3:07:50:67:17:05:bf:41:86:02:fd:69:
        2f:2b:97:6a:a6:50:2d:de:bc:cc:fa:7e:3e:67:a8:59:b5:84:
        d0:a4:e0:7e:f7:fa:0e:64:7d:96:4d:e2:f8:d4:db:75:6a:02:
        30:21:ba:80:5e:9a:e8:d7:bc:da:6e:41:54:ea:bc:19:68:e4:
        b2:ba:15:06:51:fc:14:12:ba:9b:8a:32:47:3a:c7:18:70:9b:
        5e:38:d7:ef:8e:e6:f3:3b:6e:33:dd:2f:d9


So this is test-ca
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 0 (0x0)
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: C = CA, ST = TEST, L = TEST, O = Test, emailAddress = Test@gmail.com, CN = test-ca
        Validity
            Not Before: Apr  3 23:19:45 2024 GMT
            Not After : Apr  3 23:19:45 2025 GMT
        Subject: C = CA, ST = TEST, L = TEST, O = Test, emailAddress = Test@gmail.com, CN = test-ca
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (384 bit)
                pub:
                    04:19:10:8b:69:9b:6e:2c:e6:50:14:8e:65:c9:a9:
                    d2:a1:27:3e:ee:90:6b:ef:ea:96:62:5c:6a:08:e4:
                    a5:ed:ba:bc:cc:5b:93:f4:35:dc:01:6a:3d:48:94:
                    ea:dc:73:ce:a1:90:10:05:14:d4:ac:d3:69:c9:e4:
                    a5:8f:91:37:ae:d5:a0:e7:24:f4:04:05:ff:1e:03:
                    9c:4b:f0:11:1d:f0:9a:f1:c0:c5:b4:73:7e:2a:db:
                    31:ad:f4:42:d2:d1:35
                ASN1 OID: secp384r1
                NIST CURVE: P-384
        X509v3 extensions:
            Netscape Comment:
                OPNsense Generated Certificate Authority
            X509v3 Subject Key Identifier:
                52:29:10:B0:B7:16:67:C3:C4:44:49:82:3F:30:4D:C2:BB:BA:E4:84
            X509v3 Authority Key Identifier:
                52:29:10:B0:B7:16:67:C3:C4:44:49:82:3F:30:4D:C2:BB:BA:E4:84
            X509v3 Basic Constraints: critical
                CA:TRUE
            X509v3 Key Usage: critical
                Digital Signature, Certificate Sign, CRL Sign
    Signature Algorithm: ecdsa-with-SHA256
    Signature Value:
        30:65:02:30:64:6b:58:b0:14:77:2d:9c:66:23:5e:7c:58:bd:
        22:04:b7:e1:96:9a:65:79:18:8b:46:66:8f:b8:74:e0:1b:e7:
        f4:89:aa:50:82:03:0a:f5:83:78:c3:39:d3:e4:8b:56:02:31:
        00:d1:47:0f:42:e1:6c:95:40:3e:2d:65:bd:14:04:04:b9:cb:
        b2:60:2f:5e:f8:a0:fe:1f:88:28:e7:85:77:bb:eb:f9:48:60:
        a2:e7:b5:8e:c2:2e:7b:20:cd:c0:a8:ec:4f
-----BEGIN CERTIFICATE-----
MIICoDCCAiagAwIBAgIBADAKBggqhkjOPQQDAjBrMQswCQYDVQQGEwJDQTENMAsG
A1UECAwEVEVTVDENMAsGA1UEBwwEVEVTVDENMAsGA1UECgwEVGVzdDEdMBsGCSqG
SIb3DQEJARYOVGVzdEBnbWFpbC5jb20xEDAOBgNVBAMMB3Rlc3QtY2EwHhcNMjQw
NDAzMjMxOTQ1WhcNMjUwNDAzMjMxOTQ1WjBrMQswCQYDVQQGEwJDQTENMAsGA1UE
CAwEVEVTVDENMAsGA1UEBwwEVEVTVDENMAsGA1UECgwEVGVzdDEdMBsGCSqGSIb3
DQEJARYOVGVzdEBnbWFpbC5jb20xEDAOBgNVBAMMB3Rlc3QtY2EwdjAQBgcqhkjO
PQIBBgUrgQQAIgNiAAQZEItpm24s5lAUjmXJqdKhJz7ukGvv6pZiXGoI5KXturzM
W5P0NdwBaj1IlOrcc86hkBAFFNSs02nJ5KWPkTeu1aDnJPQEBf8eA5xL8BEd8Jrx
wMW0c34q2zGt9ELS0TWjgZ0wgZowNwYJYIZIAYb4QgENBCoWKE9QTnNlbnNlIEdl
bmVyYXRlZCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHQYDVR0OBBYEFFIpELC3FmfD
xERJgj8wTcK7uuSEMB8GA1UdIwQYMBaAFFIpELC3FmfDxERJgj8wTcK7uuSEMA8G
A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUC
MGRrWLAUdy2cZiNefFi9IgS34ZaaZXkYi0Zmj7h04Bvn9ImqUIIDCvWDeMM50+SL
VgIxANFHD0LhbJVAPi1lvRQEBLnLsmAvXvig/h+IKOeFd7vr+Uhgoue1jsIueyDN
wKjsTw==
-----END CERTIFICATE-----


Intermediate CA

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 1 (0x1)
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: C = CA, ST = TEST, L = TEST, O = Test, emailAddress = Test@gmail.com, CN = test-ca
        Validity
            Not Before: Apr  3 23:20:18 2024 GMT
            Not After : Dec 24 23:20:18 2024 GMT
        Subject: C = CA, ST = TEST, L = TEST, O = Test, emailAddress = Test@gmail.com, CN = Test-ca-inter
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (384 bit)
                pub:
                    04:19:10:8b:69:9b:6e:2c:e6:50:14:8e:65:c9:a9:
                    d2:a1:27:3e:ee:90:6b:ef:ea:96:62:5c:6a:08:e4:
                    a5:ed:ba:bc:cc:5b:93:f4:35:dc:01:6a:3d:48:94:
                    ea:dc:73:ce:a1:90:10:05:14:d4:ac:d3:69:c9:e4:
                    a5:8f:91:37:ae:d5:a0:e7:24:f4:04:05:ff:1e:03:
                    9c:4b:f0:11:1d:f0:9a:f1:c0:c5:b4:73:7e:2a:db:
                    31:ad:f4:42:d2:d1:35
                ASN1 OID: secp384r1
                NIST CURVE: P-384
        X509v3 extensions:
            Netscape Comment:
                OPNsense Generated Certificate Authority
            X509v3 Subject Key Identifier:
                52:29:10:B0:B7:16:67:C3:C4:44:49:82:3F:30:4D:C2:BB:BA:E4:84
            X509v3 Authority Key Identifier:
                52:29:10:B0:B7:16:67:C3:C4:44:49:82:3F:30:4D:C2:BB:BA:E4:84
            X509v3 Basic Constraints: critical
                CA:TRUE
            X509v3 Key Usage: critical
                Digital Signature, Certificate Sign, CRL Sign
    Signature Algorithm: ecdsa-with-SHA256
    Signature Value:
        30:65:02:31:00:b4:31:71:cb:d6:cc:57:62:67:49:13:5f:a4:
        f1:76:4b:ee:a5:dc:e7:c2:8f:47:97:cf:0b:33:4f:90:ed:66:
        a7:b5:29:55:31:d7:df:b6:98:0c:59:1e:09:40:19:dd:d9:02:
        30:2a:0a:ee:dc:ec:55:81:f0:ee:7a:b6:a5:9d:5e:d6:a3:9e:
        d4:94:6f:d6:cb:ab:15:70:a0:b6:54:8a:45:b8:f9:69:2c:fd:
        5b:01:2b:16:f5:16:e2:ed:dc:c5:8e:f4:87
-----BEGIN CERTIFICATE-----
MIICpjCCAiygAwIBAgIBATAKBggqhkjOPQQDAjBrMQswCQYDVQQGEwJDQTENMAsG
A1UECAwEVEVTVDENMAsGA1UEBwwEVEVTVDENMAsGA1UECgwEVGVzdDEdMBsGCSqG
SIb3DQEJARYOVGVzdEBnbWFpbC5jb20xEDAOBgNVBAMMB3Rlc3QtY2EwHhcNMjQw
NDAzMjMyMDE4WhcNMjQxMjI0MjMyMDE4WjBxMQswCQYDVQQGEwJDQTENMAsGA1UE
CAwEVEVTVDENMAsGA1UEBwwEVEVTVDENMAsGA1UECgwEVGVzdDEdMBsGCSqGSIb3
DQEJARYOVGVzdEBnbWFpbC5jb20xFjAUBgNVBAMMDVRlc3QtY2EtaW50ZXIwdjAQ
BgcqhkjOPQIBBgUrgQQAIgNiAAQZEItpm24s5lAUjmXJqdKhJz7ukGvv6pZiXGoI
5KXturzMW5P0NdwBaj1IlOrcc86hkBAFFNSs02nJ5KWPkTeu1aDnJPQEBf8eA5xL
8BEd8JrxwMW0c34q2zGt9ELS0TWjgZ0wgZowNwYJYIZIAYb4QgENBCoWKE9QTnNl
bnNlIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHQYDVR0OBBYEFFIp
ELC3FmfDxERJgj8wTcK7uuSEMB8GA1UdIwQYMBaAFFIpELC3FmfDxERJgj8wTcK7
uuSEMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMC
A2gAMGUCMQC0MXHL1sxXYmdJE1+k8XZL7qXc58KPR5fPCzNPkO1mp7UpVTHX37aY
DFkeCUAZ3dkCMCoK7tzsVYHw7nq2pZ1e1qOe1JRv1surFXCgtlSKRbj5aSz9WwEr
FvUW4u3cxY70hw==
-----END CERTIFICATE-----


The Certificate
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 1 (0x1)
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: C = CA, ST = TEST, L = TEST, O = Test, emailAddress = Test@gmail.com, CN = Test-ca-inter
        Validity
            Not Before: Apr  3 23:21:02 2024 GMT
            Not After : Apr  3 23:21:02 2025 GMT
        Subject: C = CA, ST = TEST, L = TEST, O = Test, emailAddress = Test@gmail.com, CN = test-cert
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (384 bit)
                pub:
                    04:33:d9:49:c6:0b:fd:1d:91:d3:59:5b:40:5e:06:
                    e2:66:d5:aa:f9:91:31:89:37:93:49:6e:36:17:9f:
                    d4:75:0d:60:1a:30:57:cd:90:56:2d:88:aa:df:08:
                    85:d2:29:6b:4c:88:34:d2:c0:32:18:fd:9f:ec:d7:
                    e0:4a:34:83:80:59:f8:ca:2a:9b:b8:9b:5c:c9:a5:
                    66:94:fc:37:9c:04:41:ef:c9:ee:89:93:02:2d:d9:
                    38:72:25:03:f0:15:21
                ASN1 OID: secp384r1
                NIST CURVE: P-384
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Cert Type:
                SSL Server
            Netscape Comment:
                OPNsense Generated Server Certificate
            X509v3 Subject Key Identifier:
                91:78:17:C4:6C:A3:F0:A6:E9:04:8F:B8:2A:2A:54:FA:A9:08:F7:9B
            X509v3 Authority Key Identifier:
                keyid:52:29:10:B0:B7:16:67:C3:C4:44:49:82:3F:30:4D:C2:BB:BA:E4:84
                DirName:/C=CA/ST=TEST/L=TEST/O=Test/emailAddress=Test@gmail.com/CN=test-ca
                serial:01
            X509v3 Extended Key Usage:
                TLS Web Server Authentication, 1.3.6.1.5.5.8.2.2
            X509v3 Key Usage:
                Digital Signature, Key Encipherment
    Signature Algorithm: ecdsa-with-SHA256
    Signature Value:
        30:65:02:31:00:fd:67:a2:f4:d4:4b:15:79:47:96:20:2f:eb:
        2d:72:83:a3:74:ef:e2:f2:4c:fd:bc:aa:72:a0:87:5a:be:b0:
        3c:20:ce:f4:f5:bf:ca:ef:35:01:4f:78:1a:3a:08:a5:4f:02:
        30:36:b3:8a:17:9c:0b:65:0c:30:8a:47:5f:20:be:50:35:c6:
        ef:52:9c:cb:f3:11:4f:f1:9e:a8:6d:32:40:53:98:34:1e:7e:
        b7:6c:cd:67:7d:d3:13:c5:02:b0:d4:1f:fa
-----BEGIN CERTIFICATE-----
MIIDRzCCAs2gAwIBAgIBATAKBggqhkjOPQQDAjBxMQswCQYDVQQGEwJDQTENMAsG
A1UECAwEVEVTVDENMAsGA1UEBwwEVEVTVDENMAsGA1UECgwEVGVzdDEdMBsGCSqG
SIb3DQEJARYOVGVzdEBnbWFpbC5jb20xFjAUBgNVBAMMDVRlc3QtY2EtaW50ZXIw
HhcNMjQwNDAzMjMyMTAyWhcNMjUwNDAzMjMyMTAyWjBtMQswCQYDVQQGEwJDQTEN
MAsGA1UECAwEVEVTVDENMAsGA1UEBwwEVEVTVDENMAsGA1UECgwEVGVzdDEdMBsG
CSqGSIb3DQEJARYOVGVzdEBnbWFpbC5jb20xEjAQBgNVBAMMCXRlc3QtY2VydDB2
MBAGByqGSM49AgEGBSuBBAAiA2IABDPZScYL/R2R01lbQF4G4mbVqvmRMYk3k0lu
Nhef1HUNYBowV82QVi2Iqt8IhdIpa0yINNLAMhj9n+zX4Eo0g4BZ+Moqm7ibXMml
ZpT8N5wEQe/J7omTAi3ZOHIlA/AVIaOCATswggE3MAkGA1UdEwQCMAAwEQYJYIZI
AYb4QgEBBAQDAgZAMDQGCWCGSAGG+EIBDQQnFiVPUE5zZW5zZSBHZW5lcmF0ZWQg
U2VydmVyIENlcnRpZmljYXRlMB0GA1UdDgQWBBSReBfEbKPwpukEj7gqKlT6qQj3
mzCBlQYDVR0jBIGNMIGKgBRSKRCwtxZnw8RESYI/ME3Cu7rkhKFvpG0wazELMAkG
A1UEBhMCQ0ExDTALBgNVBAgMBFRFU1QxDTALBgNVBAcMBFRFU1QxDTALBgNVBAoM
BFRlc3QxHTAbBgkqhkiG9w0BCQEWDlRlc3RAZ21haWwuY29tMRAwDgYDVQQDDAd0
ZXN0LWNhggEBMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQgCAjALBgNVHQ8E
BAMCBaAwCgYIKoZIzj0EAwIDaAAwZQIxAP1novTUSxV5R5YgL+stcoOjdO/i8kz9
vKpyoIdavrA8IM709b/K7zUBT3gaOgilTwIwNrOKF5wLZQwwikdfIL5QNcbvUpzL
8xFP8Z6obTJAU5g0Hn63bM1nfdMTxQKw1B/6
-----END CERTIFICATE-----

Quote from: jsingh on April 04, 2024, 01:26:25 AM
The Certificate

Usually the CN on the certificate is the DNS name of the web host, and I plug in a SAN of DNS:<host name>.  I usually bundle the server cert + intermediate cert and configure that as the certificate on the web server, and the server private key, and then install the root certificate in the OS trusted store.

Usually I miss marking it as a Server certificate.  But I have issued several certs in OPNsense and imported into other services/containers/etc that host web apps and everything just works fine.
Topton N5105 | 16GB RAM | 128GB NVMe | 4x i226-V

So first the good news, I kicked my son from his FIFA challenge and used his Windows 11 machine (OS Build: 22631.3374) out of curiosity.

Imported the Root CA from OPNsense to the Edge browser, via: Settings -> Privacy, search, and service -> Manage Certificates -> Trusted Root Certificate Authorities -> Import

Let the wizard automaticly choose the store, which seems to end up in the Trust Store: Certificates -> Current User -> Trusted Root Certificate Authorities -> Certificates

If I point this Edge browser to my OPNsense web interface (hint: valid DNS name) I get a perfect Chain-of-Trust from Root -> Intermediate -> Server , no errors what so ever. So it should work out of the box (see screenshot).

Looking at your Server Certificate a critical note which you should solve, and a remark witch isn't directly related to your issue but you might want to 'fix' it.

Critical:

Your Server Certificate is missing a DNS Subject Alternative Name (SAN) matching the DNS hostname, you would normally match both Common Name in the Subject and DNS SAN in the X509v3 extensions with the same DNS Hostname (FQDN) for consistency, but there's no modern crypto library that will look at the Common Name (CN) in the subject anymore to match the hostname, Windows included.


X509v3 Subject Alternative Name:
    DNS:opnsense.domain.tld



You _shouldn't_ add this DNS SAN to both Root and Intermediate CA, they don't need a valid DNS entry. You can use whatever Common Name you want in the Subject for both Root & Intermediate CA certs.

Remark:

Leave the "Email Address" in the Subject blank ("Distinguished Name" Section) while creating the certs via the OPNsense wizzard, this attribute isn't used at all and only clutters your Subject field. You should set at least, Country (C), Organization (O) and Common Name (CN) to create a "valid" Subject in almost all situations (Microsoft, Linux, Apple), all others (City, State, Email Address and others) are optional.

I did see some other stuff, but you shouldn't care at this point, import the Root CA in the right store and fix your DNS SAN and it should work.

@franco

Looking at the certificates created with the OPNsense Trust wizzard, there're some defaults which are a bit "strange" IMHO:

* "Server" certificates are missing a "critical" attribute for both X509v3 Basic Constraints & X509v3 Key Usage. Both Root & Intermediate CA's created with the wizzard _are_ correctly tagged.

* The X509v3 Subject Key Identifier of an Intermediate CA is a duplicate of the Root CA, so both X509v3 Subject & Authority Key ID's are exactly the same on a Intermediate CA ?!?! One would expect a unique Subject Key ID for the Intermediate CA with an Authority Key ID of the Root CA that signed it. The Authority Key ID in the Root CA certificate itself could be left out, it's not a self-signed cert but the start of the chain.

* The X509v3 Authority Key Identifier of a Server Certificate is pointing to this duplicate X509v3 Subject Key ID, so it could be directly signed by the Intermediate CA _OR_ the Root CA (see previous point).

First of all thanks for taking the time out for this , I've been banging my head around on this weird thing for a few days now.
So I created all my certificates through the wizard and used the GUI for everything and I made-up those certs to show the chain issue. The actual certs have all the information you suggested except the email and the SAN part for root certificate. That I will correct when I recreate them. I have attached some images from another attempt. It's the same problem that these certificates have no chain.

I had import my intermediate certificate in the root store for the server certificate to be validated. I followed the same steps on my pfsense box gui with no such issue in cert chain.

Quote from: jsingh on April 04, 2024, 08:21:58 PM
I had import my intermediate certificate in the root store for the server certificate to be validated. I followed the same steps on my pfsense box gui with no such issue in cert chain.

So you're not _exactly_ following the two working examples (with proof) I gave you, ignoring the _exact_ steps (hint: they matter) and keep clicking around and play Chinese juggling with X509 certificates.

Good luck with pfsense!

I apologize on the previous post, since I did make some mistakes. I was looking into the permutations on what seems to be the behaviour. You replied while I was making corrections to the previous post. Anyways, I had followed the steps you outlined. I used secp384 r1 and sha 256 throughout with 365 days validity. I did add a common name for my final certificate.

The only difference being I used the local machine store rather than the user store to for the certificates. I am viewing the certificate directly in windows rather than using the browser and installing it on the router web interface, but I don't think these should make any difference.UPDATE: It does make a difference especially with pfsense certs.

I did notice some differences between the certs I created in both pfsense and opnsense GUIs and hence the whole reason for my OP


  • For Pfsense certs, I imported the root cert in the Windows local machine store in root certificates section. I found out that the final certificate does not validate without importing the intermediate CA as well.
    UPDATE: Google chrome does validate against the root certificate but windows certificate viewer does not validate the server cert against the root certificate. It requires the Intermediate certificate to be installed in the certificate store.
    Additionally, if I let automatically let windows choose, it installs the root certificate in the intermediate certificates store, I don't know why thats so.

  • I followed same steps with opnsense. The opnsense cert validates itself with the root certificate installed. The intermediate certificate never shows itself as a part of the certificate chain, even if I install the intermediate certificate.
    Update: Google Chrome shows the whole certificate chain as you said, but weirdly windows certificate viewer does not

@netnut With your clarifications, I do have an understanding of what's going on. I don't understand the real reason behind these differences but it seems to be so. I am newbie in understanding certificate implementation. I studied these back in college and that was a long time ago.