// --- 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);
}
}
}