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.BufferedReader; import java.io.File; import java.io.InputStreamReader; import java.net.URL; import java.sql.SQLException; import java.sql.Statement; import java.util.Arrays; import java.util.Vector; import org.fnppl.opensdx.gui.Dialogs; import org.fnppl.opensdx.keyserver.PostgresBackend; import org.fnppl.opensdx.pdf.PDFUtil; import org.fnppl.opensdx.xml.Element; import com.sun.corba.se.impl.transport.ReadTCPTimeoutsImpl; import com.sun.org.apache.bcel.internal.generic.GETSTATIC; public class ReportGenerator { public static void buildFileSignatureVerificationReport(Element report, File outputPDF) { URL html_template = ReportGenerator.class.getResource("resources/file_verification_report_DE.html"); try { String text = readTemplate(html_template); //structue of report: //preSig //for all signatures : sig { // preID // for all identity fields : id field { // idTemplate // } // postID // keylogsTemplatePre // for all keylogs : kl { // for all identity fields : id field { // keylogTemplate // } // } // keylogsTemplatePost //} //postSig int sigStart = text.indexOf("<!-- signature start -->"); int sigEnd = text.indexOf("<!-- signature end -->"); String preSig = text.substring(0,sigStart); String postSig = text.substring(sigEnd); String sigTemplate = text.substring(sigStart,sigEnd); int idStart = sigTemplate.indexOf("<!-- identity field start -->"); int idEnd = sigTemplate.indexOf("<!-- identity field end -->"); String preID = sigTemplate.substring(0,idStart); String idTemplate = sigTemplate.substring(idStart, idEnd); String postID = sigTemplate.substring(idEnd); int keylogsStart = postID.indexOf("<!-- keylog fields start -->"); int keylogsEnd = postID.indexOf("<!-- keylog fields end -->"); int keylogStart = postID.indexOf("<!-- keylog field start -->"); int keylogEnd = postID.indexOf("<!-- keylog field end -->"); String keylogsTemplatePre = postID.substring(keylogsStart, keylogStart); String keylogTemplate = postID.substring(keylogStart, keylogEnd); String keylogsTemplatePost = postID.substring(keylogsEnd); preSig = preSig.replace("[check_datetime]", report.getChildTextNN("check_datetime")); preSig = preSig.replace("[orig_filename]", report.getChildTextNN("signed_filename")); preSig = preSig.replace("[signature_filename]", report.getChildTextNN("signature_filename")); preSig = preSig.replace("[orig_md5]", report.getChildTextNN("md5")); preSig = preSig.replace("[orig_sha1]", report.getChildTextNN("sha1")); preSig = preSig.replace("[orig_sha256]", report.getChildTextNN("sha256")); StringBuffer tb = new StringBuffer(); tb.append(preSig+"\n"); Vector<Element> sigs = report.getChildren("signature_verification_report"); for (Element es : sigs) { String sig = ""+preID; String keyid = es.getChildTextNN("keyid"); sig = sig.replace("[sig_datetime]", es.getChildTextNN("signature_datetime")); sig = sig.replace("[sig_keyid]", keyid); sig = sig.replace("[sig_key_valid_from]", es.getChildTextNN("key_valid_from")); sig = sig.replace("[sig_key_valid_until]", es.getChildTextNN("key_valid_until")); sig = sig.replace("[sig_keyserver]", keyid.substring(keyid.indexOf('@')+1)); tb.append(sig); Element eID = es.getChild("identity"); if (eID!=null) { Vector<Element> eIDparts = eID.getChildren(); for (Element ep : eIDparts) { String name = ep.getName(); if (!name.equals("photo") && !name.equals("sha256")) { String part = idTemplate.replace("[id_name]", name); part = part.replace("[id_value]", ep.getText()); tb.append(part); } } } String sigAppend = ""+keylogsTemplatePost; Element eKeylogs = es.getChild("keylogs_report"); if (eKeylogs!=null) { Vector<Element> ekls = eKeylogs.getChildren("keylog_entry"); if (ekls!=null && ekls.size()>0) { StringBuffer klTemp = new StringBuffer(); klTemp.append(keylogsTemplatePre); for (Element ec : ekls) { String keyid_from = ec.getChildTextNN("keyid_from"); String action = ec.getChildTextNN("action"); String email = ec.getChildTextNN("email"); String date = ec.getChildTextNN("date"); String tmp = keylogTemplate.replace("[keylog_action]", action); tmp = tmp.replace("[keylog_date]", date); tmp = tmp.replace("[keylog_id_from]", keyid_from); tmp = tmp.replace("[keylog_email]", email); klTemp.append(tmp); } klTemp.append(keylogsTemplatePost); sigAppend = klTemp.toString(); } } Vector<Element> checks = es.getChildren("check"); boolean md5ok = false, sha1ok = false, sha256ok = false; for (Element ec : checks) { String msg = ec.getChildTextNN("message"); String value = ec.getChildTextNN("result"); if (msg.equals("md5 hash matches")) { if (value.equals("OK")) { md5ok = true; } } else if (msg.equals("sha1 hash matches")) { if (value.equals("OK")) { sha1ok = true; } } else if (msg.equals("sha256 hash matches")) { if (value.equals("OK")) { sha256ok = true; } } else if (msg.equals("key id matches sha1 of modulus")) { sigAppend = sigAppend.replace("[check_keyid]", getStatusMsg(value)); } else if (msg.equals("key valid at signature datetime")) { sigAppend = sigAppend.replace("[check_valid]", getStatusMsg(value)); } else if (msg.equals("signature bytes sign hashes and datetime")) { sigAppend = sigAppend.replace("[check_sig_bytes]", getStatusMsg(value)); } else if (msg.equals("key allows signing")) { sigAppend = sigAppend.replace("[check_can_sign]", getStatusMsg(value)); } } if (md5ok && sha1ok && sha256ok) { sigAppend = sigAppend.replace("[check_hash]", getStatusMsg("OK")); } else { sigAppend = sigAppend.replace("[check_hash]", getStatusMsg("FAILED")); } //key data match key data on keyserver String keyMatch = sUNKNOWN; Element eKeyMatch = es.getChild("key_data_match_report"); if (eKeyMatch!=null) { checks = eKeyMatch.getChildren("check"); for (Element ec : checks) { String msg = ec.getChildTextNN("message"); String value = ec.getChildTextNN("result"); if (msg.equals("key data matches key data on keyserver")) { keyMatch = getStatusMsg(value); } } } sigAppend = sigAppend.replace("[check_key_keyserver]", keyMatch); //key verificator report and keylogs Element eVerify = es.getChild("key_verification_report"); if (eVerify!=null) { checks = eVerify.getChildren("check"); for (Element ec : checks) { String msg = ec.getChildTextNN("message"); String value = ec.getChildTextNN("result"); if (msg.equals("")) { } else if (msg.equals("key is directly trusted")) { sigAppend = sigAppend.replace("[check_direct_trust]", getStatusMsg(value)); } } Element ekt = es.getChild("key_trustings_report"); String appByDirTrustedKey = sUNKNOWN; if (ekt!=null) { checks = es.getChildren("check"); for (Element ec : checks) { String msg = ec.getChildTextNN("message"); String value = ec.getChildTextNN("result"); if (msg.equals("key is approved by a directly trusted key")) { appByDirTrustedKey = getStatusMsg(value); } } } sigAppend = sigAppend.replace("[check_approved_by_directly_trusted_key]",appByDirTrustedKey); } else { sigAppend = sigAppend.replace("[check_direct_trust]", getStatusMsg(sUNKNOWN)); } tb.append(sigAppend); tb.append("\n"); } tb.append(postSig); //Dialogs.showText("html", tb.toString()); PDFUtil.fromHTMLtoPDF(tb.toString(), outputPDF); } catch (Exception ex) { ex.printStackTrace(); } } private static String sOK = "OK"; private static String sFAILED = "NEIN"; private static String sUNKNOWN = "?"; private static String getStatusMsg(String value) { if (value.equals("OK")) { return sOK; } else if (value.equals("FAILED")) { return sFAILED; } else { return sUNKNOWN; } } private static String readTemplate(URL html_template) { try { BufferedReader in = new BufferedReader(new InputStreamReader(html_template.openStream())); StringBuffer textBuffer = new StringBuffer(); String line = null; while ((line = in.readLine())!=null) { textBuffer.append(line+"\n"); } String text = textBuffer.toString(); return text; } catch (Exception ex) { ex.printStackTrace(); } return null; } }