diff --git a/source/de/anomic/server/serverCore.java b/source/de/anomic/server/serverCore.java index 336e4fd35..69ffbb2f7 100644 --- a/source/de/anomic/server/serverCore.java +++ b/source/de/anomic/server/serverCore.java @@ -47,6 +47,7 @@ package de.anomic.server; // standard server import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -81,6 +82,7 @@ import de.anomic.http.httpc; import de.anomic.icap.icapd; import de.anomic.plasma.plasmaSwitchboard; import de.anomic.server.logging.serverLog; +import de.anomic.tools.PKCS12Tool; import de.anomic.urlRedirector.urlRedirectord; import de.anomic.yacy.yacyCore; import de.anomic.yacy.yacySeed; @@ -1327,12 +1329,54 @@ public final class serverCore extends serverAbstractThread implements serverThre private SSLSocketFactory initSSLFactory() { // getting the keystore file name - String keyStoreFileName = this.switchboard.getConfig("keyStore", ""); - if (keyStoreFileName.length() == 0) return null; + String keyStoreFileName = this.switchboard.getConfig("keyStore", "").trim(); // getting the keystore pwd - String keyStorePwd = this.switchboard.getConfig("keyStorePassword", ""); - if (keyStorePwd.length() == 0) return null; + String keyStorePwd = this.switchboard.getConfig("keyStorePassword", "").trim(); + + // take a look if we have something to import + String pkcs12ImportFile = this.switchboard.getConfig("pkcs12ImportFile", "").trim(); + if (pkcs12ImportFile.length() > 0) { + this.log.logInfo("Import certificates from import file '" + pkcs12ImportFile + "'."); + + try { + // getting the password + String pkcs12ImportPwd = this.switchboard.getConfig("pkcs12ImportPwd", "").trim(); + + // creating tool to import cert + PKCS12Tool pkcsTool = new PKCS12Tool(pkcs12ImportFile,pkcs12ImportPwd); + + // creating a new keystore file + if (keyStoreFileName.length() == 0) { + // using the default keystore name + keyStoreFileName = "DATA/SETTINGS/myPeerKeystore"; + + // creating an empty java keystore + KeyStore ks = KeyStore.getInstance("JKS"); + ks.load(null,keyStorePwd.toCharArray()); + FileOutputStream ksOut = new FileOutputStream(keyStoreFileName); + ks.store(ksOut, keyStorePwd.toCharArray()); + ksOut.close(); + + // storing path to keystore into config file + this.switchboard.setConfig("keyStore", keyStoreFileName); + } + + // importing certificate + pkcsTool.importToJKS(keyStoreFileName, keyStorePwd); + + // removing entries from config file + this.switchboard.setConfig("pkcs12ImportFile", ""); + this.switchboard.setConfig("keyStorePassword", ""); + + // deleting original import file + // TODO: should we do this + + } catch (Exception e) { + this.log.logSevere("Unable to import certificate from import file '" + pkcs12ImportFile + "'.",e); + } + } else if (keyStoreFileName.length() == 0) return null; + // get the ssl context try { diff --git a/source/de/anomic/tools/PKCS12Tool.java b/source/de/anomic/tools/PKCS12Tool.java new file mode 100644 index 000000000..e1e9f9523 --- /dev/null +++ b/source/de/anomic/tools/PKCS12Tool.java @@ -0,0 +1,146 @@ +//PKCS12Tool.java +//------------------------------------- +//part of YACY +//(C) by Michael Peter Christen; mc@anomic.de +//first published on http://www.anomic.de +//Frankfurt, Germany, 2006 +// +//This file ist contributed by Martin Thelian +// +//last change: $LastChangedDate: 2006-05-12 16:35:56 +0200 (Fr, 12 Mai 2006) $ by $LastChangedBy: theli $ +//Revision: $LastChangedRevision: 2086 $ +// +//This program is free software; you can redistribute it and/or modify +//it under the terms of the GNU General Public License as published by +//the Free Software Foundation; either version 2 of the License, or +//(at your option) any later version. +// +//This program is distributed in the hope that it will be useful, +//but WITHOUT ANY WARRANTY; without even the implied warranty of +//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//GNU General Public License for more details. +// +//You should have received a copy of the GNU General Public License +//along with this program; if not, write to the Free Software +//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//Using this software in any meaning (reading, learning, copying, compiling, +//running) means that you agree that the Author(s) is (are) not responsible +//for cost, loss of data or any harm that may be caused directly or indirectly +//by usage of this softare or this documentation. The usage of this software +//is on your own risk. The installation and usage (starting/running) of this +//software may allow other people or application to access your computer and +//any attached devices and is highly dependent on the configuration of the +//software which must be done by the user of the software; the author(s) is +//(are) also not responsible for proper configuration and usage of the +//software, even if provoked by documentation provided together with +//the software. +// +//Any changes to this file according to the GPL as documented in the file +//gpl.txt aside this file in the shipment you received can be done to the +//lines that follows this copyright notice here, but changes must not be +//done inside the copyright notive above. A re-distribution must contain +//the intact and unchanged copyright notice. +//Contributions and changes to the program code must be marked as such. + + +package de.anomic.tools; + +import java.security.KeyStore; +import java.security.Key; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.util.Enumeration; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; + +public class PKCS12Tool { + + private KeyStore kspkcs12; + private String kspkcs12Pass; + + public PKCS12Tool(String pkcs12FileName, String pkcs12Pwd) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException { + if (pkcs12FileName == null) throw new NullPointerException(); + this.kspkcs12Pass = pkcs12Pwd; + + // creating PKCS12 keystore + this.kspkcs12 = KeyStore.getInstance("PKCS12"); + + // load pkcs12 file into keystore object + FileInputStream fileIn = new FileInputStream(pkcs12FileName); + this.kspkcs12.load(fileIn,(pkcs12Pwd!=null)?pkcs12Pwd.toCharArray():null); + + // close stream + fileIn.close(); + } + + public Enumeration aliases() throws KeyStoreException { + Enumeration aliases = this.kspkcs12.aliases(); + return aliases; + } + + public void printAliases() throws KeyStoreException { + Enumeration aliases = aliases(); + while(aliases.hasMoreElements()) { + System.out.println(aliases.nextElement()); + } + } + + public void importToJKS(String jksName, String jksPassword) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, UnrecoverableKeyException { + // creating java keystore + KeyStore jks=KeyStore.getInstance("JKS"); + + // loading keystore from file + FileInputStream jksFileIn = null; + File jksFile = new File(jksName); + + if (jksFile.exists()) { + System.err.println("Loading java keystore from file '" + jksFile + "'"); + jksFileIn = new FileInputStream(jksFile); + } else{ + System.err.println("Creating new java keystore '" + jksFile + "'"); + } + jks.load(jksFileIn,(jksPassword!=null)?jksPassword.toCharArray():null); + if (jksFileIn != null) jksFileIn.close(); + + Enumeration pkcs12Aliases = aliases(); + while (pkcs12Aliases.hasMoreElements()) { + String strAlias = (String)pkcs12Aliases.nextElement(); + System.err.println("Importing Alias '" + strAlias + "'"); + + if (this.kspkcs12.isKeyEntry(strAlias)) { + System.err.println("- Alias has key"); + Key key = this.kspkcs12.getKey(strAlias, (this.kspkcs12Pass!=null)?this.kspkcs12Pass.toCharArray():null); + System.err.println("- Alias key imported"); + + Certificate[] chain = this.kspkcs12.getCertificateChain(strAlias); + System.err.println("- Alias certificate chain size: " + chain.length); + + jks.setKeyEntry(strAlias, key, (jksPassword!=null)?jksPassword.toCharArray():null, chain); + } + } + + // storing jdk into file + System.err.print("Storing java keystore"); + FileOutputStream jksFileOut = new FileOutputStream(jksName); + jks.store(jksFileOut,(jksPassword!=null)?jksPassword.toCharArray():null); + jksFileOut.close(); + System.err.print("Import finished."); + } + + /** + * @param args + */ + public static void main(String[] args) throws Exception { + PKCS12Tool pkcs12 = new PKCS12Tool("c:/temp/keystore.pkcs12","test"); + //pkcs12.printAliases(); + pkcs12.importToJKS("c:/temp/jks.ks", "test"); + } + +} diff --git a/yacy.init b/yacy.init index 6456e8875..311463270 100644 --- a/yacy.init +++ b/yacy.init @@ -18,17 +18,35 @@ port = 8080 # SSL support: # With this you can access your peer using https://localhost:8080 # -# For testing purposes, you can create a keystore with a self-signed certificate, -# using the following command: +# There are two possibilities to specify which certificate should +# be used by YaCy. +# +# 1) Create a new Certificate: +# +# *) For testing purposes, you can create a keystore with a self-signed certificate, +# using the following command: +# C:\> keytool -keystore mySrvKeystore -genkey -keyalg RSA -alias mycert +# +# *) Then configure the keyStoreXXXX properties accordingly, e.g. +# keyStore = c:/yacy/DATA/SETTINGS/mySrvKeystore +# keyStorePassword = mypwd +# +# 2) Import an existing certificate: # -# |> keytool -keystore mySrvKeystore -genkey -keyalg RSA -alias mycert +# Alternatively you can import an existing certificate in pkcs12 format into +# the keystore. +# +# This can be done by setting the pkcs12XXX properties accordingly, e.g. +# pkcs12ImportFile = c:/temp/keystore.pkcs12 +# pkcs12ImportPwd = test # -# Then configure the keyStore properties accordingly, e.g. -# keyStore = c:/yacy/DATA/SETTINGS/mySrvKeystore -# keyStorePassword = mypwd +# If the property keyStore is not specified, then a new keystore file +# DATA/SETTINGS/myPeerKeystore will be created. # keyStore = keyStorePassword = +pkcs12ImportFile = +pkcs12ImportPwd = # peer-to-peer construction for distributed search # we have several stages: