// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package com.netscape.cmsutil.ocsp; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.ANY; import org.mozilla.jss.asn1.ASN1Template; import org.mozilla.jss.asn1.ASN1Value; import org.mozilla.jss.asn1.EXPLICIT; import org.mozilla.jss.asn1.GeneralizedTime; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.asn1.Tag; import org.mozilla.jss.pkix.cert.Extension; /** * RFC 2560: * *
* ResponseData ::= SEQUENCE { * version [0] EXPLICIT Version DEFAULT v1, * responderID ResponderID, * producedAt GeneralizedTime, * responses SEQUENCE OF SingleResponse, * responseExtensions [1] EXPLICIT Extensions OPTIONAL } ** * @version $Revision$ $Date$ */ public class ResponseData implements ASN1Value { 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(v1, rid, produced, sr, null); } public ResponseData(ResponderID rid, GeneralizedTime produced, SingleResponse sr[], Extension 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(); 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(); 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())));
}
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 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);
}
}
//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 < extns_array.length; x++) {
extns_array[x] = (Extension) extns_seq.elementAt(x);
}
}
return new ResponseData(ver, rid, producedAt, sr, extns_array);
}
}
}