001: package org.bouncycastle.asn1.isismtt.ocsp;
002:
003: import org.bouncycastle.asn1.ASN1Choice;
004: import org.bouncycastle.asn1.ASN1Encodable;
005: import org.bouncycastle.asn1.ASN1OctetString;
006: import org.bouncycastle.asn1.ASN1Sequence;
007: import org.bouncycastle.asn1.ASN1TaggedObject;
008: import org.bouncycastle.asn1.DERObject;
009: import org.bouncycastle.asn1.DEROctetString;
010: import org.bouncycastle.asn1.DERTaggedObject;
011: import org.bouncycastle.asn1.x509.X509CertificateStructure;
012:
013: import java.io.IOException;
014:
015: /**
016: * ISIS-MTT-Optional: The certificate requested by the client by inserting the
017: * RetrieveIfAllowed extension in the request, will be returned in this
018: * extension.
019: * <p/>
020: * ISIS-MTT-SigG: The signature act allows publishing certificates only then,
021: * when the certificate owner gives his explicit permission. Accordingly, there
022: * may be �nondownloadable� certificates, about which the responder must provide
023: * status information, but MUST NOT include them in the response. Clients may
024: * get therefore the following three kind of answers on a single request
025: * including the RetrieveIfAllowed extension:
026: * <ul>
027: * <li> a) the responder supports the extension and is allowed to publish the
028: * certificate: RequestedCertificate returned including the requested
029: * certificate
030: * <li>b) the responder supports the extension but is NOT allowed to publish
031: * the certificate: RequestedCertificate returned including an empty OCTET
032: * STRING
033: * <li>c) the responder does not support the extension: RequestedCertificate is
034: * not included in the response
035: * </ul>
036: * Clients requesting RetrieveIfAllowed MUST be able to handle these cases. If
037: * any of the OCTET STRING options is used, it MUST contain the DER encoding of
038: * the requested certificate.
039: * <p/>
040: * <pre>
041: * RequestedCertificate ::= CHOICE {
042: * Certificate Certificate,
043: * publicKeyCertificate [0] EXPLICIT OCTET STRING,
044: * attributeCertificate [1] EXPLICIT OCTET STRING
045: * }
046: * </pre>
047: */
048: public class RequestedCertificate extends ASN1Encodable implements
049: ASN1Choice {
050: public static final int certificate = -1;
051: public static final int publicKeyCertificate = 0;
052: public static final int attributeCertificate = 1;
053:
054: private X509CertificateStructure cert;
055: private byte[] publicKeyCert;
056: private byte[] attributeCert;
057:
058: public static RequestedCertificate getInstance(Object obj) {
059: if (obj == null || obj instanceof RequestedCertificate) {
060: return (RequestedCertificate) obj;
061: }
062:
063: if (obj instanceof ASN1Sequence) {
064: return new RequestedCertificate(X509CertificateStructure
065: .getInstance(obj));
066: }
067: if (obj instanceof ASN1TaggedObject) {
068: return new RequestedCertificate((ASN1TaggedObject) obj);
069: }
070:
071: throw new IllegalArgumentException(
072: "illegal object in getInstance: "
073: + obj.getClass().getName());
074: }
075:
076: public static RequestedCertificate getInstance(
077: ASN1TaggedObject obj, boolean explicit) {
078: if (!explicit) {
079: throw new IllegalArgumentException(
080: "choice item must be explicitly tagged");
081: }
082:
083: return getInstance(obj.getObject());
084: }
085:
086: private RequestedCertificate(ASN1TaggedObject tagged) {
087: if (tagged.getTagNo() == publicKeyCertificate) {
088: publicKeyCert = ASN1OctetString.getInstance(tagged, true)
089: .getOctets();
090: } else if (tagged.getTagNo() == attributeCertificate) {
091: attributeCert = ASN1OctetString.getInstance(tagged, true)
092: .getOctets();
093: } else {
094: throw new IllegalArgumentException("unknown tag number: "
095: + tagged.getTagNo());
096: }
097: }
098:
099: /**
100: * Constructor from a given details.
101: * <p/>
102: * Only one parameter can be given. All other must be <code>null</code>.
103: *
104: * @param certificate Given as Certificate
105: */
106: public RequestedCertificate(X509CertificateStructure certificate) {
107: this .cert = certificate;
108: }
109:
110: public RequestedCertificate(int type, byte[] certificateOctets) {
111: this (new DERTaggedObject(type, new DEROctetString(
112: certificateOctets)));
113: }
114:
115: public int getType() {
116: if (cert != null) {
117: return certificate;
118: }
119: if (publicKeyCert != null) {
120: return publicKeyCertificate;
121: }
122: return attributeCertificate;
123: }
124:
125: public byte[] getCertificateBytes() {
126: if (cert != null) {
127: try {
128: return cert.getEncoded();
129: } catch (IOException e) {
130: throw new IllegalStateException(
131: "can't decode certificate: " + e);
132: }
133: }
134: if (publicKeyCert != null) {
135: return publicKeyCert;
136: }
137: return attributeCert;
138: }
139:
140: /**
141: * Produce an object suitable for an ASN1OutputStream.
142: * <p/>
143: * Returns:
144: * <p/>
145: * <pre>
146: * RequestedCertificate ::= CHOICE {
147: * Certificate Certificate,
148: * publicKeyCertificate [0] EXPLICIT OCTET STRING,
149: * attributeCertificate [1] EXPLICIT OCTET STRING
150: * }
151: * </pre>
152: *
153: * @return a DERObject
154: */
155: public DERObject toASN1Object() {
156: if (publicKeyCert != null) {
157: return new DERTaggedObject(0, new DEROctetString(
158: publicKeyCert));
159: }
160: if (attributeCert != null) {
161: return new DERTaggedObject(1, new DEROctetString(
162: attributeCert));
163: }
164: return cert.getDERObject();
165: }
166: }
|