package com.zenika.xml.signature;
import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
/**
* A builder for generating the SignedInfo node af an xml signature document.
* You should not instantiate this class yourself, use XmlSignatureBuilder instead and attached it.
*/
public class SignedInfoBuilder {
private final XmlSignatureBuilder xmlSignatureBuilder;
private final XMLSignatureFactory xmlSignatureFactory;
private final List<Reference> references = new ArrayList<Reference>();
private final List<Transform> transforms = new ArrayList<Transform>();
private SignatureMethod signatureMethod;
private CanonicalizationMethod canonicalizationMethod;
public SignedInfoBuilder(XmlSignatureBuilder xmlSignatureBuilder) {
this.xmlSignatureBuilder = xmlSignatureBuilder;
this.xmlSignatureFactory = xmlSignatureBuilder.getXmlSignatureFactory();
}
public XMLSignatureFactory getXmlSignatureFactory() {
return xmlSignatureFactory;
}
public SignedInfoBuilder withTransform(String transform) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException {
transforms.add(xmlSignatureFactory.newTransform(transform, (TransformParameterSpec) null));
return this;
}
/**
* Set the signature method with the rsa-sha256 method.
* @return
* @throws java.security.InvalidAlgorithmParameterException
* @throws java.security.NoSuchAlgorithmException
*/
public SignedInfoBuilder withRsaSha256Signature() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException {
return withSignature("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
}
/**
* Set the signature method with the given url.
* @param url
* @return
* @throws java.security.InvalidAlgorithmParameterException
* @throws java.security.NoSuchAlgorithmException
*/
public SignedInfoBuilder withSignature(String url) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException {
signatureMethod = xmlSignatureFactory.newSignatureMethod(url, null);
return this;
}
/**
* Set the canonicalization as inclusive
* @return
* @throws java.security.InvalidAlgorithmParameterException
* @throws java.security.NoSuchAlgorithmException
*/
public SignedInfoBuilder withInclusiveCanonicalization() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException {
return withCanonicalization(CanonicalizationMethod.INCLUSIVE);
}
/**
* Set the canonicalization as exclusive
* @return
* @throws java.security.InvalidAlgorithmParameterException
* @throws java.security.NoSuchAlgorithmException
*/
public SignedInfoBuilder withExclusiveCanonicalization() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException {
return withCanonicalization(CanonicalizationMethod.EXCLUSIVE);
}
/**
* Set the canonicalization according to the given method.
* @param method
* @return
* @throws java.security.InvalidAlgorithmParameterException
* @throws java.security.NoSuchAlgorithmException
*/
public SignedInfoBuilder withCanonicalization(String method) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException {
canonicalizationMethod = xmlSignatureFactory.newCanonicalizationMethod(method, (C14NMethodParameterSpec) null);
return this;
}
/**
* Instantiate and return a ReferenceBuilder used to set the Reference node of the xml signature document.
* @return
*/
public ReferenceBuilder withReference() {
return new ReferenceBuilder(this);
}
/**
* Set the Reference that will be used to generate the Reference node of the xml signature document.
* You should not call this method directy, instead use withURI to attached the Reference.
* @return
*/
protected SignedInfoBuilder withReference(Reference reference) {
references.add(reference);
return this;
}
/**
* Instantiate and return the SignedInfo used to generate the SignedInfo node of the xml signature document.
* @return
*/
protected SignedInfo build() {
return xmlSignatureFactory.newSignedInfo(canonicalizationMethod, signatureMethod, references);
}
/**
* Instantiate and attached to the contained XMLSignature the SignedInfo used to generate the SignedInfo node of the xml signature document.
* @return
*/
public XmlSignatureBuilder buildAndAttach() {
return xmlSignatureBuilder.withSignedInfo(build());
}
}