Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for recently published ISO extensions to digital signing #106

Conversation

MatthiasValvekens
Copy link
Contributor

@MatthiasValvekens MatthiasValvekens commented Oct 28, 2022

(Warning: this is a relatively big contribution, but the vast majority of the changes are local to the sign module)

ISO published ISO/TS 32001 and ISO/TS 32002 in September and October, respectively. These technical specifications extend PDF's digital signing capabilities in the following ways:

  • ISO/TS 32001: support for SHA-3 hash functions
  • ISO/TS 32002: list of supported ECDSA curves + EdDSA support

This PR adds support for these two extensions to iText (both signing & validation) without breaking API compatibility. Here's a rough overview of the changes:

  • I cleaned house in the internals of PdfPKCS7 and PrivateKeySignature and renamed a bunch of variables and private fields so it's easier to tell what they actually represent (especially now that the number of supported algorithms is rising). I didn't touch the public API other than rewriting some Javadoc snippets, but I strongly recommend doing away with the old naming scheme at the next opportunity (i.e. major version upgrade).
  • I also fixed a long-standing and oft-complained-about bug in the ECDSA handler (DEVSIX-4842): iText currently writes wrong OIDs in all ECDSA signatures. For ECDSA, there is no generic signature algorithm OID, but only OIDs that also encode the relevant digest algorithm. In fact, the exact same problem was present for DSA signatures as well. Not that anyone still cares about plain old DSA, but I fixed that too.
  • The ISO documents require registering extensions in the developer extensions dictionary, and in fact they require a multivalued developer extension prefix. This is a feature exclusive to the 2020 edition of ISO 32000-2, and wasn't implemented in kernel yet, so I added it.
  • A bunch of tests, including both round-trip tests and validation tests with known-good files.

Caveats:

  • While I added logic to PdfSigner to auto-register the relevant developer extensions when they were "obviously" required, there's a minor issue for ECDSA: from within signDetached, there's no convenient way to tell which curve is being used to sign, and in particular whether it appears on the list in ISO/TS 32002. In those cases the caller needs to declare the relevant extension manually.
  • I'm pretty sure that the changes I made to PdfPKCS7 and friends won't autoport... That's part of the reason why I tried to clean them up as much as humanly possible in one PR, since it's probably less effort to manually port those changes than it would be to get 3 separate PRs with manual porting through the merge pipeline.
  • I probably touched quite a bit of crusty old code with poor test coverage, so I'm sure SonarQube will have plenty to complain about.

Questions, comments, requests, etc. are welcome.

JcaPEMKeyConverter, when initialised using default params, uses the
current default security provider. It makes sense to make that default
the actual BouncyCastle provider that's currently relevant.

(It's also a necessity to deal with EdDSA keys on pre-15 JDKs)
Many fields and methods in PdfPKCS7 have names that are misleading,
wrong or no longer make sense in a setting where RSA is not the only
game in town.

This commit renames a number of internal fields to be less confusing
and updates the documentation accordingly. For compatibility reasons,
the public API has not been modified.
 - SHA-3 digests & signing algorithm combinations
 - RSASSA with PKCS #1 v1.5 padding + SHA3 validation test
 - Validation tests with BrainpoolP384r1, NIST-P256
   for both SHA-3 and SHA-2 digests.
 - Ensure the digest function is pinned for Ed448 and Ed25519 regardless
   of what the user specifies.
ECDSA and DSA don't have a generic signature algorithm OID, it always
depends on the choice of hash function. The one serialised by iText was
the one for keys, not signatures.

DEVSIX-4842
 - EdDSA signing integration
 - Tests for SHA-3 and ISO/TS 32002 ECC signing
@MatthiasValvekens
Copy link
Contributor Author

Rebased after the signature migration landed in develop today.

This is a breaking change that renames several pieces of the signing api
with the goal to make it more consistent and easier to navigate.

Methods and classes were renamed in accordance with the following
general principles:

 - To ensure consistency within the codebase, adopt the following
   terminological conventions as much as possible:
        - "Digest" refers to hash functions only. Examples: SHA-256,
          SHA3-512.
        - "Signature algorithm" refers to the signature algorithm only,
          not to any associated digest function (if any). Examples: ECDSA, Ed25519.
        - "Signature mechanism" refers to the combination of a signature
          algorithm with a digest function (if the algorithm requires
          one). Examples: SHA-256 with ECDSA, Ed25519 (since Ed25519
          doesn't require any digest).
        - Avoid using the term "encryption", since that is typically
          understood to refer to a _reversible_ procedure meant to
          ensure data _confidentiality_. Neither applies in the
          signing context.

 - Method name transparency:
        - Getters that return an OID are suffixed with "Oid"
        - Getters that return a JCA-style name are suffixed with "Name"

These are the most impactful changes:

 - The algorithm getters in IExternalSignature were renamed.
 - Various getters in PdfPKCS7 were renamed.
 - The EncryptionAlgorithms utility class was renamed to
   SignatureMechanisms.
@MatthiasValvekens
Copy link
Contributor Author

Since breaking changes are currently allowed on develop, I added a commit with some breaking changes to clean up the naming scheme in the API of the sign module (as discussed on Slack). The commit message describes the general principles behind the change.

I did this as a separate commit to make it easier to remove in case you'd prefer to go ahead with a "neutral" changeset after all, but if need be I can move it further back into the history so it goes together with the name changes I did in the private API of PdfPKCS7.

Side note: the choice of terminology that I'm proposing is only one of several possible alternatives. My main concern is making sure that the API uses the same convention everywhere.

There's an issue causing certificate loading to fail when BC-FIPS is
used with a CertificateFactory from the default security provider on
JDK 8, when the subject key is an EdDSA key.

This commit changes that by ensuring that the currently relevant BC
provider is always used when constructing CertificateFactory objects in
the 'sign' module. The change was applied to both BC and BCFIPS for
consistency.
@vitali-pr
Copy link
Contributor

PR has been approved and merged.
97a3598
cf96cc8
de68979
19eed45
9e65e58
abc23b7
1479901
81f254f
cf64547

@MatthiasValvekens
Copy link
Contributor Author

Thanks @vitali-pr ! I'll close this one then. As you may have noticed, I made a follow-up PR for the RSASSA-PSS stuff; see #108. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants