org.fnppl.opensdx.security.KeyLog.java Source code

Java tutorial

Introduction

Here is the source code for org.fnppl.opensdx.security.KeyLog.java

Source

package org.fnppl.opensdx.security;

import java.io.ByteArrayInputStream;
import java.util.Arrays;
import java.util.Vector;

import javax.print.Doc;

import org.bouncycastle.crypto.digests.SHA256Digest;
import org.fnppl.opensdx.gui.Dialogs;
import org.fnppl.opensdx.security.SecurityHelper.HexDecoder;
import org.fnppl.opensdx.xml.Document;
import org.fnppl.opensdx.xml.Element;
import org.fnppl.opensdx.xml.XMLHelper;

/*
 * 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".
 * 
 */

public class KeyLog {

    private String ipv4 = null;
    private String ipv6 = null;
    private KeyLogAction action;
    private byte[] sha256localproof = null;
    private Signature signature = null;
    private Vector<DataSourceStep> datapath = null;

    private KeyLog() {

    }

    public static KeyLog buildNewKeyLog(KeyLogAction keylogAction, String ip4, String ip6, OSDXKey signingKey)
            throws Exception {
        KeyLog kl = new KeyLog();
        kl.ipv4 = ip4;
        kl.ipv6 = ip6;
        kl.action = keylogAction;
        kl.sha256localproof = kl.calcSha256LocalProof();
        kl.signature = Signature.createSignatureFromLocalProof(kl.sha256localproof,
                "signature of ipv4, ipv6 and signaturebytes", signingKey);
        return kl;
    }

    public Result verify() throws Exception {
        Result v = action.verifySignature();
        if (v.succeeded && signature != null) {
            v = verifyLocalproofAndSignature();
        }
        return v;
    }

    public byte[] calcSha256LocalProof() throws Exception {
        //localproof of ipv4, ipv6, action.signature.signaturesbytes
        byte[] ret = new byte[32]; //256 bit = 32 byte
        SHA256Digest sha256 = new org.bouncycastle.crypto.digests.SHA256Digest();

        byte[] data;
        if (ipv4 != null && ipv4.length() > 0) {
            data = ipv4.getBytes("UTF-8");
            //System.out.println("ipv4: "+ipv4);
            sha256.update(data, 0, data.length);
        }
        if (ipv6 != null && ipv4.length() > 0) {
            data = ipv6.getBytes("UTF-8");
            //System.out.println("ipv6: "+ipv6);
            sha256.update(data, 0, data.length);
        }
        data = action.getSignatureBytes();
        if (data != null) {
            //System.out.println("sigbytes: "+SecurityHelper.HexDecoder.encode(data, '\0', -1));
            sha256.update(data, 0, data.length);
        }
        sha256.doFinal(ret, 0);
        return ret;
    }

    //   public static KeyLog buildNewKeyLog(String action, OSDXKey from, String toKeyID, String ip4, String ip6, Identity id) throws Exception {
    //      KeyLog kl = new KeyLog();
    //      kl.action = action;
    //      kl.datetime = System.currentTimeMillis();
    //      kl.ipv4 = ip4;
    //      kl.ipv6 = ip6;
    //      kl.fromKeyid = from.getKeyID();
    //      kl.toKeyid = toKeyID;
    //      kl.id = id;
    //      kl.datapath = new Vector<DataSourceStep>();
    //      kl.signoffAction(from);
    //      kl.sha256localproof = null;
    //      kl.signature = null;
    //         
    //      return kl;
    //   }
    //   
    //   public static KeyLog buildNewRevocationKeyLog(String fromKeyID, String toKeyID, String message, byte[] actionproof, Signature actionSignature, String ip4, String ip6, OSDXKey serverSignoffKey) throws Exception {
    //      KeyLog kl = new KeyLog();
    //      kl.action = KeyLog.REVOCATION;
    //      kl.datetime = System.currentTimeMillis();
    //      kl.ipv4 = ip4;
    //      kl.ipv6 = ip6;
    //      kl.fromKeyid = fromKeyID;
    //      kl.toKeyid = toKeyID;
    //      kl.id = null;
    //      kl.message = message;
    //      kl.datapath = new Vector<DataSourceStep>();
    //      kl.actionSha256localproof = actionproof;
    //      kl.actionSignature = actionSignature;
    //      kl.signoffKeyServer(serverSignoffKey);
    //      
    //      return kl;
    //   }

    //   public Vector<String[]> getStatusElements() {
    //      Vector<String[]> v = new Vector<String[]>();
    //      if (message!=null) {
    //         v.add(new String[]{"message", message});
    //      }
    //      if (id!=null) {
    //         v.add(new String[]{"identnum", id.getIdentNumString()});
    //         v.add(new String[]{"email", id.getEmail()});
    //         v.add(new String[]{"mnemonic", id.getMnemonic()});
    //         
    //         v.add(new String[]{"country", id.getCountry()});
    //         v.add(new String[]{"region", id.getRegion()});
    //         v.add(new String[]{"city", id.getCity()});
    //         v.add(new String[]{"postcode", id.getPostcode()});
    //         
    //         v.add(new String[]{"company", id.getCompany()});
    //         v.add(new String[]{"unit", id.getUnit()});
    //         v.add(new String[]{"subunit", id.getSubunit()});
    //         v.add(new String[]{"function", id.getFunction()});
    //         
    //         v.add(new String[]{"surname", id.getSurname()});
    //         v.add(new String[]{"middlename", id.getMiddlename()});
    //         v.add(new String[]{"name", id.getFirstNames()});
    //         
    //         v.add(new String[]{"phone", id.getPhone()});
    //         v.add(new String[]{"note", id.getNote()});
    //      }
    //      return v;
    //   }

    private Result verifyLocalproofAndSignature() throws Exception {
        Element report = new Element("signature_verification_report");

        if (signature == null) {
            report.addContent("error", "missing signature");
            return Result.error(report);
        }
        if (sha256localproof == null) {
            report.addContent("error", "missing keyserver localproof");
            return Result.error(report);
        }

        //check localproof
        byte[] bsha256 = calcSha256LocalProof();
        if (!Arrays.equals(bsha256, sha256localproof)) {
            System.out.println("sha256localproof given      : "
                    + SecurityHelper.HexDecoder.encode(sha256localproof, '\0', -1));
            System.out.println(
                    "sha256localproof calculated : " + SecurityHelper.HexDecoder.encode(bsha256, '\0', -1));
            report.addContent("error", "verification of sha256localproof failed");
            return Result.error(report);
        }
        //check signoff
        Result r = signature.tryVerificationMD5SHA1SHA256(bsha256);
        if (r.report != null) {
            //copy report content
            for (Element e : r.report.getChildren()) {
                report.addContent(XMLHelper.cloneElement(e));
            }
        } else {
            throw new RuntimeException("signature verification DID NOT return a report!");
        }
        if (r.succeeded) {
            return Result.succeeded(report);
        } else {
            return Result.error(report);
        }
    }

    //   private void updateSha1(String field, org.bouncycastle.crypto.digests.SHA1Digest sha1) throws Exception {
    //      if (field==null || field.length()==0) return;
    //      byte[] k = field.getBytes("UTF-8");
    //      if (k.length>0) {
    //         sha1.update(k, 0, k.length);
    //         //System.out.println("update: "+field);//+"::"+SecurityHelper.HexDecoder.encode(k, ':', -1));
    //      }
    //   }

    public static KeyLog fromElement(Element e) throws Exception {
        return fromElement(e, true);
    }

    private static KeyLog fromElement(Element e, boolean tryVerification) throws Exception {
        //Document.buildDocument(e).output(System.out);
        KeyLog kl = new KeyLog();
        kl.action = KeyLogAction.fromElement(e.getChild("keylogaction"));

        if (e.getName().equals("keylog")) {
            //full keylog
            kl.ipv4 = e.getChildText("ipv4");
            kl.ipv6 = e.getChildText("ipv6");
            String sSha256 = e.getChildText("sha256localproof");
            if (sSha256 != null && sSha256.length() > 0) {
                kl.sha256localproof = SecurityHelper.HexDecoder.decode(sSha256);
                kl.signature = Signature.fromElement(e.getChild("signature"));
                //System.out.println("NO SIGNATURE FOUND");
            }
            //System.out.println(sDate+" -> datetime::"+kl.datetime);
        } else {
            throw new RuntimeException("wrong keyname");
        }

        //build datapath
        kl.datapath = new Vector<DataSourceStep>();
        Element dp = e.getChild("datapath");
        if (dp != null) {
            Vector<Element> steps = dp.getChildren();
            for (Element st : steps)
                if (st.getName().startsWith("step")) {
                    DataSourceStep dst = DataSourceStep.fromElemet(st);
                    kl.datapath.add(dst);
                }
        }

        if (tryVerification) {
            Result v = kl.verify();
            //Document.buildDocument(kl.toElement(true)).output(System.out);
            if (!v.succeeded) {
                if (v.errorMessage != null) {
                    System.out.println(v.errorMessage);
                }
                if (v.report != null) {
                    Document.buildDocument(v.report).output(System.out);
                }
                throw new Exception("KeyLog:  verification of localproof and signature failed.");
            }
        }
        return kl;
    }

    public String getActionElementString() {
        Element e = action.getActionElement(true);
        return Document.buildDocument(e).toStringCompact();
    }

