Class AbstractTlsServer

java.lang.Object
org.bouncycastle.tls.AbstractTlsPeer
org.bouncycastle.tls.AbstractTlsServer
All Implemented Interfaces:
TlsPeer, TlsServer
Direct Known Subclasses:
DefaultTlsServer, PSKTlsServer, SRPTlsServer

public abstract class AbstractTlsServer extends AbstractTlsPeer implements TlsServer
Base class for a TLS server.
  • Field Details

    • context

      protected TlsServerContext context
    • protocolVersions

      protected ProtocolVersion[] protocolVersions
    • cipherSuites

      protected int[] cipherSuites
    • offeredCipherSuites

      protected int[] offeredCipherSuites
    • clientExtensions

      protected Hashtable clientExtensions
    • encryptThenMACOffered

      protected boolean encryptThenMACOffered
    • maxFragmentLengthOffered

      protected short maxFragmentLengthOffered
    • truncatedHMacOffered

      protected boolean truncatedHMacOffered
    • clientSentECPointFormats

      protected boolean clientSentECPointFormats
    • certificateStatusRequest

      protected CertificateStatusRequest certificateStatusRequest
    • statusRequestV2

      protected Vector statusRequestV2
    • trustedCAKeys

      protected Vector trustedCAKeys
    • selectedCipherSuite

      protected int selectedCipherSuite
    • clientProtocolNames

      protected Vector clientProtocolNames
    • selectedProtocolName

      protected ProtocolName selectedProtocolName
    • serverExtensions

      protected final Hashtable serverExtensions
  • Constructor Details

    • AbstractTlsServer

      public AbstractTlsServer(TlsCrypto crypto)
  • Method Details

    • allowCertificateStatus

      protected boolean allowCertificateStatus()
      Whether to echo a client's "status_request" extension (RFC 6066 sec. 8) in the extended server hello, so that a stapled OCSP response can be sent. Echoing it makes getCertificateStatus() be called with SecurityParameters.getStatusRequestVersion() of 1; it does not oblige the server to actually supply a response.

      This governs (D)TLS 1.2 and earlier, where the echo is what announces the "certificate_status" message. TLS 1.3 has no echo to send - the response rides in a per-CertificateEntry extension - so there getCertificateStatus() is called whenever the client offered "status_request", whatever this returns, and returning null from it is how a TLS 1.3 server declines to staple.

      Returns:
      true (the default) to echo "status_request" when the client offered it.
    • allowEncryptThenMAC

      protected boolean allowEncryptThenMAC()
    • allowMultiCertStatus

      protected boolean allowMultiCertStatus()
      Whether to echo a client's "status_request_v2" extension (RFC 6961 sec. 2.2) in the extended server hello. When the client offered both, echoing this one takes precedence over "status_request", and getCertificateStatus() is then called with SecurityParameters.getStatusRequestVersion() of 2 – so a server overriding this must be prepared to return a CertificateStatusType.ocsp_multi status.
      Returns:
      false (the default) to leave "status_request_v2" unanswered.
    • allowTruncatedHMac

      protected boolean allowTruncatedHMac()
    • allowTrustedCAIndication

      protected boolean allowTrustedCAIndication()
    • checkServerExtensions

      @Deprecated protected Hashtable checkServerExtensions()
      Deprecated.
      Use 'serverExtensions' directly, it is now never null
    • getDetailMessageNoCipherSuite

      protected String getDetailMessageNoCipherSuite()
    • getMaximumDefaultCurveBits

      protected int getMaximumDefaultCurveBits()
    • getMaximumDefaultFiniteFieldBits

      protected int getMaximumDefaultFiniteFieldBits()
    • getMaximumNegotiableCurveBits

      protected int getMaximumNegotiableCurveBits()
    • getMaximumNegotiableFiniteFieldBits

      protected int getMaximumNegotiableFiniteFieldBits()
    • getProtocolNames

      protected Vector getProtocolNames()
    • isSelectableCipherSuite

      protected boolean isSelectableCipherSuite(int cipherSuite, int availCurveBits, int availFiniteFieldBits, Vector sigAlgs)
    • preferLocalCipherSuites

      protected boolean preferLocalCipherSuites()
    • preferLocalSupportedGroups

      public boolean preferLocalSupportedGroups()
      Specified by:
      preferLocalSupportedGroups in interface TlsServer
    • selectCipherSuite

      protected boolean selectCipherSuite(int cipherSuite) throws IOException
      Throws:
      IOException
    • selectDH

      protected int selectDH(int minimumFiniteFieldBits)
    • selectDHDefault

      protected int selectDHDefault(int minimumFiniteFieldBits)
    • selectECDH

      protected int selectECDH(int minimumCurveBits)
    • selectECDHDefault

      protected int selectECDHDefault(int minimumCurveBits)
    • selectProtocolName

      protected ProtocolName selectProtocolName() throws IOException
      Throws:
      IOException
    • selectProtocolName

      protected ProtocolName selectProtocolName(Vector clientProtocolNames, Vector serverProtocolNames)
    • shouldSelectProtocolNameEarly

      protected boolean shouldSelectProtocolNameEarly()
    • preferLocalClientCertificateTypes

      protected boolean preferLocalClientCertificateTypes()
    • getAllowedClientCertificateTypes

      protected short[] getAllowedClientCertificateTypes()
    • getNewConnectionID

      protected byte[] getNewConnectionID()
      RFC 9146 DTLS connection ID.

      This method will be called if a connection_id extension was sent by the client. If the return value is non-null, the server will send this connection ID to the client to use in future packets. As future communication doesn't include the connection IDs length, this should either be fixed-length or include the connection ID's length. (see explanation in RFC 9146 4. "cid:")

      Returns:
      The connection ID to use.
    • init

      public void init(TlsServerContext context)
      Specified by:
      init in interface TlsServer
    • getProtocolVersions

      public ProtocolVersion[] getProtocolVersions()
      Specified by:
      getProtocolVersions in interface TlsPeer
    • getCipherSuites

      public int[] getCipherSuites()
      Specified by:
      getCipherSuites in interface TlsPeer
    • notifyHandshakeBeginning

      public void notifyHandshakeBeginning() throws IOException
      Description copied from interface: TlsPeer
      Notifies the peer that a new handshake is about to begin.
      Specified by:
      notifyHandshakeBeginning in interface TlsPeer
      Overrides:
      notifyHandshakeBeginning in class AbstractTlsPeer
      Throws:
      IOException
    • getSessionToResume

      public TlsSession getSessionToResume(byte[] sessionID)
      Description copied from interface: TlsServer
      Return the specified session, if available. Note that the peer's certificate chain for the session (if any) may need to be periodically revalidated.
      Specified by:
      getSessionToResume in interface TlsServer
      Parameters:
      sessionID - the ID of the session to resume.
      Returns:
      A TlsSession with the specified session ID, or null.
      See Also:
    • getNewSessionID

      public byte[] getNewSessionID()
      Specified by:
      getNewSessionID in interface TlsServer
    • getExternalPSK

      public TlsPSKExternal getExternalPSK(Vector identities) throws IOException
      Description copied from interface: TlsServer
      WARNING: EXPERIMENTAL FEATURE, UNSTABLE API Return the external PSK to select from the ClientHello. Note that this will only be called when TLS 1.3 or higher is amongst the offered protocol versions, and one or more PSKs are actually offered.
      Specified by:
      getExternalPSK in interface TlsServer
      Parameters:
      identities - a Vector of PskIdentity instances.
      Returns:
      the TlsPSKExternal corresponding to the selected identity, or null to not select any.
      Throws:
      IOException - if the handshake should be aborted. An implementation may throw a TlsFatalAlert to control the alert sent to the peer - e.g. AlertDescription.unknown_psk_identity when none of the offered identities is recognised, or AlertDescription.decrypt_error when an identity is recognised but is invalid or expired (see RFC 8446 6.2). Returning null instead leaves PSK unselected without aborting.
    • notifySession

      public void notifySession(TlsSession session)
      Specified by:
      notifySession in interface TlsServer
    • notifyClientVersion

      public void notifyClientVersion(ProtocolVersion clientVersion) throws IOException
      Specified by:
      notifyClientVersion in interface TlsServer
      Throws:
      IOException
    • notifyFallback

      public void notifyFallback(boolean isFallback) throws IOException
      Specified by:
      notifyFallback in interface TlsServer
      Throws:
      IOException
    • notifyOfferedCipherSuites

      public void notifyOfferedCipherSuites(int[] offeredCipherSuites) throws IOException
      Specified by:
      notifyOfferedCipherSuites in interface TlsServer
      Throws:
      IOException
    • processClientExtensions

      public void processClientExtensions(Hashtable clientExtensions) throws IOException
      Specified by:
      processClientExtensions in interface TlsServer
      Throws:
      IOException
    • getServerVersion

      public ProtocolVersion getServerVersion() throws IOException
      Specified by:
      getServerVersion in interface TlsServer
      Throws:
      IOException
    • getSupportedGroups

      public int[] getSupportedGroups() throws IOException
      Specified by:
      getSupportedGroups in interface TlsServer
      Throws:
      IOException
    • getSelectedCipherSuite

      public int getSelectedCipherSuite() throws IOException
      Specified by:
      getSelectedCipherSuite in interface TlsServer
      Throws:
      IOException
    • getServerExtensions

      public Hashtable getServerExtensions() throws IOException
      Specified by:
      getServerExtensions in interface TlsServer
      Throws:
      IOException
    • getServerExtensionsForConnection

      public void getServerExtensionsForConnection(Hashtable serverExtensions) throws IOException
      Specified by:
      getServerExtensionsForConnection in interface TlsServer
      Throws:
      IOException
    • getServerSupplementalData

      public Vector getServerSupplementalData() throws IOException
      Specified by:
      getServerSupplementalData in interface TlsServer
      Throws:
      IOException
    • getCertificateStatus

      public CertificateStatus getCertificateStatus() throws IOException
      Description copied from interface: TlsServer
      This method will be called (only) if SecurityParameters.getStatusRequestVersion() is non-zero, meaning the client asked for a stapled response and the server undertook to answer: up to (D)TLS 1.2, that it echoed an extension of type "status_request" (RFC 6066 sec. 8. Certificate Status Request) or "status_request_v2" (RFC 6961 sec. 2.2. Multiple Certificate Status Request Record) with empty "extension_data" in the extended server hello; in TLS 1.3, simply that the client offered "status_request".

      The status request version says which of the two shapes the client will accept; returning the other one is a fatal alert at the client:

      • 1 – "status_request". Return a CertificateStatusType.ocsp status carrying a single response, for the end-entity certificate.
      • 2 – "status_request_v2" was echoed. Return a CertificateStatusType.ocsp_multi status carrying one entry per certificate in the chain that was sent, in the same order, with a null entry wherever no response is available.
      Whether either extension is echoed at all up to (D)TLS 1.2 is decided by allowCertificateStatus() (defaults to true) and allowMultiCertStatus() (defaults to false).

      How the returned status reaches the client depends on the negotiated version. Up to (D)TLS 1.2 it is sent as a handshake message of type "certificate_status", for the whole chain at once. In TLS 1.3 there is no such message: the response travels in a "status_request" extension of the CertificateEntry containing the certificate it answers for (RFC 8446 sec. 4.4.2.1), and the protocol distributes what this callback returns across those entries - an CertificateStatusType.ocsp status answering for the end-entity certificate, an CertificateStatusType.ocsp_multi status answering positionally, entry i of its list for certificate i of the chain. So a TLS 1.3 server with a response for more than the end-entity certificate returns the ocsp_multi shape even though the status request version is 1. An entry the server has itself given a "status_request" extension - by attaching it to the Certificate its credentials supply, which was previously the only way to staple in TLS 1.3 - is left as it stands.

      OCSPStaplingServerExample in the misc module is a worked example.

      Specified by:
      getCertificateStatus in interface TlsServer
      Returns:
      A CertificateStatus to be sent to the client (or null for none).
      Throws:
      IOException
    • getCertificateRequest

      public CertificateRequest getCertificateRequest() throws IOException
      Specified by:
      getCertificateRequest in interface TlsServer
      Throws:
      IOException
    • getPSKIdentityManager

      public TlsPSKIdentityManager getPSKIdentityManager() throws IOException
      Specified by:
      getPSKIdentityManager in interface TlsServer
      Throws:
      IOException
    • getSRPLoginParameters

      public TlsSRPLoginParameters getSRPLoginParameters() throws IOException
      Specified by:
      getSRPLoginParameters in interface TlsServer
      Throws:
      IOException
    • getDHConfig

      public TlsDHConfig getDHConfig() throws IOException
      Specified by:
      getDHConfig in interface TlsServer
      Throws:
      IOException
    • getECDHConfig

      public TlsECConfig getECDHConfig() throws IOException
      Specified by:
      getECDHConfig in interface TlsServer
      Throws:
      IOException
    • processClientSupplementalData

      public void processClientSupplementalData(Vector clientSupplementalData) throws IOException
      Specified by:
      processClientSupplementalData in interface TlsServer
      Throws:
      IOException
    • notifyClientCertificate

      public void notifyClientCertificate(Certificate clientCertificate) throws IOException
      Description copied from interface: TlsServer
      Called by the protocol handler to report the client certificate, only if TlsServer.getCertificateRequest() returned non-null. Note: this method is responsible for certificate verification and validation.
      Specified by:
      notifyClientCertificate in interface TlsServer
      Parameters:
      clientCertificate - the effective client certificate (may be an empty chain).
      Throws:
      IOException
    • getNewSessionTicket

      public NewSessionTicket getNewSessionTicket() throws IOException
      Description copied from interface: TlsServer
      RFC 5077 3.3. NewSessionTicket Handshake Message.

      This method will be called (only) if a NewSessionTicket extension was sent by the server. See RFC 5077 4. Recommended Ticket Construction for recommended format and protection.

      Specified by:
      getNewSessionTicket in interface TlsServer
      Returns:
      The ticket.
      Throws:
      IOException