Skip to content

Instantly share code, notes, and snippets.

@jpmens
Last active March 11, 2022 16:10
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save jpmens/8029383 to your computer and use it in GitHub Desktop.
Save jpmens/8029383 to your computer and use it in GitHub Desktop.
Create openHAB (Jetty) keystore from OpenSSL certificate/key pair

Configure openHAB keystore to use our own TLS server certificates

1. Launch openHAB, and verify that the shipped cert is in effect

$ openssl s_client -connect localhost:8443
[lots of stuff truncated]
-----END CERTIFICATE-----
subject=/C=Unknown/ST=Unknown/L=Unknown/O=openHAB/OU=Unknown/CN=openhab.org
issuer=/C=Unknown/ST=Unknown/L=Unknown/O=openHAB/OU=Unknown/CN=openhab.org
---
No client certificate CA names sent
---
SSL handshake has read 1614 bytes and written 296 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : DHE-RSA-AES256-SHA
    Session-ID: 52B1FD317C19B5067235A4FDF277B0AF5FFDF7AA760A431CC53B8C0C2CC796A7
    Session-ID-ctx:
    Master-Key: 8EEAA5595C7E46BEAFABC4CAE2797A704FD79754BB2BDBF3159CC42427E497C5B58522D7ED166A1A256D1189148EB93E
    Key-Arg   : None
    Start Time: 1387396401
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)
---

Result: yes: openHAB's default SSL/TLS cert is being used (CN=openhab.org)

2. Create our own TLS certificates. We have

  • ca.crt the CA certificate in PEM format
  • server.crt the Server certificate in PEM format
  • server.key the Server key in PEM format

3. Shut down openHAB

4. Backup etc/keystore

5. Show content of keystore. Password is empty (hit enter; stupid keystore)

$ keytool -keystore etc/keystore -list -v
[...]
Alias name: mykey
Creation date: Jun 11, 2013
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=openhab.org, OU=Unknown, O=openHAB, L=Unknown, ST=Unknown, C=Unknown
Issuer: CN=openhab.org, OU=Unknown, O=openHAB, L=Unknown, ST=Unknown, C=Unknown
Serial number: 2a06f6fc
Valid from: Tue Jun 11 22:02:35 CEST 2013 until: Fri Jun 09 22:02:35 CEST 2023
Certificate fingerprints:
	 MD5:  9D:D1:7E:E2:42:A7:62:BB:14:8E:3A:4A:88:67:C8:3D
	 SHA1: 34:32:A9:52:5B:C7:08:69:40:DE:A7:AD:E4:10:C9:1E:37:54:A5:4A
	 Signature algorithm name: SHA256withRSA
	 Version: 3

Extensions:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: FC FA 42 F5 FD AF E2 C8   12 DE A5 D4 66 3B 58 E2  ..B.........f;X.
0010: 67 DC CE F4                                        g...
]
]
[...]

6. Create a PKCS#12 container file with ca.crt, server.crt and server.key

The password we're going to be asked for will encrypt the key and it protects the PKCS#12 container. The container we'll destroy in a moment, but the password we make a note of for later.

$ cat ca.crt server.crt > chain.pem

$ openssl pkcs12 -export -inkey server.key -in chain.pem -out /tmp/oh.p12
Enter Export Password:
Verifying - Enter Export Password:

$ rm chain.pem
$ ls -l oh.p12
-rw-r--r--  1 jpm  staff  4061 Dec 18 21:01 oh.p12

7. Import PKCS#12 container into keystore

$ rm etc/keystore		# yup. You made a backup, didn't you?!

$ keytool -importkeystore -srckeystore /tmp/oh.p12 -srcstoretype PKCS12 -destkeystore etc/keystore
Enter destination keystore password:		<-- 6 chars "xxxxxx"; MAKE A NOTE
Re-enter new password:
Enter source keystore password:			<-- password from step 6 above
Entry for alias 1 successfully imported.
Import command completed:  1 entries successfully imported, 0 entries failed or cancelled

