com.aaasec.sigserv.cscommon.xmldsig.EcdsaSigValue.java Source code

Java tutorial

Introduction

Here is the source code for com.aaasec.sigserv.cscommon.xmldsig.EcdsaSigValue.java

Source

/*
 *  NFCSigning - Open source library for signing/validation of NDEF messages
 *  Copyright (C) 2009-2010 The NFCSigning Team
 *
 *  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 com.aaasec.sigserv.cscommon.xmldsig;

import java.math.BigInteger;
import java.util.Enumeration;
import java.util.logging.Logger;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DERInteger;
import org.bouncycastle.asn1.DERSequence;

/**
 * ECDSA signature value functions
 */
public class EcdsaSigValue implements ASN1Encodable {

    private BigInteger r;
    private BigInteger s;

    public static EcdsaSigValue getInstance(ASN1TaggedObject obj, boolean explicit) {
        return getInstance(ASN1Sequence.getInstance(obj, explicit));
    }

    public static EcdsaSigValue getInstance(Object obj) {
        if (obj instanceof EcdsaSigValue) {
            return (EcdsaSigValue) obj;
        } else if (obj instanceof ASN1Sequence) {
            return new EcdsaSigValue((ASN1Sequence) obj);
        }

        throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName());
    }

    public static EcdsaSigValue getInstance(byte[] concatenatedRS) {
        BigInteger[] rsVals = getRSfromConcatenatedBytes(concatenatedRS);
        try {
            return new EcdsaSigValue(rsVals[0], rsVals[1]);
        } catch (Exception ex) {
            return null;
        }
    }

    public static EcdsaSigValue getInstance(ASN1Sequence a1s) {
        return new EcdsaSigValue(a1s);
    }

    public EcdsaSigValue(BigInteger r, BigInteger s) {
        this.r = r;
        this.s = s;
    }

    public EcdsaSigValue(ASN1Sequence obj) {
        Enumeration e = obj.getObjects();

        r = DERInteger.getInstance(e.nextElement()).getValue();
        s = DERInteger.getInstance(e.nextElement()).getValue();
    }

    public BigInteger getR() {
        return r;
    }

    public BigInteger getS() {
        return s;
    }

    private static BigInteger[] getRSfromConcatenatedBytes(byte[] concatenatedRS) {
        try {
            int rLen, sLen;
            int len = concatenatedRS.length;
            rLen = len / 2;
            sLen = rLen;

            byte[] rBytes = new byte[rLen];
            byte[] sBytes = new byte[sLen];

            System.arraycopy(concatenatedRS, 0, rBytes, 0, rLen);
            System.arraycopy(concatenatedRS, rLen, sBytes, 0, sLen);

            BigInteger[] srArray = new BigInteger[2];
            srArray[0] = getBigInt(rBytes);
            srArray[1] = getBigInt(sBytes);

            return srArray;

        } catch (Exception ex) {
            return null;
        }
    }

    public DERSequence toASN1Object() {
        ASN1EncodableVector v = new ASN1EncodableVector();

        v.add(new DERInteger(r));
        v.add(new DERInteger(s));

        return new DERSequence(v);
    }

    /**
     * Returns the concatenation of the bytes of r and s
     *
     * @return byte array representation of signature value
     */
    public byte[] toByteArray(int keyLen) {
        try {
            byte[] rBytes = trimByteArray(r.toByteArray(), keyLen);
            byte[] sBytes = trimByteArray(s.toByteArray(), keyLen);
            byte[] rsBytes = new byte[rBytes.length + sBytes.length];
            System.arraycopy(rBytes, 0, rsBytes, 0, rBytes.length);
            System.arraycopy(sBytes, 0, rsBytes, rBytes.length, sBytes.length);

            return rsBytes;
        } catch (Exception ex) {
            Logger.getLogger(EcdsaSigValue.class.getName()).warning(ex.getMessage());
        }
        return null;
    }

    private static byte[] trimByteArray(byte[] inpBytes, int keyLen) {
        int len = inpBytes.length;
        int tLen = keyLen / 8;
        if (len == tLen) {
            return inpBytes;
        }
        byte[] trimmed = new byte[tLen];

        if (len < tLen) {
            int padCnt = tLen - len;
            for (int i = 0; i < padCnt; i++) {
                trimmed[i] = 0x00;
                System.arraycopy(inpBytes, 0, trimmed, padCnt, len);
            }
        }

        if (len > tLen) {
            int truncCnt = len - tLen;
            System.arraycopy(inpBytes, truncCnt, trimmed, 0, len - truncCnt);
        }

        return trimmed;

    }

    private static BigInteger getBigInt(byte[] source) {
        byte[] padded = new byte[source.length + 1];
        padded[0] = 0x00;
        System.arraycopy(source, 0, padded, 1, source.length);
        return new BigInteger(padded);
    }

    public ASN1Primitive toASN1Primitive() {
        return toASN1Object();
    }
}