001    /**
002     *  Licensed to the Apache Software Foundation (ASF) under one or more
003     *  contributor license agreements.  See the NOTICE file distributed with
004     *  this work for additional information regarding copyright ownership.
005     *  The ASF licenses this file to You under the Apache License, Version 2.0
006     *  (the "License"); you may not use this file except in compliance with
007     *  the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     */
017    
018    package org.apache.geronimo.crypto.asn1;
019    
020    import java.io.IOException;
021    import java.math.BigInteger;
022    
023    public class DERInteger
024        extends DERObject
025    {
026        byte[]      bytes;
027    
028        /**
029         * return an integer from the passed in object
030         *
031         * @exception IllegalArgumentException if the object cannot be converted.
032         */
033        public static DERInteger getInstance(
034            Object  obj)
035        {
036            if (obj == null || obj instanceof DERInteger)
037            {
038                return (DERInteger)obj;
039            }
040    
041            if (obj instanceof ASN1OctetString)
042            {
043                return new DERInteger(((ASN1OctetString)obj).getOctets());
044            }
045    
046            if (obj instanceof ASN1TaggedObject)
047            {
048                return getInstance(((ASN1TaggedObject)obj).getObject());
049            }
050    
051            throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
052        }
053    
054        /**
055         * return an Integer from a tagged object.
056         *
057         * @param obj the tagged object holding the object we want
058         * @param explicit true if the object is meant to be explicitly
059         *              tagged false otherwise.
060         * @exception IllegalArgumentException if the tagged object cannot
061         *               be converted.
062         */
063        public static DERInteger getInstance(
064            ASN1TaggedObject obj,
065            boolean          explicit)
066        {
067            return getInstance(obj.getObject());
068        }
069    
070        public DERInteger(
071            int         value)
072        {
073            bytes = BigInteger.valueOf(value).toByteArray();
074        }
075    
076        public DERInteger(
077            BigInteger   value)
078        {
079            bytes = value.toByteArray();
080        }
081    
082        public DERInteger(
083            byte[]   bytes)
084        {
085            this.bytes = bytes;
086        }
087    
088        public BigInteger getValue()
089        {
090            return new BigInteger(bytes);
091        }
092    
093        /**
094         * in some cases positive values get crammed into a space,
095         * that's not quite big enough...
096         */
097        public BigInteger getPositiveValue()
098        {
099            return new BigInteger(1, bytes);
100        }
101    
102        void encode(
103            DEROutputStream out)
104            throws IOException
105        {
106            out.writeEncoded(INTEGER, bytes);
107        }
108    
109        public int hashCode()
110        {
111             int     value = 0;
112    
113             for (int i = 0; i != bytes.length; i++)
114             {
115                 value ^= (bytes[i] & 0xff) << (i % 4);
116             }
117    
118             return value;
119        }
120    
121        public boolean equals(
122            Object  o)
123        {
124            if (o == null || !(o instanceof DERInteger))
125            {
126                return false;
127            }
128    
129            DERInteger other = (DERInteger)o;
130    
131            if (bytes.length != other.bytes.length)
132            {
133                return false;
134            }
135    
136            for (int i = 0; i != bytes.length; i++)
137            {
138                if (bytes[i] != other.bytes[i])
139                {
140                    return false;
141                }
142            }
143    
144            return true;
145        }
146    }