Zimbra offers Open Source email server software and shared calendar for Linux and the Mac
 
Go Back   Zimbra - Forums > Zimbra Collaboration Suite > Administrators

Welcome to the Zimbra - Forums!
Welcome, if you would like to post a comment please register. We also encourage you to explore all things Zimbra with our team and members of the community.

Reply
 
LinkBack (4) Thread Tools Display Modes
  4 links from elsewhere to this Post. Click to view. #1 (permalink)  
Old 06-29-2007, 10:18 AM
Senior Member
 
Posts: 50
Default Exporting private key from keystore for use with Postfix/Apache

As cited elsewhere it is a rather big hassle to setup commercial ssl certificates within Zimbra for Tomcat, Postfix etc... This is definitely an area that could use some improvement!

A rather large problem we encountered is that when generating the CSR to get our certificate, the keystore (jks keystore) does not output the .key or provide any facility for obtaining the .key.
So in the end we ended up with a .pem/.crt with no way of using it with Postfix/Apache, both of which need a .key + .pem/.crt pair.
The primary reason for this forum post is that the wiki doesn't allow file uploads other than images and I wanted to make sure there was a version of the java program necessary to do this somewhere within the wiki or forums, to reference to, in the event that the original site/location is moved or removed and it consequently becomes difficult to find.

The following instructions are from this page, which originally got them from here.
Here is a summary of the steps needed to export a private key from a jks keystore
Download ExportPrivateKey.zip from the attachments of this post or the original location.
Invoke:
Code:
java -jar ExportPrivateKey.zip {keystore_path} JKS {keystore_password} {alias} {target_file}
This would export the key to PKCS #8 PEM format. Now run openssl to convert it to the format apache modssl expects the file in
Code:
openssl pkcs8 -inform PEM -nocrypt -in exported-pkcs8.key -out exported.key
The java code for exporting the private key in PKCS #8 format (already compiled and packaged within the .zip file, ready to run)
Code:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;

import sun.misc.BASE64Encoder;

public class ExportPrivateKey {
        private File keystoreFile;
        private String keyStoreType;
        private char[] password;
        private String alias;
        private File exportedFile;

        public static KeyPair getPrivateKey(KeyStore keystore, String alias, char[] password) {
                try {
                        Key key=keystore.getKey(alias,password);
                        if(key instanceof PrivateKey) {
                                Certificate cert=keystore.getCertificate(alias);
                                PublicKey publicKey=cert.getPublicKey();
                                return new KeyPair(publicKey,(PrivateKey)key);
                        }
                } catch (UnrecoverableKeyException e) {
        } catch (NoSuchAlgorithmException e) {
        } catch (KeyStoreException e) {
        }
        return null;
        }

        public void export() throws Exception{
                KeyStore keystore=KeyStore.getInstance(keyStoreType);
                BASE64Encoder encoder=new BASE64Encoder();
                keystore.load(new FileInputStream(keystoreFile),password);
                KeyPair keyPair=getPrivateKey(keystore,alias,password);
                PrivateKey privateKey=keyPair.getPrivate();
                String encoded=encoder.encode(privateKey.getEncoded());
                FileWriter fw=new FileWriter(exportedFile);
                fw.write(“—–BEGIN PRIVATE KEY—–\n“);
                fw.write(encoded);
                fw.write(“\n“);
                fw.write(“—–END PRIVATE KEY—–”);
                fw.close();
        }

