Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/quite/humla-spongycastle.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Hook <dgh@cryptoworkshop.com>2013-05-12 09:21:33 +0400
committerDavid Hook <dgh@cryptoworkshop.com>2013-05-12 09:21:33 +0400
commitbcd5d7192db73ea15afbeb35b00d6d8e2ebed765 (patch)
treed4aaad17e8cefc8fe2415fc373aa62d22dd25f59
parent9f94c6cae30c0d8296564fbc146248c8da6a5ff1 (diff)
BJA-438 fixed constructors to detect empty data
-rw-r--r--src/main/java/org/bouncycastle/cert/ocsp/OCSPReq.java310
-rw-r--r--src/main/java/org/bouncycastle/cert/ocsp/OCSPResp.java44
-rw-r--r--src/test/java/org/bouncycastle/cert/ocsp/test/OCSPTest.java30
3 files changed, 284 insertions, 100 deletions
diff --git a/src/main/java/org/bouncycastle/cert/ocsp/OCSPReq.java b/src/main/java/org/bouncycastle/cert/ocsp/OCSPReq.java
index 8a376952..7e50621a 100644
--- a/src/main/java/org/bouncycastle/cert/ocsp/OCSPReq.java
+++ b/src/main/java/org/bouncycastle/cert/ocsp/OCSPReq.java
@@ -1,27 +1,37 @@
-package org.bouncycastle.cert.ocsp;
+package org.bouncycastle.ocsp;
+import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.io.OutputStream;
+import java.io.InputStream;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.cert.CertStore;
+import java.security.cert.CertStoreParameters;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.CollectionCertStoreParameters;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Encoding;
-import org.bouncycastle.asn1.ASN1Exception;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1OutputStream;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ocsp.OCSPRequest;
import org.bouncycastle.asn1.ocsp.Request;
-import org.bouncycastle.asn1.x509.Certificate;
-import org.bouncycastle.asn1.x509.Extension;
-import org.bouncycastle.asn1.x509.Extensions;
import org.bouncycastle.asn1.x509.GeneralName;
-import org.bouncycastle.cert.CertIOException;
-import org.bouncycastle.cert.X509CertificateHolder;
-import org.bouncycastle.operator.ContentVerifier;
-import org.bouncycastle.operator.ContentVerifierProvider;
+import org.bouncycastle.asn1.x509.X509Extension;
+import org.bouncycastle.asn1.x509.X509Extensions;
/**
* <pre>
@@ -52,19 +62,18 @@ import org.bouncycastle.operator.ContentVerifierProvider;
* issuerKeyHash OCTET STRING, -- Hash of Issuers public key
* serialNumber CertificateSerialNumber }
* </pre>
+ *
+ * @deprecated use classes in org.bouncycastle.cert.ocsp.
*/
public class OCSPReq
+ implements java.security.cert.X509Extension
{
- private static final X509CertificateHolder[] EMPTY_CERTS = new X509CertificateHolder[0];
-
- private OCSPRequest req;
- private Extensions extensions;
+ private OCSPRequest req;
public OCSPReq(
OCSPRequest req)
{
this.req = req;
- this.extensions = req.getTbsRequest().getRequestExtensions();
}
public OCSPReq(
@@ -74,34 +83,54 @@ public class OCSPReq
this(new ASN1InputStream(req));
}
+ public OCSPReq(
+ InputStream in)
+ throws IOException
+ {
+ this(new ASN1InputStream(in));
+ }
+
private OCSPReq(
- ASN1InputStream aIn)
+ ASN1InputStream aIn)
throws IOException
{
try
{
this.req = OCSPRequest.getInstance(aIn.readObject());
- this.extensions = req.getTbsRequest().getRequestExtensions();
}
catch (IllegalArgumentException e)
{
- throw new CertIOException("malformed request: " + e.getMessage(), e);
+ throw new IOException("malformed request: " + e.getMessage());
}
catch (ClassCastException e)
{
- throw new CertIOException("malformed request: " + e.getMessage(), e);
+ throw new IOException("malformed request: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Return the DER encoding of the tbsRequest field.
+ * @return DER encoding of tbsRequest
+ * @throws OCSPException in the event of an encoding error.
+ */
+ public byte[] getTBSRequest()
+ throws OCSPException
+ {
+ try
+ {
+ return req.getTbsRequest().getEncoded();
}
- catch (ASN1Exception e)
+ catch (IOException e)
{
- throw new CertIOException("malformed request: " + e.getMessage(), e);
+ throw new OCSPException("problem encoding tbsRequest", e);
}
}
-
- public int getVersionNumber()
+
+ public int getVersion()
{
return req.getTbsRequest().getVersion().getValue().intValue() + 1;
}
-
+
public GeneralName getRequestorName()
{
return GeneralName.getInstance(req.getTbsRequest().getRequestorName());
@@ -120,47 +149,22 @@ public class OCSPReq
return requests;
}
- public boolean hasExtensions()
- {
- return extensions != null;
- }
-
- public Extension getExtension(ASN1ObjectIdentifier oid)
- {
- if (extensions != null)
- {
- return extensions.getExtension(oid);
- }
-
- return null;
- }
-
- public List getExtensionOIDs()
+ public X509Extensions getRequestExtensions()
{
- return OCSPUtils.getExtensionOIDs(extensions);
- }
-
- public Set getCriticalExtensionOIDs()
- {
- return OCSPUtils.getCriticalExtensionOIDs(extensions);
- }
-
- public Set getNonCriticalExtensionOIDs()
- {
- return OCSPUtils.getNonCriticalExtensionOIDs(extensions);
+ return X509Extensions.getInstance(req.getTbsRequest().getRequestExtensions());
}
/**
* return the object identifier representing the signature algorithm
*/
- public ASN1ObjectIdentifier getSignatureAlgOID()
+ public String getSignatureAlgOID()
{
if (!this.isSigned())
{
return null;
}
- return req.getOptionalSignature().getSignatureAlgorithm().getAlgorithm();
+ return req.getOptionalSignature().getSignatureAlgorithm().getObjectId().getId();
}
public byte[] getSignature()
@@ -172,33 +176,104 @@ public class OCSPReq
return req.getOptionalSignature().getSignature().getBytes();
}
-
- public X509CertificateHolder[] getCerts()
+
+ private List getCertList(
+ String provider)
+ throws OCSPException, NoSuchProviderException
{
+ List certs = new ArrayList();
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+ ASN1OutputStream aOut = new ASN1OutputStream(bOut);
+ CertificateFactory cf;
+
+ try
+ {
+ cf = OCSPUtil.createX509CertificateFactory(provider);
+ }
+ catch (CertificateException ex)
+ {
+ throw new OCSPException("can't get certificate factory.", ex);
+ }
+
//
// load the certificates if we have any
//
- if (req.getOptionalSignature() != null)
+ ASN1Sequence s = req.getOptionalSignature().getCerts();
+
+ if (s != null)
{
- ASN1Sequence s = req.getOptionalSignature().getCerts();
+ Enumeration e = s.getObjects();
- if (s != null)
+ while (e.hasMoreElements())
{
- X509CertificateHolder[] certs = new X509CertificateHolder[s.size()];
+ try
+ {
+ aOut.writeObject((ASN1Encodable)e.nextElement());
- for (int i = 0; i != certs.length; i++)
+ certs.add(cf.generateCertificate(
+ new ByteArrayInputStream(bOut.toByteArray())));
+ }
+ catch (IOException ex)
+ {
+ throw new OCSPException(
+ "can't re-encode certificate!", ex);
+ }
+ catch (CertificateException ex)
{
- certs[i] = new X509CertificateHolder(Certificate.getInstance(s.getObjectAt(i)));
+ throw new OCSPException(
+ "can't re-encode certificate!", ex);
}
- return certs;
+ bOut.reset();
}
-
- return EMPTY_CERTS;
}
- else
+
+ return certs;
+ }
+
+ public X509Certificate[] getCerts(
+ String provider)
+ throws OCSPException, NoSuchProviderException
+ {
+ if (!this.isSigned())
+ {
+ return null;
+ }
+
+ List certs = this.getCertList(provider);
+
+ return (X509Certificate[])certs.toArray(new X509Certificate[certs.size()]);
+ }
+
+ /**
+ * If the request is signed return a possibly empty CertStore containing the certificates in the
+ * request. If the request is not signed the method returns null.
+ *
+ * @param type type of CertStore to return
+ * @param provider provider to use
+ * @return null if not signed, a CertStore otherwise
+ * @throws NoSuchAlgorithmException
+ * @throws NoSuchProviderException
+ * @throws OCSPException
+ */
+ public CertStore getCertificates(
+ String type,
+ String provider)
+ throws NoSuchAlgorithmException, NoSuchProviderException, OCSPException
+ {
+ if (!this.isSigned())
+ {
+ return null;
+ }
+
+ try
+ {
+ CertStoreParameters params = new CollectionCertStoreParameters(this.getCertList(provider));
+ return OCSPUtil.createCertStoreInstance(type, params, provider);
+ }
+ catch (InvalidAlgorithmParameterException e)
{
- return EMPTY_CERTS;
+ throw new OCSPException("can't setup the CertStore", e);
}
}
@@ -215,9 +290,10 @@ public class OCSPReq
/**
* verify the signature against the TBSRequest object we contain.
*/
- public boolean isSignatureValid(
- ContentVerifierProvider verifierProvider)
- throws OCSPException
+ public boolean verify(
+ PublicKey key,
+ String sigProvider)
+ throws OCSPException, NoSuchProviderException
{
if (!this.isSigned())
{
@@ -226,16 +302,27 @@ public class OCSPReq
try
{
- ContentVerifier verifier = verifierProvider.get(req.getOptionalSignature().getSignatureAlgorithm());
- OutputStream sOut = verifier.getOutputStream();
+ Signature signature = OCSPUtil.createSignatureInstance(this.getSignatureAlgOID(), sigProvider);
+
+ signature.initVerify(key);
+
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+ ASN1OutputStream aOut = new ASN1OutputStream(bOut);
+
+ aOut.writeObject(req.getTbsRequest());
- sOut.write(req.getTbsRequest().getEncoded(ASN1Encoding.DER));
+ signature.update(bOut.toByteArray());
- return verifier.verify(this.getSignature());
+ return signature.verify(this.getSignature());
+ }
+ catch (NoSuchProviderException e)
+ {
+ // TODO Why this special case?
+ throw e;
}
catch (Exception e)
{
- throw new OCSPException("exception processing signature: " + e, e);
+ throw new OCSPException("exception processing sig: " + e, e);
}
}
@@ -252,4 +339,79 @@ public class OCSPReq
return bOut.toByteArray();
}
+
+ /**
+ * RFC 2650 doesn't specify any critical extensions so we return true
+ * if any are encountered.
+ *
+ * @return true if any critical extensions are present.
+ */
+ public boolean hasUnsupportedCriticalExtension()
+ {
+ Set extns = getCriticalExtensionOIDs();
+ if (extns != null && !extns.isEmpty())
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ private Set getExtensionOIDs(boolean critical)
+ {
+ Set set = new HashSet();
+ X509Extensions extensions = this.getRequestExtensions();
+
+ if (extensions != null)
+ {
+ Enumeration e = extensions.oids();
+
+ while (e.hasMoreElements())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
+ X509Extension ext = extensions.getExtension(oid);
+
+ if (critical == ext.isCritical())
+ {
+ set.add(oid.getId());
+ }
+ }
+ }
+
+ return set;
+ }
+
+ public Set getCriticalExtensionOIDs()
+ {
+ return getExtensionOIDs(true);
+ }
+
+ public Set getNonCriticalExtensionOIDs()
+ {
+ return getExtensionOIDs(false);
+ }
+
+ public byte[] getExtensionValue(String oid)
+ {
+ X509Extensions exts = this.getRequestExtensions();
+
+ if (exts != null)
+ {
+ X509Extension ext = exts.getExtension(new ASN1ObjectIdentifier(oid));
+
+ if (ext != null)
+ {
+ try
+ {
+ return ext.getValue().getEncoded(ASN1Encoding.DER);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("error encoding " + e.toString());
+ }
+ }
+ }
+
+ return null;
+ }
}
diff --git a/src/main/java/org/bouncycastle/cert/ocsp/OCSPResp.java b/src/main/java/org/bouncycastle/cert/ocsp/OCSPResp.java
index 43c240fc..978c9411 100644
--- a/src/main/java/org/bouncycastle/cert/ocsp/OCSPResp.java
+++ b/src/main/java/org/bouncycastle/cert/ocsp/OCSPResp.java
@@ -1,48 +1,49 @@
-package org.bouncycastle.cert.ocsp;
+package org.bouncycastle.ocsp;
-import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
-import org.bouncycastle.asn1.ASN1Exception;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ocsp.BasicOCSPResponse;
import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers;
import org.bouncycastle.asn1.ocsp.OCSPResponse;
import org.bouncycastle.asn1.ocsp.ResponseBytes;
-import org.bouncycastle.cert.CertIOException;
+/**
+ * @deprecated use classes in org.bouncycastle.cert.ocsp.
+ */
public class OCSPResp
{
- public static final int SUCCESSFUL = 0; // Response has valid confirmations
- public static final int MALFORMED_REQUEST = 1; // Illegal confirmation request
- public static final int INTERNAL_ERROR = 2; // Internal error in issuer
- public static final int TRY_LATER = 3; // Try again later
- // (4) is not used
- public static final int SIG_REQUIRED = 5; // Must sign the request
- public static final int UNAUTHORIZED = 6; // Request unauthorized
-
private OCSPResponse resp;
+ /**
+ * @deprecated use classes in org.bouncycastle.cert.ocsp.
+ */
public OCSPResp(
OCSPResponse resp)
{
this.resp = resp;
}
+ /**
+ * @deprecated use classes in org.bouncycastle.cert.ocsp.
+ */
public OCSPResp(
byte[] resp)
throws IOException
{
- this(new ByteArrayInputStream(resp));
+ this(new ASN1InputStream(resp));
}
+ /**
+ * @deprecated use classes in org.bouncycastle.cert.ocsp.
+ */
public OCSPResp(
- InputStream resp)
+ InputStream in)
throws IOException
{
- this(new ASN1InputStream(resp));
+ this(new ASN1InputStream(in));
}
private OCSPResp(
@@ -55,15 +56,11 @@ public class OCSPResp
}
catch (IllegalArgumentException e)
{
- throw new CertIOException("malformed response: " + e.getMessage(), e);
+ throw new IOException("malformed response: " + e.getMessage());
}
catch (ClassCastException e)
{
- throw new CertIOException("malformed response: " + e.getMessage(), e);
- }
- catch (ASN1Exception e)
- {
- throw new CertIOException("malformed response: " + e.getMessage(), e);
+ throw new IOException("malformed response: " + e.getMessage());
}
}
@@ -128,9 +125,4 @@ public class OCSPResp
{
return resp.hashCode();
}
-
- public OCSPResponse toASN1Structure()
- {
- return resp;
- }
}
diff --git a/src/test/java/org/bouncycastle/cert/ocsp/test/OCSPTest.java b/src/test/java/org/bouncycastle/cert/ocsp/test/OCSPTest.java
index 06a8ef29..5df298ae 100644
--- a/src/test/java/org/bouncycastle/cert/ocsp/test/OCSPTest.java
+++ b/src/test/java/org/bouncycastle/cert/ocsp/test/OCSPTest.java
@@ -1,5 +1,6 @@
package org.bouncycastle.cert.ocsp.test;
+import java.io.IOException;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.Security;
@@ -931,6 +932,35 @@ public class OCSPTest
testRSA();
testIrregularVersionReq();
testInvalidResp();
+
+ //
+ // Empty data test
+ //
+ try
+ {
+ response = new OCSPResp(new byte[0]);
+ fail("no exception thrown");
+ }
+ catch (IOException e)
+ {
+ if (!e.getMessage().equals("malformed response: no response data found"))
+ {
+ fail("wrong exception");
+ }
+ }
+
+ try
+ {
+ req = new OCSPReq(new byte[0]);
+ fail("no exception thrown");
+ }
+ catch (IOException e)
+ {
+ if (!e.getMessage().equals("malformed request: no request data found"))
+ {
+ fail("wrong exception");
+ }
+ }
}
public static void main(