1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.asn1; 2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 3b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.IOException; 4b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.util.Enumeration; 5b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 6b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam/** 7c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * BER TaggedObject - in ASN.1 notation this is any object preceded by 8c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * a [n] where n is some number - these are assumed to follow the construction 9b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * rules (as with sequences). 10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 11b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic class BERTaggedObject 124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom extends ASN1TaggedObject 13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{ 14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param tagNo the tag number for this object. 16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param obj the tagged object. 17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public BERTaggedObject( 19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int tagNo, 204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Encodable obj) 21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom super(true, tagNo, obj); 23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 25b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param explicit true if an explicitly tagged object. 27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param tagNo the tag number for this object. 28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param obj the tagged object. 29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public BERTaggedObject( 31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam boolean explicit, 32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int tagNo, 334c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Encodable obj) 34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 35b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam super(explicit, tagNo, obj); 36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 38b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 39b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * create an implicitly tagged object that contains a zero 40b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * length sequence. 41b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 42b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public BERTaggedObject( 43b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int tagNo) 44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 45b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam super(false, tagNo, new BERSequence()); 46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 47b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 484c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom boolean isConstructed() 494c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 504c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (!empty) 514c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 524c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (explicit) 534c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 544c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return true; 554c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 564c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom else 574c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 584c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Primitive primitive = obj.toASN1Primitive().toDERObject(); 594c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 604c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return primitive.isConstructed(); 614c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 624c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 634c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom else 644c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 654c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return true; 664c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 674c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 684c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 694c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom int encodedLength() 70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws IOException 71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 724c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (!empty) 73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 744c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Primitive primitive = obj.toASN1Primitive(); 754c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom int length = primitive.encodedLength(); 76b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 774c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (explicit) 784c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 794c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length; 804c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 814c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom else 82b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 834c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom // header length already in calculation 844c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom length = length - 1; 854c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 864c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return StreamUtil.calculateTagLength(tagNo) + length; 874c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 884c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 894c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom else 904c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 914c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return StreamUtil.calculateTagLength(tagNo) + 1; 924c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 934c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 944c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 954c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom void encode( 964c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1OutputStream out) 974c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom throws IOException 984c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 994c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom out.writeTag(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo); 1004c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom out.write(0x80); 1014c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 1024c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (!empty) 1034c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 1044c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (!explicit) 1054c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 1064c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom Enumeration e; 1074c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (obj instanceof ASN1OctetString) 108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1094c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (obj instanceof BEROctetString) 110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom e = ((BEROctetString)obj).getObjects(); 112b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 113b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1OctetString octs = (ASN1OctetString)obj; 1164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom BEROctetString berO = new BEROctetString(octs.getOctets()); 1174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom e = berO.getObjects(); 118c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom else if (obj instanceof ASN1Sequence) 1214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 1224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom e = ((ASN1Sequence)obj).getObjects(); 1234c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 1244c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom else if (obj instanceof ASN1Set) 1254c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 1264c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom e = ((ASN1Set)obj).getObjects(); 1274c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1304c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom throw new RuntimeException("not implemented: " + obj.getClass().getName()); 131b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1334c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom while (e.hasMoreElements()) 1344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 1354c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom out.writeObject((ASN1Encodable)e.nextElement()); 1364c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 1374c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 1384c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom else 1394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 1404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom out.writeObject(obj); 1414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 142b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 1444c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom out.write(0x00); 1454c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom out.write(0x00); 146b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 147b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam} 148