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.security.SecureRandom;
import java.security.Security;
import java.text.SimpleDateFormat;
import java.io.*;
import java.util.*;
import org.bouncycastle.crypto.digests.SHA1Digest;
import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.fnppl.opensdx.xml.Element;
import com.sun.xml.internal.ws.util.ByteArrayBuffer;
/*
* @author Henning Thieß <ht@fnppl.org>
* @author Bertram Boedeker <bboedeker@gmx.de>
*/
public class SecurityHelper {
final static String RFC1123 = "EEE, dd MMM yyyy HH:mm:ss zzz";
final static String RFC1123_CUT = "yyyy-MM-dd HH:mm:ss zzz";
final static String RFC1036 = "EEEE, dd-MMM-yy HH:mm:ss zzz";
final static String ASCTIME = "EEE MMM dd HH:mm:ss yyyy zzz";
final static Locale ml = new Locale("en", "DE");
private final static SimpleDateFormat datemeGMT = new SimpleDateFormat(RFC1123_CUT, ml);
private final static SimpleDateFormat dayGMT = new SimpleDateFormat("yyyy-MM-dd", ml);
static {
datemeGMT.setTimeZone(java.util.TimeZone.getTimeZone("GMT+00:00"));
dayGMT.setTimeZone(java.util.TimeZone.getTimeZone("GMT+00:00"));
}
public static String getFormattedDateDay(long date) {
String s = dayGMT.format(new Date(date));
return s;
}
public static long parseDateDay(String date) throws Exception {
return dayGMT.parse(date).getTime();
}
public static String getFormattedDate(long date) {
String s = datemeGMT.format(new Date(date));
return s;
}
public static long parseDate(String date) throws Exception {
//return 50923486509234860L;
if (!date.toLowerCase().contains(" gmt")) {
date += " GMT+00:00";
}
return datemeGMT.parse(date).getTime();
}
public static void ensureBC() {
if(Security.getProvider("BC")==null) {
Security.addProvider(new BouncyCastleProvider());
}
}
public static void sortKeyLogsbyDate(Vector<KeyLog> keylogs) {
Collections.sort(keylogs, new Comparator<KeyLog>() {
public int compare(KeyLog kl1, KeyLog kl2) {
try {
return (int)(kl1.getActionDatetime()-kl2.getActionDatetime());
} catch (Exception ex) {
ex.printStackTrace();
}
return 0;
}
});
}
public final static class HexDecoder {
/**
* Initial size of the decoding table.
*/
private static final int DECODING_TABLE_SIZE = 128;
/**
* Encoding table.
*/
protected static final byte[] ENCODING_TABLE = {
(byte) '0', (byte) '1', (byte) '2', (byte) '3',
(byte) '4', (byte) '5', (byte) '6', (byte) '7',
(byte) '8', (byte) '9', (byte) 'A', (byte) 'B',
(byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F'
};
/**
* Decoding table.
*/
protected static final byte[] DECODING_TABLE = new byte[DECODING_TABLE_SIZE];
/**
* Initialize the decoding table.
*/
protected static void initialiseDecodingTable() {
for (int i = 0; i < ENCODING_TABLE.length; i++) {
DECODING_TABLE[ENCODING_TABLE[i]] = (byte) i;
}
// deal with lower case letters as well
DECODING_TABLE['a'] = DECODING_TABLE['A'];
DECODING_TABLE['b'] = DECODING_TABLE['B'];
DECODING_TABLE['c'] = DECODING_TABLE['C'];
DECODING_TABLE['d'] = DECODING_TABLE['D'];
DECODING_TABLE['e'] = DECODING_TABLE['E'];
DECODING_TABLE['f'] = DECODING_TABLE['F'];
}
static {
initialiseDecodingTable();
}
/**
* Creates an instance of this class.
*/
private HexDecoder() {
// Nothing to do ...
}
/**
* Encodes the input data producing a Hex output stream.
* @param data The input data to be HEX encoded
* @param off Initial offset
* @param length Initial length of the input data array
* @param out The {@link OutputStream} instance holding the encoded input data.
* @return the number of bytes produced.
* @throws IOException If encoding fails.
*/
public static void encode(final byte[] data, final int off, final int length,
final OutputStream out, char pad, int wrapat) throws IOException {
for (int i = off; i < (off + length); i++) {
int v = data[i] & 0xff;
if(wrapat!=-1 && i>0 && i%wrapat==0) {
out.write('\n');
}
out.write(ENCODING_TABLE[(v >>> 4)]);
out.write(ENCODING_TABLE[v & 0xf]);
if(pad != '\0' && i < (off + length)-1) {
out.write(pad);
}
}
// return length * 2;
}
/**
* Indicates whether a given character should be ignored during en-/decoding.
* @param c The character at question.
* @return True if the given character should be ignored.
*/
private static boolean ignore(final char c) {
return (c == '\n' || c == '\r' || c == ':' || c == '\t' || c == ' ');
}
/**
* Decodes the Hex encoded byte data writing it to the given output stream,
* whitespace characters will be ignored.
* @param data The data to be encoded
* @param off Initial offset.
* @param length Initial length
* @param out The {@link OutputStream} instance
* @return the number of bytes produced.
* @throws IOException If encoding failed.
*/
public static int decode(final byte[] data, final int off, final int length,
final OutputStream out) throws IOException {
byte b1, b2;
int outLen = 0;
int end = off + length;
while (end > off) {
if (!ignore((char) data[end - 1])) {
break;
}
end--;
}
int i = off;
while (i < end) {
while (i < end && ignore((char) data[i])) {
i++;
}
b1 = DECODING_TABLE[data[i++]];
while (i < end && ignore((char) data[i])) {
i++;
}
b2 = DECODING_TABLE[data[i++]];
out.write((b1 << 4) | b2);
outLen++;
}
return outLen;
}
/**
* Decodes the Hex encoded String data writing it to the given output stream,
* whitespace characters will be ignored.
*
* @param data The data to be encoded
* @param out The {@link OutputStream} instance
* @return the number of bytes produced.
* @throws IOException If encoding failed.
*/
public static int decode(final String data, final OutputStream out) throws IOException {
byte b1, b2;
int length = 0;
int end = data.length();
while (end > 0) {
if (!ignore(data.charAt(end - 1))) {
break;
}
end--;
}
int i = 0;
while (i < end) {
while (i < end && ignore(data.charAt(i))) {
i++;
}
b1 = DECODING_TABLE[data.charAt(i++)];
while (i < end && ignore(data.charAt(i))) {
i++;
}
b2 = DECODING_TABLE[data.charAt(i++)];
out.write((b1 << 4) | b2);
length++;
}
return length;
}
public static String encode(final byte[] data) {
return encode(data,':',-1);
}
/**
* Encodes the input data producing a Hex output stream.
* @param data Input data to encode.
* @return the number of bytes produced.
*/
public static String encode(final byte[] data, char pad, int wrapat) {
if(data == null) {
return null;
}
try {
final ByteArrayOutputStream out = new ByteArrayOutputStream();
encode(data, 0, data.length, out, pad, wrapat);
out.close();
return new String(out.toByteArray());
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage(), e);
}
}
public static String encode(final byte[] data, int offs, int length, char pad, int wrapat) {
if(data == null) {
return null;
}
try {
final ByteArrayOutputStream out = new ByteArrayOutputStream();
encode(data, offs, length, out, pad, wrapat);
out.close();
return new String(out.toByteArray());
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage(), e);
}
}
/**
* Decodes the HEX input data producing a output stream.
* @param data Input data to be decoded.
* @return A byte array representing the decoded input data.
*/
public static byte[] decode(final String data) {
if(data == null) {
return null;
}
try {
final ByteArrayOutputStream out = new ByteArrayOutputStream();
if(data.toLowerCase().indexOf("0x")==0) {
decode(data.substring(2), out);
}
else {
decode(data, out);
}
out.close();
return out.toByteArray();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage(), e);
}
}
}
// public static byte[] getSHA1MD5(byte[] data) {
// byte[] ret = new byte[20 + 16]; //160 bit = 20 byte + md5 128bit = 16
// org.bouncycastle.crypto.digests.SHA1Digest sha1 = new org.bouncycastle.crypto.digests.SHA1Digest();
// sha1.update(data, 0,data.length);
// sha1.doFinal(ret, 0);
//
// org.bouncycastle.crypto.digests.MD5Digest md5 = new org.bouncycastle.crypto.digests.MD5Digest();
// md5.update(data, 0, data.length);
// md5.doFinal(ret, 20);
//
// return ret;
// }
public static byte[][] getMD5SHA1SHA256(byte[] data) {
byte[] ret = new byte[16 + 20 + 32]; //160 bit = 20 byte + md5 128bit = 16 + sha256 256bit = 32 byte
byte[] md5ret = new byte[16];
byte[] sha1ret = new byte[20];
byte[] sha256ret = new byte[32];
org.bouncycastle.crypto.digests.MD5Digest md5 = new org.bouncycastle.crypto.digests.MD5Digest();
md5.update(data, 0, data.length);
md5.doFinal(ret, 0);
org.bouncycastle.crypto.digests.SHA1Digest sha1 = new org.bouncycastle.crypto.digests.SHA1Digest();
sha1.update(data, 0,data.length);
sha1.doFinal(ret, 16);
org.bouncycastle.crypto.digests.SHA256Digest sha256 = new org.bouncycastle.crypto.digests.SHA256Digest();
sha256.update(data, 0,data.length);
sha256.doFinal(ret, 16+20);
System.arraycopy(ret, 0, md5ret, 0, md5ret.length);
System.arraycopy(ret, 16, sha1ret, 0, sha1ret.length);
System.arraycopy(ret, 16+20, sha256ret, 0, sha256ret.length);
return new byte[][]{
ret,
md5ret,
sha1ret,
sha256ret
};
}
public static byte[][] getMD5SHA1SHA256(File f) throws Exception {
FileInputStream fin_ = new FileInputStream(f);
BufferedInputStream fin = new BufferedInputStream(fin_);
byte[][] ret = getMD5SHA1SHA256(fin);
fin.close();
return ret;
}
public static byte[] getMD5(File f) throws Exception {
FileInputStream fin_ = new FileInputStream(f);
BufferedInputStream fin = new BufferedInputStream(fin_);
byte[] ret = getMD5(fin);
fin.close();
return ret;
}
public static byte[][] getMD5SHA1(File f) throws Exception {
FileInputStream fin_ = new FileInputStream(f);
BufferedInputStream fin = new BufferedInputStream(fin_);
byte[][] ret = getMD5SHA1(fin);
fin.close();
return ret;
}
public static byte[][] getMD5SHA1(InputStream fin) throws Exception {
byte[] md5ret = new byte[16];
byte[] sha1ret = new byte[20];
org.bouncycastle.crypto.digests.MD5Digest md5 = new org.bouncycastle.crypto.digests.MD5Digest();
org.bouncycastle.crypto.digests.SHA1Digest sha1 = new org.bouncycastle.crypto.digests.SHA1Digest();
int read = -1;
byte[] buff = new byte[4096];
while((read=fin.read(buff))!=-1) {
md5.update(buff, 0, read);
sha1.update(buff, 0, read);
}
sha1.doFinal(sha1ret, 0);
md5.doFinal(md5ret, 0);
return new byte[][]{
md5ret,
sha1ret,
};
}
public static byte[][] getMD5SHA1SHA256(InputStream fin) throws Exception {
byte[] ret = new byte[16 + 20 + 32]; //160 bit = 20 byte + md5 128bit = 16 + sha256 256bit = 32 byte
byte[] md5ret = new byte[16];
byte[] sha1ret = new byte[20];
byte[] sha256ret = new byte[32];
org.bouncycastle.crypto.digests.MD5Digest md5 = new org.bouncycastle.crypto.digests.MD5Digest();
org.bouncycastle.crypto.digests.SHA1Digest sha1 = new org.bouncycastle.crypto.digests.SHA1Digest();
org.bouncycastle.crypto.digests.SHA256Digest sha256 = new org.bouncycastle.crypto.digests.SHA256Digest();
int read = -1;
byte[] buff = new byte[4096];
while((read=fin.read(buff))!=-1) {
md5.update(buff, 0, read);
sha1.update(buff, 0, read);
sha256.update(buff, 0, read);
}
sha1.doFinal(ret, 16);
md5.doFinal(ret, 0);
sha256.doFinal(ret, 16+20);
System.arraycopy(ret, 0, md5ret, 0, md5ret.length);
System.arraycopy(ret, 16, sha1ret, 0, sha1ret.length);
System.arraycopy(ret, 16+20, sha256ret, 0, sha256ret.length);
return new byte[][]{
ret,
md5ret,
sha1ret,
sha256ret
};
}
// public static byte[] getSHA1MD5(InputStream in) throws Exception {
// byte[] ret = new byte[20 + 16];//160 bit = 20 byte + 128bit = 16 byte
//
// org.bouncycastle.crypto.digests.MD5Digest md5 = new org.bouncycastle.crypto.digests.MD5Digest();
// org.bouncycastle.crypto.digests.SHA1Digest sha1 = new org.bouncycastle.crypto.digests.SHA1Digest();
//
// int read = -1;
// byte[] buff = new byte[1024];
// while((read=in.read(buff))!=-1) {
// sha1.update(buff, 0, read);
// md5.update(buff, 0, read);
// }
//
// sha1.doFinal(ret, 0);
// md5.doFinal(ret, 20);
//
// return ret;
// }
// public static byte[] getSHA256MD5(InputStream in) {
//
// byte[] ret = new byte[48]; ////256 bit = 32 byte + 128bit = 16 byte
// org.bouncycastle.crypto.digests.MD5Digest md5 = new org.bouncycastle.crypto.digests.MD5Digest();
// org.bouncycastle.crypto.digests.SHA256Digest sha256 = new org.bouncycastle.crypto.digests.SHA256Digest();
// int l = 0;
// byte[] buffer = new byte[512];
// try {
// while ((l=in.read(buffer))>0) {
// md5.update(buffer, 0, l);
// sha256.update(buffer, 0, l);
// }
// sha256.doFinal(ret, 0);
// md5.doFinal(ret, 32);
// return ret;
// } catch (IOException e) {
// e.printStackTrace();
// }
// return null;
// }
public static byte[] getSHA1(byte[] data) {
byte[] ret = new byte[20]; //160 bit = 20 byte
org.bouncycastle.crypto.digests.SHA1Digest sha1 = new org.bouncycastle.crypto.digests.SHA1Digest();
sha1.update(data,0,data.length);
sha1.doFinal(ret, 0);
return ret;
}
public static byte[] getSHA1(InputStream in) throws Exception {
byte[] ret = new byte[20];//160 bit = 20 byte
org.bouncycastle.crypto.digests.SHA1Digest sha1 = new org.bouncycastle.crypto.digests.SHA1Digest();
int read = -1;
byte[] buff = new byte[1024];
while((read=in.read(buff))!=-1) {
sha1.update(buff, 0, read);
}
sha1.doFinal(ret, 0);
return ret;
}
public static byte[] getSHA1LocalProof(Element e) throws Exception {
Vector<Element> ve = new Vector<Element>();
ve.add(e);
return getSHA1LocalProof(ve);
}
public static byte[] getSHA1LocalProof(Vector<Element> ve) throws Exception {
byte[] ret = new byte[20];//160 bit = 20 byte
SHA1Digest sha1 = new SHA1Digest();
//System.out.println("--- sha1localproof ---");
for (Element e : ve) {
rekursiveUpdateSHA1(sha1, e);
}
sha1.doFinal(ret, 0);
//System.out.println("--- RESULT ----");
//System.out.println(SecurityHelper.HexDecoder.encode(ret, ':',-1));
return ret;
}
private static void rekursiveUpdateSHA1(SHA1Digest sha1, Element e) {
Vector<Element> ve = e.getChildren();
if (ve.size()>0) {
for (Element el : ve) {
rekursiveUpdateSHA1(sha1, el);
}
} else {
String name = e.getName();
Vector<String[]> attributes = e.getAttributes();
String text = e.getText();
if (name!=null && name.length()>0) {
updateSha1(sha1, name);
}
if (attributes!=null) {
for (String[] att : attributes) {
for (int i=0;i<att.length;i++) {
updateSha1(sha1,att[i]);
}
}
}
if (text!=null && text.length()>0) {
updateSha1(sha1,text);
}
}
}
public static byte[] getSHA256LocalProof(Element e) throws Exception {
Vector<Element> ve = new Vector<Element>();
ve.add(e);
return getSHA256LocalProof(ve);
}
public static byte[] getSHA256LocalProof(Vector<Element> ve) throws Exception {
byte[] ret = new byte[32];//256 bit = 32 byte
SHA256Digest sha256 = new SHA256Digest();
//System.out.println("--- sha1localproof ---");
for (Element e : ve) {
rekursiveUpdateSHA256(sha256, e);
}
sha256.doFinal(ret, 0);
//System.out.println("--- RESULT ----");
//System.out.println(SecurityHelper.HexDecoder.encode(ret, ':',-1));
return ret;
}
private static void rekursiveUpdateSHA256(SHA256Digest sha256, Element e) {
Vector<Element> ve = e.getChildren();
if (ve.size()>0) {
for (Element el : ve) {
rekursiveUpdateSHA256(sha256, el);
}
} else {
String name = e.getName();
Vector<String[]> attributes = e.getAttributes();
String text = e.getText();
if (name!=null && name.length()>0) {
updateSha256(sha256, name);
}
if (attributes!=null) {
for (String[] att : attributes) {
for (int i=0;i<att.length;i++) {
updateSha256(sha256,att[i]);
}
}
}
if (text!=null && text.length()>0) {
updateSha256(sha256,text);
}
}
}
private static void updateSha1(SHA1Digest sha1, String s) {
try {
byte[] b = s.getBytes("UTF-8");
sha1.update(b, 0, b.length);
//System.out.println("update sha1: "+s);
} catch (Exception ex) {
ex.printStackTrace();
}
}
private static void updateSha256(SHA256Digest sha256, String s) {
try {
byte[] b = s.getBytes("UTF-8");
//System.out.println("sha256::"+s);
sha256.update(b, 0, b.length);
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static byte[] getSHA256(byte[] data) {
byte[] ret = new byte[32]; //256 bit = 32 byte
org.bouncycastle.crypto.digests.SHA256Digest sha256 = new org.bouncycastle.crypto.digests.SHA256Digest();
sha256.update(data, 0, data.length);
sha256.doFinal(ret, 0);
return ret;
}
// public static byte[] getSHA256(InputStream in) {
// org.bouncycastle.crypto.digests.SHA256Digest sha256 = new org.bouncycastle.crypto.digests.SHA256Digest();
// int l = 0;
// byte[] buffer = new byte[512];
// try {
// while ((l=in.read(buffer))>0) {
// sha256.update(buffer, 0, l);
// }
// byte[] ret = new byte[32]; //256 bit = 32 byte
// sha256.doFinal(ret, 0);
// return ret;
// } catch (IOException e) {
// e.printStackTrace();
// }
// return null;
// }
public static byte[] getMD5(byte[] data) {
return getMD5(data, 0, data.length);
}
public static byte[] getMD5(byte[] data, int off, int len) {
org.bouncycastle.crypto.digests.MD5Digest md5 = new org.bouncycastle.crypto.digests.MD5Digest();
byte[] ret = new byte[md5.getDigestSize()];
md5.update(data, off, len);
md5.doFinal(ret, 0);
return ret;
}
public static byte[] getMD5(InputStream in) {
org.bouncycastle.crypto.digests.MD5Digest md5 = new org.bouncycastle.crypto.digests.MD5Digest();
int l = 0;
byte[] buffer = new byte[512];
try {
while ((l=in.read(buffer))>0) {
md5.update(buffer, 0, l);
}
byte[] ret = new byte[md5.getDigestSize()];
md5.doFinal(ret, 0);
return ret;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static byte[] concat(byte[] a, byte[] b) {
byte[] c = new byte[a.length+b.length];
System.arraycopy(a, 0, c, 0, a.length);
System.arraycopy(b, 0, c, a.length, b.length);
return c;
}
public static byte[] getRandomBytes(int bytecount) {
SecureRandom sc = new SecureRandom();//TODO HT 20.02.2011 - quite good, but should swirl it twice with tiger, or aes/rijndael itself
byte[] rb = new byte[bytecount];
sc.nextBytes(rb);
return rb;
}
public static void signoffElement(Element e, OSDXKey signoffkey) throws Exception {
//signoff
byte[] sha1proof = SecurityHelper.getSHA1LocalProof(e);
e.addContent("sha1localproof", SecurityHelper.HexDecoder.encode(sha1proof, ':', -1));
e.addContent(Signature.createSignatureFromLocalProof(sha1proof, "signature of sha1localproof", signoffkey).toElement());
}
// public static boolean checkElementsSHA1localproofAndSignature(Element e, Vector<OSDXKey> trustedKeys) throws Exception {
// OSDXKey signingKey = null;
// byte[] modulus = SecurityHelper.HexDecoder.decode(e.getChild("signature").getChild("pubkey").getChildText("modulus"));
// for (OSDXKey k: trustedKeys) {
// if (Arrays.equals(k.getPubKey().getModulusBytes(), modulus)) {
// signingKey = k;
// break;
// }
// }
// if (signingKey !=null) {
// return SecurityHelper.checkElementsSHA1localproofAndSignature(e, signingKey);
// } else {
// //TODO if (signingKey == null) try to find approved signing key on server
// throw new RuntimeException("signing key NOT in trusted keys: keyid: "+e.getChild("signature").getChildText("keyid"));
// }
// }
// public static boolean checkSHA1localproofAndSignature(Vector<Element> toProof, byte[] givenSha1localproof, Signature signature, PublicKey signingKey) {
//
// boolean verified = true;
// try {
// byte[] calcSha1localproof = SecurityHelper.getSHA1LocalProof(toProof);
// if (!Arrays.equals(givenSha1localproof, calcSha1localproof)) {
// System.out.println("given sha1: "+SecurityHelper.HexDecoder.encode(givenSha1localproof, ':', -1));
// System.out.println("calc sha1: "+SecurityHelper.HexDecoder.encode( calcSha1localproof, ':', -1));
// verified = false;
// }
// } catch (Exception ex) {
// ex.printStackTrace();
// return false;
// }
//
// //if (verified) System.out.println("checking modulus");
//
// //check modulus belongs to keyid
// byte[] givenModulus = signature.getKey().getPubKey().getModulusBytes();
// if (verified && !Arrays.equals(signingKey.getModulusBytes(),givenModulus)) {
// verified = false;
// System.out.println("given modulus: "+SecurityHelper.HexDecoder.encode(givenModulus, ':', -1));
// System.out.println("masterkey modulus: "+SecurityHelper.HexDecoder.encode(signingKey.getModulusBytes(), ':', -1));
// System.out.println("modulus verification FAILED!");
// }
//
// //check signaturebytes match sha1localproof
// if (verified) {
// try {
// verified = signature.tryVerificationMD5SHA1SHA256(givenSha1localproof);
// return verified;
// } catch (Exception ex) {
// ex.printStackTrace();
// return false;
// }
//// System.out.println("checking signaturebytes");
//// System.out.println("signature data md5 : "+e.getChild("signature").getChild("data").getChildText("md5"));
//// System.out.println("signature data sha1 : "+e.getChild("signature").getChild("data").getChildText("sha1"));
//// System.out.println("signature data sha256: "+e.getChild("signature").getChild("data").getChildText("sha256"));
//// byte[][] data = SecurityHelper.getMD5SHA1SHA256(givenSha1localproof);
//// System.out.println("calc data md5 : "+SecurityHelper.HexDecoder.encode(data[1],':',-1));
//// System.out.println("calc data sha1 : "+SecurityHelper.HexDecoder.encode(data[2],':',-1));
//// System.out.println("calc data sha256: "+SecurityHelper.HexDecoder.encode(data[3],':',-1));
// }
// return verified;
// }
// public static boolean checkElementsSHA1localproofAndSignature(Element e, OSDXKey signingKey) throws Exception {
// //get sha1localproof
// byte[] givenSha1localproof = SecurityHelper.HexDecoder.decode(e.getChildText("sha1localproof"));
// //get signature
// Signature signature = Signature.fromElement(e.getChild("signature"));
//
// //build toProof <- all content but sha1localproof and Signature
// Vector<Element> toProof = new Vector<Element>();
// Vector<Element> children = e.getChildren();
// for (Element c : children) {
// if (!c.getName().equals("sha1localproof") && !c.getName().equals("signature")) {
// toProof.add(c);
// }
// }
//
// return checkSHA1localproofAndSignature(toProof, givenSha1localproof, signature, signingKey.getPubKey());
//
// }
public static void copyResource(InputStream in, File dstDir, String fname) {
try {
File f = new File(dstDir, fname);
FileOutputStream fout = new FileOutputStream(f);
byte[] buff = new byte[1024];
int read = 0;
while((read=in.read(buff))!=-1) {
fout.write(buff,0,read);
}
fout.flush();
fout.close();
in.close();
} catch(Exception ex) {
ex.printStackTrace();
}
}
}