1 package org.bouncycastle.asn1; 2 3 import java.io.IOException; 4 import java.math.BigInteger; 5 6 import org.bouncycastle.util.Arrays; 7 8 /** 9 * Class representing the ASN.1 INTEGER type. 10 */ 11 public class ASN1Integer 12 extends ASN1Primitive 13 { 14 private final byte[] bytes; 15 16 /** 17 * return an integer from the passed in object 18 * 19 * @param obj an ASN1Integer or an object that can be converted into one. 20 * @throws IllegalArgumentException if the object cannot be converted. 21 * @return an ASN1Integer instance. 22 */ getInstance( Object obj)23 public static ASN1Integer getInstance( 24 Object obj) 25 { 26 if (obj == null || obj instanceof ASN1Integer) 27 { 28 return (ASN1Integer)obj; 29 } 30 31 if (obj instanceof byte[]) 32 { 33 try 34 { 35 return (ASN1Integer)fromByteArray((byte[])obj); 36 } 37 catch (Exception e) 38 { 39 throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); 40 } 41 } 42 43 throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); 44 } 45 46 /** 47 * return an Integer from a tagged object. 48 * 49 * @param obj the tagged object holding the object we want 50 * @param explicit true if the object is meant to be explicitly 51 * tagged false otherwise. 52 * @throws IllegalArgumentException if the tagged object cannot 53 * be converted. 54 * @return an ASN1Integer instance. 55 */ getInstance( ASN1TaggedObject obj, boolean explicit)56 public static ASN1Integer getInstance( 57 ASN1TaggedObject obj, 58 boolean explicit) 59 { 60 ASN1Primitive o = obj.getObject(); 61 62 if (explicit || o instanceof ASN1Integer) 63 { 64 return getInstance(o); 65 } 66 else 67 { 68 return new ASN1Integer(ASN1OctetString.getInstance(obj.getObject()).getOctets()); 69 } 70 } 71 ASN1Integer( long value)72 public ASN1Integer( 73 long value) 74 { 75 bytes = BigInteger.valueOf(value).toByteArray(); 76 } 77 ASN1Integer( BigInteger value)78 public ASN1Integer( 79 BigInteger value) 80 { 81 bytes = value.toByteArray(); 82 } 83 ASN1Integer( byte[] bytes)84 public ASN1Integer( 85 byte[] bytes) 86 { 87 this(bytes, true); 88 } 89 ASN1Integer(byte[] bytes, boolean clone)90 ASN1Integer(byte[] bytes, boolean clone) 91 { 92 this.bytes = (clone) ? Arrays.clone(bytes) : bytes; 93 } 94 getValue()95 public BigInteger getValue() 96 { 97 return new BigInteger(bytes); 98 } 99 100 /** 101 * in some cases positive values get crammed into a space, 102 * that's not quite big enough... 103 * @return the BigInteger that results from treating this ASN.1 INTEGER as unsigned. 104 */ getPositiveValue()105 public BigInteger getPositiveValue() 106 { 107 return new BigInteger(1, bytes); 108 } 109 isConstructed()110 boolean isConstructed() 111 { 112 return false; 113 } 114 encodedLength()115 int encodedLength() 116 { 117 return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length; 118 } 119 encode( ASN1OutputStream out)120 void encode( 121 ASN1OutputStream out) 122 throws IOException 123 { 124 out.writeEncoded(BERTags.INTEGER, bytes); 125 } 126 hashCode()127 public int hashCode() 128 { 129 int value = 0; 130 131 for (int i = 0; i != bytes.length; i++) 132 { 133 value ^= (bytes[i] & 0xff) << (i % 4); 134 } 135 136 return value; 137 } 138 asn1Equals( ASN1Primitive o)139 boolean asn1Equals( 140 ASN1Primitive o) 141 { 142 if (!(o instanceof ASN1Integer)) 143 { 144 return false; 145 } 146 147 ASN1Integer other = (ASN1Integer)o; 148 149 return Arrays.areEqual(bytes, other.bytes); 150 } 151 toString()152 public String toString() 153 { 154 return getValue().toString(); 155 } 156 157 } 158