$ rm /tmp/oh.p12

8. Verify new openHAB keystore contains our certificates

$ keytool -keystore etc/keystore -list -v
Enter keystore password:		<-- enter blank password ?!?!?!
[...]
Alias name: 1
Creation date: Dec 18, 2013
Entry type: PrivateKeyEntry
Certificate chain length: 2
Certificate[1]:
Owner: EMAILADDRESS=nobody@example.net, O=MQTTitude.org, CN=tiggr.ww.mens.de
Issuer: EMAILADDRESS=nobody@example.net, O=MQTTitude.org, CN=An MQTT broker
Serial number: a7de80faa9356517
[...]

9. Create passwords for jetty.xml

Actually we need two passwords, same command, different argument

  1. password for key from step 6 (this OBF: string goes in KeyPassword)
  2. password for keystore from step 7 (this OBF: string goes in Password)
$ java -cp server/plugins/org.eclipse.jetty.util_8.1.3.v20120522.jar org.eclipse.jetty.util.security.Password xxxxxx
xxxxxx
OBF:20lb20lb20lb20lb20lb20lb
MD5:dad3a37aa9d50688b5157698acfd7aee

Repeat for second password.

10. in etc/jetty.xml set password.

Search for SslSelectChannelConnector and copy the OBF string from step 9 into

                        <New class="org.eclipse.jetty.server.ssl.SslSelectChannelConnector">
                                <Set name="port"><Property name="jetty.port.ssl" /></Set>
                                <!-- <Set name="Host">127.0.0.1</Set> JPM: bind to loopback -->
                                <Set name="maxIdleTime">30000</Set>
                                <Set name="Acceptors">2</Set>
                                <Set name="AcceptQueueSize">100</Set>
                                <Set name="Keystore"><Property name="jetty.home" default="." />/etc/keystore</Set>
                                <Set name="Password">OBF:20lb20lb20lb20lb20lb20lb</Set>
                                <Set name="KeyPassword">OBF:010101010101010101010101</Set>

11. Launch openHAB

Verify the console, check that no errors regarding "tampering" of keystore arise.

12. Connect to openHAB and verify it's using our server certificates

$ openssl s_client -connect localhost:8443
[...]
-----END CERTIFICATE-----
subject=/CN=tiggr.ww.mens.de/O=MQTTitude.org/emailAddress=nobody@example.net
issuer=/CN=An MQTT broker/O=MQTTitude.org/emailAddress=nobody@example.net
---
@jpmens
Copy link
Author

jpmens commented Dec 18, 2013

openssl s_client -connect 127.0.0.1:8443 -CAfile ca.crt -tls1

@jpmens
Copy link
Author

jpmens commented Dec 19, 2013

If s_client reports a connection error (or rather no certificates are shown), force -ssl3.
See this /via Ben.

@ludodoucet
Copy link

I generate a server.crt and a server.key with this method: https://wiki.eclipse.org/Jetty/Howto/Configure_SSL , where can I find or how generate "ca.crt the CA certificate in PEM format"?

@papadi
Copy link

papadi commented Feb 8, 2017

Thanks, but I have the feeling that this doc is a bit obsolete. Correct me if I'm wrong.

  • I couldn't find the file anywhere org.eclipse.jetty.util_8.1.3.v20120522.jar. I googled it and downloaded it to pass step 9.
  • On Synology installation I have userdata/etc/jetty.xml and runtime/etc/jetty.xml. Neither of the two contain a SslSelectChannelConnector section.

@klaernie
Copy link

@jpmens: feel free to take a look at my fork, I found a way to avoid modifying the stock keystore and jetty.xml by creating a new keystore under /etc/openhab2 and modifying JAVA_EXTRA_VARS in /etc/default/openhab2.

Thanks for your work in writing this up, it helped a lot to find my own way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment