Category Archives: ldap

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 , , ,

Monitoring DSEE6.2 … on ubuntu

After having gotten my DSEE6.2 to run on my ubuntu laptop (with the steps laid out in this previous post), I wanted to see how to monitor the beast. Obviously, you can still write scripts as was not unusual with previous versions or gather statistics through querying “cn=monitor” over the LDAP protocol. I was looking for a more elegant integration with monitoring systems, though.

The first thing you have to realize to get started at all, is that DSEE is part of the Sun Java Enterprise System (JES). So, even if the information about monitoring is missing from the point product’s documentation (for DSEE6.0 and 6.1), you can find it in the JES documentation. Then add a few incompatibilities with ubuntu or bugs if you will (because I cannot see how this would work with any other supported Linux distro and the ZIP distribution of DSEE), and you’ll get a node agent for a host running any JES component which will provide information about server instance through JMX and SNMP.

Essentially, you need this:

0. Install DSEE6.2 to ~/dsee6.2 and configure as previously posted

1. Initialize the JES monitoring framework (mfwk)

2. Enable the monitoring plugin in the DS instances to be monitored

3. Register the DS Module with the node agent

Now for the gory (read: technical) details:

1. Initialize the JES monitoring framework (mfwk)

To use the mfwk scrips (for setup and otherwise) on ubuntu (or at all to some extent), you need to modify them as follows:

mfwksetup.pl (don’t use the shell script):

~/dsee6.2/dsee6/mfwk/bin$ diff -Naurw mfwksetup.pl.orig mfwksetup.pl
--- mfwksetup.pl.orig 2007-11-09 12:02:46.000000000 +0100
+++ mfwksetup.pl 2007-11-09 12:16:58.000000000 +0100
@@ -292,7 +292,7 @@


# Look for Cacao in default location
if ( $MFWK_INSTALL_TYPE eq "tarball" ) {
- $CACAO_RLOC_DIR = "$MFWK_BASEDIR/cacao_2.0";
+ $CACAO_RLOC_DIR = "$MFWK_BASEDIR/cacao_2";
$CACAO_ADM = "$CACAO_RLOC_DIR/cacao/bin/cacaoadm";
$CACAO_HOME = "$CACAO_RLOC_DIR/cacao";
}elsif ( $MFWK_INSTALL_TYPE eq "linux_pkg_default" ){
@@ -333,9 +333,6 @@
$OS_CONF_DIRNAME = "sun/mfwk";
# No installf on Linux
$INSTALLF = "";
- $MFWK_HOME = "$MFWK_BASEDIR/$OS_DIRNAME";
- $MFWK_ETC = "$MFWK_CONF_BASEDIR/etc/opt/$OS_CONF_DIRNAME";
- $MFWK_VAR = "$MFWK_CONF_BASEDIR/var/opt/$OS_CONF_DIRNAME";
$tmp = "/tmp";
if ( $MFWK_INSTALL_TYPE eq "tarball" ) {
$MFWK_CONF_BASEDIR = $MFWK_BASEDIR;
@@ -347,6 +344,9 @@
mLog "Error : unable to determine MFWK_INSTALL_TYPE : [$MFWK_INSTALL_TYPE]";
exit 1;
}
+ $MFWK_HOME = "$MFWK_BASEDIR/$OS_DIRNAME";
+ $MFWK_ETC = "$MFWK_CONF_BASEDIR/etc/opt/$OS_CONF_DIRNAME";
+ $MFWK_VAR = "$MFWK_CONF_BASEDIR/var/opt/$OS_CONF_DIRNAME";


}
################################

download mfwksetup diff

masetup.pl (don’t use the shell script, and remember you cannot install the Master Console on the same host as the node agent):


~/dsee6.2/dsee6/mfwk/bin$ diff -Naurw masetup.pl.orig masetup.pl
--- masetup.pl.orig 2007-11-09 12:15:59.000000000 +0100
+++ masetup.pl 2007-11-09 12:17:14.000000000 +0100
@@ -292,7 +292,7 @@


