001package org.apache.commons.ssl.org.bouncycastle.asn1; 002 003import java.io.IOException; 004import java.math.BigInteger; 005 006import org.bouncycastle.util.Arrays; 007 008/** 009 * Class representing the ASN.1 INTEGER type. 010 */ 011public class ASN1Integer 012 extends ASN1Primitive 013{ 014 byte[] bytes; 015 016 /** 017 * return an integer from the passed in object 018 * 019 * @param obj an ASN1Integer or an object that can be converted into one. 020 * @throws IllegalArgumentException if the object cannot be converted. 021 * @return an ASN1Integer instance. 022 */ 023 public static ASN1Integer getInstance( 024 Object obj) 025 { 026 if (obj == null || obj instanceof ASN1Integer) 027 { 028 return (ASN1Integer)obj; 029 } 030 031 if (obj instanceof byte[]) 032 { 033 try 034 { 035 return (ASN1Integer)fromByteArray((byte[])obj); 036 } 037 catch (Exception e) 038 { 039 throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); 040 } 041 } 042 043 throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); 044 } 045 046 /** 047 * return an Integer from a tagged object. 048 * 049 * @param obj the tagged object holding the object we want 050 * @param explicit true if the object is meant to be explicitly 051 * tagged false otherwise. 052 * @throws IllegalArgumentException if the tagged object cannot 053 * be converted. 054 * @return an ASN1Integer instance. 055 */ 056 public static ASN1Integer getInstance( 057 ASN1TaggedObject obj, 058 boolean explicit) 059 { 060 ASN1Primitive o = obj.getObject(); 061 062 if (explicit || o instanceof ASN1Integer) 063 { 064 return getInstance(o); 065 } 066 else 067 { 068 return new ASN1Integer(ASN1OctetString.getInstance(obj.getObject()).getOctets()); 069 } 070 } 071 072 public ASN1Integer( 073 long value) 074 { 075 bytes = BigInteger.valueOf(value).toByteArray(); 076 } 077 078 public ASN1Integer( 079 BigInteger value) 080 { 081 bytes = value.toByteArray(); 082 } 083 084 public ASN1Integer( 085 byte[] bytes) 086 { 087 this(bytes, true); 088 } 089 090 ASN1Integer(byte[] bytes, boolean clone) 091 { 092 this.bytes = (clone) ? Arrays.clone(bytes) : bytes; 093 } 094 095 public BigInteger getValue() 096 { 097 return new BigInteger(bytes); 098 } 099 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 */ 105 public BigInteger getPositiveValue() 106 { 107 return new BigInteger(1, bytes); 108 } 109 110 boolean isConstructed() 111 { 112 return false; 113 } 114 115 int encodedLength() 116 { 117 return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length; 118 } 119 120 void encode( 121 ASN1OutputStream out) 122 throws IOException 123 { 124 out.writeEncoded(BERTags.INTEGER, bytes); 125 } 126 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 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 152 public String toString() 153 { 154 return getValue().toString(); 155 } 156 157}