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.IOException;
import java.io.OutputStream;
import java.math.BigInteger;
import java.util.*;
import org.fnppl.opensdx.security.PGPKeyStore;
import org.fnppl.opensdx.gui.MessageHandler;
import org.fnppl.opensdx.xml.Document;
import org.fnppl.opensdx.xml.Element;
import org.fnppl.opensdx.xml.XMLHelper;
public class OSDXKey {
public static final int ALGO_RSA = 0;
private static final Vector<String> algo_name = new Vector<String>();
static {
algo_name.addElement("RSA");
};
public static final int USAGE_SIGN = 0;
public static final int USAGE_CRYPT = 1;
public static final int USAGE_WHATEVER = 2;
public static final Vector<String> usage_name = new Vector<String>();
static {
usage_name.addElement("ONLYSIGN");
usage_name.addElement("ONLYCRYPT");
usage_name.addElement("BOTH");
};
public static final long ONE_YEAR = 31557600000L; //1 year = 31557600000 = 1000*60*60*24*365.25
public static final int LEVEL_MASTER = 0;
public static final int LEVEL_REVOKE = 1;
public static final int LEVEL_SUB = 2;
public static final int LEVEL_UNKNOWN = 3;
public static final Vector<String> level_name = new Vector<String>();
static {
level_name.addElement("MASTER");
level_name.addElement("REVOKE");
level_name.addElement("SUB");
level_name.addElement("UNKNOWN");
};
private int level = LEVEL_MASTER;
protected int usage = USAGE_WHATEVER;
protected int algo = ALGO_RSA;
protected long validFrom = Long.MIN_VALUE;
protected long validUntil = Long.MAX_VALUE;
private String usage_restriction = null;
private String usage_note = null;
protected String authoritativekeyserver = null;
//protected int authoritativekeyserverPort = 8889;
protected byte[] modulussha1 = null;
protected String gpgkeyserverid = null;
protected Vector<DataSourceStep> datapath = new Vector<DataSourceStep>();
//protected char[] storepass = null;
protected AsymmetricKeyPair akp = null;
protected Element lockedPrivateKey = null;
protected boolean protectPrivateKey = true;
protected boolean unsavedChanges = false;
protected OSDXKey() {
validFrom = System.currentTimeMillis();
validFrom = validFrom - validFrom%1000; //no milliseconds in datemeGMT format;
validUntil = validFrom + 25L*ONE_YEAR; //25 years
}
public PublicKey getPubKey() {
PublicKey ll = new PublicKey(
new BigInteger(akp.getPublicModulus()),
new BigInteger(akp.getPublicExponent())
);
return ll;
}
public boolean verify(byte[] signature, byte[] md5, byte[] sha1, byte[] sha256, long timestamp) throws Exception {
return getPubKey().verify(signature, md5, sha1, sha256, timestamp);
}
public byte[] getPublicModulusBytes() {
return akp.getPublicModulus();
}
public byte[] getPublicExponentBytes() {
return akp.getPublicExponent();
}
public byte[] encrypt(byte[] bytes) {
try {
return akp.encryptWithPublicKey(bytes);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public byte[] decrypt(byte[] bytes) {
try {
return akp.decryptWithPrivateKey(bytes);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public byte[] encryptBlocks(byte[] bytes) {
try {
return akp.encryptBlocks(bytes);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public byte[] decryptBlocks(byte[] data) {
try {
return akp.decryptBlocks(data);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static OSDXKey fromPubKeyElement(Element e) throws Exception {
OSDXKey ret = null;
String levelName = e.getChildText("level");
int level = level_name.indexOf(levelName);
if (level == LEVEL_MASTER) {
ret = new MasterKey();
}
else if (level == LEVEL_SUB) {
ret = new SubKey();
}
else if (level == LEVEL_REVOKE) {
ret = new RevokeKey();
}
else {
ret = new OSDXKey();
}
ret.level = level;
ret.usage = USAGE_WHATEVER;
String usageName = e.getChildText("usage");
if (usageName!=null && !usageName.equals("")) {
int usage = usage_name.indexOf(usageName);
if (usage>=0) ret.usage = usage;
}
ret.usage_restriction = e.getChildText("usage_restriction");
ret.usage_note = e.getChildText("usage_note");
String keyid = e.getChildText("keyid");
String authServer = e.getChildText("authoritativekeyserver");
if (authServer!=null && !authServer.equals("")) {
ret.authoritativekeyserver = authServer;
} else {
if (keyid.indexOf('@')>0) {
ret.authoritativekeyserver = keyid.substring(keyid.indexOf('@')+1);
}
}
//int port = e.getChildInt("authoritativekeyserver_port");
//if (port > 0) ret.authoritativekeyserverPort = port;
ret.datapath = new Vector<DataSourceStep>();
ret.validFrom = SecurityHelper.parseDate(e.getChildText("valid_from"));
ret.validUntil = SecurityHelper.parseDate(e.getChildText("valid_until"));
ret.unsavedChanges = true;
String Salgo = e.getChildText("algo");
ret.algo = algo_name.indexOf(Salgo);
byte[] modulus = SecurityHelper.HexDecoder.decode(e.getChildText("modulus"));
byte[] pubkey_exponent = SecurityHelper.HexDecoder.decode(e.getChildText("exponent"));
byte[] exponent = null;
AsymmetricKeyPair askp = new AsymmetricKeyPair(modulus, pubkey_exponent, exponent);
ret.akp = askp;
ret.modulussha1 = SecurityHelper.getSHA1(askp.getPublicModulus());
if (ret instanceof SubKey) {
String pkid = e.getChildText("parentkeyid");
if (pkid!=null) {
((SubKey)ret).setParentKeyID(pkid);
}
}
return ret;
}//fromElement
public static OSDXKey fromElement(Element kp) throws Exception {
OSDXKey ret = null;
String levelName = kp.getChildText("level");
int level = level_name.indexOf(levelName);
if (level == LEVEL_MASTER) {
ret = new MasterKey();
}
else if (level == LEVEL_SUB) {
ret = new SubKey();
}
else if (level == LEVEL_REVOKE) {
ret = new RevokeKey();
}
else {
ret = new OSDXKey();
}
ret.level = level;
//System.out.println("adding keyobject");
//first check sha1fingerprint
String Sshafp = kp.getChildText("sha1fingerprint");
byte[] sha1fp = SecurityHelper.HexDecoder.decode(Sshafp);//sha1-checksum of moduluss
String Smodulus = kp.getChildText("modulus");
byte[] modulus = SecurityHelper.HexDecoder.decode(Smodulus);
byte[] modsha1 = SecurityHelper.getSHA1(modulus);
if(!Arrays.equals(modsha1, sha1fp)) {
System.err.println("Uargsn. sha1fingerprint given does not match calculated sha1 for given modulus ("+sha1fp+"!="+modsha1+")");
return null;
}
ret.modulussha1 = modsha1;
//fingerprint ok -> go on with identities
if (level == LEVEL_MASTER) {
Element ids = kp.getChild("identities");
if (ids!=null) {
Vector<Element> idc = ids.getChildren("identity");
if (idc!=null) {
//System.out.println("identities found: "+idc.size());
for(int j=0;j<idc.size();j++) {
Element elementID = idc.elementAt(j);
Identity id = Identity.fromElement(elementID);
//System.out.println("adding id: "+idd.email);
//System.out.println("sha1: "+id.getChildText("sha1"));
boolean ok = id.validate(SecurityHelper.HexDecoder.decode(elementID.getChildText("sha256")));
if(ok) {
((MasterKey)ret).identities.addElement(id);
} else {
System.out.println(" -> ERROR adding "+id.getIdentNumString()+" "+id.getEmail()+": SHA256 NOT VALID");
return null;
}
}
}
} //identities
}
//go on with other fields
String authoritativekeyserver = kp.getChildText("authoritativekeyserver");
ret.authoritativekeyserver = authoritativekeyserver;
//int port = kp.getChildInt("authoritativekeyserver_port");
//if (port > 0) ret.authoritativekeyserverPort = port;
//System.out.println("authoritativekeyserver: "+authoritativekeyserver);
//datapath
Element dp = kp.getChild("datapath");
boolean dsOK = false;
if (dp!=null) {
ret.datapath = new Vector<DataSourceStep>();
Vector<Element> steps = dp.getChildren();
for (Element st : steps)
if (st.getName().startsWith("step")) {
DataSourceStep dst = DataSourceStep.fromElemet(st);
ret.datapath.add(dst);
dsOK = true;
}
}
if (!dsOK) {
//System.out.println("CAUTION datasource and datainsertdatetime NOT found.");
}
String sValidFrom = kp.getChildText("valid_from");
String sValidUntil = kp.getChildText("valid_until");
ret.validFrom = SecurityHelper.parseDate(sValidFrom);
ret.validUntil = SecurityHelper.parseDate(sValidUntil);
String usage = kp.getChildText("usage");
ret.usage = usage_name.indexOf(usage);
ret.usage_restriction = kp.getChildText("usage_restriction");
ret.usage_note = kp.getChildText("usage_note");
if (level == LEVEL_SUB || level == LEVEL_REVOKE) {
String parentkeyid = kp.getChildText("parentkeyid");
if (parentkeyid==null) {
((SubKey)ret).parentkeyid = null;
} else {
int iAt = parentkeyid.indexOf('@');
if (iAt>0) {
byte[] parentid = SecurityHelper.HexDecoder.decode(parentkeyid.substring(0,iAt));
((SubKey)ret).parentkeyid = SecurityHelper.HexDecoder.encode(parentid,':',-1)+parentkeyid.substring(iAt);
} else {
byte[] parentid = SecurityHelper.HexDecoder.decode(parentkeyid);
((SubKey)ret).parentkeyid = SecurityHelper.HexDecoder.encode(parentid,':',-1);
}
}
}
String Salgo = kp.getChildText("algo");
int bits = kp.getChildInt("bits");
ret.algo = algo_name.indexOf(Salgo);
//add asymetric keypair or public key part only
Element pubkey = kp.getChild("pubkey");
String pubkey_exponentS = pubkey.getChildText("exponent");
byte[] pubkey_exponent = SecurityHelper.HexDecoder.decode(pubkey_exponentS);
byte[] exponent = null;
Element privkey = kp.getChild("privkey");
if (privkey!=null) {
//asymetric keypair
Element eExponent = privkey.getChild("exponent");
if(eExponent.getChild("locked") != null) {
//only ask for password when key is used for the first time -> see unlockPrivateKey
ret.lockedPrivateKey = eExponent.getChild("locked");
ret.protectPrivateKey = true;
}
else if(eExponent.getChild("pgp") != null) {
//only ask for password when key is used for the first time -> see unlockPrivateKey
ret.lockedPrivateKey = eExponent.getChild("pgp");
ret.protectPrivateKey = true;
}
else {
//unlocked private key
//System.err.println("You should never see me - there seems to be a private key unlocked in your keystore: "+Sshafp+"@"+authoritativekeyserver);
ret.lockedPrivateKey = null;
ret.protectPrivateKey = false;
exponent = SecurityHelper.HexDecoder.decode(eExponent.getText());
}
}
//exponent == null if no private key present or private key is locked
AsymmetricKeyPair askp = new AsymmetricKeyPair(modulus, pubkey_exponent, exponent);
ret.akp = askp;
//go on
ret.gpgkeyserverid = kp.getChildText("gpgkeyserverid");
ret.unsavedChanges = false;
return ret;
}//fromElement
public String getUsageRestriction() {
return usage_restriction;
}
public void setUsageRestricton(String value) {
unsavedChanges = true;
usage_restriction = value;
}
public String getUsageNote() {
return usage_note;
}
public void setUsageNote(String value) {
unsavedChanges = true;
usage_note = value;
}
public boolean allowsSigning() {
//double check: signing not possible without private key
if (akp.hasPrivateKey() || lockedPrivateKey != null) {
return usage == USAGE_SIGN || usage == USAGE_WHATEVER;
}
return false;
}
public boolean allowsSignatures() {
return usage == USAGE_SIGN || usage == USAGE_WHATEVER;
}
public boolean allowsCrypt() {
return usage == USAGE_CRYPT || usage == USAGE_WHATEVER;
}
public String getKeyID() {
return getKeyModulusSHA1()+"@"+authoritativekeyserver;
}
public String getKeyIDShort() {
String keyid = getKeyID();
String keyidShort;
try {
keyidShort = keyid.substring(0,8)+" ... "+keyid.substring(51);
} catch (Exception e) {
keyidShort = keyid;
}
return keyidShort;
}
public String getKeyModulusSHA1() {
//return modulussha1;
return SecurityHelper.HexDecoder.encode(modulussha1, ':', -1);
}
public byte[] getKeyModulusSHA1bytes() {
return modulussha1;
}
public Element getSimplePubKeyElement() {
if (akp!=null) {
Element ret = new Element("pubkey");
ret.addContent("keyid",getKeyID());
ret.addContent("level",getLevelName());
if (this instanceof SubKey) {
ret.addContent("parentkeyid", ((SubKey)this).getParentKeyID());
}
ret.addContent("usage",getUsageName());
if (getUsageRestriction()!=null) {
ret.addContent("usage_restriction",getUsageRestriction());
}
if (getUsageNote()!=null) {
ret.addContent("usage_note",getUsageNote());
}
//ret.addContent("authoritativekeyserver",authoritativekeyserver);
//ret.addContent("authoritativekeyserver_port",""+authoritativekeyserverPort);
ret.addContent("valid_from",getValidFromString());
ret.addContent("valid_until",getValidUntilString());
ret.addContent("algo", algo_name.elementAt(algo));
ret.addContent("bits", ""+akp.getBitCount());
ret.addContent("modulus", akp.getPublicModulusAsHex());
ret.addContent("exponent", akp.getPublicExponentAsHex());
return ret;
}
return null;
}
public byte[] sign(byte[] md5,byte[] sha1,byte[] sha256,long datetime) throws Exception {
if (!isPrivateKeyUnlocked()) throw new RuntimeException("ERROR: Private Key is locked!");
return akp.sign(
md5,
sha1,
sha256,
datetime
);
}
// public byte[] signDirectly(byte[] data) throws Exception {
// if (!isPrivateKeyUnlocked()) throw new RuntimeException("ERROR: Private Key is locked!");
// return akp.signDirectly(data);
// }
public boolean isPrivateKeyUnlocked() {
return akp.hasPrivateKey();
}
public final void unlockPrivateKey(MessageHandler mh) {
if (!akp.hasPrivateKey() && lockedPrivateKey != null) { //only once
if (lockedPrivateKey.getName().equals("locked")) {
String mantraname = lockedPrivateKey.getChildText("mantraname");
//check algo and padding
String Slock_algo = lockedPrivateKey.getChildText("algo");
String Spadding = lockedPrivateKey.getChildText("padding");
if (!Slock_algo.equals("AES@256")||!Spadding.equals("CBC/PKCS#5")) {
throw new RuntimeException("UNLOCKING METHOD NOT IMPLEMENTED, please use AES@265 encryption with CBC/PKCS#7 padding");
}
try {
char[] pp = mh.requestPassword(getKeyID(), mantraname);
unlockPrivateKey(pp);
} catch(Exception ex) {
if (ex.getMessage().startsWith("pad block corrupted")) {
mh.fireWrongPasswordMessage();
} else {
ex.printStackTrace();
}
}
}
else if (lockedPrivateKey.getName().equals("pgp")) {
try {
char[] pp = mh.requestPassword(getKeyID(), "pgp/gpg key import");
unlockPrivateKey(pp);
} catch(Exception ex) {
if (ex.getMessage().startsWith("pad block corrupted")) {
mh.fireWrongPasswordMessage();
} else {
ex.printStackTrace();
}
}
}
}
}
public void createLockedPrivateKey(MessageHandler mh) throws Exception {
if (akp.hasPrivateKey()) {
String[] ans = mh.requestNewPasswordAndMantra("Saving Key: "+getKeyID()+"\n\nLevel: "+getLevelName()+"\n\n");
if (ans != null) {
if (ans.length==1 && ans[0].equals("no password")) {
protectPrivateKey = false;
} else {
createLockedPrivateKey(ans[0],ans[1]);
}
} else {
System.out.println("CAUTION: private key NOT saved.");
}
}
}
public void createLockedPrivateKey(String mantra, String password) throws Exception {
if (akp.hasPrivateKey()) {
byte[] iv = SecurityHelper.getRandomBytes(16);
SymmetricKey sk = SymmetricKey.getKeyFromPass(password.toCharArray(), iv);
byte[] encprivkey = akp.getEncrytedPrivateKey(sk);
Element el = new Element("locked");
el.addContent("mantraname",mantra);
el.addContent("algo","AES@256");
el.addContent("initvector", SecurityHelper.HexDecoder.encode(iv, ':',-1));
el.addContent("padding", "CBC/PKCS#5");
el.addContent("bytes", SecurityHelper.HexDecoder.encode(encprivkey, ':',-1));
lockedPrivateKey = el;
}
}
public void unlockPrivateKey(char[] password) throws Exception{
if (akp.hasPrivateKey() && !protectPrivateKey) return;
if (password!=null) {
if (lockedPrivateKey.getName().equals("locked")) {
String Sinitv = lockedPrivateKey.getChildText("initvector");
String Sbytes = lockedPrivateKey.getChildText("bytes");
byte[] bytes = SecurityHelper.HexDecoder.decode(Sbytes);
SymmetricKey sk = SymmetricKey.getKeyFromPass(password, SecurityHelper.HexDecoder.decode(Sinitv));
byte[] exponent = sk.decrypt(bytes);
byte[] modulus = akp.getPublicModulus();
byte[] pubkey_exponent = akp.getPublicExponent();
akp = new AsymmetricKeyPair(modulus, pubkey_exponent, exponent);
}
// else if (lockedPrivateKey.getName().equals("pgp")) {
// byte[] exponent = PGPKeyStore.getExponentFromSecretKey(SecurityHelper.HexDecoder.decode(lockedPrivateKey.getText()), password);
// if (exponent == null) throw new Exception("wrong password");
// byte[] modulus = akp.getPublicModulus();
// byte[] pubkey_exponent = akp.getPublicExponent();
// akp = new AsymmetricKeyPair(modulus, pubkey_exponent, exponent);
// }
}
}
public void unlockPrivateKey(String password) throws Exception{
unlockPrivateKey(password.toCharArray());
}
public Element toElement(MessageHandler mh) throws Exception {
return toElement(mh, true);
}
public Element toElementWithoutPrivateKey() throws Exception {
return toElement(null, false);
}
private Element toElement(MessageHandler mh, boolean withPrivateKey) throws Exception {
Element ekp = new Element("keypair");
if (this instanceof MasterKey) {
MasterKey mk = (MasterKey)this;
//identities
if (mk.identities!=null && mk.identities.size()>0) {
Element eids = new Element("identities");
for (Identity id : mk.identities) {
eids.addContent(id.toElement(true));
}
ekp.addContent(eids);
}
}
ekp.addContent("sha1fingerprint", getKeyModulusSHA1());
ekp.addContent("authoritativekeyserver", authoritativekeyserver);
//ekp.addContent("authoritativekeyserver_port", ""+authoritativekeyserverPort);
//datapath
Element edp = new Element("datapath");
for (int i=0;i<datapath.size();i++) {
edp.addContent(datapath.get(i).toElement(i));
}
ekp.addContent(edp);
ekp.addContent("valid_from",getValidFromString());
ekp.addContent("valid_until",getValidUntilString());
ekp.addContent("usage",usage_name.get(usage));
if (usage_restriction!=null) {
ekp.addContent("usage_restriction",usage_restriction);
}
if (usage_note!=null) {
ekp.addContent("usage_note",usage_note);
}
ekp.addContent("level",level_name.get(level));
if (this instanceof SubKey) {
ekp.addContent("parentkeyid", ((SubKey)this).getParentKeyID());
} else {
ekp.addContent("parentkeyid", "");
}
ekp.addContent("algo",algo_name.get(algo));
ekp.addContent("bits", ""+akp.getBitCount());
ekp.addContent("modulus", SecurityHelper.HexDecoder.encode(akp.getPublicModulus(), ':', -1));
//pubkey
Element epk = new Element("pubkey");
epk.addContent("exponent", SecurityHelper.HexDecoder.encode(akp.getPublicExponent(), ':', -1));
ekp.addContent(epk);
if (withPrivateKey) {
if (protectPrivateKey) {
//privkey
if (lockedPrivateKey == null) {
createLockedPrivateKey(mh);
}
if (lockedPrivateKey != null) {
if (lockedPrivateKey.getName().equals("locked")) {
Element el = new Element("locked");
el.addContent("mantraname",lockedPrivateKey.getChildText("mantraname"));
el.addContent("algo",lockedPrivateKey.getChildText("algo"));
el.addContent("initvector", lockedPrivateKey.getChildText("initvector"));
el.addContent("padding",lockedPrivateKey.getChildText("padding"));
el.addContent("bytes",lockedPrivateKey.getChildText("bytes"));
Element eexp = new Element("exponent");
eexp.addContent(el);
Element esk = new Element("privkey");
esk.addContent(eexp);
ekp.addContent(esk);
}
else if (lockedPrivateKey.getName().equals("pgp")) {
Element eexp = new Element("exponent");
eexp.addContent(XMLHelper.cloneElement(lockedPrivateKey));
Element esk = new Element("privkey");
esk.addContent(eexp);
ekp.addContent(esk);
}
} else if (akp.hasPrivateKey()) {
System.out.println("CAUTION: private key NOT saved.");
}// -- end privkey
}
if (!protectPrivateKey) { //BB:: protectPrivateKey can be changed by createLockedPrivateKey(mh)
//save unlocked private key
Element ePrivkey = new Element("privkey");
ePrivkey.addContent("exponent", SecurityHelper.HexDecoder.encode(akp.getPrivateExponent(), ':', -1));
ekp.addContent(ePrivkey);
}
}
ekp.addContent("gpgkeyserverid", gpgkeyserverid);
unsavedChanges = false;
return ekp;
}
public String getValidFromString() {
return SecurityHelper.getFormattedDate(validFrom);
}
public String getValidUntilString() {
return SecurityHelper.getFormattedDate(validUntil);
}
public void setValidFrom(long datetime) {
unsavedChanges = true;
validFrom = datetime;
validFrom = validFrom - validFrom%1000; //no milliseconds in datemeGMT format;
}
public long getValidFrom() {
return validFrom;
}
public long getValidUntil() {
return validUntil;
}
public void setValidUntil(long datetime) {
unsavedChanges = true;
validUntil = datetime;
}
public int getLevel() {
return level;
}
public String getLevelName() {
if (level>=0) {
return level_name.get(level);
}
return "NOT SET";
}
public void setLevel(int level) {
unsavedChanges = true;
this.level = level;
}
public String getUsageName() {
return usage_name.get(usage);
}
public int getUsage() {
return usage;
}
public void setUsage(int u) {
unsavedChanges = true;
usage = u;
}
public Vector<DataSourceStep> getDatapath() {
return datapath;
}
public String getAuthoritativekeyserver() {
return authoritativekeyserver;
}
// public int getAuthoritativekeyserverPort() {
// return authoritativekeyserverPort;
// }
public void addDataSourceStep(DataSourceStep ds) {
unsavedChanges = true;
if (datapath == null) datapath = new Vector<DataSourceStep>();
datapath.add(ds);
}
public void setAuthoritativeKeyServer(String aks) {
authoritativekeyserver = aks;
unsavedChanges = true;
}
public void setUnsavedChanges(boolean b) {
unsavedChanges = b;
}
public boolean hasUnsavedChanges() {
if (unsavedChanges) return true;
return false;
}
public boolean isMaster() {
if (level == LEVEL_MASTER) return true;
else return false;
}
public boolean isRevoke() {
if (level == LEVEL_REVOKE) return true;
else return false;
}
public boolean isSub() {
if (level == LEVEL_SUB) return true;
else return false;
}
public boolean hasPrivateKey() {
return lockedPrivateKey!=null || akp.hasPrivateKey();
}
public String getJavaCodeString() {
try {
OutputStream out = new OutputStream() {
private StringBuilder string = new StringBuilder();
public void write(int b) throws IOException {
this.string.append((char) b );
}
public String toString(){
return string.toString();
}
};
Document.buildDocument(toElement(null)).outputCompact(out);
StringBuffer s = new StringBuffer();
s.append("OSDXKey key = OSDXKey.fromElement(Document.fromString(\"");
s.append(out.toString().replace('\n',' ').replace('\r',' ').replace("\"", "\\\""));
s.append("\").getRootElement());\n");
return s.toString();
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static String getFormattedKeyIDModulusOnly(String id) {
if (id.charAt(4)==':') {//starts with idnum e.g. 0001:
id = id.substring(4);
}
int iat = id.indexOf('@');
if (iat>0) {
return SecurityHelper.HexDecoder.encode(SecurityHelper.HexDecoder.decode(id.substring(0,iat)), ':', -1);
} else {
return SecurityHelper.HexDecoder.encode(SecurityHelper.HexDecoder.decode(id), ':', -1);
}
}
public static String getKeyServerFromKeyID(String id) {
int iat = id.indexOf('@');
if (iat>0) {
return id.substring(iat+1);
} else {
return "";
}
}
public static void main(String[] args) throws Exception {
String l = "2011-02-24 21:21:36 GMT+00:00";
String l2 = "2011-02-24 15:00:00 GMT+01:00";
// System.out.println("1: "+SecurityHelper.datemeGMT.format(new Date()));
// System.out.println("2: "+SecurityHelper.datemeGMT.parse(l));
// System.out.println("3: "+SecurityHelper.datemeGMT.parse(l2));
//
// System.out.println("4: "+SecurityHelper.datemeGMT.format(SecurityHelper.datemeGMT.parse(l)));
// System.out.println("5: "+SecurityHelper.datemeGMT.format(SecurityHelper.datemeGMT.parse(l2)));
//
// long now = System.currentTimeMillis();
// now = now - now%1000;
// System.out.println("6: "+SecurityHelper.datemeGMT.format(now));
// System.out.println("7: "+SecurityHelper.datemeGMT.format(new Date(now)));
//
// 1: 2011-02-24 21:26:51 GMT+00:00
// 2: Thu Feb 24 22:21:36 CET 2011
// 3: Thu Feb 24 15:00:00 CET 2011
// 4: 2011-02-24 21:21:36 GMT+00:00
// 5: 2011-02-24 14:00:00 GMT+00:00
}
}