From 15ef35871a91a6bc15b0d829606b340638360f91 Mon Sep 17 00:00:00 2001 From: Carlos Monastyrski Date: Mon, 20 Jul 2026 16:51:44 -0300 Subject: [PATCH 1/3] Support pre-hashed RSA signing for HSM-backed PKCS#11 signers --- packages/gateway-v2/pkcs11_enabled.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/gateway-v2/pkcs11_enabled.go b/packages/gateway-v2/pkcs11_enabled.go index 5808a3ea..985a265c 100644 --- a/packages/gateway-v2/pkcs11_enabled.go +++ b/packages/gateway-v2/pkcs11_enabled.go @@ -415,6 +415,8 @@ func (m *pkcs11ModuleImpl) Sign(slotLabel string, pin []byte, keyLabel, mechanis func resolveMechanism(name string, isDigest bool) (uint, []byte, error) { switch name { + case "CKM_RSA_PKCS": + return pkcs11.CKM_RSA_PKCS, nil, nil case "CKM_SHA256_RSA_PKCS": return pkcs11.CKM_SHA256_RSA_PKCS, nil, nil case "CKM_SHA384_RSA_PKCS": From 1236905945caf86cd870130c3357de7d420927fa Mon Sep 17 00:00:00 2001 From: Carlos Monastyrski Date: Mon, 20 Jul 2026 17:11:14 -0300 Subject: [PATCH 2/3] Address greptile comment --- packages/gateway-v2/pkcs11_enabled.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/gateway-v2/pkcs11_enabled.go b/packages/gateway-v2/pkcs11_enabled.go index 985a265c..8c359222 100644 --- a/packages/gateway-v2/pkcs11_enabled.go +++ b/packages/gateway-v2/pkcs11_enabled.go @@ -416,6 +416,9 @@ func (m *pkcs11ModuleImpl) Sign(slotLabel string, pin []byte, keyLabel, mechanis func resolveMechanism(name string, isDigest bool) (uint, []byte, error) { switch name { case "CKM_RSA_PKCS": + if !isDigest { + return 0, nil, &Pkcs11Error{Code: Pkcs11ErrBadRequest, Message: "CKM_RSA_PKCS requires a pre-hashed DigestInfo input (isDigest=true)"} + } return pkcs11.CKM_RSA_PKCS, nil, nil case "CKM_SHA256_RSA_PKCS": return pkcs11.CKM_SHA256_RSA_PKCS, nil, nil From 8a83a43ad1225505b93ba8eb152cc58b7e3863ab Mon Sep 17 00:00:00 2001 From: Carlos Monastyrski Date: Mon, 20 Jul 2026 17:25:08 -0300 Subject: [PATCH 3/3] Improve RSA signing hash allowlist --- packages/gateway-v2/pkcs11_enabled.go | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/packages/gateway-v2/pkcs11_enabled.go b/packages/gateway-v2/pkcs11_enabled.go index 8c359222..ceaef4a5 100644 --- a/packages/gateway-v2/pkcs11_enabled.go +++ b/packages/gateway-v2/pkcs11_enabled.go @@ -392,6 +392,11 @@ func (m *pkcs11ModuleImpl) Sign(slotLabel string, pin []byte, keyLabel, mechanis if err != nil { return err } + if mechanism == "CKM_RSA_PKCS" { + if err := validateRsaPkcs1DigestInfo(data); err != nil { + return err + } + } handle, found, err := findObject(m.ctx, session, keyLabel, pkcs11.CKO_PRIVATE_KEY) if err != nil { return err @@ -413,6 +418,24 @@ func (m *pkcs11ModuleImpl) Sign(slotLabel string, pin []byte, keyLabel, mechanis return sig, err } +var rsaPkcs1DigestInfos = []struct { + prefix []byte + digestLen int +}{ + {[]byte{0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20}, 32}, + {[]byte{0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30}, 48}, + {[]byte{0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40}, 64}, +} + +func validateRsaPkcs1DigestInfo(data []byte) error { + for _, di := range rsaPkcs1DigestInfos { + if len(data) == len(di.prefix)+di.digestLen && bytes.Equal(data[:len(di.prefix)], di.prefix) { + return nil + } + } + return &Pkcs11Error{Code: Pkcs11ErrBadRequest, Message: "CKM_RSA_PKCS input must be a SHA-256, SHA-384, or SHA-512 DigestInfo"} +} + func resolveMechanism(name string, isDigest bool) (uint, []byte, error) { switch name { case "CKM_RSA_PKCS":