feat: add PKCS#1 v1.5 padding to support PKCS#7 signing#291
Conversation
Add RSA PKCS#1 v1.5 signature algorithm support (RS256, RS384, RS512) alongside the existing PSS algorithms. This is required for dm-verity kernel signature verification which expects PKCS#1 v1.5 signatures. Changes: - Add PKCS1 key spec variants to Protocol/KeySpec.cs - Extend KeySpecExtension to map PKCS1 specs to Azure Key Vault algorithms - Update GenerateSignature to select the correct signing scheme - Add unit tests for new key specs and algorithm mappings Signed-off-by: Dallas Delaney <dadelan@microsoft.com>
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #291 +/- ##
==========================================
- Coverage 93.03% 92.97% -0.06%
==========================================
Files 17 17
Lines 617 683 +66
Branches 78 89 +11
==========================================
+ Hits 574 635 +61
- Misses 31 33 +2
- Partials 12 15 +3 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Improve CI patch coverage for tests to get over 80% Add tests for all RSA key sizes (2048/3072/4096) and EC key sizes (256/384/521) through the PKCS1 code paths. Add tests for empty string and rsassa-pss scheme routing. Add direct tests for ToKeyVaultSignatureAlgorithmPKCS1 and ToSigningAlgorithmPKCS1. Fix trailing whitespace in KeySpec.cs. Signed-off-by: Dallas Delaney <dadelan@microsoft.com>
shizhMSFT
left a comment
There was a problem hiding this comment.
Caution
AI-generated review. This review was produced by an AI agent (Claude Opus 4.7, shizh-reviewer skill) on behalf of @shizhMSFT. It is posted as COMMENT (not REQUEST_CHANGES) — please weigh findings on their merits and treat them as starting points, not gating concerns.
Thanks @dallasd1. The plugin layer is the right place for AKV-specific signature scheme selection, but a few things are worth reconsidering before merge — the most important being that this PR alone does not appear to work end-to-end without coordinated changes in notaryproject/specifications, notation-core-go, and notation-go.
Concerns
-
signingAlgorithm = "RSASSA-PKCS1-v1_5-SHA-*"is not in the Notary signature spec, so notation will reject this AKV response. AKV'sGenerateSignatureresponse (perProtocol/KeySpec.cs) will setsigningAlgorithmto one of"RSASSA-PKCS1-v1_5-SHA-{256,384,512}". But:notation-core-go'ssignature.Algorithmenum (signature/algorithm.go:29-34) defines onlyPS{256,384,512}andES{256,384,512}. There is no PKCS#1 v1.5 member.notation-go'sproto.DecodeSigningAlgorithmwill not recognize the new value.- Per
notaryproject/specificationsplugin-extensibility.md §generate-signature,response.signingAlgorithmMUST be one of the spec-listed algorithms — and PKCS#1 v1.5 isn't in the table. - End result: the standard envelope flow will reject AKV's response.
So this PR alone, even with all other concerns addressed, appears non-functional end-to-end. It depends on coordinated PRs to:
notaryproject/specifications— addRSASSA-PKCS1-v1_5-SHA-{256,384,512}to the algorithm-selection table,notation-core-go— extendsignature.Algorithmandproto.DecodeSigningAlgorithm,notation-go— updatePluginSigner.generateSignaturevalidation.
Worth opening a tracking issue covering all three repos and linking from this PR. /cc @yizha1 @priteshbandi
-
ToKeyVaultSignatureAlgorithmPKCS1over-promises for EC keys. The function name promises PKCS#1 v1.5 but forKeyType.ECit returnsES256/ES384/ES512(ECDSA). Technically correct (EC has no padding variant) but the naming makes a CLI that requestssigning_scheme=rsassa-pkcs1-v1_5against an EC key silently get ECDSA, which the kernel cannot consume for dm-verity. Consider either (a) rejecting EC keys explicitly when the scheme isrsassa-pkcs1-v1_5, or (b) renaming toToDmVeritySignatureAlgorithmand documenting the EC fallback as deliberate. -
Public ABI growth in a NuGet package.
Notation.Plugin.Protocol.SigningScheme,SigningAlgorithms.RSASSA_PKCS1_V1_5_SHA_*,KeySpec.ToSigningAlgorithmPKCS1(),KeySpec.ToSigningAlgorithm(string?),KeySpecExtension.ToKeyVaultSignatureAlgorithmPKCS1(),KeySpecExtension.ToKeyVaultSignatureAlgorithm(string?),GenerateSignature.SigningSchemeConfigKey— that's seven new public symbols for what could be one. Worth reducing by (a) keepingToSigningAlgorithmPKCS1/ToKeyVaultSignatureAlgorithmPKCS1internal(they're only used as fallbacks of the scheme-aware variants), and (b) only exposingToSigningAlgorithm(string? scheme)/ToKeyVaultSignatureAlgorithm(string? scheme)plus theSigningSchemeconstants.
Design questions / non-blocking
- Cross-vendor coordination of
signing_scheme. Plugin config is the established mechanism for vendor-specific configuration (this plugin already usesca_certs,self_signed,credential_typewithout spec entries) — so there's no protocol violation. But other notation plugins (HashiCorp Vault, AWS KMS, GCP KMS) will need the same scheme switch for dm-verity. Should we coordinate withnotaryproject/specificationsto registersigning_schemeas a standard plugin config key before each vendor invents their own? - Key-policy validation. AKV has keys whose policy disallows PKCS#1 v1.5 (managed-HSM keys frequently restrict to PSS). When the CLI requests
rsassa-pkcs1-v1_5against such a key, the AKV REST call will fail mid-stream with a confusing error. Pre-flighting viaGetKeyPropertieswould surface a clear error early — but adds a round-trip on every sign. Worth doing only if the in-stream error message turns out to be opaque in practice. Defer until we see real complaints.
Verdict: COMMENT (AI review only — not gating).
- expand SigningSchemeConfigKey XML doc to clarify supported values - reject rsassa-pkcs1-v1_5 + EC key in RunAsync (new theory test) - mark PKCS1 helpers internal to hide EC fallback - collapse null / "" switch arms to 'null or ""' - rename ToSignatureAlgorithm_WithScheme_* tests to ToKeyVaultSignatureAlgorithm_WithScheme_* - assert offending scheme value in ArgumentException Signed-off-by: Dallas Delaney <dadelan@microsoft.com>
- hoist signing_scheme validation upstream in RunAsync so the failure reports the plugin's VALIDATION_ERROR code - add RSA happy-path and EC-rejection PKCS1 RunAsync tests - add uppercase-scheme row for case-insensitivity - split mixed RSA+EC PKCS1 helper tests - rename EC variant to ReturnsECDSAForSymmetry - mirror PKCS1 helper docs across KeySpec and KeySpecExtension - note scheme-router switch must stay in lock-step - rename SigningScheme to SigningSchemes Signed-off-by: Dallas Delaney <dadelan@microsoft.com>
|
Thanks for the feedback @shizhMSFT! The comments have been addressed listed have been addressed in the last commit. |
Add RSA PKCS#1 v1.5 signature algorithm support alongside the existing PSS algorithms. This is required for dm-verity kernel signature verification which expects PKCS#1 v1.5 signature padding. The signing scheme is now selected using the signing_scheme plugin config key. AKV already supports PKCS#1 v1.5 so this change adds the option to select it from the plugin.