Home Explore Blog CI



postgresql

23th chunk of `doc/src/sgml/protocol.sgml`
ed044d1ca2a3bde360caeed73cb2518b704f74c33bfb05cd0000000100000fa3
 <productname>PostgreSQL</productname> was built with
    <acronym>SSL</acronym> support, frontend/backend communications
    can be encrypted using <acronym>SSL</acronym>.  This provides
    communication security in environments where attackers might be
    able to capture the session traffic. For more information on
    encrypting <productname>PostgreSQL</productname> sessions with
    <acronym>SSL</acronym>, see <xref linkend="ssl-tcp"/>.
   </para>

   <para>
    To initiate an <acronym>SSL</acronym>-encrypted connection, the
    frontend initially sends an SSLRequest message rather than a
    StartupMessage.  The server then responds with a single byte
    containing <literal>S</literal> or <literal>N</literal>, indicating that it is
    willing or unwilling to perform <acronym>SSL</acronym>,
    respectively.  The frontend might close the connection at this point
    if it is dissatisfied with the response.  To continue after
    <literal>S</literal>, perform an <acronym>SSL</acronym> startup handshake
    (not described here, part of the <acronym>SSL</acronym>
    specification) with the server.  If this is successful, continue
    with sending the usual StartupMessage.  In this case the
    StartupMessage and all subsequent data will be
    <acronym>SSL</acronym>-encrypted.  To continue after
    <literal>N</literal>, send the usual StartupMessage and proceed without
    encryption.
    (Alternatively, it is permissible to issue a GSSENCRequest message
    after an <literal>N</literal> response to try to
    use <acronym>GSSAPI</acronym> encryption instead
    of <acronym>SSL</acronym>.)
   </para>

   <para>
    The frontend should also be prepared to handle an ErrorMessage
    response to SSLRequest from the server. The frontend should not display
    this error message to the user/application, since the server has not been
    authenticated
    (<ulink url="https://www.postgresql.org/support/security/CVE-2024-10977/">CVE-2024-10977</ulink>).
    In this case the connection must
    be closed, but the frontend might choose to open a fresh connection
    and proceed without requesting <acronym>SSL</acronym>.
   </para>

   <para>
    When <acronym>SSL</acronym> encryption can be performed, the server
    is expected to send only the single <literal>S</literal> byte and then
    wait for the frontend to initiate an <acronym>SSL</acronym> handshake.
    If additional bytes are available to read at this point, it likely
    means that a man-in-the-middle is attempting to perform a
    buffer-stuffing attack
    (<ulink url="https://www.postgresql.org/support/security/CVE-2021-23222/">CVE-2021-23222</ulink>).
    Frontends should be coded either to read exactly one byte from the
    socket before turning the socket over to their SSL library, or to
    treat it as a protocol violation if they find they have read additional
    bytes.
   </para>

   <para>
     Likewise the server expects the client to not begin
     the <acronym>SSL</acronym> negotiation until it receives the server's
     single byte response to the <acronym>SSL</acronym> request.  If the
     client begins the <acronym>SSL</acronym> negotiation immediately without
     waiting for the server response to be received it can reduce connection
     latency by one round-trip.  However this comes at the cost of not being
     able to handle the case where the server sends a negative response to the
     <acronym>SSL</acronym> request.  In that case instead of continuing with either GSSAPI or an
     unencrypted connection or a protocol error the server will simply
     disconnect.
   </para>

   <para>
    An initial SSLRequest can also be used in a connection that is being
    opened to send a CancelRequest message.
   </para>

   <para>
     A second alternate way to initiate <acronym>SSL</acronym> encryption is
     available.  The server will recognize connections which immediately
     begin <acronym>SSL</acronym> negotiation without any previous SSLRequest

Title: Initiating SSL Encryption in PostgreSQL
Summary
To establish an SSL-encrypted connection in PostgreSQL, the frontend sends an SSLRequest message, and the server responds with a single byte indicating willingness or unwillingness to perform SSL, after which the frontend can proceed with an SSL startup handshake, or alternatively, use GSSAPI encryption or proceed without encryption, with the frontend required to handle potential error messages and protocol violations, and the server expecting the client to wait for its response before initiating SSL negotiation.