diff options
Diffstat (limited to 'core/src/main/java/org/spongycastle/asn1/BEROctetString.java')
-rw-r--r-- | core/src/main/java/org/spongycastle/asn1/BEROctetString.java | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/core/src/main/java/org/spongycastle/asn1/BEROctetString.java b/core/src/main/java/org/spongycastle/asn1/BEROctetString.java new file mode 100644 index 00000000..b32f5c53 --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/BEROctetString.java @@ -0,0 +1,168 @@ +package org.spongycastle.asn1; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Enumeration; +import java.util.Vector; + +public class BEROctetString + extends ASN1OctetString +{ + private static final int MAX_LENGTH = 1000; + + private ASN1OctetString[] octs; + + /** + * convert a vector of octet strings into a single byte string + */ + static private byte[] toBytes( + ASN1OctetString[] octs) + { + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + + for (int i = 0; i != octs.length; i++) + { + try + { + DEROctetString o = (DEROctetString)octs[i]; + + bOut.write(o.getOctets()); + } + catch (ClassCastException e) + { + throw new IllegalArgumentException(octs[i].getClass().getName() + " found in input should only contain DEROctetString"); + } + catch (IOException e) + { + throw new IllegalArgumentException("exception converting octets " + e.toString()); + } + } + + return bOut.toByteArray(); + } + + /** + * @param string the octets making up the octet string. + */ + public BEROctetString( + byte[] string) + { + super(string); + } + + public BEROctetString( + ASN1OctetString[] octs) + { + super(toBytes(octs)); + + this.octs = octs; + } + + public byte[] getOctets() + { + return string; + } + + /** + * return the DER octets that make up this string. + */ + public Enumeration getObjects() + { + if (octs == null) + { + return generateOcts().elements(); + } + + return new Enumeration() + { + int counter = 0; + + public boolean hasMoreElements() + { + return counter < octs.length; + } + + public Object nextElement() + { + return octs[counter++]; + } + }; + } + + private Vector generateOcts() + { + Vector vec = new Vector(); + for (int i = 0; i < string.length; i += MAX_LENGTH) + { + int end; + + if (i + MAX_LENGTH > string.length) + { + end = string.length; + } + else + { + end = i + MAX_LENGTH; + } + + byte[] nStr = new byte[end - i]; + + System.arraycopy(string, i, nStr, 0, nStr.length); + + vec.addElement(new DEROctetString(nStr)); + } + + return vec; + } + + boolean isConstructed() + { + return true; + } + + int encodedLength() + throws IOException + { + int length = 0; + for (Enumeration e = getObjects(); e.hasMoreElements();) + { + length += ((ASN1Encodable)e.nextElement()).toASN1Primitive().encodedLength(); + } + + return 2 + length + 2; + } + + public void encode( + ASN1OutputStream out) + throws IOException + { + out.write(BERTags.CONSTRUCTED | BERTags.OCTET_STRING); + + out.write(0x80); + + // + // write out the octet array + // + for (Enumeration e = getObjects(); e.hasMoreElements();) + { + out.writeObject((ASN1Encodable)e.nextElement()); + } + + out.write(0x00); + out.write(0x00); + } + + static BEROctetString fromSequence(ASN1Sequence seq) + { + ASN1OctetString[] v = new ASN1OctetString[seq.size()]; + Enumeration e = seq.getObjects(); + int index = 0; + + while (e.hasMoreElements()) + { + v[index++] = (ASN1OctetString)e.nextElement(); + } + + return new BEROctetString(v); + } +} |