Using both ECC and RSA keys with Oracle Unified Directory

Something technical again, for once. While I was reviewing the new minimum standards recommended by the German Bundesamt für Sicherheit in der Informationstechnologie and checking the lists of TLS ciphers accepted by certain instances of the Oracle Unified Directory (OUD) I manage, I have to admit I only realised for the first time how the ciphers suites you can actually use depend on the certificate you have, or more properly the type of private key you have and then got stamped by a CA.

Turns out if you want to support ciphers suites that don’t use RSA at all, you cannot be using an RSA private key, either (doh … yes, well.) Arguably, I’m not convinced it’s as important to offer alternatives where the authentication part is concerned, but if you configure your server to only support strong ciphers and then only half of those are actually usable, because you don’t have the corresponding private key for the other half, that may at some point cause problems with supporting a broad range of clients. Therefore, and because it’s not actually explained in the Oracle documentation anywhere, here’s how to get the best of both worlds.

If you feel like you want to research the background of all this some more first, these links helped me:

  • HashedOut by the SSLStore (Everything I’m talking about, here, appertains to the parts of the cipher suite name colour-coded green, there.)
  • OWASP
  • Hackernoon (this is about nginx but describes the same challenge, there called hybrid setup.)

TLDR: To get OUD to support both an ECC and an RSA certificate, the key is to let the server decide, i. e. to NOT set a certificate nickname to use on the definition of the connection handler.

The complete procedure is this:

  • Create both keys, e. g.:
    • openssl genrsa -out example.rsa.key 2048
    • openssl ecparam -genkey -name secp384r1 | openssl ec -out example.ecc.key
  • Get certificates for your keys
    • If you’re trying this out, check this page on how to use openssl ca, (I skipped the intermediate CA bit) e. g.:
      • openssl req -config openssl.cnf -key ~/example.ecc.key -new -sha256 -out example.eccWithRsa.csr
      • openssl req -config openssl.cnf -key ~/example.rsa.key -new -sha256 -out example.rsa.csr
      • openssl ca -config openssl.cnf -extensions server_cert -days 375 -notext -md sha256 -in example.rsa.csr -out certs/example.rsa.pem
      • openssl ca -config openssl.cnf -extensions server_cert -days 375 -notext -md sha256 -in example.eccWithRsa.csr -out certs/example.eccWithRsa.pem
  • Import certificates and private keys into your keystore
    • cat ca/certs/ca.cert.rsa.pem ca/certs/example.eccWithRsa.pem > chain.eccWithRsa.pem
    • cat ca/certs/ca.cert.rsa.pem ca/certs/example.rsa.pem > chain.rsa.pem
    • openssl pkcs12 -export -inkey example.ecc.key -in chain.eccWithRsa.pem -name oud.eccWithRsa -out oud.eccWithRsa.p12
    • openssl pkcs12 -export -inkey example.rsa.key -in chain.rsa.pem -name oud.rsa -out oud.rsa.p12
    • keytool -importkeystore -srckeystore oud.eccWithRsa.p12 -srcstoretype pkcs12 -destkeystore oud.jks -deststoretype pkcs12
    • keytool -importkeystore -srckeystore oud.rsa.p12 -srcstoretype pkcs12 -destkeystore oud.jks 
  • Configure your connection handler
    • bin/dsconfig -h debian -p 4444 -D cn=dirmanager -j ~/pass set-connection-handler-prop --handler-name "LDAPS Connection Handler" --reset ssl-cert-nickname

One thing to note here: The example commands are from my later tests where I explicitly tested getting an ECC key signed by a CA that does NOT have an ECC CA key, itself. That’s what eccWithRsa means in the examples above: An ECC key signed with RSA. And you can see from the lines where the certificate chain is created and then imported into the keystore that we are definitely adding ca.cert.rsa.pem to the chain. I explicitly wanted to test this, because I might need to order certificates from a CA that does not have ECC signing certificates. Turns out this works like a charm, at least for TLS 1.2. It might not work for TLS 1.1, ref. RFC5246 cap. 7.4.2:

If the client provided a “signature_algorithms” extension, then all certificates provided by the server MUST be signed by a hash/signature algorithm pair that appears in that extension. Note that this implies that a certificate containing a key for one signature algorithm MAY be signed using a different signature algorithm (for instance, an RSA key signed with a DSA key). This is a departure from TLS 1.1, which required that the algorithms be the same. Note that this also implies that the DH_DSS, DH_RSA, ECDH_ECDSA, and ECDH_RSA key exchange algorithms do not restrict the algorithm used to sign the certificate. Fixed DH certificates MAY be signed with any hash/signature algorithm pair appearing in the extension. The names DH_DSS, DH_RSA, ECDH_ECDSA, and ECDH_RSA are historical.

Verify that everything works as expected:

First, let’s try an EC suite that also uses ECDSA for authentication. The certificate is signed by an RSA CA and validated against that CA cert, though.

% openssl s_client -connect 192.168.56.101:1636 -tls1_2 -cipher ECDHE-
ECDSA-AES256-GCM-SHA384 
-CAfile /Users/khb/ca.cert.rsa.pem -servername debian.example.com 
CONNECTED(00000003)
depth=1 C = DE, ST = Hassia, O = ACME, CN = ACME CA
verify return:1
depth=0 C = DE, ST = Hassia, O = KHB, OU = ecc with rsa, CN = debian.example.com
verify return:1
---
Certificate chain
 0 s:C = DE, ST = Hassia, O = KHB, OU = ecc with rsa, CN = debian.example.com
   i:C = DE, ST = Hassia, O = ACME, CN = ACME CA
 1 s:C = DE, ST = Hassia, O = ACME, CN = ACME CA
   i:C = DE, ST = Hassia, O = ACME, CN = ACME CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIEqzCCApOgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwPzELMAkGA1UEBhMCREUx
