ed25519-zebra/ed25519jni
Douglas Roark 346f4cde27
Add DER & PEM support for SigningKeySeed and VerificationKeyBytes (RFC 8410) (#46)
* Add DER & PEM support for SigningKeySeed and VerificationKeyBytes (RFC 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.

* Accommodate extra octet string in private key DER bytes

- 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.

* Update pkcs8 to 0.7.0

* Cleanup

- Enhance PEM capabilities for SigningKey and VerificationKeyBytes. This also allowed for some tests to be simplified.
- From -> TryFrom for some VerificationKeyBytes impls.

* Upgrade JNI Rust bindings to PKCS8 0.7.5

- Make necessary changes to support the newer crate.
- Fix an unrelated compiler warning.

* More fixups

- Get code to compile after updating to the latest Rust.
- Fix a couple of failing tests (add LF to expected encoding output).

* Major update

- 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.

* Further code cleanup

- 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.

* Add missing DER/PEM files for unit tests

* Add JNI comments to resolve publisher warnings

When executing `sbt publishLocal` and generating a JAR file, there are warnings regarding some functions not having public comments. Add public comments as needed.

* JNI README update

* Comment touchup

* Review fixups

- 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.

* Upgrade jni crate to 0.20.0

The 0.21.X crates feature a major refactor that breaks the code. Don't upgrade to them until some issues are resolved. (See https://github.com/jni-rs/jni-rs/issues/432 for more info.)

* Upgrade jni crate to 0.21.1

- A path forward to upgrading to 0.21.X was suggested by the jni-rs library developer (https://github.com/jni-rs/jni-rs/issues/439#issuecomment-1493074721). Upgrade the code, improving the safety of the JNI code.
- Cargo.toml fixups.

* cargo clippy / cargo fmt cleanup

Also do minor JNI README cleanup.

* Use an export to clean up some tests a bit

---------

Co-authored-by: Douglas Roark <douglas.roark@gemini.com>
2023-04-21 17:56:37 -03:00
..
jvm Add DER & PEM support for SigningKeySeed and VerificationKeyBytes (RFC 8410) (#46) 2023-04-21 17:56:37 -03:00
project Add DER & PEM support for SigningKeySeed and VerificationKeyBytes (RFC 8410) (#46) 2023-04-21 17:56:37 -03:00
rust Add DER & PEM support for SigningKeySeed and VerificationKeyBytes (RFC 8410) (#46) 2023-04-21 17:56:37 -03:00
scripts Add DER & PEM support for SigningKeySeed and VerificationKeyBytes (RFC 8410) (#46) 2023-04-21 17:56:37 -03:00
README.md Add DER & PEM support for SigningKeySeed and VerificationKeyBytes (RFC 8410) (#46) 2023-04-21 17:56:37 -03:00

README.md

JNI

Code that provides a JNI for the library is included. Allows any JNI-using language to interact with specific ed25519-zebra calls and provides a minor analogue for some Rust classes, allowing for things like basic sanity checks of certain values. Tests written in Scala have also been included.

Note that Scala 3 is required to build and test the JNI code.

Build Requirements

  • For PEM support, the pem feature must be enabled in both Cargo.toml files (pem = ["der"]).
  • For PKCS #8 (DER) support, the pkcs8 feature must be enabled in both Cargo.toml files (pkcs8 = ["dep:pkcs8"]).

Compilation / Library Usage

To build the JNI code, there are several steps. The exact path forward depends on the user's preferred deployment method. No matter what, the following steps must be performed at the beginning.

  • Run cargo build in the root directory. This generates the core Rust code.
  • Run cargo build in the ed25519jni/rust subdirectory. This generates the Rust glue code libraries (libed25519jni.a and libed25519jni.{so/dylib}).

From here, there are two deployment methods: Direct library usage and JARs.

JAR

It's possible to generate a JAR that can be loaded into a project via SciJava's NativeLoader, along with the Java JNI interface file. There are two extra steps to perform after the mandatory compilation steps.

  • Run jni_jar_prereq.sh from the ed25519jni/scripts subdirectory. Use the -d flag if working with debug builds. This script performs some JAR setup steps, and enables the local Scala tests against the JNI code.
  • Run sbt clean publishLocal from the ed25519jni/jvm subdirectory. This generates the final ed25519jni.jar file in the {$HOME}/.ivy2/local subdirectory.

Direct library usage

Use a preferred method to load the Rust core and JNI libraries directly as needed. If necessary, include the JNI Java files too.

Note that the code is designed to support only the aforementioned JAR method. Local changes may be required to support other deployment methods.

Testing

Prerequisites

To reiterate, before running any tests, execute the first step from the JAR compilation method section above.

Commands

The precise test command will depend on if you built the code with PKCS8 and/or PEM support. Both are disabled by default. This also means that, without disabling the associated tests or enabling the features, an UnsatisfiedLinkError Java error will occur.

The following examples show how to run tests.

  • sbt test - Run all tests. Must compile with PEM and PKCS #8 support.
  • sbt "testOnly * -- -l Pkcs8Test" - Run all tests unrelated to PKCS #8.
  • sbt "testOnly * -- -l \"PemTest Pkcs8Test\"" - Run all tests unrelated to PEM and PKCS #8.

Capabilities

Among other things, the JNI code can perform the following actions.

  • Generate a random 32 byte signing key seed.
  • Generate a 32 byte verification key from a signing key seed.
  • Sign arbitrary data with a signing key seed.
  • Verify a signature for arbitrary data with verification key bytes.
  • Generate DER bytes and PEM strings for signing key seeds and verification key bytes, and read back the DER bytes and PEM strings into signing key seeds and verification key bytes.