# Look for Cacao in default location
if ( $MFWK_INSTALL_TYPE eq "tarball" ) {
- $CACAO_RLOC_DIR = "$MFWK_BASEDIR/cacao_2.0";
+ $CACAO_RLOC_DIR = "$MFWK_BASEDIR/cacao_2";
$CACAO_ADM = "$CACAO_RLOC_DIR/cacao/bin/cacaoadm";
$CACAO_HOME = "$CACAO_RLOC_DIR/cacao";
}elsif ( $MFWK_INSTALL_TYPE eq "linux_pkg_default" ){
@@ -333,9 +333,6 @@
$OS_CONF_DIRNAME = "sun/mfwk";
# No installf on Linux
$INSTALLF = "";
- $MFWK_HOME = "$MFWK_BASEDIR/$OS_DIRNAME";
- $MFWK_ETC = "$MFWK_CONF_BASEDIR/etc/opt/$OS_CONF_DIRNAME";
- $MFWK_VAR = "$MFWK_CONF_BASEDIR/var/opt/$OS_CONF_DIRNAME";
$tmp = "/tmp";
if ( $MFWK_INSTALL_TYPE eq "tarball" ) {
$MFWK_CONF_BASEDIR = $MFWK_BASEDIR;
@@ -347,7 +344,9 @@
mLog "Error : unable to determine MFWK_INSTALL_TYPE : [$MFWK_INSTALL_TYPE]";
exit 1;
}
-
+ $MFWK_HOME = "$MFWK_BASEDIR/$OS_DIRNAME";
+ $MFWK_ETC = "$MFWK_CONF_BASEDIR/etc/opt/$OS_CONF_DIRNAME";
+ $MFWK_VAR = "$MFWK_CONF_BASEDIR/var/opt/$OS_CONF_DIRNAME";
}
################################
#setupEnvironmentLinux

download masetup diff

Then run this to initialize the framework:

cd ~/dsee6.2/dsee6/mfwk/bin
./mfwksetup.pl -i

2. Enable the monitoring plugin in the DS instances to be monitored

Read on here.

3. Register the DS Module with the node agent

This is a tricky bit, because it is not documented well (should I say at all?). I assume it just works out of the box with the JES installer. Not so here:

cp ~/dsee6.2/dsee6/etc/opt/sun/mfwk/xml/com.sun.cmm.ds.xml ~/dsee6.2/

Then find this paragraph in the new copy in ~/dsee6.2/:

<parameter>
<!--
Java ES Product Name (exhaustive human readable string identifying the product)
This parameter must be filled and is case sensitive.
This paraneter string MUST be the SAME as the "PRODUCT_NAME_CTX_KEY" provided
at the initialize method (Managed Element Server API) in the instrumented component product.
-->
<param-name>ProductName</param-name>
<param-value>DirectoryServer</param-value>
</parameter>

Change the parameter value to “Directory Server” (notice the blank) and locate this paragraph:

<parameter>
<!--
Java ES Installation Location
This parameter must be filled and is case sensitive.
The String used here MUST be the SAME as the "PRODUCT_COLLECTIONID_CTX_KEY" provided at
the initialize method (Managed Element Server API) in the instrumented component product.
-->
<param-name>InstalledLocation</param-name>
<param-value>/opt/SUNWds</param-value>
</parameter>

Here change the parameter value to the location where your DS installation resides (not the instance path). In our example that would be “/home/<username>/dsee6.2/ds6”. Finally, register the module:

$ ~/dsee6.2/dsee6/cacao_2/cacao/bin/cacaoadm deploy ~/dsee6.2/com.sun.cmm.ds.xml
$ ~/dsee6.2/dsee6/cacao_2/cacao/bin/cacaoadm register-module ~/dsee6.2/com.sun.cmm.ds.xml
$ ~/dsee6.2/dsee6/cacao_2/cacao/bin/cacaoadm stop
$ ~/dsee6.2/dsee6/cacao_2/cacao/bin/cacaoadm start
$ ~/dsee6.2/dsee6/cacao_2/cacao/bin/cacaoadm list-modules
$ ~/dsee6.2/dsee6/mfwk/bin/mfwkadm.orig list-modules