...
aAE=
-----END CERTIFICATE-----
subject=C = DE, ST = Hassia, O = KHB, OU = ecc with rsa, CN = debian.example.com


issuer=C = DE, ST = Hassia, O = ACME, CN = ACME CA


---
Acceptable client certificate CA names
C = DE, ST = Hassia, L = Test, O = KHB, CN = debian.example.com
Client Certificate Types: RSA sign, DSA sign, ECDSA sign
Requested Signature Algorithms: ECDSA+SHA512:RSA+SHA512:ECDSA+SHA384:RSA+SHA384:ECDSA+SHA256:RSA+SHA256:DSA+SHA256:ECDSA+SHA224:RSA+SHA224:DSA+SHA224:ECDSA+SHA1:RSA+SHA1:DSA+SHA1
Shared Requested Signature Algorithms: ECDSA+SHA512:RSA+SHA512:ECDSA+SHA384:RSA+SHA384:ECDSA+SHA256:RSA+SHA256:DSA+SHA256:ECDSA+SHA224:RSA+SHA224:DSA+SHA224:ECDSA+SHA1:RSA+SHA1:DSA+SHA1
Peer signing digest: SHA256
Peer signature type: 
ECDSA
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 3063 bytes and written 307 bytes
Verification: OK
---
New, TLSv1.2, Cipher is ECDHE-
ECDSA-AES256-GCM-SHA384
Server public key is 384 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-ECDSA-AES256-GCM-SHA384
    Session-ID: 5E4E5EDC0C144D514F5FA54E50530C19D0EB98C384E2F7482E680D2532CD6D0F
    Session-ID-ctx: 
    Master-Key: B27BDAE231540A08F32C8BEABB50B286AD2EDCFA0A3CE86A50ED707D92D15DE05ABAE86A1B5790949350B4334E8077E2
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1582194397
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: yes
---
^C

Next, try an RSA suite:

% openssl s_client -connect 192.168.56.101:1636 -tls1_2 -cipher DHE-
RSA
-AES128-GCM-SHA256 
-CAfile /Users/khb/ca.cert.rsa.pem -servername debian.example.com 
CONNECTED(00000003)
depth=1 C = DE, ST = Hassia, O = ACME, CN = ACME CA
verify return:1
depth=0 C = DE, ST = Hassia, O = KHB, OU = rsa, CN = debian.example.com
verify return:1
---
Certificate chain
 0 s:C = DE, ST = Hassia, O = KHB, OU = rsa, CN = debian.example.com
   i:C = DE, ST = Hassia, O = ACME, CN = ACME CA
 1 s:C = DE, ST = Hassia, O = ACME, CN = ACME CA
   i:C = DE, ST = Hassia, O = ACME, CN = ACME CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIFUD
CCAzigAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwPzELMAkGA1UEBhMCREUx
...
/jTQpxrZyObmcSxS3TSlw+Ixy74=
-----END CERTIFICATE-----
subject=C = DE, ST = Hassia, O = KHB, OU = rsa, CN = debian.example.com


issuer=C = DE, ST = Hassia, O = ACME, CN = ACME CA


---
Acceptable client certificate CA names
C = DE, ST = Hassia, L = Test, O = KHB, CN = debian.example.com
Client Certificate Types: RSA sign, DSA sign, ECDSA sign
Requested Signature Algorithms: ECDSA+SHA512:RSA+SHA512:ECDSA+SHA384:RSA+SHA384:ECDSA+SHA256:RSA+SHA256:DSA+SHA256:ECDSA+SHA224:RSA+SHA224:DSA+SHA224:ECDSA+SHA1:RSA+SHA1:DSA+SHA1
Shared Requested Signature Algorithms: ECDSA+SHA512:RSA+SHA512:ECDSA+SHA384:RSA+SHA384:ECDSA+SHA256:RSA+SHA256:DSA+SHA256:ECDSA+SHA224:RSA+SHA224:DSA+SHA224:ECDSA+SHA1:RSA+SHA1:DSA+SHA1
Peer signing digest: SHA256
Peer signature type: 
RSA
Server Temp Key: DH, 1024 bits
---
SSL handshake has read 3574 bytes and written 347 bytes
Verification: OK
---
New, TLSv1.2, Cipher is DHE-
RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : DHE-RSA-AES128-GCM-SHA256
    Session-ID: 5E4E5EF298FC9D0F81B60A1E3C36A872673BA32E548CD428C936559FAD53D316
    Session-ID-ctx: 
    Master-Key: 7B04C38682E3C52DA7BDCA30CC67A78BB9AB33DA270C10217C77F7FF4D631FA1AE351660E17D0ABF38A7AC6C4407FAFB
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1582194420
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: yes
---
^C

As you can see, both cipher suites work, the server sent different server certificates in each case, automatically picked to match the cipher suite the client requested. Conversely, if you set a cert nickname to one of the certificates (oud.rsa e. g.), you can see how the other cipher stops working.

This seems to work quite well, if you just let the JVM do its thing.

Tagged , , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: