|
View:
New views
1 Messages
—
Rating Filter:
Alert me
|
|
|
DER External typeHello,
I came along an ASN1-structure containing an element of type external (the user information element in an AARE-element). To be able to read that structure in using BC I added the corresponding class, parser and support in ASN1StreamParser and ASN1InputStream. Attached you can find the patch-file containing these changes (including ASN1Dump). I'm not sure if I found all places where a ASN1-class is instantiated, so maybe other classes need to be changed as well. Best regards, Lothar Index: ASN1InputStream.java =================================================================== RCS file: /home/users/bouncy/cvsroot/java/crypto/src/org/bouncycastle/asn1/ASN1InputStream.java,v retrieving revision 1.28 diff -u -r1.28 ASN1InputStream.java --- ASN1InputStream.java 25 Jun 2009 09:36:28 -0000 1.28 +++ ASN1InputStream.java 12 Oct 2009 12:58:54 -0000 @@ -229,6 +229,8 @@ return new BERSequenceParser(sp).getDERObject(); case SET: return new BERSetParser(sp).getDERObject(); + case EXTERNAL: + return new DERExternalParser(sp).getDERObject(); default: throw new IOException("unknown BER object encountered"); } @@ -298,7 +300,7 @@ if (size > 4) { - throw new IOException("DER length more than 4 bytes"); + throw new IOException("DER length more than 4 bytes: " + size); } length = 0; Index: ASN1StreamParser.java =================================================================== RCS file: /home/users/bouncy/cvsroot/java/crypto/src/org/bouncycastle/asn1/ASN1StreamParser.java,v retrieving revision 1.17 diff -u -r1.17 ASN1StreamParser.java --- ASN1StreamParser.java 6 Mar 2009 01:46:58 -0000 1.17 +++ ASN1StreamParser.java 12 Oct 2009 12:58:54 -0000 @@ -87,8 +87,11 @@ return new BERSequenceParser(sp); case DERTags.SET: return new BERSetParser(sp); + case DERTags.EXTERNAL:{ + return new DERExternalParser(sp); + } default: - throw new IOException("unknown BER object encountered"); + throw new IOException("unknown BER object encountered: 0x" + Integer.toHexString(tagNo)); } } else Index: BERTaggedObjectParser.java =================================================================== RCS file: /home/users/bouncy/cvsroot/java/crypto/src/org/bouncycastle/asn1/BERTaggedObjectParser.java,v retrieving revision 1.9 diff -u -r1.9 BERTaggedObjectParser.java --- BERTaggedObjectParser.java 26 Feb 2008 22:02:16 -0000 1.9 +++ BERTaggedObjectParser.java 12 Oct 2009 12:58:55 -0000 @@ -86,7 +86,7 @@ } catch (IOException e) { - throw new IllegalStateException(e.getMessage()); + throw new IllegalStateException(e.getMessage(), e); } } Index: util/ASN1Dump.java =================================================================== RCS file: /home/users/bouncy/cvsroot/java/crypto/src/org/bouncycastle/asn1/util/ASN1Dump.java,v retrieving revision 1.5 diff -u -r1.5 ASN1Dump.java --- util/ASN1Dump.java 9 Mar 2009 00:18:25 -0000 1.5 +++ util/ASN1Dump.java 12 Oct 2009 12:58:55 -0000 @@ -14,6 +14,7 @@ import org.bouncycastle.asn1.DERConstructedSequence; import org.bouncycastle.asn1.DERConstructedSet; import org.bouncycastle.asn1.DEREncodable; +import org.bouncycastle.asn1.DERExternal; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERInteger; @@ -37,6 +38,8 @@ import java.util.Enumeration; import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; public class ASN1Dump { @@ -48,15 +51,15 @@ * * @param obj the DERObject to be dumped out. */ - static String _dumpAsString( + static void _dumpAsString( String indent, boolean verbose, - DERObject obj) + DERObject obj, + StringBuffer buf) { String nl = System.getProperty("line.separator"); if (obj instanceof ASN1Sequence) { - StringBuffer buf = new StringBuffer(); Enumeration e = ((ASN1Sequence)obj).getObjects(); String tab = indent + TAB; @@ -96,18 +99,16 @@ } else if (o instanceof DERObject) { - buf.append(_dumpAsString(tab, verbose, (DERObject)o)); + _dumpAsString(tab, verbose, (DERObject)o, buf); } else { - buf.append(_dumpAsString(tab, verbose, ((DEREncodable)o).getDERObject())); + _dumpAsString(tab, verbose, ((DEREncodable)o).getDERObject(), buf); } } - return buf.toString(); } else if (obj instanceof DERTaggedObject) { - StringBuffer buf = new StringBuffer(); String tab = indent + TAB; buf.append(indent); @@ -140,14 +141,11 @@ } else { - buf.append(_dumpAsString(tab, verbose, o.getObject())); + _dumpAsString(tab, verbose, o.getObject(), buf); } - - return buf.toString(); } else if (obj instanceof DERConstructedSet) { - StringBuffer buf = new StringBuffer(); Enumeration e = ((ASN1Set)obj).getObjects(); String tab = indent + TAB; @@ -167,18 +165,16 @@ } else if (o instanceof DERObject) { - buf.append(_dumpAsString(tab, verbose, (DERObject)o)); + _dumpAsString(tab, verbose, (DERObject)o, buf); } else { - buf.append(_dumpAsString(tab, verbose, ((DEREncodable)o).getDERObject())); + _dumpAsString(tab, verbose, ((DEREncodable)o).getDERObject(), buf); } } - return buf.toString(); } else if (obj instanceof BERSet) { - StringBuffer buf = new StringBuffer(); Enumeration e = ((ASN1Set)obj).getObjects(); String tab = indent + TAB; @@ -198,18 +194,16 @@ } else if (o instanceof DERObject) { - buf.append(_dumpAsString(tab, verbose, (DERObject)o)); + _dumpAsString(tab, verbose, (DERObject)o, buf); } else { - buf.append(_dumpAsString(tab, verbose, ((DEREncodable)o).getDERObject())); + _dumpAsString(tab, verbose, ((DEREncodable)o).getDERObject(), buf); } } - return buf.toString(); } else if (obj instanceof DERSet) { - StringBuffer buf = new StringBuffer(); Enumeration e = ((ASN1Set)obj).getObjects(); String tab = indent + TAB; @@ -229,104 +223,128 @@ } else if (o instanceof DERObject) { - buf.append(_dumpAsString(tab, verbose, (DERObject)o)); + _dumpAsString(tab, verbose, (DERObject)o, buf); } else { - buf.append(_dumpAsString(tab, verbose, ((DEREncodable)o).getDERObject())); + _dumpAsString(tab, verbose, ((DEREncodable)o).getDERObject(), buf); } } - return buf.toString(); } else if (obj instanceof DERObjectIdentifier) { - return indent + "ObjectIdentifier(" + ((DERObjectIdentifier)obj).getId() + ")" + nl; + buf.append(indent + "ObjectIdentifier(" + ((DERObjectIdentifier)obj).getId() + ")" + nl); } else if (obj instanceof DERBoolean) { - return indent + "Boolean(" + ((DERBoolean)obj).isTrue() + ")" + nl; + buf.append(indent + "Boolean(" + ((DERBoolean)obj).isTrue() + ")" + nl); } else if (obj instanceof DERInteger) { - return indent + "Integer(" + ((DERInteger)obj).getValue() + ")" + nl; + buf.append(indent + "Integer(" + ((DERInteger)obj).getValue() + ")" + nl); } else if (obj instanceof BERConstructedOctetString) { ASN1OctetString oct = (ASN1OctetString)obj; + buf.append(indent + "BER Constructed Octet String" + "[" + oct.getOctets().length + "] "); if (verbose) { - return indent + "BER Constructed Octet String" + "[" + oct.getOctets().length + "] " + dumpBinaryDataAsString(indent, oct.getOctets()) + nl; + buf.append(dumpBinaryDataAsString(indent, oct.getOctets())); + } + else{ + buf.append(nl); } - return indent + "BER Constructed Octet String" + "[" + oct.getOctets().length + "] " + nl; } else if (obj instanceof DEROctetString) { ASN1OctetString oct = (ASN1OctetString)obj; + buf.append(indent + "DER Octet String" + "[" + oct.getOctets().length + "] "); if (verbose) { - return indent + "DER Octet String" + "[" + oct.getOctets().length + "] " + dumpBinaryDataAsString(indent, oct.getOctets()) + nl; + buf.append(dumpBinaryDataAsString(indent, oct.getOctets())); + } + else{ + buf.append(nl); } - return indent + "DER Octet String" + "[" + oct.getOctets().length + "] " + nl; } else if (obj instanceof DERBitString) { DERBitString bt = (DERBitString)obj; + buf.append(indent + "DER Bit String" + "[" + bt.getBytes().length + ", " + bt.getPadBits() + "] "); if (verbose) { - return indent + "DER Bit String" + "[" + bt.getBytes().length + ", " + bt.getPadBits() + "] " + dumpBinaryDataAsString(indent, bt.getBytes()) + nl; + buf.append(dumpBinaryDataAsString(indent, bt.getBytes())); + } + else{ + buf.append(nl); } - return indent + "DER Bit String" + "[" + bt.getBytes().length + ", " + bt.getPadBits() + "] " + nl; } else if (obj instanceof DERIA5String) { - return indent + "IA5String(" + ((DERIA5String)obj).getString() + ") " + nl; + buf.append(indent + "IA5String(" + ((DERIA5String)obj).getString() + ") " + nl); } else if (obj instanceof DERUTF8String) { - return indent + "UTF8String(" + ((DERUTF8String)obj).getString() + ") " + nl; + buf.append(indent + "UTF8String(" + ((DERUTF8String)obj).getString() + ") " + nl); } else if (obj instanceof DERPrintableString) { - return indent + "PrintableString(" + ((DERPrintableString)obj).getString() + ") " + nl; + buf.append(indent + "PrintableString(" + ((DERPrintableString)obj).getString() + ") " + nl); } else if (obj instanceof DERVisibleString) { - return indent + "VisibleString(" + ((DERVisibleString)obj).getString() + ") " + nl; + buf.append(indent + "VisibleString(" + ((DERVisibleString)obj).getString() + ") " + nl); } else if (obj instanceof DERBMPString) { - return indent + "BMPString(" + ((DERBMPString)obj).getString() + ") " + nl; + buf.append(indent + "BMPString(" + ((DERBMPString)obj).getString() + ") " + nl); } else if (obj instanceof DERT61String) { - return indent + "T61String(" + ((DERT61String)obj).getString() + ") " + nl; + buf.append(indent + "T61String(" + ((DERT61String)obj).getString() + ") " + nl); } else if (obj instanceof DERUTCTime) { - return indent + "UTCTime(" + ((DERUTCTime)obj).getTime() + ") " + nl; + buf.append(indent + "UTCTime(" + ((DERUTCTime)obj).getTime() + ") " + nl); } else if (obj instanceof DERGeneralizedTime) { - return indent + "GeneralizedTime(" + ((DERGeneralizedTime)obj).getTime() + ") " + nl; + buf.append(indent + "GeneralizedTime(" + ((DERGeneralizedTime)obj).getTime() + ") " + nl); } else if (obj instanceof DERUnknownTag) { - return indent + "Unknown " + Integer.toString(((DERUnknownTag)obj).getTag(), 16) + " " + new String(Hex.encode(((DERUnknownTag)obj).getData())) + nl; + buf.append(indent + "Unknown " + Integer.toString(((DERUnknownTag)obj).getTag(), 16) + " " + new String(Hex.encode(((DERUnknownTag)obj).getData())) + nl); } else if (obj instanceof BERApplicationSpecific) { - return outputApplicationSpecific("BER", indent, verbose, obj, nl); + buf.append(outputApplicationSpecific("BER", indent, verbose, obj, nl)); } else if (obj instanceof DERApplicationSpecific) { - return outputApplicationSpecific("DER", indent, verbose, obj, nl); + buf.append(outputApplicationSpecific("DER", indent, verbose, obj, nl)); + } + else if (obj instanceof DERExternal){ + DERExternal ext = (DERExternal) obj; + buf.append(indent + "External " + nl); + String tab = indent + TAB; + if (ext.getDirectReferemce() != null){ + buf.append(tab + "Direct Reference: " + ext.getDirectReferemce().getId() + nl); + } + if (ext.getIndirectReference() != null){ + buf.append(tab + "Indirect Reference: " + ext.getIndirectReference().toString() + nl); + } + if (ext.getDataValueDescriptor() != null){ + _dumpAsString(tab, verbose, ext.getDataValueDescriptor(), buf); + } + buf.append(tab + "Encoding: " + ext.getEncoding() + nl); + _dumpAsString(tab, verbose, ext.getExternalContent(), buf); } else { - return indent + obj.toString() + nl; + buf.append(indent + obj.toString() + nl); } } - + private static String outputApplicationSpecific(String type, String indent, boolean verbose, DERObject obj, String nl) { DERApplicationSpecific app = (DERApplicationSpecific)obj; @@ -340,7 +358,7 @@ buf.append(indent + type + " ApplicationSpecific[" + app.getApplicationTag() + "]" + nl); for (Enumeration e = s.getObjects(); e.hasMoreElements();) { - buf.append(_dumpAsString(indent + TAB, verbose, (DERObject)e.nextElement())); + _dumpAsString(indent + TAB, verbose, (DERObject)e.nextElement(), buf); } } catch (IOException e) @@ -376,16 +394,29 @@ Object obj, boolean verbose) { - if (obj instanceof DERObject) - { - return _dumpAsString("", verbose, (DERObject)obj); + StringBuffer buf = new StringBuffer(); + try{ + if (obj instanceof DERObject) + { + _dumpAsString("", verbose, (DERObject)obj, buf); + } + else if (obj instanceof DEREncodable) + { + _dumpAsString("", verbose, ((DEREncodable)obj).getDERObject(), buf); + } + else{ + return "unknown object type " + obj.toString(); + } } - else if (obj instanceof DEREncodable) - { - return _dumpAsString("", verbose, ((DEREncodable)obj).getDERObject()); + catch(Exception e){ + buf.append("\nError while trying to dump DER-data: "); + buf.append(e.getMessage()); + buf.append("\n"); + StringWriter sw = new StringWriter(); + e.printStackTrace(new PrintWriter(sw, true)); + buf.append(sw.toString()); } - - return "unknown object type " + obj.toString(); + return buf.toString(); } private static String dumpBinaryDataAsString(String indent, byte[] bytes) Index: util/DERDump.java =================================================================== RCS file: /home/users/bouncy/cvsroot/java/crypto/src/org/bouncycastle/asn1/util/DERDump.java,v retrieving revision 1.2 diff -u -r1.2 DERDump.java --- util/DERDump.java 9 Mar 2009 00:26:09 -0000 1.2 +++ util/DERDump.java 12 Oct 2009 12:58:56 -0000 @@ -7,7 +7,6 @@ * @deprecated use ASN1Dump. */ public class DERDump - extends ASN1Dump { /** * dump out a DER object as a formatted string @@ -17,7 +16,7 @@ public static String dumpAsString( DERObject obj) { - return _dumpAsString("", false, obj); + return ASN1Dump.dumpAsString(obj, false); } /** @@ -28,6 +27,6 @@ public static String dumpAsString( DEREncodable obj) { - return _dumpAsString("", false, obj.getDERObject()); + return ASN1Dump.dumpAsString(obj.getDERObject(), false); } } Index: DERExternal.java =================================================================== RCS file: DERExternal.java diff -N DERExternal.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ DERExternal.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,206 @@ +/* + * Created on 09.10.2009 + * + */ +package org.bouncycastle.asn1; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +/** + * Class representing the DER-type External + * @author Lothar Kimmeringer <lothar@...> + * + */ +public class DERExternal extends ASN1Object { + private DERObjectIdentifier directReferemce; + private DERInteger indirectReference; + private ASN1Object dataValueDescriptor; + private int encoding; + private DERObject externalContent; + + public DERExternal(DEREncodableVector vector){ + int offset = 0; + DERObject enc = vector.get(offset).getDERObject(); + if (enc instanceof DERObjectIdentifier){ + directReferemce = (DERObjectIdentifier) enc; + offset++; + enc = vector.get(offset).getDERObject(); + } + if (enc instanceof DERInteger){ + indirectReference = (DERInteger) enc; + offset++; + enc = vector.get(offset).getDERObject(); + } + if (!(enc instanceof DERTaggedObject)){ + dataValueDescriptor = (ASN1Object) enc; + offset++; + enc = vector.get(offset).getDERObject(); + } + if (!(enc instanceof DERTaggedObject)){ + throw new IllegalArgumentException("No tagged object found in vector. Structure doesn't seem to be of type External"); + } + DERTaggedObject obj = (DERTaggedObject) enc; + encoding = obj.getTagNo(); + externalContent = obj.getDERObject(); + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + int ret = 0; + if (directReferemce != null){ + ret = directReferemce.hashCode(); + } + if (indirectReference != null){ + ret ^= indirectReference.hashCode(); + } + if (dataValueDescriptor != null){ + ret ^= dataValueDescriptor.hashCode(); + } + ret ^= externalContent.hashCode(); + return ret; + } + + /* (non-Javadoc) + * @see org.bouncycastle.asn1.DERObject#encode(org.bouncycastle.asn1.DEROutputStream) + */ + void encode(DEROutputStream out) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + if (directReferemce != null){ + baos.write(directReferemce.getDEREncoded()); + } + if (indirectReference != null){ + baos.write(indirectReference.getDEREncoded()); + } + if (dataValueDescriptor != null){ + baos.write(dataValueDescriptor.getDEREncoded()); + } + DERTaggedObject obj = new DERTaggedObject(DERTags.EXTERNAL, externalContent); + baos.write(obj.getDEREncoded()); + out.writeEncoded(DERTags.CONSTRUCTED, DERTags.EXTERNAL, baos.toByteArray()); + } + + /* (non-Javadoc) + * @see org.bouncycastle.asn1.ASN1Object#asn1Equals(org.bouncycastle.asn1.DERObject) + */ + boolean asn1Equals(DERObject o) { + if (!(o instanceof DERExternal)){ + return false; + } + if (this == o){ + return true; + } + DERExternal other = (DERExternal) o; + if (directReferemce != null){ + if (other.directReferemce == null || !other.directReferemce.equals(directReferemce)){ + return false; + } + } + if (indirectReference != null){ + if (other.indirectReference == null || !other.indirectReference.equals(indirectReference)){ + return false; + } + } + if (dataValueDescriptor != null){ + if (other.dataValueDescriptor == null || !other.dataValueDescriptor.equals(dataValueDescriptor)){ + return false; + } + } + return externalContent.equals(other.externalContent); + } + + /** + * Returns the data value descriptor + * @return The descriptor + */ + public ASN1Object getDataValueDescriptor() { + return dataValueDescriptor; + } + + /** + * Sets the data value descriptor + * @param dataValueDescriptor The descriptor + */ + public void setDataValueDescriptor(ASN1Object dataValueDescriptor) { + this.dataValueDescriptor = dataValueDescriptor; + } + + /** + * Returns the direct reference of the external element + * @return The reference + */ + public DERObjectIdentifier getDirectReferemce() { + return directReferemce; + } + + /** + * Sets the direct reference of the external element + * @param directReferemce The reference + */ + public void setDirectReferemce(DERObjectIdentifier directReferemce) { + this.directReferemce = directReferemce; + } + + /** + * Returns the encoding of the content. Valid values are + * <ul> + * <li><code>0</code> single-ASN1-type</li> + * <li><code>1</code> OCTET STRING</li> + * <li><code>2</code> BIT STRING</li> + * </ul> + * @return The encoding + */ + public int getEncoding() { + return encoding; + } + + /** + * Sets the encoding of the content. Valid values are + * <ul> + * <li><code>0</code> single-ASN1-type</li> + * <li><code>1</code> OCTET STRING</li> + * <li><code>2</code> BIT STRING</li> + * </ul> + * @param encoding The encoding + */ + public void setEncoding(int encoding) { + if (encoding < 0 || encoding > 2){ + throw new IllegalArgumentException("invalid encoding value"); + } + this.encoding = encoding; + } + + /** + * Returns the content of this element + * @return The content + */ + public DERObject getExternalContent() { + return externalContent; + } + + /** + * Sets the content of this element + * @param externalContent The content + */ + public void setExternalContent(DERObject externalContent) { + this.externalContent = externalContent; + } + + /** + * Returns the indirect reference of this element + * @return The reference + */ + public DERInteger getIndirectReference() { + return indirectReference; + } + + /** + * Sets the indirect reference of this element + * @param indirectReference The reference + */ + public void setIndirectReference(DERInteger indirectReference) { + this.indirectReference = indirectReference; + } +} Index: DERExternalParser.java =================================================================== RCS file: DERExternalParser.java diff -N DERExternalParser.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ DERExternalParser.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,40 @@ +/* + * Created on 09.10.2009 + * + */ +package org.bouncycastle.asn1; + +import java.io.IOException; + +/** + * @author Lothar Kimmeringer <lothar@...> + * + */ +public class DERExternalParser implements DEREncodable{ + private ASN1StreamParser _parser; + + /** + * + */ + public DERExternalParser(ASN1StreamParser parser) { + this._parser = parser; + } + + public DEREncodable readObject() throws IOException{ + try{ + return new DERExternal(_parser.readVector()); + } + catch(IllegalArgumentException iae){ + throw (IOException) new IOException("unable to read in external data").initCause(iae); + } + } + + public DERObject getDERObject() { + try{ + return new DERExternal(_parser.readVector()); + } + catch(IOException ioe){ + throw new IllegalArgumentException("unable to get DER object", ioe); + } + } +} |
| Free embeddable forum powered by Nabble | Forum Help |