        public static void main(String args[]) throws Exception{
                ExportPrivateKey export=new ExportPrivateKey();
                export.keystoreFile=new File(args[0]);
                export.keyStoreType=args[1];
                export.password=args[2].toCharArray();
                export.alias=args[3];
                export.exportedFile=new File(args[4]);
                export.export();
        }
}
How we used it:
Code:
# Export the tomcat key (from the tomcat csr request) in pkcs8 format
java -jar ExportPrivateKey.zip /opt/zimbra/tomcat/conf/keystore JKS zimbra tomcat /opt/zimbra/ssl/ssl/server/tomcat-pkcs8.key
# Convert the pkcs8 formatted key to a non binary one
openssl pkcs8 -inform PEM -nocrypt -in /opt/zimbra/ssl/ssl/server/tomcat-pkcs8.key -out /opt/zimbra/ssl/ssl/server/tomcat.key
# Copy the tomcat.key and tomcat.pem to overwrite the default self signed smtpd ones
cp /opt/zimbra/ssl/ssl/server/tomcat.key /opt/zimbra/conf/smtpd.key
cp /opt/zimbra/ssl/ssl/server/tomcat.pem /opt/zimbra/conf/smtpd.crt
# Restart Zimbra (or just Postfix if you choose)
su zimbra
zmcontrol stop
zmcontrol start
Now to test and see if it worked.
For Postfix:
Code:
nc postfix.host.com 25                       (or telnet instead of nc if you don't have netcat but do have telnet)
220 postfix.host.com ESMTP Postfix
ehlo world                                   <-- type this line
250-intraz.rio.com
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250 8BITMIME
starttls                                     <-- type this line
# If you get this:
220 Ready to start TLS                       <-- SUCCESS !!!
454 TLS not available due to local problem   <-- FAILURE :(
For Apache (which needs slightly separate instructions for setting up the file pair, but the principles for extracting the key and such are the same):
Open a browser, browse to the site, use your browser to verify the validity of the certificate.

Disclaimer: I did not write the java code used for exporting the private key and the instructions on this page are only slightly edited and updated instructions found on the linked websites. This edited version of the instructions is what worked for us, there are no guarantees that it will work for you. If you have any problems running the java program to extract the key, please seek help from the person who wrote it. For anything Zimbra related however feel free to follow up in this post and someone will surely try to help.

Cheers,

RioGD

Post Scriptum: To the Zimbra devs reading this... Wouldn't it be nice if Zimbra included the functionality to do all of this from within the interface so that people who require commercial certificates (most likely a large majority of your NE users) don't have to follow half baked howtos/tutorials, like the one I have just done , which are the source of much frustration ?
Attached Files
File Type: zip ExportPrivateKey.zip (2.2 KB, 359 views)
Reply With Quote
  #2 (permalink)  
Old 06-29-2007, 10:54 AM
Zimbra Consultant
 
Posts: 5,606
Default

Thanks for the Tip!
I've filed a bug, and we'll get this into the wiki

Bug 18021 - Support Export of Private Key via Admin UI
Reply With Quote
  #3 (permalink)  
Old 06-29-2007, 11:32 AM
Senior Member
 
Posts: 50
Default

Thanks for the prompt response. Would it be possible to actually unify the whole ordeal within the Admin UI ? This would mean giving the ability to:
  • Generate a CSR for sending to the Certificate Authority.
  • Paste the PEM certificate sent back from the Certificate Authority.
  • Install the received PEM certificate into Tomcat's keystore for HTTPS access.
  • Install, by exporting and converting per the above instructions, the certificate & key pair for Postfix.

The reason I would lead towards this is that the folks who are using commercial certificates are really met with a hassle to install them. And before you say "Save the hassle use the simple self signed ones" as some people in the forums have, it is important to note that all mobile users with Palm Treo's newer than the 650 will require a commercial certificate as there is no "easy way" to make them accept a self signed certificate. So basically Zimbra Mobile will not work properly on some phones without a commercial certificate.
My reasoning is that it should be more simple than it currently is, to install a commercial certificate on a product geared towards business / enterprise use.
Also unifying the whole thing in the UI using similar steps as outlined in this post will prevent ever exposing the private key via the UI. The only thing which will be exposed via the Admin UI is the CSR to generate the PEM certificate. Once generated and submitted through the Admin UI everything can take place internally.

Thank you again for the prompt response and for submitting the bug request.

Cheers,

RioGD

Post Scriptum: I had added this to the wiki here but would actually like for it to be redone by someone who has better wikifu than I do and perhaps placed in a better location etc...
Reply With Quote
Reply


Thread Tools
Display Modes


Similar Threads

Why Join?

Registering let's you ask questions, makes it easier to search, displays any files attached to posts, and notifies you about replies.

Zimbrablog.com