package org.fnppl.opensdx.security; /* * Copyright (C) 2010-2015 * fine people e.V. <opensdx@fnppl.org> * Henning Thieß <ht@fnppl.org> * * http://fnppl.org */ /* * Software license * * As far as this file or parts of this file is/are software, rather than documentation, this software-license applies / shall be applied. * * This file is part of openSDX * openSDX is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * openSDX 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 Lesser General Public License * and GNU General Public License along with openSDX. * If not, see <http://www.gnu.org/licenses/>. * */ /* * Documentation license * * As far as this file or parts of this file is/are documentation, rather than software, this documentation-license applies / shall be applied. * * This file is part of openSDX. * Permission is granted to copy, distribute and/or modify this document * under the terms of the GNU Free Documentation License, Version 1.3 * or any later version published by the Free Software Foundation; * with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. * A copy of the license is included in the section entitled "GNU * Free Documentation License" resp. in the file called "FDL.txt". * */ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.security.Security; import java.util.Iterator; import java.util.Vector; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.provider.JCERSAPrivateKey; import org.bouncycastle.jce.provider.JCERSAPublicKey; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPPublicKeyRingCollection; import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; import org.bouncycastle.openpgp.PGPUtil; import org.fnppl.opensdx.gui.DefaultMessageHandler; import org.fnppl.opensdx.xml.Document; import org.fnppl.opensdx.xml.Element; public class PGPKeyStore { private File publicKeyFile = null; private File privateKeyFile =null; private PGPPublicKeyRingCollection keyringcollectionPub; private PGPSecretKeyRingCollection keyringcollectionSec; public PGPKeyStore(File public_key_file, File private_key_file) { Security.addProvider(new BouncyCastleProvider()); publicKeyFile = public_key_file; privateKeyFile = private_key_file; if (privateKeyFile==null || !privateKeyFile.exists() || publicKeyFile == null || !publicKeyFile.exists()) { throw new RuntimeException("missing keyfiles."); } } public PGPKeyStore() { Security.addProvider(new BouncyCastleProvider()); File path = new File(System.getProperty("user.home")); if (path.exists()) { path = new File(path,".gnupg"); } if (path.exists()) { publicKeyFile = new File(path, "pubring.gpg"); privateKeyFile = new File(path, "secring.gpg"); } if (privateKeyFile==null || !privateKeyFile.exists() || publicKeyFile == null || !publicKeyFile.exists()) { throw new RuntimeException("missing keyfiles."); } } // public static byte[] getExponentFromSecretKey(byte[] sec_key_bytes, char[] password) { // PGPSecretKey key = null; // try { // PGPSecretKeyRing ring = new PGPSecretKeyRing(sec_key_bytes); // Iterator<PGPSecretKey> iterKeys = ring.getSecretKeys(); // while (iterKeys.hasNext() && key==null) { // key = iterKeys.next(); // } // if (key != null) { // try { // PGPPrivateKey priv_key = key.extractPrivateKey(password, "BC"); // if (priv_key != null) { // JCERSAPrivateKey priv_keyparam = (JCERSAPrivateKey)priv_key.getKey(); // byte[] priv_exp_bytes = priv_keyparam.getPrivateExponent().toByteArray(); // //System.out.println("skeyparam: exp :: "+SecurityHelper.HexDecoder.encode(s_exp_bytes)); // System.out.println("private key unlocked"); // return priv_exp_bytes; // } // } catch (Exception ex) { // System.out.println("Error unlocking private key, wrong password?"); // } // } else { // System.out.println("format error, no private key found"); // } // } catch (Exception ex) { // if (key!=null) { // System.out.println("could NOT unlock private key"); // } // ex.printStackTrace(); // } // return null; // } public PGPSecretKey findSecretKey(long keyID) throws Exception { if (keyringcollectionSec==null) { InputStream keyIn = new FileInputStream(privateKeyFile); keyringcollectionSec = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(keyIn)); } PGPSecretKey secretKey = keyringcollectionSec.getSecretKey(keyID); return secretKey; } // public Vector<OSDXKey> parseOSDXKeys() throws Exception { // Vector<OSDXKey> keys = new Vector<OSDXKey>(); // InputStream keyIn = new FileInputStream(publicKeyFile); // keyringcollectionPub = new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(keyIn)); // // Iterator<PGPPublicKeyRing> iterKeyRings = keyringcollectionPub.getKeyRings(); // while (iterKeyRings.hasNext()) { // PGPPublicKeyRing ring = iterKeyRings.next(); // Iterator<PGPPublicKey> iterKeys = ring.getPublicKeys(); // while (iterKeys.hasNext()) { // try { // PGPPublicKey key = iterKeys.next(); // String userID = ""; // Iterator iterUserIDs = key.getUserIDs(); // Element eIds = new Element("identities"); // int idcount = 0; // while (iterUserIDs.hasNext()) { // Object o = iterUserIDs.next(); // String sid = o.toString(); // userID += ", "+sid; // Identity id = Identity.newEmptyIdentity(); // id.setIdentNum(idcount+1); // int email_start = sid.lastIndexOf("<"); // int email_end = sid.lastIndexOf(">"); // id.setMnemonic("pgp/gpg import"); // id.set_mnemonic_restricted(false); // id.setNote(sid); // id.set_note_restricted(false); // if (email_start>0 && email_end>0 && email_start < email_end) { // id.setEmail(sid.substring(email_start+1,email_end)); // } // eIds.addContent(id.toElement(true)); // idcount++; // } // if (userID.length()>2) userID = userID.substring(2); // System.out.println("\n\nkey :: "+Long.toHexString(key.getKeyID())+", "+key.getAlgorithm()+", "+key.getBitStrength()+", "+SecurityHelper.HexDecoder.encode(key.getFingerprint())+", "+userID+", "+key.isEncryptionKey()+", "+key.isMasterKey()+", "+key.isRevoked()); // JCERSAPublicKey keyparam = (JCERSAPublicKey)key.getKey("BC"); // //System.out.println("keyparam: "+keyparam.getModulus()+", "+keyparam.getPublicExponent()); // // long valid_from = key.getCreationTime().getTime(); // long valid_until = valid_from+key.getValidSeconds()*1000; // // int a = key.getAlgorithm(); // String algo = "num="+a; // if (a == PGPPublicKey.RSA_GENERAL || a == PGPPublicKey.RSA_ENCRYPT || a == PGPPublicKey.RSA_SIGN) { // algo = "RSA"; // } // byte[] modulus_bytes = keyparam.getModulus().toByteArray(); // byte[] exp_bytes = keyparam.getPublicExponent().toByteArray(); // System.out.println(" keyparam: mod :: "+SecurityHelper.HexDecoder.encode(modulus_bytes)+"\n keyparam: exp :: "+SecurityHelper.HexDecoder.encode(exp_bytes)); // byte[] keyid = SecurityHelper.getSHA1(modulus_bytes); // // Element ekp = new Element("keypair"); // if (eIds.getChildren().size()>0) { // ekp.addContent(eIds); // } // ekp.addContent("sha1fingerprint", SecurityHelper.HexDecoder.encode(keyid)); // ekp.addContent("authoritativekeyserver", "pgp_import"); // ekp.addContent("valid_from",SecurityHelper.getFormattedDate(valid_from)); // ekp.addContent("valid_until",SecurityHelper.getFormattedDate(valid_until)); // ekp.addContent("level",(key.isMasterKey()?OSDXKey.level_name.get(OSDXKey.LEVEL_MASTER):OSDXKey.level_name.get(OSDXKey.LEVEL_SUB))); // ekp.addContent("usage",(key.isEncryptionKey()?OSDXKey.usage_name.get(OSDXKey.USAGE_WHATEVER):OSDXKey.usage_name.get(OSDXKey.USAGE_SIGN))); // ekp.addContent("algo", algo); // ekp.addContent("bits", ""+key.getBitStrength()); // ekp.addContent("modulus", SecurityHelper.HexDecoder.encode(modulus_bytes)); // Element epubkey = new Element("pubkey"); // epubkey.addContent("exponent",SecurityHelper.HexDecoder.encode(exp_bytes)); // ekp.addContent(epubkey); // ekp.addContent("gpgkeyserverid", SecurityHelper.HexDecoder.encode(key.getFingerprint())); // // try { // PGPSecretKey seckey = findSecretKey(key.getKeyID()); // if (seckey!=null) { // ByteArrayOutputStream bout = new ByteArrayOutputStream(); // seckey.encode(bout); // byte[] sec_key_bytes = bout.toByteArray(); // Element eexp = new Element("exponent"); // eexp.addContent("pgp",SecurityHelper.HexDecoder.encode(sec_key_bytes)); // Element esk = new Element("privkey"); // esk.addContent(eexp); // ekp.addContent(esk); // System.out.println(" priv enc: exp :: "+SecurityHelper.HexDecoder.encode(sec_key_bytes)); // } // } catch (Exception ex) { // System.out.println("error adding private key"); // } // // OSDXKey osdxkey = OSDXKey.fromElement(ekp); // keys.add(osdxkey); //// if (osdxkey.hasPrivateKey()) { //// Document.buildDocument(osdxkey.toElement(new DefaultMessageHandler())).output(System.out); //// } // // } catch (Exception e) { // e.printStackTrace(); // } // } // } // return keys; // } //testing public static void main(String[] args) { // PGPKeyStore pgp = new PGPKeyStore(); // try { // Vector<OSDXKey> keys = pgp.parseOSDXKeys(); // for (OSDXKey key : keys) { // System.out.println(key.getKeyID()); // } // OSDXKey key = keys.lastElement(); // try { // key.unlockPrivateKey(new DefaultMessageHandler()); // } catch (Exception e) {} // // if (!key.isPrivateKeyUnlocked()) return; // // File testFile = new File("fnppl_contributor_license.pdf"); // Signature sig = Signature.createSignature(testFile, key); // // Result res = sig.tryVerificationFile(testFile); // // if (res.report!=null) { // Document.buildDocument(res.report).output(System.out); // } // // // } catch (Exception ex) { // ex.printStackTrace(); // } } }