Révision 19b58bab
Ajouté par Remy Menard il y a plus de 11 ans
SigMa/SigMa-Commons/src/main/java/fr/unicaen/iota/sigma/SigMaFunctions.java | ||
---|---|---|
/*
|
||
* This program is a part of the IoTa Project.
|
||
* This program is a part of the IoTa project.
|
||
*
|
||
* Copyright © 2012 Université de Caen Basse-Normandie, GREYC
|
||
* Copyright © 2012-2013 Université de Caen Basse-Normandie, GREYC
|
||
*
|
||
* This program is free software: you can redistribute it and/or modify
|
||
* it under the terms of the GNU General Public License as published by
|
||
... | ... | |
*/
|
||
package fr.unicaen.iota.sigma;
|
||
|
||
import fr.unicaen.iota.mu.Constants;
|
||
import fr.unicaen.iota.mu.Utils;
|
||
import java.io.*;
|
||
import java.math.BigInteger;
|
||
import java.security.*;
|
||
import java.security.cert.CertificateException;
|
||
import java.util.Enumeration;
|
||
import java.util.List;
|
||
import javax.crypto.BadPaddingException;
|
||
import javax.crypto.Cipher;
|
||
import javax.crypto.IllegalBlockSizeException;
|
||
import javax.crypto.NoSuchPaddingException;
|
||
import javax.security.cert.CertificateException;
|
||
import javax.xml.bind.*;
|
||
import javax.xml.namespace.QName;
|
||
import javax.xml.parsers.DocumentBuilder;
|
||
import javax.xml.parsers.DocumentBuilderFactory;
|
||
import javax.xml.parsers.ParserConfigurationException;
|
||
import javax.xml.transform.Transformer;
|
||
import javax.xml.transform.TransformerConfigurationException;
|
||
import javax.xml.transform.TransformerException;
|
||
import javax.xml.transform.TransformerFactory;
|
||
import javax.xml.transform.stream.StreamResult;
|
||
import javax.xml.transform.stream.StreamSource;
|
||
import org.apache.commons.logging.Log;
|
||
import org.apache.commons.logging.LogFactory;
|
||
import org.apache.xml.security.c14n.CanonicalizationException;
|
||
import org.apache.xml.security.c14n.Canonicalizer;
|
||
import org.apache.xml.security.c14n.InvalidCanonicalizerException;
|
||
import org.apache.xml.security.signature.XMLSignatureException;
|
||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||
import org.fosstrak.epcis.model.*;
|
||
import org.w3c.dom.Element;
|
||
import org.w3c.dom.Node;
|
||
import org.xml.sax.SAXException;
|
||
|
||
/**
|
||
* This
|
||
* <code>SigMAFunctions</code> class contains the functions that enable the
|
||
* This <code>SigMAFunctions</code> class contains the functions that enable the
|
||
* signatures creation and verification.
|
||
*/
|
||
public class SigMaFunctions {
|
||
... | ... | |
private static final Log log = LogFactory.getLog(SigMaFunctions.class);
|
||
private final String keyStoreFilePath;
|
||
private final String keyStorePassword;
|
||
private String signerId;
|
||
|
||
static {
|
||
// TODO: maybe this should be better done at the application level
|
||
... | ... | |
public SigMaFunctions(String keyStoreFilePath, String keyStorePassword) {
|
||
this.keyStoreFilePath = keyStoreFilePath;
|
||
this.keyStorePassword = keyStorePassword;
|
||
this.signerId = null;
|
||
}
|
||
|
||
/**
|
||
* Compute and insert a signature in an EPCISEventType.
|
||
*
|
||
* @param event the event to be signed.
|
||
* @throws ParserConfigurationException
|
||
* @throws SAXException
|
||
* @throws InvalidCanonicalizerException
|
||
* @throws CanonicalizationException
|
||
* @throws UnsupportedEncodingException
|
||
* @throws NoSuchAlgorithmException
|
||
* @throws NoSuchPaddingException
|
||
* @throws XMLSignatureException
|
||
* @throws InvalidKeyException
|
||
* @throws IllegalBlockSizeException
|
||
* @throws BadPaddingException
|
||
* @throws SignatureException
|
||
* @throws NoSuchProviderException
|
||
* @throws KeyStoreException
|
||
* @throws FileNotFoundException
|
||
* @throws IOException
|
||
* @throws CertificateException
|
||
* @throws UnrecoverableKeyException
|
||
* @throws JAXBException
|
||
* @throws TransformerConfigurationException
|
||
* @throws TransformerException
|
||
*/
|
||
public void sign(EPCISEventType event) throws ParserConfigurationException, SAXException, InvalidCanonicalizerException,
|
||
CanonicalizationException, UnsupportedEncodingException, NoSuchAlgorithmException, XMLSignatureException,
|
||
InvalidKeyException, SignatureException, NoSuchProviderException, KeyStoreException, FileNotFoundException,
|
||
IOException, CertificateException, UnrecoverableKeyException, JAXBException, TransformerConfigurationException,
|
||
TransformerException {
|
||
String cForm = createCanonicalForm(event);
|
||
log.debug(cForm);
|
||
String signature = createECDSASignature(cForm);
|
||
Utils.insertExtension(event, Constants.URN_IOTA, Constants.EXTENSION_SIGNATURE, signature);
|
||
Utils.insertExtension(event, Constants.URN_IOTA, Constants.EXTENSION_SIGNER_ID, signerId);
|
||
String cForm2 = createCanonicalForm(event);
|
||
log.debug(cForm2);
|
||
}
|
||
|
||
/**
|
||
* Compute and insert a signature in an EPCISEventType.
|
||
*
|
||
* @param event the event to be signed.
|
||
* @param signerId the alias associated to the public key.
|
||
* @throws ParserConfigurationException
|
||
* @throws SAXException
|
||
* @throws InvalidCanonicalizerException
|
||
* @throws CanonicalizationException
|
||
* @throws UnsupportedEncodingException
|
||
* @throws NoSuchAlgorithmException
|
||
* @throws XMLSignatureException
|
||
* @throws InvalidKeyException
|
||
* @throws SignatureException
|
||
* @throws NoSuchProviderException
|
||
* @throws KeyStoreException
|
||
* @throws FileNotFoundException
|
||
* @throws IOException
|
||
* @throws CertificateException
|
||
* @throws UnrecoverableKeyException
|
||
* @throws JAXBException
|
||
* @throws TransformerConfigurationException
|
||
* @throws TransformerException
|
||
*/
|
||
public void sign(EPCISEventType event) throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, ParserConfigurationException, SAXException, IOException {
|
||
public void sign(EPCISEventType event, String signerId) throws ParserConfigurationException, SAXException, InvalidCanonicalizerException,
|
||
CanonicalizationException, UnsupportedEncodingException, NoSuchAlgorithmException, XMLSignatureException,
|
||
InvalidKeyException, SignatureException, NoSuchProviderException, KeyStoreException, FileNotFoundException, IOException,
|
||
CertificateException, UnrecoverableKeyException, JAXBException, TransformerConfigurationException, TransformerException {
|
||
this.signerId = signerId;
|
||
String cForm = createCanonicalForm(event);
|
||
log.trace(cForm);
|
||
String signature = createRSASignature(cForm, keyStoreFilePath);
|
||
insertSignature(event, signature);
|
||
log.info(cForm);
|
||
String signature = createECDSASignature(cForm);
|
||
Utils.insertExtension(event, Constants.URN_IOTA, Constants.EXTENSION_SIGNATURE, signature);
|
||
Utils.insertExtension(event, Constants.URN_IOTA, Constants.EXTENSION_SIGNER_ID, signerId);
|
||
String cForm2 = createCanonicalForm(event);
|
||
log.trace(cForm2);
|
||
log.info(cForm2);
|
||
}
|
||
|
||
/**
|
||
... | ... | |
* @return <code>true</code> if the siganture is correct.
|
||
* @throws FileNotFoundException
|
||
* @throws CertificateException
|
||
* @throws IOException
|
||
* @throws NoSuchAlgorithmException
|
||
* @throws InvalidKeyException
|
||
* @throws SignatureException
|
||
... | ... | |
* @throws BadPaddingException
|
||
* @throws ParserConfigurationException
|
||
* @throws SAXException
|
||
* @throws InvalidCanonicalizerException
|
||
* @throws CanonicalizationException
|
||
* @throws KeyStoreException
|
||
* @throws IOException
|
||
* @throws JAXBException
|
||
* @throws TransformerConfigurationException
|
||
* @throws TransformerException
|
||
*/
|
||
public boolean verify(EPCISEventType event) throws FileNotFoundException, CertificateException, IOException, NoSuchAlgorithmException, InvalidKeyException, SignatureException, java.security.cert.CertificateException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, ParserConfigurationException, SAXException {
|
||
public boolean verify(EPCISEventType event) throws FileNotFoundException, CertificateException, NoSuchAlgorithmException,
|
||
InvalidKeyException, SignatureException, java.security.cert.CertificateException, NoSuchPaddingException,
|
||
IllegalBlockSizeException, BadPaddingException, ParserConfigurationException, SAXException,
|
||
InvalidCanonicalizerException, CanonicalizationException, KeyStoreException, IOException, JAXBException,
|
||
TransformerConfigurationException, TransformerException {
|
||
// get the the signature in event's extensions.
|
||
this.signerId = getSignerId(event);
|
||
deleteSignerId(event);
|
||
String signature = getSignature(event);
|
||
deleteSignature(event);
|
||
String cForm = createCanonicalForm(event);
|
||
log.trace(cForm);
|
||
PublicKey publicKey = getPublicKey(keyStoreFilePath);
|
||
Signature rsa = Signature.getInstance("SHA1withRSA");
|
||
rsa.initVerify(publicKey);
|
||
log.info(cForm);
|
||
PublicKey publicKey = getPublicKey();
|
||
Signature ecdsa = Signature.getInstance("SHA1withECDSA");
|
||
ecdsa.initVerify(publicKey);
|
||
byte[] cFormByte = cForm.getBytes("UTF-8");
|
||
rsa.update(cFormByte);
|
||
ecdsa.update(cFormByte);
|
||
|
||
byte[] signatureByte = stringToByte(signature);
|
||
return ecdsa.verify(signatureByte);
|
||
// Get an SHA-1 message digest object and compute the plaintext digest
|
||
MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
|
||
// MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
|
||
// To verify, start by decrypting the signature with the
|
||
// RSA private key
|
||
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
|
||
cipher.init(Cipher.DECRYPT_MODE, getPublicKey(keyStoreFilePath));
|
||
// Cipher cipher = Cipher.getInstance("EC");
|
||
// cipher.init(Cipher.DECRYPT_MODE, getPublicKey());
|
||
// the sigOffset permits the substraction of the sign byte that the BigInteger
|
||
// class adds.
|
||
int sigOffset = signatureByte.length % 2;
|
||
byte[] newMD = cipher.doFinal(signatureByte, sigOffset, (signatureByte.length - sigOffset));
|
||
// class adds.
|
||
// int sigOffset = signatureByte.length % 2;
|
||
// byte[] newMD = cipher.doFinal(signatureByte, sigOffset, (signatureByte.length - sigOffset));
|
||
|
||
// Then, recreate the message digest from the plaintext
|
||
// to simulate what a recipient must do
|
||
int offset = cFormByte.length % 2;
|
||
messageDigest.reset();
|
||
messageDigest.update(cFormByte, offset, (cFormByte.length - offset));
|
||
byte[] oldMD = messageDigest.digest();
|
||
// int offset = cFormByte.length % 2;
|
||
// messageDigest.reset();
|
||
// messageDigest.update(cFormByte, offset, (cFormByte.length - offset));
|
||
// byte[] oldMD = messageDigest.digest();
|
||
|
||
// Verify that the two message digests match
|
||
int len = newMD.length;
|
||
if (len > oldMD.length) {
|
||
return false;
|
||
}
|
||
for (int i = 0; i < len; ++i) {
|
||
if (oldMD[i] != newMD[i]) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
// int len = newMD.length;
|
||
// if (len > oldMD.length) {
|
||
// return false;
|
||
// }
|
||
// for (int i = 0; i < len; ++i) {
|
||
// if (oldMD[i] != newMD[i]) {
|
||
// return false;
|
||
// }
|
||
// }
|
||
// return true;
|
||
}
|
||
|
||
private byte[] stringToByte(String text) {
|
||
... | ... | |
return sig.toString(16);
|
||
}
|
||
|
||
private String createCanonicalForm(EPCISEventType event) throws ParserConfigurationException, SAXException, IOException {
|
||
JAXBElement<EPCISEventType> elem = new JAXBElement<EPCISEventType>(new QName("urn:epcglobal:epcis:xsd:1", "XMLType"),
|
||
EPCISEventType.class, event);
|
||
|
||
log.trace(elem.getName().getNamespaceURI());
|
||
log.trace(elem.getName().getPrefix());
|
||
log.trace(elem.getName().getLocalPart());
|
||
log.trace(elem.getName().toString());
|
||
|
||
private String createCanonicalForm(EPCISEventType event) throws ParserConfigurationException, SAXException,
|
||
InvalidCanonicalizerException, CanonicalizationException, JAXBException, IOException,
|
||
TransformerConfigurationException, TransformerException {
|
||
String eventXMLForm = "";
|
||
if (event instanceof ObjectEventType) {
|
||
ObjectEventType obEvent = (ObjectEventType) event;
|
||
... | ... | |
TransactionEventType traEvent = (TransactionEventType) event;
|
||
eventXMLForm = createCanonicalForm(traEvent);
|
||
}
|
||
|
||
return eventXMLForm;
|
||
}
|
||
|
||
private String createCanonicalForm(AggregationEventType event) {
|
||
private String createCanonicalForm(AggregationEventType event) throws InvalidCanonicalizerException,
|
||
ParserConfigurationException, SAXException, CanonicalizationException, JAXBException, IOException,
|
||
TransformerConfigurationException, TransformerException {
|
||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||
try {
|
||
JAXBContext jc = JAXBContext.newInstance("org.fosstrak.epcis.model");
|
||
Unmarshaller u = jc.createUnmarshaller();
|
||
Marshaller m = jc.createMarshaller();
|
||
m.marshal(new JAXBElement<AggregationEventType>(new QName("urn:epcglobal:epcis:xsd:1", "XMLType"),
|
||
AggregationEventType.class, event), baos);
|
||
} catch (JAXBException ex) {
|
||
log.fatal("Couldn’t marshal event", ex);
|
||
}
|
||
return baos.toString();
|
||
JAXBContext jc = JAXBContext.newInstance(AggregationEventType.class);
|
||
Marshaller m = jc.createMarshaller();
|
||
m.marshal(event, baos);
|
||
byte[] nonCanonicalXML = baos.toByteArray();
|
||
Node node = byteArrayToNode(nonCanonicalXML);
|
||
byte[] canonicalXML = canonicalizeXML(node);
|
||
return new String(canonicalXML);
|
||
}
|
||
|
||
private String createCanonicalForm(ObjectEventType event) {
|
||
private String createCanonicalForm(ObjectEventType event) throws InvalidCanonicalizerException,
|
||
ParserConfigurationException, IOException, SAXException, CanonicalizationException, JAXBException,
|
||
TransformerConfigurationException, TransformerException {
|
||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||
try {
|
||
JAXBContext jc = JAXBContext.newInstance("org.fosstrak.epcis.model");
|
||
Unmarshaller u = jc.createUnmarshaller();
|
||
Marshaller m = jc.createMarshaller();
|
||
m.marshal(new JAXBElement<ObjectEventType>(new QName("urn:epcglobal:epcis:xsd:1", "XMLType"),
|
||
ObjectEventType.class, event), baos);
|
||
} catch (JAXBException ex) {
|
||
log.fatal("Couldn’t marsal event", ex);
|
||
}
|
||
return baos.toString();
|
||
JAXBContext jc = JAXBContext.newInstance(ObjectEventType.class);
|
||
Marshaller m = jc.createMarshaller();
|
||
m.marshal(event, baos);
|
||
byte[] nonCanonicalXML = baos.toByteArray();
|
||
Node node = byteArrayToNode(nonCanonicalXML);
|
||
byte[] canonicalXML = canonicalizeXML(node);
|
||
return new String(canonicalXML);
|
||
}
|
||
|
||
private String createCanonicalForm(QuantityEventType event) {
|
||
private String createCanonicalForm(QuantityEventType event) throws InvalidCanonicalizerException,
|
||
ParserConfigurationException, SAXException, IOException, CanonicalizationException, JAXBException,
|
||
TransformerConfigurationException, TransformerException {
|
||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||
try {
|
||
JAXBContext jc = JAXBContext.newInstance("org.fosstrak.epcis.model");
|
||
Unmarshaller u = jc.createUnmarshaller();
|
||
Marshaller m = jc.createMarshaller();
|
||
m.marshal(new JAXBElement<QuantityEventType>(new QName("urn:epcglobal:epcis:xsd:1", "XMLType"),
|
||
QuantityEventType.class, event), baos);
|
||
} catch (JAXBException ex) {
|
||
log.fatal("Couldn’t marsal event", ex);
|
||
}
|
||
return baos.toString();
|
||
JAXBContext jc = JAXBContext.newInstance(QuantityEventType.class);
|
||
Marshaller m = jc.createMarshaller();
|
||
m.marshal(event, baos);
|
||
byte[] nonCanonicalXML = baos.toByteArray();
|
||
Node node = byteArrayToNode(nonCanonicalXML);
|
||
byte[] canonicalXML = canonicalizeXML(node);
|
||
return new String(canonicalXML);
|
||
}
|
||
|
||
private String createCanonicalForm(TransactionEventType event) {
|
||
private String createCanonicalForm(TransactionEventType event) throws InvalidCanonicalizerException,
|
||
ParserConfigurationException, IOException, SAXException, CanonicalizationException, JAXBException,
|
||
TransformerConfigurationException, TransformerException {
|
||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||
try {
|
||
JAXBContext jc = JAXBContext.newInstance("org.fosstrak.epcis.model");
|
||
Unmarshaller u = jc.createUnmarshaller();
|
||
Marshaller m = jc.createMarshaller();
|
||
m.marshal(new JAXBElement<TransactionEventType>(new QName("urn:epcglobal:epcis:xsd:1", "XMLType"),
|
||
TransactionEventType.class, event), baos);
|
||
} catch (JAXBException ex) {
|
||
log.fatal("Couldn’t marsal event", ex);
|
||
}
|
||
return baos.toString();
|
||
JAXBContext jc = JAXBContext.newInstance(TransactionEventType.class);
|
||
Marshaller m = jc.createMarshaller();
|
||
m.marshal(event, baos);
|
||
byte[] nonCanonicalXML = baos.toByteArray();
|
||
Node node = byteArrayToNode(nonCanonicalXML);
|
||
byte[] canonicalXML = canonicalizeXML(node);
|
||
return new String(canonicalXML);
|
||
}
|
||
|
||
private byte[] canonicalizeXML(byte[] xml) throws InvalidCanonicalizerException, ParserConfigurationException,
|
||
IOException, SAXException, CanonicalizationException {
|
||
org.apache.xml.security.Init.init();
|
||
Canonicalizer canonicalizer = Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
|
||
return canonicalizer.canonicalize(xml);
|
||
}
|
||
|
||
private KeyStore getKeyStore(String filename) {
|
||
private byte[] canonicalizeXML(Node xml) throws InvalidCanonicalizerException, ParserConfigurationException,
|
||
IOException, SAXException, CanonicalizationException {
|
||
org.apache.xml.security.Init.init();
|
||
Canonicalizer canonicalizer = Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
|
||
return canonicalizer.canonicalizeSubtree(xml);
|
||
}
|
||
|
||
private Node byteArrayToNode(byte[] xml) throws ParserConfigurationException, SAXException, IOException,
|
||
TransformerConfigurationException, TransformerException {
|
||
InputStream namespaceInput = SigMaFunctions.class.getClassLoader().getResourceAsStream("removeNamespaces.xml");
|
||
Transformer xformer = TransformerFactory.newInstance().newTransformer(new StreamSource(namespaceInput));
|
||
InputStream is = new ByteArrayInputStream(xml);
|
||
ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
|
||
xformer.transform(new StreamSource(is), new StreamResult(byteOutput));
|
||
InputStream transformedInput = new ByteArrayInputStream(byteOutput.toByteArray());
|
||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||
DocumentBuilder builder = factory.newDocumentBuilder();
|
||
org.w3c.dom.Document doc = builder.parse(transformedInput);
|
||
Element nroot = doc.getDocumentElement();
|
||
Node node = nroot.getParentNode();
|
||
return node;
|
||
}
|
||
|
||
private KeyStore getKeyStore(String filename) throws KeyStoreException, FileNotFoundException,
|
||
IOException, NoSuchAlgorithmException, CertificateException, java.security.cert.CertificateException {
|
||
KeyStore ks;
|
||
char[] password;
|
||
|
||
try {
|
||
ks = KeyStore.getInstance("PKCS12");
|
||
password = keyStorePassword.toCharArray();
|
||
ks.load(new FileInputStream(filename), password);
|
||
return ks;
|
||
} catch (Exception e) {
|
||
log.warn("Keystor logging failed", e);
|
||
return null;
|
||
}
|
||
ks = KeyStore.getInstance("PKCS12");
|
||
password = keyStorePassword.toCharArray();
|
||
ks.load(new FileInputStream(filename), password);
|
||
return ks;
|
||
}
|
||
|
||
private PrivateKey getPrivateKey(String filename) {
|
||
private PrivateKey getPrivateKey() throws KeyStoreException, FileNotFoundException, IOException,
|
||
NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException {
|
||
PrivateKey privateKey = null;
|
||
char[] password = keyStorePassword.toCharArray();
|
||
KeyStore ks = getKeyStore(filename);
|
||
try {
|
||
KeyStore ks = getKeyStore(keyStoreFilePath);
|
||
if (this.signerId == null) {
|
||
Enumeration<String> en = ks.aliases();
|
||
// TODO: hard value
|
||
String ALIAS = "anonymous";
|
||
|
||
while (en.hasMoreElements()) {
|
||
String alias = en.nextElement();
|
||
if (ks.isKeyEntry(alias)) {
|
||
ALIAS = alias;
|
||
this.signerId = alias;
|
||
break;
|
||
}
|
||
}
|
||
privateKey = (PrivateKey) ks.getKey(ALIAS, password);
|
||
} catch (Exception e) {
|
||
log.error("While seeking private key", e);
|
||
}
|
||
privateKey = (PrivateKey) ks.getKey(this.signerId, password);
|
||
return privateKey;
|
||
}
|
||
|
||
private PublicKey getPublicKey(String filename) {
|
||
KeyStore ks = getKeyStore(filename);
|
||
private PublicKey getPublicKey() throws KeyStoreException, FileNotFoundException, IOException,
|
||
NoSuchAlgorithmException, CertificateException {
|
||
KeyStore ks = getKeyStore(keyStoreFilePath);
|
||
PublicKey publicKey = null;
|
||
|
||
try {
|
||
Enumeration<String> en = ks.aliases();
|
||
// TODO: hard value
|
||
String ALIAS = "anonymous";
|
||
while (en.hasMoreElements()) {
|
||
String alias = en.nextElement();
|
||
if (ks.isKeyEntry(alias)) {
|
||
ALIAS = alias;
|
||
break;
|
||
}
|
||
}
|
||
publicKey = ks.getCertificate(ALIAS).getPublicKey();
|
||
} catch (Exception e) {
|
||
log.warn("While seeking public key", e);
|
||
}
|
||
Enumeration<String> en = ks.aliases();
|
||
// TODO: hard value
|
||
publicKey = ks.getCertificate(this.signerId).getPublicKey();
|
||
return publicKey;
|
||
}
|
||
|
||
private String createRSASignature(String event, String keyStoreFilePath) throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
|
||
private String createECDSASignature(String event) throws KeyStoreException, FileNotFoundException, IOException,
|
||
NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException, InvalidKeyException, SignatureException {
|
||
PrivateKey privateKey = getPrivateKey();
|
||
byte[] plainText = event.getBytes("UTF-8");
|
||
Signature signature = Signature.getInstance("SHA1withECDSA");
|
||
signature.initSign(privateKey);
|
||
signature.update(plainText);
|
||
byte[] signatureBytes = signature.sign();
|
||
return byteToString(signatureBytes);
|
||
}
|
||
|
||
private String createRSASignature(String event) throws UnsupportedEncodingException, KeyStoreException,
|
||
FileNotFoundException, IOException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException,
|
||
NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
|
||
byte[] plainText = event.getBytes("UTF-8");
|
||
MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
|
||
messageDigest.update(plainText);
|
||
byte[] md = messageDigest.digest();
|
||
KeyPair key = new KeyPair(getPublicKey(keyStoreFilePath), getPrivateKey(keyStoreFilePath));
|
||
KeyPair key = new KeyPair(getPublicKey(), getPrivateKey());
|
||
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
|
||
cipher.init(Cipher.ENCRYPT_MODE, key.getPrivate());
|
||
byte[] cipherText = cipher.doFinal(md);
|
||
return byteToString(cipherText);
|
||
}
|
||
|
||
private void insertSignature(EPCISEventType event, String signature) throws IOException, ParserConfigurationException, SAXException {
|
||
JAXBElement<String> elem = new JAXBElement<String>(new QName("urn:unicaen:iota:sigma:signature", "signature"), String.class, signature);
|
||
private String getSignature(EPCISEventType event) {
|
||
String signature = "";
|
||
List<Object> extensions;
|
||
|
||
if (event instanceof ObjectEventType) {
|
||
((ObjectEventType) event).getAny().add(elem);
|
||
extensions = ((ObjectEventType) event).getAny();
|
||
} else if (event instanceof AggregationEventType) {
|
||
((AggregationEventType) event).getAny().add(elem);
|
||
extensions = ((AggregationEventType) event).getAny();
|
||
} else if (event instanceof QuantityEventType) {
|
||
((QuantityEventType) event).getAny().add(elem);
|
||
extensions = ((QuantityEventType) event).getAny();
|
||
} else if (event instanceof TransactionEventType) {
|
||
((TransactionEventType) event).getAny().add(elem);
|
||
extensions = ((TransactionEventType) event).getAny();
|
||
} else {
|
||
return null;
|
||
}
|
||
for (Object object : extensions) {
|
||
// we really don’t know what’s in an extension
|
||
// JAXBElement elem = (JAXBElement) object;
|
||
// if (("signature".equals(elem.getName().getLocalPart()))) {
|
||
// signature = elem.getValue().toString();
|
||
// }
|
||
Element elem = (Element) object;
|
||
if ((Constants.URN_IOTA.equals(elem.getNamespaceURI()) && Constants.EXTENSION_SIGNATURE.equals(elem.getLocalName()))) {
|
||
signature = elem.getTextContent().toString();
|
||
}
|
||
}
|
||
return signature;
|
||
}
|
||
|
||
private String getSignature(EPCISEventType event) {
|
||
String signature = "";
|
||
private void deleteSignature(EPCISEventType event) {
|
||
List<Object> extensions;
|
||
|
||
if (event instanceof ObjectEventType) {
|
||
extensions = ((ObjectEventType) event).getAny();
|
||
} else if (event instanceof AggregationEventType) {
|
||
extensions = ((AggregationEventType) event).getAny();
|
||
} else if (event instanceof QuantityEventType) {
|
||
extensions = ((QuantityEventType) event).getAny();
|
||
} else if (event instanceof TransactionEventType) {
|
||
extensions = ((TransactionEventType) event).getAny();
|
||
} else {
|
||
return;
|
||
}
|
||
|
||
Element elem = null;
|
||
for (Object object : extensions) {
|
||
// we really don’t know what’s in an extension
|
||
// JAXBElement elemTmp = (JAXBElement) object;
|
||
// if (("signature".equals(elemTmp.getName().getLocalPart()))) {
|
||
// elem = elemTmp;
|
||
// break;
|
||
// }
|
||
Element elemTmp = (Element) object;
|
||
if ((Constants.URN_IOTA.equals(elemTmp.getNamespaceURI()) && Constants.EXTENSION_SIGNATURE.equals(elemTmp.getLocalName()))) {
|
||
elem = elemTmp;
|
||
break;
|
||
}
|
||
}
|
||
if (elem != null) {
|
||
extensions.remove(elem);
|
||
}
|
||
}
|
||
|
||
private String getSignerId(EPCISEventType event) {
|
||
String signerId = "";
|
||
List<Object> extensions;
|
||
|
||
if (event instanceof ObjectEventType) {
|
||
... | ... | |
}
|
||
for (Object object : extensions) {
|
||
// we really don’t know what’s in an extension
|
||
JAXBElement elem = (JAXBElement) object;
|
||
if (("signature".equals(elem.getName().getLocalPart()))) {
|
||
signature = elem.getValue().toString();
|
||
// JAXBElement elem = (JAXBElement) object;
|
||
// if (("signature".equals(elem.getName().getLocalPart()))) {
|
||
// signature = elem.getValue().toString();
|
||
// }
|
||
Element elem = (Element) object;
|
||
if ((Constants.URN_IOTA.equals(elem.getNamespaceURI()) && Constants.EXTENSION_SIGNER_ID.equals(elem.getLocalName()))) {
|
||
signerId = elem.getTextContent().toString();
|
||
}
|
||
}
|
||
return signature;
|
||
return signerId;
|
||
}
|
||
|
||
private void deleteSignature(EPCISEventType event) {
|
||
private void deleteSignerId(EPCISEventType event) {
|
||
List<Object> extensions;
|
||
|
||
if (event instanceof ObjectEventType) {
|
||
... | ... | |
return;
|
||
}
|
||
|
||
JAXBElement elem = null;
|
||
Element elem = null;
|
||
for (Object object : extensions) {
|
||
// we really don’t know what’s in an extension
|
||
JAXBElement elemTmp = (JAXBElement) object;
|
||
if (("signature".equals(elemTmp.getName().getLocalPart()))) {
|
||
// JAXBElement elemTmp = (JAXBElement) object;
|
||
// if (("signature".equals(elemTmp.getName().getLocalPart()))) {
|
||
// elem = elemTmp;
|
||
// break;
|
||
// }
|
||
Element elemTmp = (Element) object;
|
||
if ((Constants.URN_IOTA.equals(elemTmp.getNamespaceURI()) && Constants.EXTENSION_SIGNER_ID.equals(elemTmp.getLocalName()))) {
|
||
elem = elemTmp;
|
||
break;
|
||
}
|
||
... | ... | |
extensions.remove(elem);
|
||
}
|
||
}
|
||
|
||
}
|
Formats disponibles : Unified diff
Version 1.9
- use TLS for secured links
- SigMa is now fully functionnal
- completed documention
- a lot of bugs fixed!
- signature creation from the canonical form of the event
- signature creation using ECDSA algorithm
- signature is correctly verified
- manage the extension identifying the owner of the event
- if no identity is provided, the identity of the certificate is used
- access to the web interface of policy management is made by
certificate
- if no identity is provided, the identity of the certificate is used
- create and use certificates for TLS
- configure Apache Tomcat for TLS
- show SigMa library (SigMa-Commons)