• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.bouncycastle.asn1;
2 
3 import java.io.IOException;
4 
5 /**
6  * A BIT STRING with DER encoding - the first byte contains the count of padding bits included in the byte array's last byte.
7  */
8 public class DERBitString
9     extends ASN1BitString
10 {
11     /**
12      * return a Bit String from the passed in object
13      *
14      * @param obj a DERBitString or an object that can be converted into one.
15      * @exception IllegalArgumentException if the object cannot be converted.
16      * @return a DERBitString instance, or null.
17      */
getInstance( Object obj)18     public static DERBitString getInstance(
19         Object  obj)
20     {
21         if (obj == null || obj instanceof DERBitString)
22         {
23             return (DERBitString)obj;
24         }
25         if (obj instanceof DLBitString)
26         {
27             return new DERBitString(((DLBitString)obj).data, ((DLBitString)obj).padBits);
28         }
29         if (obj instanceof byte[])
30         {
31             try
32             {
33                 return (DERBitString)fromByteArray((byte[])obj);
34             }
35             catch (Exception e)
36             {
37                 throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
38             }
39         }
40 
41         throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
42     }
43 
44     /**
45      * return a Bit String from a tagged object.
46      *
47      * @param obj the tagged object holding the object we want
48      * @param explicit true if the object is meant to be explicitly
49      *              tagged false otherwise.
50      * @exception IllegalArgumentException if the tagged object cannot
51      *               be converted.
52      * @return a DERBitString instance, or null.
53      */
getInstance( ASN1TaggedObject obj, boolean explicit)54     public static DERBitString getInstance(
55         ASN1TaggedObject obj,
56         boolean          explicit)
57     {
58         ASN1Primitive o = obj.getObject();
59 
60         if (explicit || o instanceof DERBitString)
61         {
62             return getInstance(o);
63         }
64         else
65         {
66             return fromOctetString(ASN1OctetString.getInstance(o).getOctets());
67         }
68     }
69 
DERBitString(byte data, int padBits)70     protected DERBitString(byte data, int padBits)
71     {
72         super(data, padBits);
73     }
74 
75     /**
76      * @param data the octets making up the bit string.
77      * @param padBits the number of extra bits at the end of the string.
78      */
DERBitString( byte[] data, int padBits)79     public DERBitString(
80         byte[]  data,
81         int     padBits)
82     {
83         super(data, padBits);
84     }
85 
DERBitString( byte[] data)86     public DERBitString(
87         byte[]  data)
88     {
89         this(data, 0);
90     }
91 
DERBitString( int value)92     public DERBitString(
93         int value)
94     {
95         super(getBytes(value), getPadBits(value));
96     }
97 
DERBitString( ASN1Encodable obj)98     public DERBitString(
99         ASN1Encodable obj)
100         throws IOException
101     {
102         super(obj.toASN1Primitive().getEncoded(ASN1Encoding.DER), 0);
103     }
104 
isConstructed()105     boolean isConstructed()
106     {
107         return false;
108     }
109 
encodedLength()110     int encodedLength()
111     {
112         return 1 + StreamUtil.calculateBodyLength(data.length + 1) + data.length + 1;
113     }
114 
encode(ASN1OutputStream out, boolean withTag)115     void encode(ASN1OutputStream out, boolean withTag) throws IOException
116     {
117         int len = data.length;
118         if (0 == len
119             || 0 == padBits
120             || (data[len - 1] == (byte)(data[len - 1] & (0xFF << padBits))))
121         {
122             out.writeEncoded(withTag, BERTags.BIT_STRING, (byte)padBits, data);
123         }
124         else
125         {
126             byte der = (byte)(data[len - 1] & (0xFF << padBits));
127             out.writeEncoded(withTag, BERTags.BIT_STRING, (byte)padBits, data, 0, len - 1, der);
128         }
129     }
130 
toDERObject()131     ASN1Primitive toDERObject()
132     {
133         return this;
134     }
135 
toDLObject()136     ASN1Primitive toDLObject()
137     {
138         return this;
139     }
140 
fromOctetString(byte[] bytes)141     static DERBitString fromOctetString(byte[] bytes)
142     {
143         if (bytes.length < 1)
144         {
145             throw new IllegalArgumentException("truncated BIT STRING detected");
146         }
147 
148         int padBits = bytes[0];
149         byte[] data = new byte[bytes.length - 1];
150 
151         if (data.length != 0)
152         {
153             System.arraycopy(bytes, 1, data, 0, bytes.length - 1);
154         }
155 
156         return new DERBitString(data, padBits);
157     }
158 }
159