Class ASN1Choice

java.lang.Object
org.apache.harmony.security.asn1.ASN1Type
org.apache.harmony.security.asn1.ASN1Choice
All Implemented Interfaces:
ASN1Constants

public abstract class ASN1Choice
extends ASN1Type
This abstract class represents ASN.1 Choice type. To implement custom ASN.1 choice type an application class must provide implementation for the following methods: getIndex() getObjectToEncode() There are two ways to implement custom ASN.1 choice type: with application class that represents ASN.1 custom choice type or without. The key point is how a value of choice type is stored by application classes. For example, let's consider the following ASN.1 notations (see http://www.ietf.org/rfc/rfc3280.txt) Time ::= CHOICE { utcTime UTCTime, generalTime GeneralizedTime } Validity ::= SEQUENCE { notBefore Time, notAfter Time } 1)First approach: No application class to represent ASN.1 Time notation The Time notation is a choice of different time formats: UTC and Generalized. Both of them are mapped to java.util.Date object, so an application class that represents ASN.1 Validity notation may keep values as Date objects. So a custom ASN.1 Time choice type should map its notation to Date object. class Time { // custom ASN.1 choice class: maps Time to is notation public static final ASN1Choice asn1 = new ASN1Choice(new ASN1Type[] { ASN1GeneralizedTime.asn1, ASN1UTCTime.asn1 }) { public int getIndex(java.lang.Object object) { return 0; // always encode as ASN1GeneralizedTime } public Object getObjectToEncode(Object object) { // A value to be encoded value is a Date object // pass it to custom time class return object; } }; } class Validity { private Date notBefore; // choice as Date private Date notAfter; // choice as Date ... // constructors and other methods go here // custom ASN.1 sequence class: maps Validity class to is notation public static final ASN1Sequence ASN1 = new ASN1Sequence(new ASN1Type[] {Time.asn1, Time.asn1 }) { protected Object getObject(Object[] values) { // ASN.1 Time choice passed Data object - use it return new Validity((Date) values[0], (Date) values[1]); } protected void getValues(Object object, Object[] values) { Validity validity = (Validity) object; // pass Date objects to ASN.1 Time choice values[0] = validity.notBefore; values[1] = validity.notAfter; } } } 2)Second approach: There is an application class to represent ASN.1 Time notation If it is a matter what time format should be used to decode/encode Date objects a class to represent ASN.1 Time notation must be created. For example, class Time { private Date utcTime; private Date gTime; ... // constructors and other methods go here // custom ASN.1 choice class: maps Time to is notation public static final ASN1Choice asn1 = new ASN1Choice(new ASN1Type[] { ASN1GeneralizedTime.asn1, ASN1UTCTime.asn1 }) { public Object getDecodedObject(BerInputStream in) { // create Time object to pass as decoded value Time time = new Time(); if (in.choiceIndex==0) { // we decoded GeneralizedTime // store decoded Date value in corresponding field time.gTime = in.content; // return it return time; } else { // we decoded UTCTime // store decoded Date value in corresponding field time.utcTime = in.content; // return it return time; } } public int getIndex(java.lang.Object object) { Time time = (Time)object; if(time.utcTime!=null){ // encode Date as UTCTime return 1; } else { // otherwise encode Date as GeneralizedTime return 0; } } public Object getObjectToEncode(Object object) { Time time = (Time)object; if(time.utcTime!=null){ // encode Date as UTCTime return 1; } else { // otherwise encode Date as GeneralizedTime return 0; } } }; } So now Validity class must keep all values in Time object and its custom ASN.1 sequence class must handle this class of objects class Validity { private Time notBefore; // now it is a Time!!! private Time notAfter; // now it is a Time!!! ... // constructors and other methods go here // custom ASN.1 sequence class: maps Validity class to is notation public static final ASN1Sequence ASN1 = new ASN1Sequence(new ASN1Type[] {Time.asn1, Time.asn1 }) { protected Object getObject(Object[] values) { // We've gotten Time objects here !!! return new Validity((Time) values[0], (Time) values[1]); } protected void getValues(Object object, Object[] values) { Validity validity = (Validity) object; // pass Time objects to ASN.1 Time choice values[0] = validity.notBefore; values[1] = validity.notAfter; } } }
See Also:
ASN.1
  • Field Details

  • Constructor Details

    • ASN1Choice

      public ASN1Choice​(ASN1Type[] type)
      Constructs ASN.1 choice type.
      Parameters:
      type - - an array of one or more ASN.1 type alternatives.
      Throws:
      IllegalArgumentException - - type parameter is invalid
  • Method Details

    • checkTag

      public final boolean checkTag​(int identifier)
      Tests whether one of choice alternatives has the same identifier or not.
      Specified by:
      checkTag in class ASN1Type
      Parameters:
      identifier - - ASN.1 identifier to be verified
      Returns:
      - true if one of choice alternatives has the same identifier, otherwise false;
    • decode

      public Object decode​(BerInputStream in) throws IOException
      Description copied from class: ASN1Type
      Decodes ASN.1 type.
      Specified by:
      decode in class ASN1Type
      Throws:
      IOException - if an I/O error occurs or the end of the stream is reached
    • encodeASN

      public void encodeASN​(BerOutputStream out)
      Description copied from class: ASN1Type
      Encodes ASN.1 type.
      Specified by:
      encodeASN in class ASN1Type
    • encodeContent

      public final void encodeContent​(BerOutputStream out)
      Specified by:
      encodeContent in class ASN1Type
    • getIndex

      public abstract int getIndex​(Object object)
    • getObjectToEncode

      public abstract Object getObjectToEncode​(Object object)
    • setEncodingContent

      public final void setEncodingContent​(BerOutputStream out)
      Specified by:
      setEncodingContent in class ASN1Type