eu.europa.esig.dss.xades.signature.DSSSignatureUtils.java Source code

Java tutorial

Introduction

Here is the source code for eu.europa.esig.dss.xades.signature.DSSSignatureUtils.java

Source

/**
 * DSS - Digital Signature Services
 * Copyright (C) 2015 European Commission, provided under the CEF programme
 *
 * This file is part of the "DSS - Digital Signature Services" project.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
package eu.europa.esig.dss.xades.signature;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

import org.apache.commons.io.IOUtils;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.util.BigIntegers;

import eu.europa.esig.dss.DSSException;
import eu.europa.esig.dss.EncryptionAlgorithm;

/**
 * This is the utility class to manipulate different signature types.
 *
 */
public final class DSSSignatureUtils {

    private DSSSignatureUtils() {
    }

    /**
     * Converts the binary signature value to the Xml DSig format in function of used algorithm
     *
     * @param algorithm
     *            Signature algorithm used to create the signatureValue
     * @param signatureValue
     * @return
     */
    public static byte[] convertToXmlDSig(final EncryptionAlgorithm algorithm, byte[] signatureValue) {
        if (EncryptionAlgorithm.ECDSA == algorithm) {
            return convertECDSAASN1toXMLDSIG(signatureValue);
        } else if (EncryptionAlgorithm.DSA == algorithm) {
            return convertDSAASN1toXMLDSIG(signatureValue);
        } else {
            return signatureValue;
        }
    }

    /**
     * Converts an ASN.1 ECDSA value to a XML Signature ECDSA Value.
     *
     * The JAVA JCE ECDSA Signature algorithm creates ASN.1 encoded (r,s) value pairs; the XML Signature requires the
     * core BigInteger values.
     *
     * @param binaries
     *            the ASN1 signature value
     * @return the decode bytes
     * @throws IOException
     * @see <A HREF="http://www.w3.org/TR/xmldsig-core/#dsa-sha1">6.4.1 DSA</A>
     * @see <A HREF="ftp://ftp.rfc-editor.org/in-notes/rfc4050.txt">3.3. ECDSA Signatures</A>
     */
    private static byte[] convertECDSAASN1toXMLDSIG(byte[] binaries) {
        ASN1InputStream is = null;
        try {
            is = new ASN1InputStream(binaries);

            ASN1Sequence seq = (ASN1Sequence) is.readObject();
            if (seq.size() != 2) {
                throw new IllegalArgumentException("ASN1 Sequence size should be 2 !");
            }
            ASN1Integer r = (ASN1Integer) seq.getObjectAt(0);
            ASN1Integer s = (ASN1Integer) seq.getObjectAt(1);

            byte[] rBytes = r.getValue().toByteArray();
            int rSize = rBytes.length;
            byte[] sBytes = s.getValue().toByteArray();
            int sSize = sBytes.length;

            int max = Math.max(rSize, sSize);

            ByteArrayOutputStream buffer = new ByteArrayOutputStream(max * 2);
            if (sSize > rSize) {
                buffer.write(0x00);
            }
            buffer.write(rBytes);
            if (rSize > sSize) {
                buffer.write(0x00);
            }
            buffer.write(sBytes);
            return buffer.toByteArray();
        } catch (Exception e) {
            throw new DSSException("Unable to convert to xmlDsig : " + e.getMessage(), e);
        } finally {
            IOUtils.closeQuietly(is);
        }
    }

    /**
     * Converts an ASN.1 DSA value to a XML Signature DSA Value.
     *
     * The JAVA JCE DSA Signature algorithm creates ASN.1 encoded (r,s) value pairs; the XML Signature requires the
     * core BigInteger values.
     *
     * @param binaries
     *            the ASN1 signature value
     * @return the decode bytes
     * @throws IOException
     * @see <A HREF="http://www.w3.org/TR/xmldsig-core/#dsa-sha1">6.4.1 DSA</A>
     * @see <A HREF="ftp://ftp.rfc-editor.org/in-notes/rfc4050.txt">3.3. ECDSA Signatures</A>
     */
    private static byte[] convertDSAASN1toXMLDSIG(byte[] binaries) {
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        ASN1InputStream is = null;
        try {
            is = new ASN1InputStream(binaries);

            ASN1Sequence seq = (ASN1Sequence) is.readObject();
            if (seq.size() != 2) {
                throw new IllegalArgumentException("ASN1 Sequence size should be 2 !");
            }

            ASN1Integer r = (ASN1Integer) seq.getObjectAt(0);
            ASN1Integer s = (ASN1Integer) seq.getObjectAt(1);

            buffer.write(BigIntegers.asUnsignedByteArray(r.getValue()));
            buffer.write(BigIntegers.asUnsignedByteArray(s.getValue()));
        } catch (Exception e) {
            throw new DSSException("Unable to convert to xmlDsig : " + e.getMessage(), e);
        } finally {
            IOUtils.closeQuietly(is);
        }
        return buffer.toByteArray();
    }

}