Search in sources :

Example 1 with ObjectContainer

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;
}
Also used : Reference(org.apache.xml.security.signature.Reference) DataObjectFormatProperty(xades4j.properties.DataObjectFormatProperty) ObjectContainer(org.apache.xml.security.signature.ObjectContainer)

Example 2 with ObjectContainer

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;
}
Also used : PrivateKey(java.security.PrivateKey) XMLSignature(org.apache.xml.security.signature.XMLSignature) Element(org.w3c.dom.Element) Document(org.w3c.dom.Document) KeyStore(java.security.KeyStore) ObjectContainer(org.apache.xml.security.signature.ObjectContainer) FileInputStream(java.io.FileInputStream) X509Certificate(java.security.cert.X509Certificate)

Example 3 with ObjectContainer

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);
}
Also used : Reference(org.apache.xml.security.signature.Reference) IdentityHashMap(java.util.IdentityHashMap) Transforms(org.apache.xml.security.transforms.Transforms) ResolverAnonymous(org.apache.xml.security.utils.resolver.implementations.ResolverAnonymous) DataObjectDesc(xades4j.properties.DataObjectDesc) UnsupportedAlgorithmException(xades4j.UnsupportedAlgorithmException) ResourceResolver(org.apache.xml.security.utils.resolver.ResourceResolver) ObjectContainer(org.apache.xml.security.signature.ObjectContainer) XMLSignatureException(org.apache.xml.security.signature.XMLSignatureException)

Example 4 with ObjectContainer

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);
}
Also used : PrivateKey(java.security.PrivateKey) SigningCertChainException(xades4j.providers.SigningCertChainException) Element(org.w3c.dom.Element) Transforms(org.apache.xml.security.transforms.Transforms) ArrayList(java.util.ArrayList) Document(org.w3c.dom.Document) DataObjectDesc(xades4j.properties.DataObjectDesc) SigAndDataObjsPropertiesData(xades4j.properties.data.SigAndDataObjsPropertiesData) XAdES4jXMLSigException(xades4j.XAdES4jXMLSigException) XAdES4jException(xades4j.XAdES4jException) XMLSignature(org.apache.xml.security.signature.XMLSignature) Reference(org.apache.xml.security.signature.Reference) QualifyingProperties(xades4j.properties.QualifyingProperties) SignedSignatureProperty(xades4j.properties.SignedSignatureProperty) Algorithm(xades4j.algorithms.Algorithm) X509Certificate(java.security.cert.X509Certificate) UnsupportedAlgorithmException(xades4j.UnsupportedAlgorithmException) UnsignedSignatureProperty(xades4j.properties.UnsignedSignatureProperty) ObjectContainer(org.apache.xml.security.signature.ObjectContainer) XMLSignatureException(org.apache.xml.security.signature.XMLSignatureException)

Example 5 with ObjectContainer

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);
    }
}
Also used : CannotAddDataToDigestInputException(xades4j.utils.CannotAddDataToDigestInputException) HashMap(java.util.HashMap) Reference(org.apache.xml.security.signature.Reference) Element(org.w3c.dom.Element) KeyInfo(org.apache.xml.security.keys.KeyInfo) HashMap(java.util.HashMap) Map(java.util.Map) ObjectContainer(org.apache.xml.security.signature.ObjectContainer)

Aggregations

ObjectContainer (org.apache.xml.security.signature.ObjectContainer)8 Reference (org.apache.xml.security.signature.Reference)5 XMLSignature (org.apache.xml.security.signature.XMLSignature)5 Document (org.w3c.dom.Document)5 Transforms (org.apache.xml.security.transforms.Transforms)4 Element (org.w3c.dom.Element)4 PrivateKey (java.security.PrivateKey)3 DataObjectDesc (xades4j.properties.DataObjectDesc)3 FileInputStream (java.io.FileInputStream)2 KeyStore (java.security.KeyStore)2 X509Certificate (java.security.cert.X509Certificate)2 XMLSignatureException (org.apache.xml.security.signature.XMLSignatureException)2 XPathContainer (org.apache.xml.security.transforms.params.XPathContainer)2 UnsupportedAlgorithmException (xades4j.UnsupportedAlgorithmException)2 ByteArrayInputStream (java.io.ByteArrayInputStream)1 File (java.io.File)1 FileOutputStream (java.io.FileOutputStream)1 InputStream (java.io.InputStream)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1