Skip to content

Commit

Permalink
Encode/parse status_request_v2 extension
Browse files Browse the repository at this point in the history
  • Loading branch information
peterdettman committed Apr 4, 2020
1 parent 1ddeea3 commit 61ca8b5
Show file tree
Hide file tree
Showing 3 changed files with 193 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package org.bouncycastle.tls;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
* Implementation of the RFC 6961 2.2. CertificateStatusRequestItemV2.
*/
public class CertificateStatusRequestItemV2
{
protected short statusType;
protected Object request;

public CertificateStatusRequestItemV2(short statusType, Object request)
{
if (!isCorrectType(statusType, request))
{
throw new IllegalArgumentException("'request' is not an instance of the correct type");
}

this.statusType = statusType;
this.request = request;
}

public short getStatusType()
{
return statusType;
}

public Object getRequest()
{
return request;
}

public OCSPStatusRequest getOCSPStatusRequest()
{
if (!(request instanceof OCSPStatusRequest))
{
throw new IllegalStateException("'request' is not an OCSPStatusRequest");
}
return (OCSPStatusRequest)request;
}

/**
* Encode this {@link CertificateStatusRequestItemV2} to an {@link OutputStream}.
*
* @param output
* the {@link OutputStream} to encode to.
* @throws IOException
*/
public void encode(OutputStream output) throws IOException
{
TlsUtils.writeUint8(statusType, output);

ByteArrayOutputStream buf = new ByteArrayOutputStream();
switch (statusType)
{
case CertificateStatusType.ocsp:
case CertificateStatusType.ocsp_multi:
((OCSPStatusRequest)request).encode(buf);
break;
default:
throw new TlsFatalAlert(AlertDescription.internal_error);
}
byte[] requestBytes = buf.toByteArray();
TlsUtils.writeOpaque16(requestBytes, output);
}

/**
* Parse a {@link CertificateStatusRequestItemV2} from an {@link InputStream}.
*
* @param input
* the {@link InputStream} to parse from.
* @return a {@link CertificateStatusRequestItemV2} object.
* @throws IOException
*/
public static CertificateStatusRequestItemV2 parse(InputStream input) throws IOException
{
short status_type = TlsUtils.readUint8(input);

Object request;
byte[] requestBytes = TlsUtils.readOpaque16(input);
ByteArrayInputStream buf = new ByteArrayInputStream(requestBytes);
switch (status_type)
{
case CertificateStatusType.ocsp:
case CertificateStatusType.ocsp_multi:
request = OCSPStatusRequest.parse(buf);
break;
default:
throw new TlsFatalAlert(AlertDescription.decode_error);
}
TlsProtocol.assertEmpty(buf);

return new CertificateStatusRequestItemV2(status_type, request);
}

protected static boolean isCorrectType(short statusType, Object request)
{
switch (statusType)
{
case CertificateStatusType.ocsp:
case CertificateStatusType.ocsp_multi:
return request instanceof OCSPStatusRequest;
default:
throw new IllegalArgumentException("'statusType' is an unsupported CertificateStatusType");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
public class CertificateStatusType
{
/*
* RFC 3546 3.6
* RFC 6066
*/
public static final short ocsp = 1;

/*
* RFC 6961
*/
public static final short ocsp_multi = 2;
}
78 changes: 75 additions & 3 deletions tls/src/main/java/org/bouncycastle/tls/TlsExtensionsUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public class TlsExtensionsUtils
public static final Integer EXT_signature_algorithms = Integers.valueOf(ExtensionType.signature_algorithms);
public static final Integer EXT_signature_algorithms_cert = Integers.valueOf(ExtensionType.signature_algorithms_cert);
public static final Integer EXT_status_request = Integers.valueOf(ExtensionType.status_request);
public static final Integer EXT_status_request_v2 = Integers.valueOf(ExtensionType.status_request_v2);
public static final Integer EXT_supported_groups = Integers.valueOf(ExtensionType.supported_groups);
public static final Integer EXT_supported_versions = Integers.valueOf(ExtensionType.supported_versions);
public static final Integer EXT_truncated_hmac = Integers.valueOf(ExtensionType.truncated_hmac);
Expand Down Expand Up @@ -221,6 +222,12 @@ public static void addStatusRequestExtension(Hashtable extensions, CertificateSt
extensions.put(EXT_status_request, createStatusRequestExtension(statusRequest));
}

public static void addStatusRequestV2Extension(Hashtable extensions, Vector statusRequestV2)
throws IOException
{
extensions.put(EXT_status_request_v2, createStatusRequestV2Extension(statusRequestV2));
}

public static void addSupportedGroupsExtension(Hashtable extensions, Vector namedGroups) throws IOException
{
extensions.put(EXT_supported_groups, createSupportedGroupsExtension(namedGroups));
Expand Down Expand Up @@ -425,6 +432,13 @@ public static CertificateStatusRequest getStatusRequestExtension(Hashtable exten
return extensionData == null ? null : readStatusRequestExtension(extensionData);
}

public static Vector getStatusRequestV2Extension(Hashtable extensions)
throws IOException
{
byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_status_request_v2);
return extensionData == null ? null : readStatusRequestV2Extension(extensionData);
}

public static int[] getSupportedGroupsExtension(Hashtable extensions) throws IOException
{
byte[] extensionData = TlsUtils.getExtensionData(extensions, EXT_supported_groups);
Expand Down Expand Up @@ -829,6 +843,32 @@ public static byte[] createStatusRequestExtension(CertificateStatusRequest statu
return buf.toByteArray();
}

public static byte[] createStatusRequestV2Extension(Vector statusRequestV2)
throws IOException
{
if (statusRequestV2 == null || statusRequestV2.isEmpty())
{
throw new TlsFatalAlert(AlertDescription.internal_error);
}

ByteArrayOutputStream buf = new ByteArrayOutputStream();

// Placeholder for length
TlsUtils.writeUint16(0, buf);

for (int i = 0; i < statusRequestV2.size(); ++i)
{
CertificateStatusRequestItemV2 entry = (CertificateStatusRequestItemV2)statusRequestV2.elementAt(i);
entry.encode(buf);
}

int length = buf.size() - 2;
TlsUtils.checkUint16(length);
byte[] extensionData = buf.toByteArray();
TlsUtils.writeUint16(length, extensionData, 0);
return extensionData;
}

public static byte[] createSupportedGroupsExtension(Vector namedGroups) throws IOException
{
if (namedGroups == null || namedGroups.isEmpty())
Expand Down Expand Up @@ -897,10 +937,13 @@ public static byte[] createTrustedCAKeysExtensionClient(Vector trustedAuthoritie
// Placeholder for length
TlsUtils.writeUint16(0, buf);

for (int i = 0; i < trustedAuthoritiesList.size(); ++i)
if (trustedAuthoritiesList != null)
{
TrustedAuthority entry = (TrustedAuthority)trustedAuthoritiesList.elementAt(i);
entry.encode(buf);
for (int i = 0; i < trustedAuthoritiesList.size(); ++i)
{
TrustedAuthority entry = (TrustedAuthority)trustedAuthoritiesList.elementAt(i);
entry.encode(buf);
}
}

int length = buf.size() - 2;
Expand Down Expand Up @@ -1280,6 +1323,35 @@ public static CertificateStatusRequest readStatusRequestExtension(byte[] extensi
return statusRequest;
}

public static Vector readStatusRequestV2Extension(byte[] extensionData)
throws IOException
{
if (extensionData == null)
{
throw new IllegalArgumentException("'extensionData' cannot be null");
}
if (extensionData.length < 3)
{
throw new TlsFatalAlert(AlertDescription.decode_error);
}

ByteArrayInputStream buf = new ByteArrayInputStream(extensionData);

int length = TlsUtils.readUint16(buf);
if (length != (extensionData.length - 2))
{
throw new TlsFatalAlert(AlertDescription.decode_error);
}

Vector statusRequestV2 = new Vector();
while (buf.available() > 0)
{
CertificateStatusRequestItemV2 entry = CertificateStatusRequestItemV2.parse(buf);
statusRequestV2.add(entry);
}
return statusRequestV2;
}

public static int[] readSupportedGroupsExtension(byte[] extensionData) throws IOException
{
if (extensionData == null)
Expand Down

0 comments on commit 61ca8b5

Please sign in to comment.