diff mbox series

Add RSA-PSS support

Message ID 20250319134625.11765-2-lpmeyer@ics.com
State Not Applicable
Delegated to: Stefano Babic
Headers show
Series Add RSA-PSS support | expand

Commit Message

Lisandro Pérez Meyer March 19, 2025, 1:45 p.m. UTC
Simply expand the existing RSA support to RSA-PSS following the command
line on the documentation.

Signed-By: Lisandro Perez Meyer <lpmeyer@ics.com>
---
 swugenerator/main.py     | 19 ++++++++++++++++---
 swugenerator/swu_sign.py | 15 +++++++++++++++
 tests/test_main.py       |  5 ++++-
 3 files changed, 35 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/swugenerator/main.py b/swugenerator/main.py
index 78aa0dd..3983565 100644
--- a/swugenerator/main.py
+++ b/swugenerator/main.py
@@ -16,7 +16,7 @@  from typing import List, Optional, Tuple, Union
 import libconf
 
 from swugenerator import __about__, generator
-from swugenerator.swu_sign import SWUSignCMS, SWUSignCustom, SWUSignPKCS11, SWUSignRSA
+from swugenerator.swu_sign import SWUSignCMS, SWUSignCustom, SWUSignPKCS11, SWUSignRSA, SWUSignRSAPSS
 
 
 class InvalidKeyFile(ValueError):
@@ -83,7 +83,7 @@  def parse_config_file(config_file_arg: str) -> dict:
 
 def parse_signing_option(
     sign_arg: str,
-) -> Union[SWUSignCMS, SWUSignRSA, SWUSignPKCS11, SWUSignCustom]:
+) -> Union[SWUSignCMS, SWUSignRSA, SWUSignRSAPSS, SWUSignPKCS11, SWUSignCustom]:
     """Parses signgning option passed by user. Valid options can be found below.
 
     CMS,<private key>,<certificate used to sign>,<file with password>,<file with certs>
@@ -91,6 +91,8 @@  def parse_signing_option(
     CMS,<private key>,<certificate used to sign>
     RSA,<private key>,<file with password>
     RSA,<private key>
+    RSA-PSS,<private key>,<file with password>
+    RSA-PSS,<private key>
     PKCS11,<pin>
     CUSTOM,<custom command>
 
@@ -101,7 +103,7 @@  def parse_signing_option(
         InvalidSigningOption: If option passed by user is invalid
 
     Returns:
-        Union[SWUSignCMS, SWUSignRSA, SWUSignPKCS11, SWUSignCustom]: Signing option to use
+        Union[SWUSignCMS, SWUSignRSA, SWUSignRSAPSS, SWUSignPKCS11, SWUSignCustom]: Signing option to use
     """
     sign_parms = sign_arg.split(",")
     cmd = sign_parms[0]
@@ -129,6 +131,16 @@  def parse_signing_option(
             return SWUSignRSA(sign_parms[1], sign_parms[2])
         # Format : RSA,<private key>
         return SWUSignRSA(sign_parms[1], None)
+    if cmd == "RSA-PSS":
+        if len(sign_parms) not in (2, 3) or not all(sign_parms):
+            raise InvalidSigningOption(
+                "RSA-PSS requires private key and an optional password file"
+            )
+        # Format : RSA-PSS,<private key>,<file with password>
+        if len(sign_parms) == 3:
+            return SWUSignRSAPSS(sign_parms[1], sign_parms[2])
+        # Format : RSA-PSS,<private key>
+        return SWUSignRSAPSS(sign_parms[1], None)
     if cmd == "PKCS11":
         # Format : PKCS11,<pin>
         if len(sign_parms) != 2 or not all(sign_parms):
@@ -251,6 +263,7 @@  def parse_args(args: List[str]) -> None:
             One of :
             CMS,<private key>,<certificate used to sign>,<file with password if any>,<file with certs if any>
             RSA,<private key>,<file with password if any>
+            RSA-PSS,<private key>,<file with password if any>
             PKCS11,<pin>
             CUSTOM,<custom command> """
         ),
diff --git a/swugenerator/swu_sign.py b/swugenerator/swu_sign.py
index 5bd0db3..813f2df 100644
--- a/swugenerator/swu_sign.py
+++ b/swugenerator/swu_sign.py
@@ -92,6 +92,21 @@  class SWUSignRSA(SWUSign):
             + ["-out", sw_desc_sig, sw_desc_in]
         )
 
+class SWUSignRSAPSS(SWUSign):
+    def __init__(self, key, passin):
+        super().__init__()
+        self.type = "RSA-PSS"
+        self.key = key
+        self.passin = passin
+
+    def prepare_cmd(self, sw_desc_in, sw_desc_sig):
+        self.signcmd = (
+            ["openssl", "dgst", "-sha256", "-sign", self.key]
+            + self.get_passwd_file_args()
+            + ["-sigopt", "rsa_padding_mode:pss"]
+            + ["-sigopt", "rsa_pss_saltlen:-2"]
+            + ["-out", sw_desc_sig, sw_desc_in]
+        )
 
 class SWUSignCustom(SWUSign):
     def __init__(self, cmd):
diff --git a/tests/test_main.py b/tests/test_main.py
index 5dbf51f..18ffd41 100644
--- a/tests/test_main.py
+++ b/tests/test_main.py
@@ -4,7 +4,7 @@  import libconf
 import pytest
 
 from swugenerator import main
-from swugenerator.swu_sign import SWUSignCMS, SWUSignCustom, SWUSignPKCS11, SWUSignRSA
+from swugenerator.swu_sign import SWUSignCMS, SWUSignCustom, SWUSignPKCS11, SWUSignRSA, SWURSAPSS
 
 VALID_KEY = "390ad54490a4a5f53722291023c19e08ffb5c4677a59e958c96ffa6e641df040"
 VALID_IV = "d5d601bacfe13100b149177318ebc7a4"
@@ -102,6 +102,8 @@  SIGNING_TEST_PARAMETERS = [
     ("CMS,foo,bar", SWUSignCMS("foo", "bar", None, None)),
     ("RSA,foo,bar", SWUSignRSA("foo", "bar")),
     ("RSA,foo", SWUSignRSA("foo", None)),
+    ("RSA-PSS,foo,bar", SWUSignRSAPSS("foo", "bar")),
+    ("RSA-PSS,foo", SWUSignRSAPSS("foo", None)),
     ("PKCS11,foo", SWUSignPKCS11("foo")),
     ("CUSTOM,foo", SWUSignCustom("foo")),
 ]
@@ -134,6 +136,7 @@  INVALID_SIGNING_TEST_PARAMETERS = [
         "CMS requires private key, certificate, an optional password file and an optional file with additional certificates",
     ),
     ("RSA,foo,bar,baz", "RSA requires private key and an optional password file"),
+    ("RSA-PSS,foo,bar,baz", "RSA requires private key and an optional password file"),
     ("PKCS11", "PKCS11 requires URI"),
     ("PKCS11,", "PKCS11 requires URI"),
     ("PKCS11,,", "PKCS11 requires URI"),