001package org.apache.commons.ssl.org.bouncycastle.asn1.isismtt.ocsp; 002 003import java.io.IOException; 004 005import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Choice; 006import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Object; 007import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1OctetString; 008import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Primitive; 009import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Sequence; 010import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1TaggedObject; 011import org.apache.commons.ssl.org.bouncycastle.asn1.DEROctetString; 012import org.apache.commons.ssl.org.bouncycastle.asn1.DERTaggedObject; 013import org.apache.commons.ssl.org.bouncycastle.asn1.x509.Certificate; 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 * <pre> 040 * RequestedCertificate ::= CHOICE { 041 * Certificate Certificate, 042 * publicKeyCertificate [0] EXPLICIT OCTET STRING, 043 * attributeCertificate [1] EXPLICIT OCTET STRING 044 * } 045 * </pre> 046 */ 047public class RequestedCertificate 048 extends ASN1Object 049 implements ASN1Choice 050{ 051 public static final int certificate = -1; 052 public static final int publicKeyCertificate = 0; 053 public static final int attributeCertificate = 1; 054 055 private Certificate cert; 056 private byte[] publicKeyCert; 057 private byte[] attributeCert; 058 059 public static RequestedCertificate getInstance(Object obj) 060 { 061 if (obj == null || obj instanceof RequestedCertificate) 062 { 063 return (RequestedCertificate)obj; 064 } 065 066 if (obj instanceof ASN1Sequence) 067 { 068 return new RequestedCertificate(Certificate.getInstance(obj)); 069 } 070 if (obj instanceof ASN1TaggedObject) 071 { 072 return new RequestedCertificate((ASN1TaggedObject)obj); 073 } 074 075 throw new IllegalArgumentException("illegal object in getInstance: " 076 + obj.getClass().getName()); 077 } 078 079 public static RequestedCertificate getInstance(ASN1TaggedObject obj, boolean explicit) 080 { 081 if (!explicit) 082 { 083 throw new IllegalArgumentException("choice item must be explicitly tagged"); 084 } 085 086 return getInstance(obj.getObject()); 087 } 088 089 private RequestedCertificate(ASN1TaggedObject tagged) 090 { 091 if (tagged.getTagNo() == publicKeyCertificate) 092 { 093 publicKeyCert = ASN1OctetString.getInstance(tagged, true).getOctets(); 094 } 095 else if (tagged.getTagNo() == attributeCertificate) 096 { 097 attributeCert = ASN1OctetString.getInstance(tagged, true).getOctets(); 098 } 099 else 100 { 101 throw new IllegalArgumentException("unknown tag number: " + tagged.getTagNo()); 102 } 103 } 104 105 /** 106 * Constructor from a given details. 107 * <p> 108 * Only one parameter can be given. All other must be <code>null</code>. 109 * 110 * @param certificate Given as Certificate 111 */ 112 public RequestedCertificate(Certificate certificate) 113 { 114 this.cert = certificate; 115 } 116 117 public RequestedCertificate(int type, byte[] certificateOctets) 118 { 119 this(new DERTaggedObject(type, new DEROctetString(certificateOctets))); 120 } 121 122 public int getType() 123 { 124 if (cert != null) 125 { 126 return certificate; 127 } 128 if (publicKeyCert != null) 129 { 130 return publicKeyCertificate; 131 } 132 return attributeCertificate; 133 } 134 135 public byte[] getCertificateBytes() 136 { 137 if (cert != null) 138 { 139 try 140 { 141 return cert.getEncoded(); 142 } 143 catch (IOException e) 144 { 145 throw new IllegalStateException("can't decode certificate: " + e); 146 } 147 } 148 if (publicKeyCert != null) 149 { 150 return publicKeyCert; 151 } 152 return attributeCert; 153 } 154 155 /** 156 * Produce an object suitable for an ASN1OutputStream. 157 * <p> 158 * Returns: 159 * <pre> 160 * RequestedCertificate ::= CHOICE { 161 * Certificate Certificate, 162 * publicKeyCertificate [0] EXPLICIT OCTET STRING, 163 * attributeCertificate [1] EXPLICIT OCTET STRING 164 * } 165 * </pre> 166 * 167 * @return a DERObject 168 */ 169 public ASN1Primitive toASN1Primitive() 170 { 171 if (publicKeyCert != null) 172 { 173 return new DERTaggedObject(0, new DEROctetString(publicKeyCert)); 174 } 175 if (attributeCert != null) 176 { 177 return new DERTaggedObject(1, new DEROctetString(attributeCert)); 178 } 179 return cert.toASN1Primitive(); 180 } 181}