From 0b4143e348abaf1a6ca0bff7aea0e189594b8bb3 Mon Sep 17 00:00:00 2001 From: vakwetu Date: Tue, 9 Nov 2010 05:42:13 +0000 Subject: BZ488253, BZ551410, BZ550331 - oscp asn1 encoding fixes, including code provided by David Studzman git-svn-id: svn+ssh://svn.fedorahosted.org/svn/pki/trunk@1482 c9f7a03b-bd48-0410-a16d-cbbf54688b0b --- .../netscape/cmsutil/ocsp/BasicOCSPResponse.java | 282 +++++++++-------- .../com/netscape/cmsutil/ocsp/ResponseData.java | 329 ++++++++++---------- .../src/com/netscape/cmsutil/ocsp/TBSRequest.java | 341 +++++++++++---------- 3 files changed, 512 insertions(+), 440 deletions(-) (limited to 'pki') diff --git a/pki/base/util/src/com/netscape/cmsutil/ocsp/BasicOCSPResponse.java b/pki/base/util/src/com/netscape/cmsutil/ocsp/BasicOCSPResponse.java index fbdeb656d..b59854a2f 100644 --- a/pki/base/util/src/com/netscape/cmsutil/ocsp/BasicOCSPResponse.java +++ b/pki/base/util/src/com/netscape/cmsutil/ocsp/BasicOCSPResponse.java @@ -40,125 +40,167 @@ import org.mozilla.jss.pkix.cert.Certificate; */ public class BasicOCSPResponse implements Response { - private byte mData[] = null; - private ResponseData _rd = null; - private AlgorithmIdentifier _signAlg = null; - private BIT_STRING _signature = null; - private Certificate _certs[] = null; - - public BasicOCSPResponse(ResponseData rd, AlgorithmIdentifier signAlg, - BIT_STRING signature, Certificate certs[]) - { - _rd = rd; - _signAlg = signAlg; - _signature = signature; - _certs = certs; - } - - public BasicOCSPResponse(OCTET_STRING os) - { - mData = os.toByteArray(); - } - - public BasicOCSPResponse(byte data[]) - { - mData = data; - } - - private static final Tag TAG = SEQUENCE.TAG; - - public Tag getTag() - { - return TAG; - } - - public void encode(Tag t, OutputStream os) throws IOException - { - os.write(mData); - } - - public void encode(OutputStream os) throws IOException - { - os.write(mData); - } - - public OCTET_STRING getBytes() - { - return null; - } - - public ResponseData getResponseData() - { - return _rd; - } - - public AlgorithmIdentifier getSignatureAlgorithm() - { - return _signAlg; - } - - public BIT_STRING getSignature() - { - return _signature; - } - - public int getCertsCount() - { - return _certs.length; - } - - public Certificate getCertificateAt(int pos) - { - return _certs[pos]; - } - - private static final Template templateInstance = new Template(); - - public static Template getTemplate() { - return templateInstance; - } - - /** - * A Template for decoding ResponseBytes. - */ - public static class Template implements ASN1Template - { - - private SEQUENCE.Template seqt; - - public Template() - { - seqt = new SEQUENCE.Template(); - seqt.addElement( ResponseData.getTemplate() ); - seqt.addElement( AlgorithmIdentifier.getTemplate() ); - seqt.addElement( BIT_STRING.getTemplate() ); - seqt.addOptionalElement( new EXPLICIT.Template( - new Tag(0), new SEQUENCE.OF_Template( - Certificate.getTemplate())) ); - } - - public boolean tagMatch(Tag tag) - { - return TAG.equals(tag); - } - - public ASN1Value decode(InputStream istream) - throws InvalidBERException, IOException - { - return decode(TAG, istream); + private byte mData[] = null; + private ResponseData _rd = null; + private AlgorithmIdentifier _signAlg = null; + private BIT_STRING _signature = null; + private Certificate _certs[] = null; + + public BasicOCSPResponse(ResponseData rd, AlgorithmIdentifier signAlg, + BIT_STRING signature, Certificate certs[]) + { + _rd = rd; + _signAlg = signAlg; + _signature = signature; + _certs = certs; + } + + public BasicOCSPResponse(OCTET_STRING os) + { + this(os.toByteArray()); + } + + public BasicOCSPResponse(byte data[]) + { + mData = data; + + // extract _rd, _signAlg, _signature and _certs + try { + BasicOCSPResponse resp = (BasicOCSPResponse) getTemplate().decode(new ByteArrayInputStream(data)); + _rd = resp.getResponseData(); + _signAlg = resp.getSignatureAlgorithm(); + _signature = resp.getSignature(); + _certs = resp.getCerts(); + } catch (Exception e) { + // exception in decoding byte data + } + } + + private static final Tag TAG = SEQUENCE.TAG; + + public Tag getTag() + { + return TAG; + } + + public void encode(Tag t, OutputStream os) throws IOException + { + if (mData != null) { + os.write(mData); + } else { + SEQUENCE seq = new SEQUENCE(); + seq.addElement(_rd); + seq.addElement(_signAlg); + seq.addElement(_signature); + if (_certs != null) { + SEQUENCE certsSeq = new SEQUENCE(); + for (Certificate c : _certs) { + certsSeq.addElement(c); } - - public ASN1Value decode(Tag implicitTag, InputStream istream) - throws InvalidBERException, IOException - { - SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); - - ResponseData rd = (ResponseData)seq.elementAt(0); - AlgorithmIdentifier alg = - (AlgorithmIdentifier)seq.elementAt(1); - BIT_STRING bs = - (BIT_STRING)seq.elementAt(2); - return new BasicOCSPResponse(rd, alg, bs, null); - } - } + EXPLICIT certsExplicit = new EXPLICIT(new Tag(0),certsSeq); + seq.addElement(certsExplicit); + } + seq.encode(t,os); + } + } + + public void encode(OutputStream os) throws IOException + { + encode(TAG, os); + } + + public OCTET_STRING getBytes() + { + return null; + } + + public ResponseData getResponseData() + { + return _rd; + } + + public AlgorithmIdentifier getSignatureAlgorithm() + { + return _signAlg; + } + + public BIT_STRING getSignature() + { + return _signature; + } + + public int getCertsCount() + { + return (_certs != null) ? _certs.length : 0; + } + + public Certificate[] getCerts() + { + return _certs; + } + + public Certificate getCertificateAt(int pos) + { + return (_certs != null) ? _certs[pos] : null; + } + + private static final Template templateInstance = new Template(); + + public static Template getTemplate() { + return templateInstance; + } + + /** + * A Template for decoding ResponseBytes. + */ + public static class Template implements ASN1Template + { + private SEQUENCE.Template seqt; + + public Template() + { + seqt = new SEQUENCE.Template(); + seqt.addElement( ResponseData.getTemplate() ); + seqt.addElement( AlgorithmIdentifier.getTemplate() ); + seqt.addElement( BIT_STRING.getTemplate() ); + seqt.addOptionalElement( new EXPLICIT.Template( + new Tag(0), new SEQUENCE.OF_Template( + Certificate.getTemplate())) ); + } + + public boolean tagMatch(Tag tag) + { + return TAG.equals(tag); + } + + public ASN1Value decode(InputStream istream) + throws InvalidBERException, IOException + { + return decode(TAG, istream); + } + + public ASN1Value decode(Tag implicitTag, InputStream istream) + throws InvalidBERException, IOException + { + SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); + + ResponseData rd = (ResponseData)seq.elementAt(0); + AlgorithmIdentifier alg = (AlgorithmIdentifier)seq.elementAt(1); + BIT_STRING bs = (BIT_STRING)seq.elementAt(2); + Certificate[] certs = null; + if (seq.size() == 4) { + // optional certificates are present + EXPLICIT certSeqExplicit = (EXPLICIT) seq.elementAt(3); + SEQUENCE certSeq = (SEQUENCE) certSeqExplicit.getContent(); + if (certSeq != null) { + certs = new Certificate[certSeq.size()]; + for (int x = 0; x < certSeq.size(); x++) { + certs[x] = (Certificate) certSeq.elementAt(x); + } + } + } + + return new BasicOCSPResponse(rd, alg, bs, certs); + } + } } diff --git a/pki/base/util/src/com/netscape/cmsutil/ocsp/ResponseData.java b/pki/base/util/src/com/netscape/cmsutil/ocsp/ResponseData.java index 3de5538d3..c70229ce2 100644 --- a/pki/base/util/src/com/netscape/cmsutil/ocsp/ResponseData.java +++ b/pki/base/util/src/com/netscape/cmsutil/ocsp/ResponseData.java @@ -42,174 +42,191 @@ import org.mozilla.jss.pkix.cert.Extension; */ public class ResponseData implements ASN1Value { - private ResponderID mRID = null; - private GeneralizedTime mProduced = null; - private SingleResponse mSR[] = null; - private Extension mExts[] = null; - - private static final Tag TAG = SEQUENCE.TAG; - - public ResponseData(ResponderID rid, GeneralizedTime produced, + private static final INTEGER v1 = new INTEGER(0); + private INTEGER mVer; + private ResponderID mRID = null; + private GeneralizedTime mProduced = null; + private SingleResponse mSR[] = null; + private Extension mExts[] = null; + + private static final Tag TAG = SEQUENCE.TAG; + + public ResponseData(INTEGER ver, ResponderID rid, GeneralizedTime produced, + SingleResponse sr[], Extension exts[]) { + mVer = (ver != null) ? ver : v1; + mRID = rid; + mProduced = produced; + mSR = sr; + mExts = exts; + } + + public ResponseData(ResponderID rid, GeneralizedTime produced, SingleResponse sr[]) - { - this(rid, produced, sr, null); - } + { + this(v1, rid, produced, sr, null); + } - public ResponseData(ResponderID rid, GeneralizedTime produced, + public ResponseData(ResponderID rid, GeneralizedTime produced, SingleResponse sr[], Extension exts[]) - { - mRID = rid; - mProduced = produced; - mSR = sr; - mExts = exts; - } + { + this(v1, rid, produced, sr, exts); + } - public Tag getTag() - { - return TAG; - } - - public void encode(OutputStream os) throws IOException - { - encode(null, os); - } - - public void encode(Tag t, OutputStream os) throws IOException - { - SEQUENCE seq = new SEQUENCE(); - seq.addElement(new EXPLICIT(Tag.get(0), new INTEGER(0))); - seq.addElement(new EXPLICIT(mRID.getTag(), mRID)); - seq.addElement(mProduced); - SEQUENCE responses = new SEQUENCE(); - for (int i = 0; i < mSR.length; i++) { - responses.addElement(mSR[i]); - } - seq.addElement(responses); - if (mExts != null) { - SEQUENCE exts = new SEQUENCE(); - for (int i = 0; i < mExts.length; i++) { - exts.addElement(mExts[i]); - } - seq.addElement(new EXPLICIT(Tag.get(1), exts)); - } - if (t == null) { - seq.encode(os); - } else { - seq.encode(t, os); - } - } - - public ResponderID getResponderID() - { - return mRID; - } - - public GeneralizedTime getProducedAt() - { - return mProduced; - } - - public int getResponseCount() - { - if (mSR == null) - return 0; - else - return mSR.length; - } - - public SingleResponse getResponseAt(int pos) - { - if (mSR == null) - return null; - else - return mSR[pos]; - } - - public int getResponseExtensionCount() - { - return 0; - } - - public Extension getResponseExtensionAt(int pos) - { - return null; - } - - private static final Template templateInstance = new Template(); - - public static Template getTemplate() { - return templateInstance; + public Tag getTag() + { + return TAG; + } + + public void encode(OutputStream os) throws IOException + { + encode(null, os); + } + + public void encode(Tag t, OutputStream os) throws IOException + { + SEQUENCE seq = new SEQUENCE(); + + if (mVer != v1) { + seq.addElement(new EXPLICIT(Tag.get(0), new INTEGER(mVer))); + } + + seq.addElement(new EXPLICIT(mRID.getTag(), mRID)); + seq.addElement(mProduced); + SEQUENCE responses = new SEQUENCE(); + for (int i = 0; i < mSR.length; i++) { + responses.addElement(mSR[i]); } + seq.addElement(responses); + if (mExts != null) { + SEQUENCE exts = new SEQUENCE(); + for (int i = 0; i < mExts.length; i++) { + exts.addElement(mExts[i]); + } + seq.addElement(new EXPLICIT(Tag.get(1), exts)); + } + if (t == null) { + seq.encode(os); + } else { + seq.encode(t, os); + } + } + + public ResponderID getResponderID() + { + return mRID; + } + + public GeneralizedTime getProducedAt() + { + return mProduced; + } + + public int getResponseCount() + { + return (mSR != null) ? mSR.length : 0; + } + + public SingleResponse getResponseAt(int pos) + { + return (mSR != null) ? mSR[pos] : null; + } + + public int getResponseExtensionCount() + { + return (mExts != null) ? mExts.length : 0; + } + + public Extension getResponseExtensionAt(int pos) + { + return (mExts != null) ? mExts[pos] : null; + } + + private static final Template templateInstance = new Template(); - /** - * A Template for decoding ResponseBytes. - */ - public static class Template implements ASN1Template + public static Template getTemplate() { + return templateInstance; + } + + /** + * A Template for decoding ResponseBytes. + */ + public static class Template implements ASN1Template + { + + private SEQUENCE.Template seqt; + + public Template() { + seqt = new SEQUENCE.Template(); + seqt.addOptionalElement(new EXPLICIT.Template( + new Tag (0), new INTEGER.Template()) ); + seqt.addElement(new ANY.Template() ); + seqt.addElement(new GeneralizedTime.Template() ); + seqt.addElement(new SEQUENCE.OF_Template( + SingleResponse.getTemplate())); + seqt.addOptionalElement(new EXPLICIT.Template( + new Tag(1), new SEQUENCE.OF_Template( + Extension.getTemplate()))); + } - private SEQUENCE.Template seqt; - - public Template() - { - seqt = new SEQUENCE.Template(); - seqt.addOptionalElement(new EXPLICIT.Template( - new Tag (0), new INTEGER.Template()) ); - seqt.addElement(new ANY.Template() ); - seqt.addElement(new GeneralizedTime.Template() ); - seqt.addElement(new SEQUENCE.OF_Template( - SingleResponse.getTemplate())); - seqt.addOptionalElement(new EXPLICIT.Template( - new Tag(1), new SEQUENCE.OF_Template( - Extension.getTemplate()))); + public boolean tagMatch(Tag tag) + { + return TAG.equals(tag); + } - } + public ASN1Value decode(InputStream istream) + throws InvalidBERException, IOException + { + return decode(TAG, istream); + } - public boolean tagMatch(Tag tag) - { - return TAG.equals(tag); + public ASN1Value decode(Tag implicitTag, InputStream istream) + throws InvalidBERException, IOException + { + SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, + istream); + + INTEGER ver = v1; + EXPLICIT e_ver = (EXPLICIT)seq.elementAt(0); + if (e_ver != null && e_ver.getTag().getNum() == 0) { + ver = (INTEGER)e_ver.getContent(); + } + ResponderID rid = null; + ANY e_rid = (ANY)seq.elementAt(1); + if (e_rid.getTag().getNum() == 1) { + // name id + rid = (NameID) + NameID.getTemplate().decode(e_rid.getTag(), + new ByteArrayInputStream(e_rid.getEncoded())); + } else if (e_rid.getTag().getNum() == 2) { + // key hash id + rid = (KeyHashID) + KeyHashID.getTemplate().decode(e_rid.getTag(), + new ByteArrayInputStream(e_rid.getEncoded())); + } + GeneralizedTime producedAt = (GeneralizedTime) seq.elementAt(2); + SEQUENCE responses = (SEQUENCE)seq.elementAt(3); + SingleResponse sr[] = null; + if ((responses != null) && (responses.size() > 0)) { + sr = new SingleResponse[responses.size()]; + for (int i = 0; i < responses.size(); i++) { + sr[i] = (SingleResponse)responses.elementAt(i); } - - public ASN1Value decode(InputStream istream) - throws InvalidBERException, IOException - { - return decode(TAG, istream); + } + + //decode response extension sequence + EXPLICIT extns_exp = (EXPLICIT) seq.elementAt(4); + SEQUENCE extns_seq; + Extension[] extns_array = null; + if (extns_exp != null) { + extns_seq = (SEQUENCE)extns_exp.getContent(); + extns_array = new Extension[extns_seq.size()]; + for (int x=0;x 0) { - sr = new SingleResponse[responses.size()]; - for (int i = 0; i < responses.size(); i++) { - sr[i] = (SingleResponse)responses.elementAt(i); - } - } - return new ResponseData(rid, producedAt, sr); - } + return new ResponseData(ver, rid, producedAt, sr, extns_array); } + } } diff --git a/pki/base/util/src/com/netscape/cmsutil/ocsp/TBSRequest.java b/pki/base/util/src/com/netscape/cmsutil/ocsp/TBSRequest.java index b9b5ac3b8..833ebfb2a 100644 --- a/pki/base/util/src/com/netscape/cmsutil/ocsp/TBSRequest.java +++ b/pki/base/util/src/com/netscape/cmsutil/ocsp/TBSRequest.java @@ -37,170 +37,183 @@ import java.io.*; public class TBSRequest implements ASN1Value { - /////////////////////////////////////////////////////////////////////// - // members and member access - /////////////////////////////////////////////////////////////////////// - private static final INTEGER version = new INTEGER (1); - private ANY requestorName; - private SEQUENCE requestList; - private SEQUENCE requestExtensions; - private SEQUENCE sequence; - - public INTEGER getVersion() - { - return version; - } - - public ANY getRequestorName() - { - return requestorName; - } - - public int getRequestCount() - { - if( requestList == null ) { - return 0; - } else { - return requestList.size(); - } - } - - public Request getRequestAt(int index) - { - return (Request) requestList.elementAt(index); - } - - public int getExtensionsCount() - { - if( requestExtensions == null ) { - return 0; - } else { - return requestExtensions.size(); - } - } - - public Extension getRequestExtensionAt(int index) - { - return (Extension) requestExtensions.elementAt(index); - } - - /////////////////////////////////////////////////////////////////////// - // constructors - /////////////////////////////////////////////////////////////////////// - /* this code is probably broken - it doesn't do appropriate tagging */ - private TBSRequest() {} - - public TBSRequest(INTEGER version, ANY requestorName, - SEQUENCE requestList, SEQUENCE requestExtensions) - { - sequence = new SEQUENCE(); - - if (version != null) { - sequence.addElement (version); - } - - this.requestorName = requestorName; - if (requestorName != null) { - sequence.addElement (requestorName); - } - - this.requestList = requestList; - sequence.addElement (requestList); - - this.requestExtensions = requestExtensions; - if (requestExtensions != null) { - sequence.addElement (requestExtensions); - } - } - - /////////////////////////////////////////////////////////////////////// - // encode / decode - /////////////////////////////////////////////////////////////////////// - public static final Tag TAG = SEQUENCE.TAG; - - public Tag getTag() - { - return TAG; - } - - public void encode(OutputStream ostream) - throws IOException - { - encode(TAG, ostream); - } - - public void encode(Tag implicitTag, OutputStream ostream) - throws IOException - { - sequence.encode(implicitTag, ostream); - } - - private static final Template templateInstance = new Template(); - - public static Template getTemplate() - { - return templateInstance; - } - - /** - * A Template for decoding POPOSigningKey. - */ - public static class Template implements ASN1Template - { - - private SEQUENCE.Template seqt; - - public Template() - { - seqt = new SEQUENCE.Template(); - seqt.addElement( - new EXPLICIT.Template( - new Tag(0), new INTEGER.Template()), + /////////////////////////////////////////////////////////////////////// + // members and member access + /////////////////////////////////////////////////////////////////////// + private static final INTEGER v1 = new INTEGER (0); + private INTEGER version; + private ANY requestorName; + private SEQUENCE requestList; + private SEQUENCE requestExtensions; + + public INTEGER getVersion() + { + return version; + } + + public ANY getRequestorName() + { + return requestorName; + } + + public int getRequestCount() + { + if (requestList == null) { + return 0; + } else { + return requestList.size(); + } + } + + public Request getRequestAt(int index) + { + return (Request) requestList.elementAt(index); + } + + public int getExtensionsCount() + { + if (requestExtensions == null) { + return 0; + } else { + return requestExtensions.size(); + } + } + + public Extension getRequestExtensionAt(int index) + { + return (Extension) requestExtensions.elementAt(index); + } + + /////////////////////////////////////////////////////////////////////// + // constructors + /////////////////////////////////////////////////////////////////////// + + private TBSRequest() {} + + public TBSRequest(INTEGER version, ANY requestorName, + SEQUENCE requestList, SEQUENCE requestExtensions) + { + this.version = (version != null) ? version : v1; + this.requestorName = requestorName; + this.requestList = requestList; + this.requestExtensions = requestExtensions; + } + + /////////////////////////////////////////////////////////////////////// + // encode / decode + /////////////////////////////////////////////////////////////////////// + public static final Tag TAG = SEQUENCE.TAG; + + public Tag getTag() + { + return TAG; + } + + public void encode(OutputStream ostream) + throws IOException + { + encode(TAG, ostream); + } + + public void encode(Tag implicitTag, OutputStream ostream) + throws IOException + { + SEQUENCE seq = new SEQUENCE(); + + if (version != v1) { + seq.addElement(new EXPLICIT(Tag.get(0), version)); + } + + if (requestorName != null) { + seq.addElement(new EXPLICIT(Tag.get(1), requestorName)); + } + + seq.addElement(requestList); + + if (requestExtensions != null) { + seq.addElement(new EXPLICIT(Tag.get(2), requestExtensions)); + } + if (implicitTag == null) { + seq.encode(ostream); + } else { + seq.encode(implicitTag, ostream); + } + } + + private static final Template templateInstance = new Template(); + + public static Template getTemplate() + { + return templateInstance; + } + + /** + * A Template for decoding TBSRequest. + */ + public static class Template implements ASN1Template + { + + private SEQUENCE.Template seqt; + + public Template() + { + seqt = new SEQUENCE.Template(); + seqt.addElement( + new EXPLICIT.Template( + new Tag(0), new INTEGER.Template()), new EXPLICIT( new Tag(0), new INTEGER(0)) ); - seqt.addOptionalElement( - new EXPLICIT.Template( - new Tag (1), new ANY.Template()) ); - seqt.addElement( new SEQUENCE.OF_Template(new Request.Template()) ); - seqt.addOptionalElement(new EXPLICIT.Template(new Tag(2), - new SEQUENCE.OF_Template(new Extension.Template())) ); - } - - public boolean tagMatch(Tag tag) - { - return TAG.equals(tag); - } - - public ASN1Value decode(InputStream istream) - throws InvalidBERException, IOException - { - return decode(TAG, istream); - } - - public ASN1Value decode(Tag implicitTag, InputStream istream) - throws InvalidBERException, IOException - { - SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); - - EXPLICIT exts = (EXPLICIT) seq.elementAt(3); - SEQUENCE exts_seq; - if (exts != null) { - exts_seq = (SEQUENCE)exts.getContent(); - } else { - exts_seq = null; - } - - INTEGER v = (INTEGER) ((EXPLICIT)seq.elementAt(0)).getContent(); - ANY requestorname = null; - if (seq.elementAt(1) != null) { - requestorname = (ANY) ((EXPLICIT)seq.elementAt(1)).getContent(); - } - - return new TBSRequest( - v, - requestorname, - (SEQUENCE) seq.elementAt(2), - exts_seq); - } - } + seqt.addOptionalElement( + new EXPLICIT.Template( + new Tag (1), new ANY.Template()) ); + seqt.addElement( new SEQUENCE.OF_Template(new Request.Template()) ); + seqt.addOptionalElement(new EXPLICIT.Template(new Tag(2), + new SEQUENCE.OF_Template(new Extension.Template())) ); + } + + public boolean tagMatch(Tag tag) + { + return TAG.equals(tag); + } + + public ASN1Value decode(InputStream istream) + throws InvalidBERException, IOException + { + return decode(TAG, istream); + } + + public ASN1Value decode(Tag implicitTag, InputStream istream) + throws InvalidBERException, IOException + { + SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); + + INTEGER v = v1; //assume default version + EXPLICIT e_ver = (EXPLICIT) seq.elementAt(0); + if (e_ver != null) { + v = (INTEGER) e_ver.getContent(); + } + + ANY requestorname = null; + EXPLICIT e_requestorName = (EXPLICIT) seq.elementAt(1); + if (e_requestorName != null) { + requestorname = (ANY) e_requestorName.getContent(); + } + + //request sequence (element 2) done below + + EXPLICIT exts = (EXPLICIT) seq.elementAt(3); + SEQUENCE exts_seq; + if (exts != null) { + exts_seq = (SEQUENCE)exts.getContent(); + } else { + exts_seq = null; + } + + return new TBSRequest( + v, + requestorname, + (SEQUENCE) seq.elementAt(2), + exts_seq); + } + } } -- cgit