1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.asn1; 2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 3b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.IOException; 4b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 5b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam/** 6c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * DER TaggedObject - in ASN.1 notation this is any object preceded by 7c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * a [n] where n is some number - these are assumed to follow the construction 8b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * rules (as with sequences). 9b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic class DERTaggedObject 11b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam extends ASN1TaggedObject 12b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{ 13c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private static final byte[] ZERO_BYTES = new byte[0]; 14c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom * @param explicit true if an explicitly tagged object. 17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param tagNo the tag number for this object. 18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param obj the tagged object. 19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public DERTaggedObject( 214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom boolean explicit, 224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom int tagNo, 234c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Encodable obj) 24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 254c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom super(explicit, tagNo, obj); 26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 284c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom public DERTaggedObject(int tagNo, ASN1Encodable encodable) 29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 304c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom super(true, tagNo, encodable); 31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 334c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom boolean isConstructed() 34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 354c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (!empty) 364c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 374c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (explicit) 384c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return true; 404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom else 424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Primitive primitive = obj.toASN1Primitive().toDERObject(); 444c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 454c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return primitive.isConstructed(); 464c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 474c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 484c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom else 494c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 504c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return true; 514c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 524c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 534c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 544c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom int encodedLength() 554c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom throws IOException 564c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 574c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (!empty) 584c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 594c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Primitive primitive = obj.toASN1Primitive().toDERObject(); 604c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom int length = primitive.encodedLength(); 614c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 624c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (explicit) 634c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 644c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length; 654c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 664c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom else 674c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 684c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom // header length already in calculation 694c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom length = length - 1; 704c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 714c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return StreamUtil.calculateTagLength(tagNo) + length; 724c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 734c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 744c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom else 754c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 764c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return StreamUtil.calculateTagLength(tagNo) + 1; 774c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 79b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam void encode( 814c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1OutputStream out) 82b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws IOException 83b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 84b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (!empty) 85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 864c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Primitive primitive = obj.toASN1Primitive().toDERObject(); 87b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (explicit) 89b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 904c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom out.writeTag(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo); 914c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom out.writeLength(primitive.encodedLength()); 924c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom out.writeObject(primitive); 93b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 95b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 96b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 97b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // need to mark constructed types... 98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 99c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int flags; 1004c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (primitive.isConstructed()) 101b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1024c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom flags = BERTags.CONSTRUCTED | BERTags.TAGGED; 103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1064c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom flags = BERTags.TAGGED; 107b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 109c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom out.writeTag(flags, tagNo); 1104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom out.writeImplicitObject(primitive); 111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 112b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 113b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom out.writeEncoded(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo, ZERO_BYTES); 116b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam} 119