use of org.apache.xml.security.signature.XMLSignature in project xades4j by luisgoncalves.
the class SignerBES method sign.
@Override
public final XadesSignatureResult sign(SignedDataObjects signedDataObjects, Node referenceNode, SignatureAppendingStrategy appendingStrategy) throws XAdES4jException {
if (null == referenceNode) {
throw new NullPointerException("Reference node node cannot be null");
}
if (null == signedDataObjects) {
throw new NullPointerException("References cannot be null");
}
if (signedDataObjects.isEmpty()) {
throw new IllegalArgumentException("Data objects list is empty");
}
Document signatureDocument = DOMHelper.getOwnerDocument(referenceNode);
// Generate unique identifiers for the Signature and the SignedProperties.
String signatureId = String.format("xmldsig-%s", UUID.randomUUID());
String signedPropsId = String.format("%s-signedprops", signatureId);
// Signing certificate chain (may contain only the signing certificate).
List<X509Certificate> signingCertificateChain = this.keyingProvider.getSigningCertificateChain();
if (null == signingCertificateChain || signingCertificateChain.isEmpty()) {
throw new SigningCertChainException("Signing certificate not provided");
}
X509Certificate signingCertificate = signingCertificateChain.get(0);
// The XMLSignature (ds:Signature).
XMLSignature signature = createSignature(signatureDocument, signedDataObjects.getBaseUri(), signingCertificate.getPublicKey().getAlgorithm());
signature.setId(signatureId);
/* References */
// Process the data object descriptions to get the References and mappings.
// After this call all the signed data objects References and XMLObjects
// are added to the signature.
Map<DataObjectDesc, Reference> referenceMappings = this.dataObjectDescsProcessor.process(signedDataObjects, signature);
/* ds:KeyInfo */
this.keyInfoBuilder.buildKeyInfo(signingCertificate, signature);
/* QualifyingProperties element */
// Create the QualifyingProperties element
Element qualifyingPropsElem = ElementProxy.createElementForFamily(signature.getDocument(), QualifyingProperty.XADES_XMLNS, QualifyingProperty.QUALIFYING_PROPS_TAG);
qualifyingPropsElem.setAttributeNS(null, QualifyingProperty.TARGET_ATTR, '#' + signatureId);
qualifyingPropsElem.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:xades141", QualifyingProperty.XADESV141_XMLNS);
// ds:Object to contain QualifyingProperties
ObjectContainer qPropsXmlObj = new ObjectContainer(signature.getDocument());
qPropsXmlObj.appendChild(qualifyingPropsElem);
try {
signature.appendObject(qPropsXmlObj);
} catch (XMLSignatureException ex) {
// -> xmlSignature.appendObject(xmlObj): not thrown when signing.
throw new IllegalStateException(ex);
}
/* Collect the properties */
// Get the format specific signature properties.
Collection<SignedSignatureProperty> fsssp = new ArrayList<SignedSignatureProperty>(2);
Collection<UnsignedSignatureProperty> fsusp = new ArrayList<UnsignedSignatureProperty>(2);
getFormatSpecificSignatureProperties(fsssp, fsusp, signingCertificateChain);
// Gather all the signature and data objects properties.
QualifyingProperties qualifProps = qualifPropsProcessor.getQualifyingProperties(signedDataObjects, fsssp, fsusp);
try {
// The signature needs to be appended to the document from now on because
// property data generation may need to dereference same-document data
// object references.
appendingStrategy.append(signature.getElement(), referenceNode);
/* Signed properties */
// Create the context for signed properties data objects generation.
PropertiesDataGenerationContext propsDataGenCtx = new PropertiesDataGenerationContext(signedDataObjects.getDataObjectsDescs(), referenceMappings, signatureDocument);
// Generate the signed properties data objects. The data objects structure
// is verifier in the process.
SigAndDataObjsPropertiesData signedPropsData = this.propsDataObjectsGenerator.generateSignedPropertiesData(qualifProps.getSignedProperties(), propsDataGenCtx);
// Marshal the signed properties data to the QualifyingProperties node.
this.signedPropsMarshaller.marshal(signedPropsData, qualifyingPropsElem);
Element signedPropsElem = DOMHelper.getFirstChildElement(qualifyingPropsElem);
DOMHelper.setIdAsXmlId(signedPropsElem, signedPropsId);
// SignedProperties reference
// XAdES 6.3.1: "In order to protect the properties with the signature,
// a ds:Reference element MUST be added to the XMLDSIG signature (...)
// composed in such a way that it uses the SignedProperties element (...)
// as the input for computing its corresponding digest. Additionally,
// (...) use the Type attribute of this particular ds:Reference element,
// with its value set to: http://uri.etsi.org/01903#SignedProperties."
String digestAlgUri = algorithmsProvider.getDigestAlgorithmForDataObjsReferences();
if (StringUtils.isNullOrEmptyString(digestAlgUri)) {
throw new NullPointerException("Digest algorithm URI not provided");
}
// Use same canonicalization URI as specified in the ds:CanonicalizationMethod for Signature.
Algorithm canonAlg = this.algorithmsProvider.getCanonicalizationAlgorithmForSignature();
try {
CanonicalizerUtils.checkC14NAlgorithm(canonAlg);
Transforms transforms = TransformUtils.createTransforms(canonAlg, this.algorithmsParametersMarshaller, signatureDocument);
signature.addDocument('#' + signedPropsId, transforms, digestAlgUri, null, QualifyingProperty.SIGNED_PROPS_TYPE_URI);
} catch (XMLSignatureException ex) {
// shouldn't be thrown now!
throw new UnsupportedAlgorithmException("Digest algorithm not supported in the XML Signature provider", digestAlgUri, ex);
}
// Apply the signature
try {
PrivateKey signingKey = keyingProvider.getSigningKey(signingCertificate);
signature.sign(signingKey);
} catch (XMLSignatureException ex) {
throw new XAdES4jXMLSigException(ex.getMessage(), ex);
}
// Set the ds:SignatureValue id.
Element sigValueElem = DOMHelper.getFirstDescendant(signature.getElement(), Constants.SignatureSpecNS, Constants._TAG_SIGNATUREVALUE);
DOMHelper.setIdAsXmlId(sigValueElem, String.format("%s-sigvalue", signatureId));
/* Marshal unsigned properties */
// Generate the unsigned properties data objects. The data objects structure
// is verifier in the process.
propsDataGenCtx.setTargetXmlSignature(signature);
SigAndDataObjsPropertiesData unsignedPropsData = this.propsDataObjectsGenerator.generateUnsignedPropertiesData(qualifProps.getUnsignedProperties(), propsDataGenCtx);
// Marshal the unsigned properties to the final QualifyingProperties node.
this.unsignedPropsMarshaller.marshal(unsignedPropsData, qualifyingPropsElem);
} catch (XAdES4jException ex) {
appendingStrategy.revert(signature.getElement(), referenceNode);
throw ex;
}
return new XadesSignatureResult(signature, qualifProps);
}
use of org.apache.xml.security.signature.XMLSignature in project xades4j by luisgoncalves.
the class XadesSignatureFormatExtenderImplTest method testEnrichSignatureWithT.
@Test
public void testEnrichSignatureWithT() throws Exception {
System.out.println("enrichSignatureWithT");
Document doc = getDocument("document.signed.bes.xml");
Element signatureNode = (Element) doc.getElementsByTagNameNS(Constants.SignatureSpecNS, "Signature").item(0);
XadesSignatureFormatExtenderImpl instance = (XadesSignatureFormatExtenderImpl) new XadesFormatExtenderProfile().getFormatExtender();
XMLSignature sig = new XMLSignature(signatureNode, "");
Collection<UnsignedSignatureProperty> usp = new ArrayList<UnsignedSignatureProperty>(1);
usp.add(new SignatureTimeStampProperty());
instance.enrichSignature(sig, new UnsignedProperties(usp));
outputDocument(doc, "document.signed.bes.enriched.t.xml");
}
use of org.apache.xml.security.signature.XMLSignature in project xades4j by luisgoncalves.
the class XadesVerifierImpl method verify.
@Override
public XAdESVerificationResult verify(Element signatureElem, SignatureSpecificVerificationOptions verificationOptions) throws XAdES4jException {
if (null == signatureElem) {
throw new NullPointerException("Signature node not specified");
}
if (null == verificationOptions) {
verificationOptions = SignatureSpecificVerificationOptions.empty;
}
/* Unmarshal the signature */
XMLSignature signature;
try {
signature = new XMLSignature(signatureElem, verificationOptions.getBaseUri(), this.secureValidation);
} catch (XMLSecurityException ex) {
throw new UnmarshalException("Bad XML signature", ex);
}
String signatureId = signature.getId();
if (null == signatureId) {
throw new UnmarshalException("XML signature doesn't have an Id");
}
ReferencesRes referencesRes = SignatureUtils.processReferences(signature);
/* Apply early verifiers */
RawSignatureVerifierContext rawCtx = new RawSignatureVerifierContext(signature);
for (RawSignatureVerifier rawSignatureVerifier : this.rawSigVerifiers) {
rawSignatureVerifier.verify(rawCtx);
}
/* Get and check the QualifyingProperties element */
Element qualifyingPropsElem = SignatureUtils.getQualifyingPropertiesElement(signature);
SignatureUtils.checkSignedPropertiesIncorporation(qualifyingPropsElem, referencesRes.signedPropsReference);
// Check the QualifyingProperties 'Target' attribute.
Node targetAttr = qualifyingPropsElem.getAttributeNodeNS(null, QualifyingProperty.TARGET_ATTR);
if (null == targetAttr) {
targetAttr = qualifyingPropsElem.getAttributeNodeNS(QualifyingProperty.XADES_XMLNS, QualifyingProperty.TARGET_ATTR);
if (null == targetAttr) {
throw new QualifyingPropertiesIncorporationException("QualifyingProperties Target attribute not present");
}
}
String targetValue = targetAttr.getNodeValue();
if (null == targetValue || !targetValue.startsWith("#") || !targetValue.substring(1).equals(signatureId)) {
throw new QualifyingPropertiesIncorporationException("QualifyingProperties target doesn't match the signature's Id");
}
/* Unmarshal the qualifying properties */
QualifPropsDataCollectorImpl propsDataCollector = new QualifPropsDataCollectorImpl();
qualifPropsUnmarshaller.unmarshalProperties(qualifyingPropsElem, propsDataCollector);
Collection<PropertyDataObject> qualifPropsData = propsDataCollector.getPropertiesData();
/* Certification path */
KeyInfoRes keyInfoRes = SignatureUtils.processKeyInfo(signature.getKeyInfo());
Date validationDate = getValidationDate(qualifPropsData, signature, verificationOptions);
ValidationData certValidationRes = this.certificateValidator.validate(keyInfoRes.certSelector, validationDate, keyInfoRes.keyInfoCerts);
if (null == certValidationRes || certValidationRes.getCerts().isEmpty()) {
throw new NullPointerException("Certificate validator returned null or empty data");
}
X509Certificate validationCert = certValidationRes.getCerts().get(0);
/* Signature verification */
// Core XML-DSIG verification.
doCoreVerification(signature, verificationOptions, validationCert);
// Create the properties verification context.
QualifyingPropertyVerificationContext qPropsCtx = new QualifyingPropertyVerificationContext(signature, new QualifyingPropertyVerificationContext.CertificationChainData(certValidationRes.getCerts(), certValidationRes.getCrls(), keyInfoRes.issuerSerial), /**/
new QualifyingPropertyVerificationContext.SignedObjectsData(referencesRes.dataObjsReferences, signature));
// Verify the properties. Data structure verification is included.
Collection<PropertyInfo> props = this.qualifyingPropertiesVerifier.verifyProperties(qualifPropsData, qPropsCtx);
XAdESVerificationResult res = new XAdESVerificationResult(XAdESFormChecker.checkForm(props), signature, certValidationRes, props, referencesRes.dataObjsReferences);
// Apply the custom signature verifiers.
for (CustomSignatureVerifier customVer : this.customSigVerifiers) {
customVer.verify(res, qPropsCtx);
}
return res;
}
use of org.apache.xml.security.signature.XMLSignature in project xades4j by luisgoncalves.
the class KeyInfoBuilderTest method testSignSigningCertificateIfIncluded.
@Test
public void testSignSigningCertificateIfIncluded() throws Exception {
System.out.println("signSigningCertificateIfIncluded");
KeyInfoBuilder keyInfoBuilder = new KeyInfoBuilder(new TestBasicSignatureOptionsProvider(true, true, true), new TestAlgorithmsProvider(), new TestAlgorithmsParametersMarshallingProvider());
XMLSignature xmlSignature = getTestSignature();
keyInfoBuilder.buildKeyInfo(testCertificate, xmlSignature);
SignedInfo signedInfo = xmlSignature.getSignedInfo();
Assert.assertEquals(1, signedInfo.getLength());
Node refNode = signedInfo.item(0).getContentsBeforeTransformation().getSubNode();
Assert.assertSame(xmlSignature.getKeyInfo().getElement(), refNode);
Assert.assertEquals(1, xmlSignature.getKeyInfo().lengthX509Data());
}
use of org.apache.xml.security.signature.XMLSignature in project xades4j by luisgoncalves.
the class SignedDataObjectsProcessorTest method testAddMultipleNullReferencesFails.
@Test(expected = IllegalStateException.class)
public void testAddMultipleNullReferencesFails() throws Exception {
System.out.println("addMultipleNullReferencesFails");
Document doc = SignatureServicesTestBase.getNewDocument();
SignedDataObjects dataObjsDescs = new SignedDataObjects().withSignedDataObject(new AnonymousDataObjectReference("data1".getBytes())).withSignedDataObject(new AnonymousDataObjectReference("data2".getBytes()));
XMLSignature xmlSignature = new XMLSignature(doc, "", XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256);
xmlSignature.setId("sigId");
SignedDataObjectsProcessor processor = new SignedDataObjectsProcessor(new TestAlgorithmsProvider(), new AllwaysNullAlgsParamsMarshaller());
processor.process(dataObjsDescs, xmlSignature);
}
Aggregations