如何在 C# 或 Java 中的握手期间读取 ocsp 装订响应

How to read ocsp stapled response during handshake in C# or Java

有一个 OCSP 响应程序,服务器将与之通信并装订响应。客户端如何检查 C# 或 Java 中的装订响应。 Bouncy Castle、Chiklat、本机库 - 他们调用似乎有办法让客户端与 OCSP 响应器交谈但不读取装订的响应。

正如您已经正确提到的那样,装订是在握手期间完成的。我只知道如何在 Bouncy Castle 的 C# 端口中执行此操作,因为我正在实现一个基于 BC 的 PKIX 加密组件,它也考虑了 OCSP 并且大大简化了 BC 调用(我准备好后会在这里报告发布 alpha 版本,很可能是开源的)。

首先,根据 RFC6066,仅当您在 Client-Hello 中要求时才会发送装订回复。要启用此功能,您必须覆盖 TlsClientGetClientExtensions(例如,当您从 DefaultTlsClient 继承时):

  using BouncyTls = Org.BouncyCastle.Crypto.Tls;
  ...
  public override IDictionary GetClientExtensions() // Override in your TlsClient class
  {
    IDictionary clientExtensions = base.GetClientExtensions();
    clientExtensions = BouncyTls.TlsExtensionsUtilities.EnsureExtensionsInitialised(clientExtensions);
    byte type = BouncyTls.CertificateStatusType.ocsp;
    var request = new BouncyTls.OcspStatusRequest(null, null);
    BouncyTls.TlsExtensionsUtilities.AddStatusRequestExtension(clientExtensions, new BouncyTls.CertificateStatusRequest(type, request));

    return clientExtensions;
  }

之后,如果支持,服务器将发送装订响应。 但是,响应仅在握手期间可用,如果您看到 Bouncy Castle 的源代码,它会在 TlsClientProtocol 实例中的 CompleteHandshake 上被清除。 所以你也必须在这里拦截:

  protected override void CompleteHandshake() // Override in your TlsClientProtocol class
  {
    // After the handshake completed, we do not have any access to the handshake data anymore
    // (see TlsClientProtocol.CleanupHandshake). Therefore we must intercept here to gather information
    YourValidationOfTheOcspResponse(mCertificateStatus);
    // mCertificateStatus holds the response. It is cleared after the following call:
    base.CompleteHandshake();
  }

我花了几个小时才明白充气城堡在这里做什么以及如何提取装订响应,尽管这样做的代码非常简单。 一个好的起点总是找到相应的 RFC 并将字段与 BC 进行比较,因为 Bouncy Castle 在大多数情况下使用完全相同的标识符。

只是另一个旁注;为了符合 TLS 标准,使用 RaiseAlertFatal 写入正确的错误记录(参见 RFC8446)如果状态条目表明证书已被吊销等