(**************************************************************************)
(*                                                                        *)
(*  Transport Layer Security                                              *)
(*  Copyright (C) 2025   Peter Moylan                                     *)
(*                                                                        *)
(*  This program is free software: you can redistribute it and/or modify  *)
(*  it under the terms of the GNU General Public License as published by  *)
(*  the Free Software Foundation, either version 3 of the License, or     *)
(*  (at your option) any later version.                                   *)
(*                                                                        *)
(*  This program is distributed in the hope that it will be useful,       *)
(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)
(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *)
(*  GNU General Public License for more details.                          *)
(*                                                                        *)
(*  You should have received a copy of the GNU General Public License     *)
(*  along with this program.  If not, see <http://www.gnu.org/licenses/>. *)
(*                                                                        *)
(*  To contact author:   http://www.pmoylan.org   peter@pmoylan.org       *)
(*                                                                        *)
(**************************************************************************)

DEFINITION MODULE TLSRecord;

        (********************************************************)
        (*                                                      *)
        (*                The TLS record protocol               *)
        (*                                                      *)
        (*  Programmer:         P. Moylan                       *)
        (*  Started:            2 April 2018                    *)
        (*  Last edited:        29 July 2025                    *)
        (*  Status:             Probably complete, needs testing*)
        (*                                                      *)
        (********************************************************)

(************************************************************************)
(*  NOTE ABOUT VERSIONS                                                 *)
(*  Version numbering continues on from the SSL version numbers.        *)
(*  Thus we have:                                                       *)
(*          3.0 or lower    SSL versions pre-TLS                        *)
(*          3.1             TSL version 1.0                             *)
(*          3.2             TSL version 1.1                             *)
(*          3.3             TSL version 1.2                             *)
(*  I am still trying to understand the differences between these       *)
(*  versions.  Firefox for OS/2 is still using 3.1, and this does       *)
(*  make a difference to the handshake details for initial connection.  *)
(*                                                                      *)
(*  This module based on version 1.2, RFC 5246.                         *)
(************************************************************************)


FROM SYSTEM IMPORT CARD8, CARD16;

FROM TLSBase IMPORT
    (* type *)  TextType;

FROM TLSHMAC IMPORT
    (* type *)  HMACType;

FROM TLSCrypt IMPORT
    (* type *)  BulkCipherAlgorithm;

FROM Sockets IMPORT
    (* type *)  Socket;

FROM VarStrings IMPORT
    (* type *)  ByteStringPtr;

FROM TransLog IMPORT
    (* type *)  TransactionLogID;


TYPE
    RLState;           (* is private *)

(************************************************************************)
(*                              RECORD LAYER                            *)
(************************************************************************)

PROCEDURE TLSRecordInit(S: Socket;  server: BOOLEAN;
                                logID: TransactionLogID): RLState;

    (* Initialises the record layer state for a TLS session. *)

PROCEDURE TLSRecordClose (VAR (*INOUT*) rlstate: RLState);

    (* Closes this record layer state. *)

PROCEDURE SetCipher (sess: RLState;  server_write, truncate_MAC: BOOLEAN;
                newcipher: BulkCipherAlgorithm;  newmac: HMACType;
                    MACKey: ARRAY OF CARD8;  MACKeyLength: CARDINAL;
                    cryptKey: ARRAY OF CARD8;  cryptKeyLength: CARDINAL;
                    newIV: ARRAY OF CARD8;  IVlength: CARDINAL);

    (* Sets cipher and keys for one direction.  *)
    (* Note: this is a "commit" operation, i.e. it takes effect     *)
    (* immediately.  If there is any need to keep both current and  *)
    (* pending parameters, that is an issue for the caller to       *)
    (* handle.                                                      *)
    (* Note: the IV parameter is used only by AEAD ciphers. *)

PROCEDURE FirstNBytes (logID: TransactionLogID;  prefix: ARRAY OF CHAR;
                                        buffer: TextType;  N: CARDINAL);

    (* Writes out the first N bytes of buffer, including the header. *)

PROCEDURE RecordTraceOn;

    (* For testing/debugging.  Logs data sent or received until         *)
    (* RecordTraceOff is called.  This is a module-wide setting rather  *)
    (* that being specific to one thread, so it can be used only for    *)
    (* simple tests.  (And should probably be deleted in the long run.) *)

PROCEDURE RecordTraceOff;

    (* Stops logging of data sent or received.  *)

PROCEDURE GetFragment (sess: RLState;  logID: TransactionLogID;
                            VAR (*OUT*) buffer: TextType;
                            VAR (*OUT*) ConnectionLost: BOOLEAN): BOOLEAN;

    (* Receives one record from the sender, in raw form.  It is up to   *)
    (* the caller to work out what to do with this record.              *)

    (* NOTE: We store buffer.length in BigEndian format.    *)

PROCEDURE PutFragment (sess: RLState;  logID: TransactionLogID;
                            VAR (*IN*) buffer: TextType): BOOLEAN;

    (* Sends buffer to the recipient.  This includes any necessary      *)
    (* encryption and compression.  The data in buffer.fragment, a      *)
    (* TLSPlainText record, is then discarded.                          *)

    (* Breaks up the fragment into smaller fragments if needed because  *)
    (* of fragment size restrictions.                                   *)

    (* NOTE: The caller must use BigEndian format for buffer.length.    *)

(************************************************************************)
(*                            DEBUGGING STUFF                           *)
(************************************************************************)

PROCEDURE DumpOn;
PROCEDURE DumpOff;

END TLSRecord.

