IMPLEMENTATION MODULE Signatures;

        (********************************************************)
        (*                                                      *)
        (*                 Signing a DKIM header                *)
        (*                                                      *)
        (*     (At present, only RSA keys are implemented)      *)
        (*                                                      *)
        (*  Programmer:         P. Moylan                       *)
        (*  Started:            10 August 2023                  *)
        (*  Last edited:        23 March 2024                   *)
        (*  Status:             OK                              *)
        (*                                                      *)
        (********************************************************)


IMPORT WRSA, RSAKeys, HashAlgs;

FROM SYSTEM IMPORT CARD8;

FROM VarStrings IMPORT
    (* type *)  ByteStr;

FROM TransLog IMPORT
    (* type *)  TransactionLogID, LogTransactionL;

(************************************************************************)

CONST emptybytestring = ByteStr {0, 0, NIL};

(************************************************************************)
(*                         GENERATING A SIGNATURE                       *)
(************************************************************************)

PROCEDURE Sign (ka: PKAType;  VAR (*IN*) digest: ARRAY OF CARD8;
                                privatekey: RSAKeys.RSAKeyType): ByteStr;

    (* Creates a signature using our own private key.  *)

    BEGIN
        CASE ka OF
          | sshrsa:
                    RETURN WRSA.Sign (privatekey, HashAlgs.sha1, digest);
          | rsa_sha2_256:
                    RETURN WRSA.Sign (privatekey, HashAlgs.sha2_256, digest);
          | rsa_sha2_512:
                    RETURN WRSA.Sign (privatekey, HashAlgs.sha2_512, digest);
          | none:   RETURN emptybytestring;
        END (*CASE*);
    END Sign;

(************************************************************************)
(*                         CHECKING A SIGNATURE                         *)
(************************************************************************)

PROCEDURE SignatureValid (ka: PKAType;  digest: ARRAY OF CARD8;
                            publickey: RSAKeys.RSAKeyType;
                            VAR (*INOUT*) signature: ByteStr;
                              logID: TransactionLogID): BOOLEAN;

    (* Checks that signature is a valid signature for digest.   *)
    (* During processing the signature is discarded.            *)

    BEGIN
        CASE ka OF
          | sshrsa:
                RETURN WRSA.CheckSignature (HashAlgs.sha1, digest, publickey, signature, logID);
          | rsa_sha2_256:
                RETURN WRSA.CheckSignature (HashAlgs.sha2_256, digest, publickey, signature, logID);
          | rsa_sha2_512:
                RETURN WRSA.CheckSignature (HashAlgs.sha2_512, digest, publickey, signature, logID);
          | none:
                RETURN TRUE;
        END (*CASE*);
    END SignatureValid;

(************************************************************************)

END Signatures.

