/** * create a sequence containing a vector of objects. */ public DERSequence( ASN1EncodableVector v) { for (int i = 0; i != v.size(); i++) { this.addObject(v.get(i)); } }
/** * Return an ASN1 set from a tagged object. There is a special * case here, if an object appears to have been explicitly tagged on * reading but we were expecting it to be implictly tagged in the * normal course of events it indicates that we lost the surrounding * set - so we need to add it back (this will happen if the tagged * object is a sequence that contains other sequences). If you are * dealing with implicitly tagged sets you really <b>should</b> * be using this method. * * @param obj the tagged object. * @param explicit true if the object is meant to be explicitly tagged * false otherwise. * @exception IllegalArgumentException if the tagged object cannot * be converted. */ public static ASN1Set getInstance( ASN1TaggedObject obj, bool explicitly) { if (explicitly) { if (!obj.isExplicit()) { throw new ArgumentException("object implicit - explicit expected."); } return((ASN1Set)obj.getObject()); } else { // // constructed object which appears to be explicitly tagged // and it's really implicit means we have to add the // surrounding sequence. // if (obj.isExplicit()) { ASN1Set set = new DERSet(obj.getObject()); return(set); } else { if (obj.getObject() is ASN1Set) { return((ASN1Set)obj.getObject()); } // // in this case the parser returns a sequence, convert it // into a set. // ASN1EncodableVector v = new ASN1EncodableVector(); if (obj.getObject() is ASN1Sequence) { ASN1Sequence s = (ASN1Sequence)obj.getObject(); IEnumerator e = s.getObjects(); while (e.MoveNext()) { v.add((ASN1Encodable)e.Current); } return(new DERSet(v)); } } } throw new ArgumentException( "unknown object in getInstanceFromTagged"); }
internal DERSet( ASN1EncodableVector v, bool needsSorting) { for (int i = 0; i != v.size(); i++) { this.addObject(v.get(i)); } if (needsSorting) { this.sort(); } }
/** * @param v - a vector of objects making up the set. */ public DERSet( ASN1EncodableVector v) : this(v, true) { }
/** * create a sequence containing a vector of objects. */ public BERSequence(ASN1EncodableVector v) : base(v) { }
internal BERSet(ASN1EncodableVector v, bool needsSorting) : base(v, needsSorting) { }
/** * create a set containing a vector of objects. */ public BERSet(ASN1EncodableVector v) : base(v) { }
public ASN1Object readObject() { int tag = ReadByte(); if (tag == -1) { if (eofFound) { throw new EndOfStreamException("attempt to read past end of file."); } eofFound = true; return(null); } int length = readLength(); if (length < 0) // indefinite length method { switch (tag) { case ASN1Tags.NULL: return(new BERNull()); case ASN1Tags.SEQUENCE | ASN1Tags.CONSTRUCTED: ASN1EncodableVector v = new ASN1EncodableVector(); for (;;) { ASN1Object obj = readObject(); if (obj == END_OF_STREAM) { break; } v.add(obj); } return(new BERSequence(v)); case ASN1Tags.SET | ASN1Tags.CONSTRUCTED: v = new ASN1EncodableVector(); for (;;) { ASN1Object obj = readObject(); if (obj == END_OF_STREAM) { break; } v.add(obj); } return(new BERSet(v, false)); case ASN1Tags.OCTET_STRING | ASN1Tags.CONSTRUCTED: return(buildConstructedOctetString()); default: // // with tagged object tag number is bottom 5 bits // if ((tag & (int)ASN1Tags.TAGGED) != 0) { int tagNo = tag & 0x1f; if (tagNo == 0x1f) { int b = ReadByte(); tagNo = 0; while ((b >= 0) && ((b & 0x80) != 0)) { tagNo |= (b & 0x7f); tagNo <<= 7; b = ReadByte(); } tagNo |= (b & 0x7f); } // // simple type - implicit... return an octet string // if ((tag & (int)ASN1Tags.CONSTRUCTED) == 0) { byte[] bytes = readIndefiniteLengthFully(); return(new BERTaggedObject(false, tagNo, new DEROctetString(bytes))); } // // either constructed or explicitly tagged // ASN1Object dObj = readObject(); if (dObj == END_OF_STREAM) // empty tag! { return(new DERTaggedObject(tagNo)); } ASN1Object next = readObject(); // // explicitly tagged (probably!) - if it isn't we'd have to // tell from the context // if (next == END_OF_STREAM) { return(new BERTaggedObject(tagNo, dObj)); } // // another implicit object, we'll create a sequence... // v = new ASN1EncodableVector(); v.add(dObj); do { v.add(next); next = readObject(); }while (next != END_OF_STREAM); return(new BERTaggedObject(false, tagNo, new BERSequence(v))); } throw new IOException("unknown BER object encountered"); } } else { if (tag == 0 && length == 0) // end of contents marker. { return(END_OF_STREAM); } byte[] bytes = new byte[length]; readFully(bytes); return(buildObject(tag, bytes)); } }
/** * build an object given its tag and a byte stream to construct it * from. */ protected ASN1Object buildObject( int derTags, byte[] bytes) { int tag = derTags; if ((tag & ASN1Tags.APPLICATION) != 0) { return(new DERApplicationSpecific(derTags, bytes)); } switch (tag) { case ASN1Tags.NULL: return(new DERNull()); case ASN1Tags.SEQUENCE | ASN1Tags.CONSTRUCTED: MemoryStream bIn = new MemoryStream(bytes); ASN1InputStream aIn = new ASN1InputStream(bIn); ASN1EncodableVector v = new ASN1EncodableVector(); ASN1Object obj = aIn.readObject(); while (obj != null) { v.add(obj); obj = aIn.readObject(); } return(new DERSequence(v)); case ASN1Tags.SET | ASN1Tags.CONSTRUCTED: bIn = new MemoryStream(bytes); aIn = new ASN1InputStream(bIn); v = new ASN1EncodableVector(); obj = aIn.readObject(); while (obj != null) { v.add(obj); obj = aIn.readObject(); } return(new DERSet(v, false)); case ASN1Tags.BOOLEAN: return(new DERBoolean(bytes)); case ASN1Tags.INTEGER: return(new DERInteger(bytes)); case ASN1Tags.ENUMERATED: return(new DEREnumerated(bytes)); case ASN1Tags.OBJECT_IDENTIFIER: return(new DERObjectIdentifier(bytes)); case ASN1Tags.BIT_STRING: int padBits = bytes[0]; byte[] data = new byte[bytes.Length - 1]; Array.Copy(bytes, 1, data, 0, bytes.Length - 1); return(new DERBitString(data, padBits)); case ASN1Tags.NUMERIC_STRING: return(new DERNumericString(bytes)); case ASN1Tags.UTF8_STRING: return(new DERUTF8String(bytes)); case ASN1Tags.PRINTABLE_STRING: return(new DERPrintableString(bytes)); case ASN1Tags.IA5_STRING: return(new DERIA5String(bytes)); case ASN1Tags.T61_STRING: return(new DERT61String(bytes)); case ASN1Tags.VISIBLE_STRING: return(new DERVisibleString(bytes)); case ASN1Tags.GENERAL_STRING: return(new DERGeneralString(bytes)); case ASN1Tags.UNIVERSAL_STRING: return(new DERUniversalString(bytes)); case ASN1Tags.BMP_STRING: return(new DERBMPString(bytes)); case ASN1Tags.OCTET_STRING: return(new DEROctetString(bytes)); case ASN1Tags.UTC_TIME: return(new DERUTCTime(bytes)); case ASN1Tags.GENERALIZED_TIME: return(new DERGeneralizedTime(bytes)); default: // // with tagged object tag number is bottom 5 bits // if ((tag & (int)ASN1Tags.TAGGED) != 0) { int tagNo = tag & 0x1f; if (tagNo == 0x1f) { int idx = 0; tagNo = 0; while ((bytes[idx] & 0x80) != 0) { tagNo |= (bytes[idx++] & 0x7f); tagNo <<= 7; } tagNo |= (bytes[idx] & 0x7f); byte[] tmp = bytes; bytes = new byte[tmp.Length - (idx + 1)]; Array.Copy(tmp, idx + 1, bytes, 0, bytes.Length); } if (bytes.Length == 0) // empty tag! { if ((tag & (int)ASN1Tags.CONSTRUCTED) == 0) { return(new DERTaggedObject(false, tagNo, new DERNull())); } else { return(new DERTaggedObject(false, tagNo, new DERSequence())); } } // // simple type - implicit... return an octet string // if ((tag & (int)ASN1Tags.CONSTRUCTED) == 0) { return(new DERTaggedObject(false, tagNo, new DEROctetString(bytes))); } bIn = new MemoryStream(bytes); aIn = new ASN1InputStream(bIn); ASN1Encodable dObj = aIn.readObject(); // // explicitly tagged (probably!) - if it isn't we'd have to // tell from the context // // if (aIn.available() == 0) if (aIn.Position == bytes.Length) //FIXME? { return(new DERTaggedObject(tagNo, dObj)); } // // another implicit object, we'll create a sequence... // v = new ASN1EncodableVector(); while (dObj != null) { v.add(dObj); dObj = aIn.readObject(); } return(new DERTaggedObject(false, tagNo, new DERSequence(v))); } return(new DERUnknownTag(tag, bytes)); } }