This last command should show a result like the following:

Installed products and their running instances:
==============================================


Instances for installed product: com.sun.cmm.ds:collectionID="/home/username/dsee6.2/ds6",name=Directory Server,type=CMM_InstalledProduct
-------------------------------


//home/username/dsee6-instances/6/com.sun.cmm.ds:name=/home/username/dsee6-instances/6,type=CMM_ApplicationSystem

If the DS shows up as an installed product but no active instance is displayed, then you either have not started your DS instance with the monitoring plugin enabled or have messed up the XML changes for the DS registration with the node agent. Watch out for warnings in the most recent “~/dsee6.2/dsee6/var/opt/sun/mfwk/logs/agent.log.?”. If there is a message about it not knowing what to do with a discovery message, look for a string like this “Directory Server#ds#/home/username/dsee6.2/ds6”. The first bit is the name, the second bit should be ok, the third bit is the installation path. Make sure that is exactly what you have in your XML.

What next?

Fire up jconsole:

jconsole connect

Connect to the cacao agent and start monitoring your directory server:

jconsole monitoring

Next, install the Management Console on another machine as per JES docs.
Then go and write a DS plugin to Nagios or Munin :). Maybe this post by Steffo will be of use to you.

Tagged , , , , , ,

Directory Server Enterprise Edition (DSEE) 6.2 on … ubuntu

Among the billion other things I seem to be doing at the moment, I’ve invested some time into installing DSEE 6.2 on my ubuntu (feisty) laptop rather than setting up a vmware image of a supported Linux platform. “6.2”, I hear you say, “hasn’t even been released, yet.” You’re right, but rest assured it will 😉 Also, the stuff I’ve found may well help a 6.1 install, as well. I haven’t tested that, though.

How to do it? Follow these easy steps:

  1. Download the zip installer from the http://www.sun.com/downloads site once 6.2 becomes available, or try with 6.1.
  2. Install in the documented way. The installation will fail to register the JES mgmt. framework. Apparently there is a problem with <dsee-install-dir>/dsee6/cacao_2/configure . Instead of fixing that, it is very easy to do the following.
  3. Go to <dsee-install-dir>/dsee6/cacao_2/cacao and do this (feel free to use other ports):
    dsee6/cacao_2/cacao$ bin/cacaoadm set-param jmxmp-connector-port=11162
    dsee6/cacao_2/cacao$ bin/cacaoadm set-param snmp-adaptor-port=11160
    dsee6/cacao_2/cacao$ bin/cacaoadm set-param snmp-adaptor-trap-port=11161
    dsee6/cacao_2/cacao$ bin/cacaoadm set-param commandstream-adaptor-port=11163
    dsee6/cacao_2/cacao$ bin/cacaoadm set-param rmi-registry-port=11164
    dsee6/cacao_2/cacao$ bin/cacaoadm set-param secure-webserver-port=11165
    dsee6/cacao_2/cacao$ bin/cacaoadm start
  4. Then go to <dsee-install-dir>/dscc and do:
    bin/dsccsetup dismantle
    bin/dsccsetup initialize
  5. Deploy the dscc war file found under <dsee-install-dir>/var/dscc6/dscc.war to the app server of your choice.
  6. This would allow you to start the dscc web console and do anything that does not need cacao (yummy). To e. g. install a new instance, you also need to give suexec the right permissions:
    $ sudo chown root.root /dsee6/cacao_2/cacao/private/bin/suexec
    $ sudo chmod u+s /dsee6/cacao_2/cacao/private/bin/suexec

That’s it, you’re ready to go.

Tagged , , ,