blob: 5409d1cc37464649e739c37b531dfa417ce72c4a [file] [log] [blame]
package com.r_bg.stax;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.RSAPublicKeySpec;
import javax.xml.crypto.XMLStructure;
import javax.xml.crypto.dsig.Reference;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.XMLValidateContext;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import org.apache.xml.security.Init;
import org.apache.xml.security.c14n.Canonicalizer;
import org.apache.xml.security.signature.ObjectContainer;
import org.apache.xml.security.transforms.Transforms;
import org.apache.xml.security.utils.Base64;
import org.apache.xml.security.utils.XMLUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
import sun.security.rsa.RSAKeyFactory;
import sun.security.rsa.RSAPrivateKeyImpl;
import junit.framework.TestCase;
public class XMLSignatureTest extends TestCase {
static Key getKey() throws Exception {
byte[] modulus=Base64.decode("skqbW7oBwM1lCWNwC1obkgj4VV58G1AX7ERMWEIrQQlZ8uFdQ3FNkgMdtmx/XUjNF+zXTDmxe+K/\n" +
"lne+0KDwLWskqhS6gnkQmxZoR4FUovqRngoqU6bnnn0pM9gF/AI/vcdu7aowbF9S7TVlSw7IpxIQ\n" +
"VjevEfohDpn/+oxljm0=\n");
byte[] exponent=Base64.decode("AQAB");
RSAPublicKeySpec spec=new RSAPublicKeySpec(new BigInteger(1,modulus),new BigInteger(1,exponent));
return KeyFactory.getInstance("rsa").generatePublic(spec);
}
static PrivateKey obtainPrivateKey() throws Exception {
KeyStore ks = KeyStore.getInstance("JKS");
FileInputStream fis = new FileInputStream("keystore.jks");
ks.load(fis, "secret".toCharArray());
return (PrivateKey) ks.getKey("tfc",
"secret".toCharArray());
}
static PublicKey obtainPublicKey() throws Exception {
KeyStore ks = KeyStore.getInstance("JKS");
FileInputStream fis = new FileInputStream("keystore.jks");
ks.load(fis, "secret".toCharArray());
return ks.getCertificate("tfc").getPublicKey();
}
static String generateSignature(int size,String name) throws Exception{
DocumentBuilderFactory fact=DocumentBuilderFactory.newInstance();
fact.setNamespaceAware(true);
Document doc=fact.newDocumentBuilder().newDocument();
org.apache.xml.security.signature.XMLSignature sig=new org.apache.xml.security.signature.XMLSignature(doc,"",
org.apache.xml.security.signature.XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1,
Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
Transforms trs=new Transforms(doc);
trs.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
sig.addDocument("#1",trs);
doc.appendChild(sig.getElement());
ObjectContainer ob=new ObjectContainer(doc);
ob.setId("1");
sig.appendObject(ob);
sig.addKeyInfo(obtainPublicKey());
for (int i=0;i<size;i++) {
Element el=doc.createElement("Prueba");
Element el2=doc.createElement("SubPrueba");
el2.appendChild(doc.createTextNode("Prueba de firmas gordas"));
el.appendChild(el2);
Element el3=doc.createElement("SubPrueba");
el3.appendChild(doc.createElement("SubSubPrueba"));
el3.appendChild(doc.createTextNode("Otro textillo por aqui"));
el2.appendChild(el3);
el.appendChild(doc.createTextNode("\n"));
ob.appendChild(el);
}
sig.sign(obtainPrivateKey());
FileOutputStream bos=new FileOutputStream(name);
XMLUtils.outputDOM(doc, bos);
//System.out.println(bos.toByteArray().length);
return "";
}
static Key checkSignature(String sig) throws Exception {
DocumentBuilderFactory fact=DocumentBuilderFactory.newInstance();
fact.setNamespaceAware(true);
Document doc=fact.newDocumentBuilder().parse(new ByteArrayInputStream(sig.getBytes()));
org.apache.xml.security.signature.XMLSignature signature = new org.apache.xml.security.signature.XMLSignature((Element)doc.getDocumentElement().getFirstChild(),"");
System.out.println("Her:"+signature.checkSignatureValue(signature.getKeyInfo().getPublicKey()));
System.out.println("Her2:"+(getKey().equals(signature.getKeyInfo().getPublicKey()))) ;
return signature.getKeyInfo().getPublicKey();
}
public void testEnvelopedSignature() throws Exception {
String in="<RootObject><ds:Signature xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\">\n" +
"<ds:SignedInfo>\n" +
"<ds:CanonicalizationMethod Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\"/>\n" +
"<ds:SignatureMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#rsa-sha1\"/>\n" +
"<ds:Reference URI=\"#1\">\n" +
"<ds:Transforms>\n" +
"<ds:Transform Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\"></ds:Transform>\n" +
"</ds:Transforms>\n" +
"<ds:DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"></ds:DigestMethod>\n" +
"<ds:DigestValue>oMQoFufPA7Un6cfz0GaEOJpE4Z8=</ds:DigestValue>\n" +
"</ds:Reference>\n" +
"</ds:SignedInfo>\n" +
"<ds:SignatureValue>\n" +
"AhyiFQ6hucykYJOJDBV3wbPBe2TAURXXfCUD7BmSAecT+izT9fHFsxRVez3s+6hYSgtaVhmeVgbd\n" +
"ZEOMPFihBGldi1NV73Z/tpXxqNvY+/NwQmmasQp9gzFHxYF2cqi8m7sAHM03BIC1YoBctxVw/jxV\n" +
"ClhLJuTSHoKwlzKH24g=\n" +
"</ds:SignatureValue>\n" +
"<ds:KeyInfo>\n" +
"<ds:KeyValue>\n" +
"<ds:RSAKeyValue>\n" +
"<ds:Modulus>\n" +
"skqbW7oBwM1lCWNwC1obkgj4VV58G1AX7ERMWEIrQQlZ8uFdQ3FNkgMdtmx/XUjNF+zXTDmxe+K/\n" +
"lne+0KDwLWskqhS6gnkQmxZoR4FUovqRngoqU6bnnn0pM9gF/AI/vcdu7aowbF9S7TVlSw7IpxIQ\n" +
"VjevEfohDpn/+oxljm0=\n" +
"</ds:Modulus>\n" +
"<ds:Exponent>AQAB</ds:Exponent>\n" +
"</ds:RSAKeyValue>\n" +
"</ds:KeyValue>\n" +
"</ds:KeyInfo>\n" +
"<ds:Object Id=\"1\"><UnderObject>A text in a box<OtherObject><OtherObject2></OtherObject2><OtherObject6></OtherObject6><OtherObject></OtherObject></OtherObject></UnderObject></ds:Object>\n" +
"</ds:Signature></RootObject>";
XMLInputFactory im=XMLInputFactory.newInstance();
im.setProperty("javax.xml.stream.supportDTD", new Boolean(false));
XMLStreamReader reader=im.createXMLStreamReader(new ByteArrayInputStream(in.getBytes()));
StaxValidateContext stx = StaxValidateContext.createEnvolopedValidator(getKey(),reader);
reader=im.createFilteredReader(reader, stx.getStreamFilter());
while ((reader.getEventType())!=XMLStreamReader.END_DOCUMENT) {
reader.next();
}
XMLSignatureFactory fac=XMLSignatureFactory.getInstance("Stax", new com.r_bg.stax.StaxProvider());
stx.setSignatureNumber(0);
XMLSignature sig=fac.unmarshalXMLSignature(stx);
if (!((Reference)sig.getSignedInfo().getReferences().get(0)).validate(stx)) {
//Firma invalida.
}
//generateSignature(262144/34,"Enveloped1MB.xml");
assertTrue("Signature References must be right",
((Reference)sig.getSignedInfo().getReferences().get(0)).validate(stx));
assertTrue("Signature must be right",
sig.validate(stx));
}
public void testTamperedEnvelopedSignature() throws Exception {
String in="<RootObject><ds:Signature xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\">\n" +
"<ds:SignedInfo>\n" +
"<ds:CanonicalizationMethod Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\"/>\n" +
"<ds:SignatureMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#rsa-sha1\"/>\n" +
"<ds:Reference URI=\"#1\">\n" +
"<ds:Transforms>\n" +
"<ds:Transform Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\"></ds:Transform>\n" +
"</ds:Transforms>\n" +
"<ds:DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"></ds:DigestMethod>\n" +
"<ds:DigestValue>oMQoFufPA7Un6cfz0GaEOJpE4Z8=</ds:DigestValue>\n" +
"</ds:Reference>\n" +
"</ds:SignedInfo>\n" +
"<ds:SignatureValue>\n" +
"AhyiFQ6hucykYJOJDBV3wbPBe2TAURXXfCUD7BmSAecT+izT9fHFsxRVez3s+6hYSgtaVhmeVgbd\n" +
"ZEOMPFihBGldi1NV73Z/tpXxqNvY+/NwQmmasQp9gzFHxYF2cqi8m7sAHM03BIC1YoBctxVw/jxV\n" +
"ClhLJuTSHoKwlzKH24g=\n" +
"</ds:SignatureValue>\n" +
"<ds:KeyInfo>\n" +
"<ds:KeyValue>\n" +
"<ds:RSAKeyValue>\n" +
"<ds:Modulus>\n" +
"skqbW7oBwM1lCWNwC1obkgj4VV58G1AX7ERMWEIrQQlZ8uFdQ3FNkgMdtmx/XUjNF+zXTDmxe+K/\n" +
"lne+0KDwLWskqhS6gnkQmxZoR4FUovqRngoqU6bnnn0pM9gF/AI/vcdu7aowbF9S7TVlSw7IpxIQ\n" +
"VjevEfohDpn/+oxljm0=\n" +
"</ds:Modulus>\n" +
"<ds:Exponent>AQAB</ds:Exponent>\n" +
"</ds:RSAKeyValue>\n" +
"</ds:KeyValue>\n" +
"</ds:KeyInfo>\n" +
"<ds:Object Id=\"1\"><UnderObject>a text in a box<OtherObject><OtherObject2></OtherObject2><OtherObject6></OtherObject6><OtherObject></OtherObject></OtherObject></UnderObject></ds:Object>\n" +
"</ds:Signature></RootObject>";
XMLInputFactory im=XMLInputFactory.newInstance();
im.setProperty("javax.xml.stream.supportDTD", new Boolean(false));
XMLStreamReader reader=im.createXMLStreamReader(new ByteArrayInputStream(in.getBytes()));
StaxValidateContext stx = StaxValidateContext.createEnvolopedValidator(getKey(),reader);
reader=im.createFilteredReader(reader, stx.getStreamFilter());
while ((reader.getEventType())!=XMLStreamReader.END_DOCUMENT) {
reader.next();
}
XMLSignatureFactory fac=XMLSignatureFactory.getInstance("Stax", new com.r_bg.stax.StaxProvider() );
stx.setSignatureNumber(0);
XMLSignature sig=fac.unmarshalXMLSignature(stx);
assertFalse("Signature must be wrong",
((Reference)sig.getSignedInfo().getReferences().get(0)).validate(stx));
assertFalse("Signature must be false",
sig.validate(stx));
}
final static String ALUMNO_NS="http://fi.upm.es/alumnos/1/0";
public void atestParsing() throws Exception {
XMLInputFactory im=XMLInputFactory.newInstance();
im.setProperty("javax.xml.stream.supportDTD", new Boolean(false));
XMLStreamReader reader=im.createXMLStreamReader(new FileInputStream("alumnoEnveloped.xml"));
StaxValidateContext stx = StaxValidateContext.createEnvolopedValidator(getKey(),reader);
reader=im.createFilteredReader(reader, stx.getStreamFilter());
String nombre=null;
String apellidos=null;
do {
if (reader.getEventType()==XMLStreamReader.START_ELEMENT) {
if (!ALUMNO_NS.equals(reader.getNamespaceURI()))
continue;
if ("Nombre".equals(reader.getLocalName())) {
reader.next();
nombre=reader.getText();
continue;
}
if ("Apellidos".equals(reader.getLocalName())) {
reader.next();
apellidos=reader.getText();
continue;
}
}
reader.next();
} while ((reader.getEventType())!=XMLStreamReader.END_DOCUMENT);
System.out.println("Nombre: "+nombre+" Apellidos:"+apellidos);
XMLSignatureFactory fac=XMLSignatureFactory.getInstance("Stax", new com.r_bg.stax.StaxProvider());
stx.setSignatureNumber(0);
XMLSignature sig=fac.unmarshalXMLSignature(stx);
if (!sig.validate(stx)) {
//Firma invalida.
System.out.println("Firma Invalida");
}
}
static {
Init.init();
StaxXMLSignatureFactory.getInstance("Stax", new StaxProvider());
};
}