001package org.apache.commons.ssl.org.bouncycastle.asn1; 002 003import java.io.IOException; 004import java.util.Enumeration; 005 006/** 007 * A DER encoded set object 008 */ 009public class DERSet 010 extends ASN1Set 011{ 012 private int bodyLength = -1; 013 014 /** 015 * create an empty set 016 */ 017 public DERSet() 018 { 019 } 020 021 /** 022 * @param obj - a single object that makes up the set. 023 */ 024 public DERSet( 025 ASN1Encodable obj) 026 { 027 super(obj); 028 } 029 030 /** 031 * @param v - a vector of objects making up the set. 032 */ 033 public DERSet( 034 ASN1EncodableVector v) 035 { 036 super(v, true); 037 } 038 039 /** 040 * create a set from an array of objects. 041 */ 042 public DERSet( 043 ASN1Encodable[] a) 044 { 045 super(a, true); 046 } 047 048 DERSet( 049 ASN1EncodableVector v, 050 boolean doSort) 051 { 052 super(v, doSort); 053 } 054 055 private int getBodyLength() 056 throws IOException 057 { 058 if (bodyLength < 0) 059 { 060 int length = 0; 061 062 for (Enumeration e = this.getObjects(); e.hasMoreElements();) 063 { 064 Object obj = e.nextElement(); 065 066 length += ((ASN1Encodable)obj).toASN1Primitive().toDERObject().encodedLength(); 067 } 068 069 bodyLength = length; 070 } 071 072 return bodyLength; 073 } 074 075 int encodedLength() 076 throws IOException 077 { 078 int length = getBodyLength(); 079 080 return 1 + StreamUtil.calculateBodyLength(length) + length; 081 } 082 083 /* 084 * A note on the implementation: 085 * <p> 086 * As DER requires the constructed, definite-length model to 087 * be used for structured types, this varies slightly from the 088 * ASN.1 descriptions given. Rather than just outputting SET, 089 * we also have to specify CONSTRUCTED, and the objects length. 090 */ 091 void encode( 092 ASN1OutputStream out) 093 throws IOException 094 { 095 ASN1OutputStream dOut = out.getDERSubStream(); 096 int length = getBodyLength(); 097 098 out.write(BERTags.SET | BERTags.CONSTRUCTED); 099 out.writeLength(length); 100 101 for (Enumeration e = this.getObjects(); e.hasMoreElements();) 102 { 103 Object obj = e.nextElement(); 104 105 dOut.writeObject((ASN1Encodable)obj); 106 } 107 } 108}