use of org.apache.xml.security.signature.ObjectContainer in project xades4j by luisgoncalves.
the class DataObjFormatVerifier method verify.
@Override
public QualifyingProperty verify(DataObjectFormatData propData, QualifyingPropertyVerificationContext ctx) throws DataObjectFormatVerificationException {
QualifyingPropertyVerificationContext.SignedObjectsData signedObjsData = ctx.getSignedObjectsData();
String encoding = propData.getEncoding(), mimeType = propData.getMimeType();
// XAdES G.2.2.8: "The verifier should check that the ObjectReference element
// actually references one ds:Reference element from the signature."
RawDataObjectDesc signedObj = signedObjsData.findSignedDataObject(propData.getObjectRef());
if (null == signedObj)
throw new DataObjectFormatReferenceException(propData.getObjectRef());
// "In addition, should this property refer to a ds:Reference that in turn
// refers to a ds:Object, the verifier should check the values of attributes
// MimeType and Encoding (...)."
Reference signedObjRef = signedObj.getReference();
if (Reference.OBJECT_URI.equals(signedObjRef.getType())) {
// Get the referenced Object.
ObjectContainer signedObjObj = signedObjsData.findXMLObject(signedObjRef.getURI());
if (null == signedObjObj)
throw new DataObjectFormatReferenceException(signedObjRef.getURI());
String objEncoding = signedObjObj.getEncoding(), objMimeType = signedObjObj.getMimeType();
// Compare 'encoding' and 'mimeType', if present on both.
if (StringUtils.differentStringsIfNotNullNorEmpty(objEncoding, encoding) || StringUtils.differentStringsIfNotNullNorEmpty(objMimeType, mimeType))
throw new DataObjectFormatMismatchException(mimeType, encoding, signedObjRef, signedObjObj);
}
// Create the property.
DataObjectFormatProperty formatProp = new DataObjectFormatProperty(mimeType, encoding);
formatProp.withDescription(propData.getDescription());
Collection<String> docsUris = propData.getDocumentationUris();
if (docsUris != null)
formatProp.withDocumentationUris(docsUris);
formatProp.withIdentifier(propData.getIdentifier());
// Associate the property to the data object.
signedObj.withDataObjectFormat(formatProp);
return formatProp;
}
use of org.apache.xml.security.signature.ObjectContainer in project santuario-java by apache.
the class Bug45961Test method getSignedDocument.
private Document getSignedDocument() throws Exception {
KeyStore ks = KeyStore.getInstance("JKS");
FileInputStream fis = new FileInputStream(getAbsolutePath("src/test/resources/test.jks"));
ks.load(fis, PASSWORD);
fis.close();
PrivateKey privateKey = (PrivateKey) ks.getKey(ALIAS, PASSWORD);
X509Certificate signingCert = (X509Certificate) ks.getCertificate(ALIAS);
Document document = _builder.newDocument();
XMLSignature signature = new XMLSignature(document, null, XMLSignature.ALGO_ID_SIGNATURE_DSA, MOCK_CANONICALIZATION_METHOD);
Element root = document.createElementNS("", "RootElement");
root.appendChild(document.createTextNode("Some simple test\n"));
root.appendChild(signature.getElement());
document.appendChild(root);
// document.appendChild(signature.getElement());
Element root2 = document.createElementNS("", "RootElement");
root2.appendChild(document.createTextNode("Some simple test\n"));
object = new ObjectContainer(document);
object.appendChild(root2);
object.setId(OBJECT_ID);
root.appendChild(object.getElement());
signature.addDocument("#" + OBJECT_ID);
signature.addDocument("", getTransforms(document));
signature.addKeyInfo(signingCert);
signature.sign(privateKey);
return document;
}
use of org.apache.xml.security.signature.ObjectContainer in project xades4j by luisgoncalves.
the class SignedDataObjectsProcessor method process.
/**
* Processes the signed data objects and adds the corresponding {@code Reference}s
* and {@code Object}s to the signature. This method must be invoked before
* adding any other {@code Reference}s to the signature.
*
* @return the reference mappings resulting from the data object descriptions.
*
* @throws UnsupportedAlgorithmException
* @throws IllegalStateException if the signature already contains {@code Reference}s
*/
Map<DataObjectDesc, Reference> process(SignedDataObjects signedDataObjects, XMLSignature xmlSignature) throws UnsupportedAlgorithmException {
if (xmlSignature.getSignedInfo().getLength() != 0) {
throw new IllegalStateException("XMLSignature already contais references");
}
for (ResourceResolver resolver : signedDataObjects.getResourceResolvers()) {
xmlSignature.addResourceResolver(resolver);
}
Collection<DataObjectDesc> dataObjsDescs = signedDataObjects.getDataObjectsDescs();
Map<DataObjectDesc, Reference> referenceMappings = new IdentityHashMap<DataObjectDesc, Reference>(dataObjsDescs.size());
String refUri, refType;
Transforms transforms;
String digestMethodUri = this.algorithmsProvider.getDigestAlgorithmForDataObjsReferences();
boolean hasNullURIReference = false;
/**/
try {
for (DataObjectDesc dataObjDesc : dataObjsDescs) {
transforms = processTransforms(dataObjDesc, xmlSignature.getDocument());
if (dataObjDesc instanceof DataObjectReference) {
// If the data object info is a DataObjectReference, the Reference uri
// and type are the ones specified on the object.
DataObjectReference dataObjRef = (DataObjectReference) dataObjDesc;
refUri = dataObjRef.getUri();
refType = dataObjRef.getType();
} else if (dataObjDesc instanceof EnvelopedXmlObject) {
// If the data object info is a EnvelopedXmlObject we need to create a
// XMLObject to embed it. The Reference uri will refer the new
// XMLObject's id.
EnvelopedXmlObject envXmlObj = (EnvelopedXmlObject) dataObjDesc;
refUri = String.format("%s-object%d", xmlSignature.getId(), xmlSignature.getObjectLength());
refType = Reference.OBJECT_URI;
ObjectContainer xmlObj = new ObjectContainer(xmlSignature.getDocument());
xmlObj.setId(refUri);
xmlObj.appendChild(envXmlObj.getContent());
xmlObj.setMimeType(envXmlObj.getMimeType());
xmlObj.setEncoding(envXmlObj.getEncoding());
xmlSignature.appendObject(xmlObj);
refUri = '#' + refUri;
} else if (dataObjDesc instanceof AnonymousDataObjectReference) {
if (hasNullURIReference) {
// This shouldn't happen because SignedDataObjects does the validation.
throw new IllegalStateException("Multiple AnonymousDataObjectReference detected");
}
hasNullURIReference = true;
refUri = refType = null;
AnonymousDataObjectReference anonymousRef = (AnonymousDataObjectReference) dataObjDesc;
xmlSignature.addResourceResolver(new ResolverAnonymous(anonymousRef.getDataStream()));
} else {
throw new ClassCastException("Unsupported SignedDataObjectDesc. Must be one of DataObjectReference, EnvelopedXmlObject and AnonymousDataObjectReference");
}
// Add the Reference. References need an ID because data object
// properties may refer them.
xmlSignature.addDocument(refUri, transforms, digestMethodUri, // id
String.format("%s-ref%d", xmlSignature.getId(), referenceMappings.size()), refType);
// SignedDataObjects doesn't allow repeated instances, so there's no
// need to check for duplicate entries on the map.
Reference ref = xmlSignature.getSignedInfo().item(referenceMappings.size());
referenceMappings.put(dataObjDesc, ref);
}
} catch (XMLSignatureException ex) {
// algorithm is not supported.
throw new UnsupportedAlgorithmException("Digest algorithm not supported in the XML Signature provider", digestMethodUri, ex);
} catch (org.apache.xml.security.exceptions.XMLSecurityException ex) {
// when signing.
throw new IllegalStateException(ex);
}
return Collections.unmodifiableMap(referenceMappings);
}
use of org.apache.xml.security.signature.ObjectContainer 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.ObjectContainer in project xades4j by luisgoncalves.
the class DataGenArchiveTimeStamp method addPropSpecificTimeStampInput.
@Override
protected void addPropSpecificTimeStampInput(ArchiveTimeStampProperty prop, TimeStampDigestInput digestInput, PropertiesDataGenerationContext ctx) throws CannotAddDataToDigestInputException, PropertyDataGenerationException {
Element unsignedSigPropsElem = DOMHelper.getFirstDescendant(ctx.getTargetXmlSignature().getElement(), QualifyingProperty.XADES_XMLNS, QualifyingProperty.UNSIGNED_SIGNATURE_PROPS_TAG);
if (null == unsignedSigPropsElem)
throw new PropertyDataGenerationException(prop, "no unsigned signature properties to get inputs");
try {
// References, processed accordingly to XML-DSIG.
List<Reference> refs = ctx.getReferences();
for (Reference r : refs) {
digestInput.addReference(r);
}
// SignedInfo.
Element e = ctx.getTargetXmlSignature().getSignedInfo().getElement();
digestInput.addNode(e);
// SignatureValue.
e = DOMHelper.getFirstDescendant(ctx.getTargetXmlSignature().getElement(), Constants.SignatureSpecNS, Constants._TAG_SIGNATUREVALUE);
digestInput.addNode(e);
// KeyInfo, if present.
KeyInfo ki = ctx.getTargetXmlSignature().getKeyInfo();
if (ki != null)
digestInput.addNode(ki.getElement());
// Unsigned properties, in order of appearance.
Map<String, Integer> propsCnt = new HashMap<String, Integer>(5);
propsCnt.put(CertificateValuesProperty.PROP_NAME, 0);
propsCnt.put(RevocationValuesProperty.PROP_NAME, 0);
propsCnt.put(CompleteCertificateRefsProperty.PROP_NAME, 0);
propsCnt.put(CompleteRevocationRefsProperty.PROP_NAME, 0);
propsCnt.put(SignatureTimeStampProperty.PROP_NAME, 0);
e = DOMHelper.getFirstChildElement(unsignedSigPropsElem);
// UnsignedProperties shouldn't be empty!
do {
digestInput.addNode(e);
Integer pCnt = propsCnt.get(e.getLocalName());
if (pCnt != null)
propsCnt.put(e.getLocalName(), pCnt += 1);
} while ((e = DOMHelper.getNextSiblingElement(e)) != null);
for (Map.Entry<String, Integer> entry : propsCnt.entrySet()) {
if (entry.getValue() == 0)
throw new PropertyDataGenerationException(prop, String.format("no %s for input", entry.getKey()));
}
// Objects, except the one containing the qualifying properties.
for (int i = 0; i < ctx.getTargetXmlSignature().getObjectLength(); i++) {
ObjectContainer obj = ctx.getTargetXmlSignature().getObjectItem(i);
if (null == DOMHelper.getFirstDescendant(obj.getElement(), QualifyingProperty.XADES_XMLNS, "*"))
digestInput.addNode(obj.getElement());
}
} catch (CannotAddDataToDigestInputException ex) {
throw new PropertyDataGenerationException(prop, "cannot create time stamp input", ex);
}
}
Aggregations