1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.asn1; 2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 3b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.IOException; 46e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 579d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro/** 679d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro * A BIT STRING with DER encoding. 779d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro */ 8b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic class DERBitString 979d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro extends ASN1BitString 10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{ 11b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 12b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * return a Bit String from the passed in object 13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 14d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root * @param obj a DERBitString or an object that can be converted into one. 15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @exception IllegalArgumentException if the object cannot be converted. 16d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root * @return a DERBitString instance, or null. 17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public static DERBitString getInstance( 19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Object obj) 20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (obj == null || obj instanceof DERBitString) 22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return (DERBitString)obj; 24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 2579d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro if (obj instanceof DLBitString) 2679d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro { 2779d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro return new DERBitString(((DLBitString)obj).data, ((DLBitString)obj).padBits); 2879d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro } 29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); 31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * return a Bit String from a tagged object. 35b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param obj the tagged object holding the object we want 37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param explicit true if the object is meant to be explicitly 38b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * tagged false otherwise. 39b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @exception IllegalArgumentException if the tagged object cannot 40b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * be converted. 41d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root * @return a DERBitString instance, or null. 42b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 43b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public static DERBitString getInstance( 44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1TaggedObject obj, 45b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam boolean explicit) 46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 474c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Primitive o = obj.getObject(); 486e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 496e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom if (explicit || o instanceof DERBitString) 506e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 516e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom return getInstance(o); 526e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 536e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom else 546e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 556e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom return fromOctetString(((ASN1OctetString)o).getOctets()); 566e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected DERBitString( 60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte data, 61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int padBits) 62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 6379d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro this(toByteArray(data), padBits); 6479d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro } 6579d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro 6679d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro private static byte[] toByteArray(byte data) 6779d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro { 6879d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro byte[] rv = new byte[1]; 6979d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro 7079d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro rv[0] = data; 7179d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro 7279d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro return rv; 73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 75b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 76b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param data the octets making up the bit string. 77b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param padBits the number of extra bits at the end of the string. 78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 79b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public DERBitString( 80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] data, 81b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int padBits) 82b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 8379d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro super(data, padBits); 84b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public DERBitString( 87b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] data) 88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 89b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam this(data, 0); 90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 91b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public DERBitString( 9370c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom int value) 94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 9579d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro super(getBytes(value), getPadBits(value)); 9670c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom } 9770c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom 9870c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom public DERBitString( 9970c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom ASN1Encodable obj) 10070c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom throws IOException 10170c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom { 10279d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro super(obj.toASN1Primitive().getEncoded(ASN1Encoding.DER), 0); 103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1044c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 1054c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom boolean isConstructed() 1064c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 1074c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return false; 1084c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 1094c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 1104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom int encodedLength() 1114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 1124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return 1 + StreamUtil.calculateBodyLength(data.length + 1) + data.length + 1; 1134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 1144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam void encode( 1164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1OutputStream out) 117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws IOException 118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 11979d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro byte[] string = derForm(data, padBits); 12079d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro byte[] bytes = new byte[string.length + 1]; 121b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam bytes[0] = (byte)getPadBits(); 12379d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro System.arraycopy(string, 0, bytes, 1, bytes.length - 1); 124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1254c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom out.writeEncoded(BERTags.BIT_STRING, bytes); 126b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 127b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1286e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom static DERBitString fromOctetString(byte[] bytes) 1296e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 1306e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom if (bytes.length < 1) 1316e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 1326e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom throw new IllegalArgumentException("truncated BIT STRING detected"); 1336e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 1346e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 1356e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom int padBits = bytes[0]; 1366e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom byte[] data = new byte[bytes.length - 1]; 1376e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 1386e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom if (data.length != 0) 1396e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 1406e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom System.arraycopy(bytes, 1, data, 0, bytes.length - 1); 1416e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 1426e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 1436e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom return new DERBitString(data, padBits); 1446e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 145b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam} 146