    public Element toElement(boolean showRestricted) {
        Element e = new Element("keylog");
        e.addContent("ipv4", ipv4);
        e.addContent("ipv6", ipv6);
        e.addContent(action.toElement(showRestricted));
        if (sha256localproof != null) {
            e.addContent("sha256localproof", SecurityHelper.HexDecoder.encode(sha256localproof, ':', -1));
            if (signature != null) {
                e.addContent(signature.toElement());
            }
        }
        Element edp = new Element("datapath");
        if (datapath != null) {
            for (int i = 0; i < datapath.size(); i++) {
                edp.addContent(datapath.get(i).toElement(i));
            }
        }
        e.addContent(edp);

        //Document doc = Document.buildDocument(e);
        //doc.output(System.out);

        return e;
    }

    //   private Vector<Element> getFullKeyLogElementsWithoutLocalProofAndDataPath() {
    //      Vector<Element> ea = new Vector<Element>();
    //      ea.add(new Element("date", getDateString()));
    //      ea.add(new Element("ipv4", ipv4));
    //      ea.add(new Element("ipv6", ipv6));
    //      ea.add(toKeyLogActionElement());
    //      return ea;
    //   }
    //   
    //   private Vector<Element> getKeyLogActionElementsWithoutLocalProof() {
    //      Vector<Element> ea = new Vector<Element>();
    //      ea.add(new Element("from_keyid",fromKeyid));
    //      ea.add(new Element("to_keyid",toKeyid));
    //      Element eAction = new Element(action);
    //      if (message!=null) {
    //         eAction.addContent("message",message);
    //      }
    //      if (id!=null) {
    //         for (Element eIDContent : id.getContentElements(true)) {
    //            eAction.addContent(eIDContent);
    //         }
    //      }
    //      ea.add(eAction);
    //      return ea;
    //   }

    public long getSignDatetime() {
        return signature.getSignDatetime();
    }

    public long getActionDatetime() {
        return action.getSignDatetime();
    }

    public String getActionDatetimeString() {
        return SecurityHelper.getFormattedDate(action.getSignDatetime());
    }

    public String getKeyIDFrom() {
        return action.getKeyIDFrom();
    }

    public String getKeyIDTo() {
        return action.getKeyIDTo();
    }

    public String getIPv4() {
        return ipv4;
    }

    public String getIPv6() {
        return ipv6;
    }

    public String getAction() {
        return action.getAction();
    }

    public byte[] getActionSha256ProofComplete() {
        return action.getSha256localproof_complete();
    }

    public byte[] getActionSha256ProofRestricted() {
        return action.getSha256localproof_restricted();
    }

    public Signature getActionSignature() {
        return action.getSignature();
    }

    public Signature getSignature() {
        return signature;
    }

    public byte[] getSHA256LocalProof() {
        return sha256localproof;
    }

    public void addDataPath(DataSourceStep step) {
        datapath.add(step);
    }

    public Vector<DataSourceStep> getDataPath() {
        return datapath;
    }

    public Identity getIdentity() {
        return action.getIdentity();
    }

    public String getMessage() {
        return action.getMessage();
    }

    public OSDXKey getActionSignatureKey() {
        return action.getSignatureKey();
    }

    public boolean hasRestrictedFields() {
        return action.hasRestrictedFields();
    }

}
//<keylog>
//   <date>2011-04-28 13:54:14 GMT+00:00</date>
//   <ipv4>127.0.0.1</ipv4>
//   <ipv6>127.0.0.1</ipv6>
//   <keylogaction>
//     <from_keyid>55:32:7D:CD:4E:37:D1:88:EB:02:B9:B9:5A:9F:8A:CF:45:2D:44:D3@localhost</from_keyid>
//     <to_keyid>D9:1C:42:50:94:E3:BF:B1:2E:86:91:07:D8:54:95:CB:C5:8F:07:71@localhost</to_keyid>
//     <approval>
//          <identity>
//               <identnum>0001</identnum>
//            <email>debug_key_0@it-is-awesome.de</email>
//            <sha1>BC:3A:6D:C7:F5:69:E1:39:A6:BC:6B:A5:96:A6:08:F7:E0:6F:3F:32</sha1>
//          </identity>
//     </approval>
//     <sha1localproof>DB:B5:D0:B4:00:26:07:83:21:1E:3A:B9:DD:E4:DA:84:4A:20:C4:61</sha1localproof>
//     <signature>
//         [of from_key] 
//       </signature>
//   </keylogaction>
//   <sha1localproof>A2:C4:B6:96:5B:19:C6:99:D5:FD:05:72:5D:DB:B6:00:02:E0:42:AB</sha1localproof>
//   <signature>
//     [of keyserver]   
//   </signature>
//   <datapath />
//</keylog>