001package org.apache.commons.ssl.asn1;
002
003import java.io.IOException;
004import java.math.BigInteger;
005
006public class DERInteger
007    extends ASN1Object {
008    byte[] bytes;
009
010    /**
011     * return an integer from the passed in object
012     *
013     * @throws IllegalArgumentException if the object cannot be converted.
014     */
015    public static DERInteger getInstance(
016        Object obj) {
017        if (obj == null || obj instanceof DERInteger) {
018            return (DERInteger) obj;
019        }
020
021        if (obj instanceof ASN1OctetString) {
022            return new DERInteger(((ASN1OctetString) obj).getOctets());
023        }
024
025        if (obj instanceof ASN1TaggedObject) {
026            return getInstance(((ASN1TaggedObject) obj).getObject());
027        }
028
029        throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
030    }
031
032    /**
033     * return an Integer from a tagged object.
034     *
035     * @param obj      the tagged object holding the object we want
036     * @param explicit true if the object is meant to be explicitly
037     *                 tagged false otherwise.
038     * @throws IllegalArgumentException if the tagged object cannot
039     *                                  be converted.
040     */
041    public static DERInteger getInstance(
042        ASN1TaggedObject obj,
043        boolean explicit) {
044        return getInstance(obj.getObject());
045    }
046
047    public DERInteger(
048        int value) {
049        bytes = BigInteger.valueOf(value).toByteArray();
050    }
051
052    public DERInteger(
053        BigInteger value) {
054        bytes = value.toByteArray();
055    }
056
057    public DERInteger(
058        byte[] bytes) {
059        this.bytes = bytes;
060    }
061
062    public BigInteger getValue() {
063        return new BigInteger(bytes);
064    }
065
066    /**
067     * in some cases positive values get crammed into a space,
068     * that's not quite big enough...
069     */
070    public BigInteger getPositiveValue() {
071        return new BigInteger(1, bytes);
072    }
073
074    void encode(
075        DEROutputStream out)
076        throws IOException {
077        out.writeEncoded(INTEGER, bytes);
078    }
079
080    public int hashCode() {
081        int value = 0;
082
083        for (int i = 0; i != bytes.length; i++) {
084            value ^= (bytes[i] & 0xff) << (i % 4);
085        }
086
087        return value;
088    }
089
090    boolean asn1Equals(
091        DERObject o) {
092        if (!(o instanceof DERInteger)) {
093            return false;
094        }
095
096        DERInteger other = (DERInteger) o;
097
098        if (bytes.length != other.bytes.length) {
099            return false;
100        }
101
102        for (int i = 0; i != bytes.length; i++) {
103            if (bytes[i] != other.bytes[i]) {
104                return false;
105            }
106        }
107
108        return true;
109    }
110
111    public String toString() {
112        return getValue().toString();
113    }
114}