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 DER & PEM support for SigningKeySeed and VerificationKeyBytes (RFC 8410) #46

Merged
merged 17 commits into from
Apr 21, 2023

Conversation

droark
Copy link
Contributor

@droark droark commented Mar 31, 2021

  • Add encoding to and decoding from DER bytes and PEM strings for SigningKeySeed and VerificationKeyBytes.
  • Add some functions so that the Java code mirrors, to a certain degree, the JDK 15 interface for Ed25519 keys and signatures.
  • Add encoding and decoding for signatures (technically identity functions).
  • Miscellaneous cleanup.

@droark
Copy link
Contributor Author

droark commented Mar 31, 2021

FYI, the code should work as is. It passes all tests locally. I'm leaving it in draft form for a little while as I clean it up and make sure it's ready for review. That said, feel free to play with the code and make suggestions.

Thanks.

src/signing_key.rs Outdated Show resolved Hide resolved
src/signing_key.rs Outdated Show resolved Hide resolved
src/signing_key.rs Outdated Show resolved Hide resolved
src/signing_key.rs Outdated Show resolved Hide resolved
src/signing_key.rs Outdated Show resolved Hide resolved
src/signing_key.rs Outdated Show resolved Hide resolved
src/signing_key.rs Outdated Show resolved Hide resolved
@tarcieri
Copy link

tarcieri commented May 21, 2021

I just discovered something interesting about PKCS#8-serialized Ed25519 private keys. Per this CURDLE draft:

https://datatracker.ietf.org/doc/html/draft-ietf-curdle-pkix-07#section-10.3

The private_key field actually contains an encapsulated 34-byte ASN.1 document containing an OCTET STRING with tag/length header:

   12 04   34:   OCTET STRING
             :     04 20 D4 EE 72 DB F9 13 58 4A D5 B6 D8 F1 F7 69
             :     F8 AD 3A FE 7C 28 CB F1 D4 FB E0 97 A8 8F 44 75
             :     58 42
             :   }

   Note that the value of the private key is:

   D4 EE 72 DB F9 13 58 4A D5 B6 D8 F1 F7 69 F8 AD
   3A FE 7C 28 CB F1 D4 FB E0 97 A8 8F 44 75 58 42

See also the second example which uses PKCS#8v2 and includes a public key:

    12  34:   OCTET STRING, encapsulates {
    14  32:     OCTET STRING D4 EE 72 DB F9 13 58 4A D5 B6 D8 F1 F7
                    69 F8 AD 3A FE 7C 28 CB F1 D4 FB E0 97 A8 8F 44
                    75 58 42
          :     }

(that's right, it's an OCTET STRING inside of another OCTET STRING)

This makes it a bit trickier, as decoding you'll need to check the private key begins with the bytes 04 20 and strip them, and then encoding you'll need to add them, creating a 34-byte ASN.1 DER document with those leading bytes to encapsulate into the private_key field.

@droark
Copy link
Contributor Author

droark commented May 22, 2021

@tarcieri - Thanks for the catch! I see that this is indeed a part of the final RFC 8410 spec. I'll add a fix for that.

@droark
Copy link
Contributor Author

droark commented May 24, 2021

@tarcieri - Pushed updated code.

@droark
Copy link
Contributor Author

droark commented Jun 2, 2021

@dconnolly - Anything I can do to get some 👀 on this one? Thanks!

@tarcieri
Copy link

tarcieri commented Jun 2, 2021

@droark FYI, I plan on cutting another release of the pkcs8 crate (prospectively v0.7.0) in the next few days.

I'm also happy to do another pass on reviewing this soon (we'd actually very much like to use it)

@tarcieri
Copy link

tarcieri commented Jun 8, 2021

pkcs8 v0.7.0 is out: https://docs.rs/pkcs8/0.7.0/

FYI: Minimum Supported Rust Version is 1.51

src/signing_key.rs Outdated Show resolved Hide resolved
src/signing_key.rs Outdated Show resolved Hide resolved
@droark
Copy link
Contributor Author

droark commented Jun 9, 2021

pkcs8 v0.7.0 is out: https://docs.rs/pkcs8/0.7.0/

FYI: Minimum Supported Rust Version is 1.51

Thanks. Pushed a new commit that uses it.

src/signing_key.rs Outdated Show resolved Hide resolved
src/verification_key.rs Outdated Show resolved Hide resolved
src/verification_key.rs Outdated Show resolved Hide resolved
src/signing_key.rs Outdated Show resolved Hide resolved
Douglas Roark and others added 12 commits March 16, 2023 20:58
…C 8410)

- Add encoding to and decoding from DER bytes and PEM strings for SigningKeySeed and VerificationKeyBytes.
- Add some functions so that the Java code mirrors, to a certain degree, the JDK 15 interface for Ed25519 keys and signatures.
- Add encoding and decoding for signatures (technically identity functions).
- Miscellaneous cleanup.
- In RFC 8410, DER-encoded private keys are in an octet string that's encapsulated by another octet string. Add the extra octet string, and adjust tests as necessary.
- In the tests, use the private key from RFC 8410, Sect. 10.3.
- Enhance PEM capabilities for SigningKey and VerificationKeyBytes. This also allowed for some tests to be simplified.
- From -> TryFrom for some VerificationKeyBytes impls.
- Make necessary changes to support the newer crate.
- Fix an unrelated compiler warning.
- Get code to compile after updating to the latest Rust.
- Fix a couple of failing tests (add LF to expected encoding output).
- Update pkcs8 crate to 0.10.0, and update code as required to support the crate. This includes supporting the Decode(Public/Private)Key and Encode(Public/Private)Key traits so as to take advantage of Ed25519 DER and PEM code in the crate.
- Add the latest ed25519 crate (2.2.0) to support KeypairBytes and other features.
- Remove the signature code and implement Signature (Signer and Verifier traits) from the "signatures" crate included with the pkcs8 crate.
- Update the JNI code. This includes mandating Scala 3 usage.
- Minor cleanup (including warning fixes) and changes to make the code a bit clearer.

A follow-up commit will clean up the tests and probably add support for v2 private DER keys.
- Update pkcs8 crate to 0.10.1.
- Fix PEM feature code.
- Update Ed25519 JNI code as needed.
- Remove dead code.
- Re-enable a couple of unit tests.

Note that a couple of Ed25519 JNI unit tests are still failing. A follow-up PR will have the fix.
When executing `sbt publishLocal` and generating a JAR file, there are warnings regarding some functions not having public comments. Add public comments as needed.
- Finish adding PEM/PKCS8 tags and cfg items as needed to separate the features from default compilation.
- Revert some minor name changes.
- Make the JNI README more precise with regards to requirements.
- Add ARM64 macOS support to JNI. Untested but it should work, and it doesn't break Intel Macs.
- Miscellaneous cleanup, including fixing cargo and sbt warnings.
@droark
Copy link
Contributor Author

droark commented Mar 18, 2023

@conradoplg - I think I caught everything you requested. All the PEM/PKCS8 stuff is optional and properly firewalled (AFAIK), Signature is left alone, and all tests pass, with and without the features. I'm thinking it might not hurt to add JNI testing to CI. We can cross that bridge another time. As is, the only quirk I don't like is that sbt test will fail by default when testing JNI. This is discussed in the README. I don't think there's a good way to work around this, so JNI users will just have to RTFM when compiling.

The 0.21.X crates feature a major refactor that breaks the code. Don't upgrade to them until some issues are resolved. (See jni-rs/jni-rs#432 for more info.)
- A path forward to upgrading to 0.21.X was suggested by the jni-rs library developer (jni-rs/jni-rs#439 (comment)). Upgrade the code, improving the safety of the JNI code.
- Cargo.toml fixups.
Copy link
Contributor

@conradoplg conradoplg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good, just needs addressing some small comments.

Can you also please cargo fmt the code and fix the 3 cargo clippy warnings?

Cargo.toml Outdated Show resolved Hide resolved
Cargo.toml Outdated Show resolved Hide resolved
ed25519jni/rust/Cargo.toml Show resolved Hide resolved
Also do minor JNI README cleanup.
@droark
Copy link
Contributor Author

droark commented Apr 18, 2023

@conradoplg - Pushed the changes. Everything should be ready now.

Copy link
Contributor

@conradoplg conradoplg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, one last detail I missed 😬

src/lib.rs Show resolved Hide resolved
tests/unit_tests.rs Outdated Show resolved Hide resolved
tests/util/mod.rs Outdated Show resolved Hide resolved
@droark
Copy link
Contributor Author

droark commented Apr 21, 2023

@conradoplg - Fixed.

Copy link
Contributor

@conradoplg conradoplg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you so much for the contribution and with the patience 😅

@conradoplg conradoplg merged commit 346f4cd into ZcashFoundation:main Apr 21, 2023
@droark droark deleted the pkcs8_support branch July 18, 2023 13:48
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.

None yet

3 participants