1

I'm trying to set positive trust attributes to a certificate, however, in openssl's documenation there is no information about how to set them:

From the OpenSSL perspective, a trust anchor is a certificate that should be augmented with an explicit designation for which uses of a target certificate the certificate may serve as a trust anchor. In PEM encoding, this is indicated by the TRUSTED CERTIFICATE string. Such a designation provides a set of positive trust attributes explicitly stating trust for the listed purposes and/or a set of negative trust attributes explicitly rejecting the use for the listed purposes. The purposes are encoded using the values defined for the extended key usages (EKUs) that may be given in X.509 extensions of end-entity certificates. See also the "Extended Key Usage" section below.

openssl-verification-options

Is there any example or more information about how to set the mentioned trust attributes about this?

I tried to modify my PEM encoded certificate file by changing the header from:

-----BEGIN CERTIFICATE-----

to

-----BEGIN TRUSTED CERTIFICATE-----

but this doesn't help. But I ultimately want to achieve is, to trust an intermediate certificate w/o setting X509_V_FLAG_PARTIAL_CHAIN or -partial_chain.

1 Answer 1

2

In my question I stated that "there is no information about how to set" trust attributes. This is not correct as man openssl-x509 describes how to set these attributes:

       -addtrust arg
           Adds a trusted certificate use.  Any object name can be used here but currently only clientAuth, serverAuth, emailProtection, and anyExtendedKeyUsage are defined.  As of OpenSSL 1.1.0, the last of these blocks all purposes when
           rejected or enables all purposes when trusted.  Other OpenSSL applications may define additional uses.

To test that openssl s_client honors an intermediate certificate as trust when validating the server's certificate chain during connection after I've set serverAuth as a trusted attribute using openssl x509 to the internediate certificate, I did the following:

1.) Start a TLS server

openssl s_server -no-CAfile -no-CApath -no-CAstore -CAfile ./intermediate.cer -cert ./server.cer -key ./server.key -www

./intermediate.cer is the signing certificate of ./server.cer.

2.) Validating that openssl s_client returns with Verify return code: 2 (unable to get issuer certificate) when "trusting" the intermediate certificate:

$ openssl s_client -no-CApath -no-CAstore -CAfile  ./intermediate.cer  localhost:4433                
CONNECTED(00000004)
Can't use SSL_get_servername
depth=1 C = US, O = Let's Encrypt, CN = R3
verify error:num=2:unable to get issuer certificate
issuer= C = US, O = Internet Security Research Group, CN = ISRG Root X1
verify return:1
depth=0 CN = <<DELETED>>
issuer= C = US, O = Let's Encrypt, CN = R3
verify return:1
---
Certificate chain
 0 s:CN = <<DELETED>>
   i:C = US, O = Let's Encrypt, CN = R3
   a:PKEY: id-ecPublicKey, 256 (bit); sigalg: RSA-SHA256
   v:NotBefore: Sep 22 XX:XX:XX 2023 GMT; NotAfter: Dec 21 XX:XX:XX 2023 GMT
 1 s:C = US, O = Let's Encrypt, CN = R3
   i:C = US, O = Internet Security Research Group, CN = ISRG Root X1
   a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
   v:NotBefore: Sep  4 00:00:00 2020 GMT; NotAfter: Sep 15 16:00:00 2025 GMT
---
Server certificate
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
subject=CN = <<DELETED>>
issuer=C = US, O = Let's Encrypt, CN = R3
---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: ECDSA
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 2746 bytes and written 377 bytes
Verification error: unable to get issuer certificate
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 256 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 2 (unable to get issuer certificate)

The connection attempt return with Verify return code: 2 (unable to get issuer certificate). This is expected as I did not specify -partial_chain

2.) Set trusted attribute

openssl x509 -in ./intermediate.cer -addtrust serverAuth  -out ./intermediate-trusted.cer

Check that the trusted attribute has been set:

$ openssl x509 -noout -text -in ./intermediate-trusted.cer
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            91:2b:08:4a:cf:0c:18:a7:53:f6:d6:2e:25:a7:5f:5a
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = US, O = Internet Security Research Group, CN = ISRG Root X1
        Validity
            Not Before: Sep  4 00:00:00 2020 GMT
            Not After : Sep 15 16:00:00 2025 GMT
        Subject: C = US, O = Let's Encrypt, CN = R3
...
Trusted Uses:
  TLS Web Server Authentication
No Rejected Uses.

4.) Connecting again using ./intermediate-trusted.cer

openssl s_client -no-CApath -no-CAstore -CAfile ./intermediate-trusted.cer localhost:4433

CONNECTED(00000004)
Can't use SSL_get_servername
depth=0 CN = <<DELETED>>
verify return:1
---
Certificate chain
 0 s:CN = <<DELETED>>
   i:C = US, O = Let's Encrypt, CN = R3
   a:PKEY: id-ecPublicKey, 256 (bit); sigalg: RSA-SHA256
   v:NotBefore: Sep 22 XX:XX:XX 2023 GMT; NotAfter: Dec 21 XX:XX:XX 2023 GMT
 1 s:C = US, O = Let's Encrypt, CN = R3
   i:C = US, O = Internet Security Research Group, CN = ISRG Root X1
   a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
   v:NotBefore: Sep  4 00:00:00 2020 GMT; NotAfter: Sep 15 16:00:00 2025 GMT
---
Server certificate
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
subject=CN = <<DELETED>>
issuer=C = US, O = Let's Encrypt, CN = R3
---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: ECDSA
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 2748 bytes and written 377 bytes
Verification: OK
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 256 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)

This time openssl s_client returns with Verify return code: 0 (ok) which as far as I know indicates a successful handshake including vadliation of the certificate chain to a trust anchor. The trusted certificate is not a self-signed (i.e. not a root) certificate.

1
  • Yes. it was contradicting to state that "openssl's documentation there is no information" about this topic while my answer pointed to the information (coming from openssl's documentation) which describes how to set trust attributes. After setting the trust attribute I was able to connect using openssl s_client (see my updated answer).
    – Cris
    Sep 23, 2023 at 12:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .