Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package parsec for openSUSE:Factory checked in at 2022-01-13 23:21:29 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/parsec (Old) and /work/SRC/openSUSE:Factory/.parsec.new.1892 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "parsec" Thu Jan 13 23:21:29 2022 rev:10 rq:946152 version:0.8.1 Changes: -------- --- /work/SRC/openSUSE:Factory/parsec/parsec.changes 2021-12-21 18:41:31.385921852 +0100 +++ /work/SRC/openSUSE:Factory/.parsec.new.1892/parsec.changes 2022-01-13 23:22:05.432072963 +0100 @@ -1,0 +2,6 @@ +Thu Jan 13 13:25:14 UTC 2022 - Guillaume GARDET <[email protected]> + +- Update to 0.8.1: + * Changelog: https://github.com/parallaxsecond/parsec/compare/0.8.0...0.8.1 + +------------------------------------------------------------------- Old: ---- parsec-0.8.0.tar.gz New: ---- parsec-0.8.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ parsec.spec ++++++ --- /var/tmp/diff_new_pack.Gv4ZNc/_old 2022-01-13 23:22:06.868073902 +0100 +++ /var/tmp/diff_new_pack.Gv4ZNc/_new 2022-01-13 23:22:06.880073911 +0100 @@ -1,7 +1,7 @@ # # spec file for package parsec # -# Copyright (c) 2021 SUSE LLC +# Copyright (c) 2022 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -20,7 +20,7 @@ %{?systemd_ordering} Name: parsec -Version: 0.8.0 +Version: 0.8.1 Release: 0 Summary: Platform AbstRaction for SECurity License: Apache-2.0 ++++++ _service ++++++ --- /var/tmp/diff_new_pack.Gv4ZNc/_old 2022-01-13 23:22:06.912073932 +0100 +++ /var/tmp/diff_new_pack.Gv4ZNc/_new 2022-01-13 23:22:06.916073934 +0100 @@ -1,7 +1,7 @@ <services> <service name="cargo_vendor" mode="disabled"> <param name="compression">xz</param> - <param name="srcdir">parsec-0.8.0</param> + <param name="srcdir">parsec-0.8.1</param> </service> </services> ++++++ cargo_config ++++++ --- /var/tmp/diff_new_pack.Gv4ZNc/_old 2022-01-13 23:22:06.936073948 +0100 +++ /var/tmp/diff_new_pack.Gv4ZNc/_new 2022-01-13 23:22:06.936073948 +0100 @@ -3,4 +3,5 @@ [source.vendored-sources] directory = "vendor" +(No newline at EOF) ++++++ parsec-0.8.0.tar.gz -> parsec-0.8.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parsec-0.8.0/.github/workflows/ci.yml new/parsec-0.8.1/.github/workflows/ci.yml --- old/parsec-0.8.0/.github/workflows/ci.yml 2021-08-05 18:38:38.000000000 +0200 +++ new/parsec-0.8.1/.github/workflows/ci.yml 2021-09-17 12:40:41.000000000 +0200 @@ -96,19 +96,20 @@ # When running the container built on the CI # run: docker run -v $(pwd):/tmp/parsec -w /tmp/parsec -t parsec-service-test-all /tmp/parsec/ci.sh cryptoauthlib --no-stress-test - fuzz-test-checker: - name: Check that the fuzz testing framework is still working - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - # Use the following step when updating the `parsec-service-test-all` image - # - name: Build the container - # run: pushd e2e_tests/docker_image && docker build -t parsec-service-test-all -f parsec-service-test-all.Dockerfile . && popd - - name: Run the fuzz test script - # Not running stress tests because rust-cryptoauthlib test-interface does not support required calls - run: ./fuzz.sh test - # When running the container built on the CI - # run: CONTAINER_TAG=parsec-service-test-all ./fuzz.sh test + # Disabled due to the issue discussed in https://github.com/parallaxsecond/parsec/issues/514 + # fuzz-test-checker: + # name: Check that the fuzz testing framework is still working + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v2 + # # Use the following step when updating the `parsec-service-test-all` image + # # - name: Build the container + # # run: pushd e2e_tests/docker_image && docker build -t parsec-service-test-all -f parsec-service-test-all.Dockerfile . && popd + # - name: Run the fuzz test script + # # Not running stress tests because rust-cryptoauthlib test-interface does not support required calls + # run: ./fuzz.sh test + # # When running the container built on the CI + # # run: CONTAINER_TAG=parsec-service-test-all ./fuzz.sh test cross-compilation: # Currently only the Mbed Crypto, PKCS 11, and TPM providers are tested as the other ones need to cross-compile other libraries. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parsec-0.8.0/.github/workflows/nightly.yml new/parsec-0.8.1/.github/workflows/nightly.yml --- old/parsec-0.8.0/.github/workflows/nightly.yml 2021-08-05 18:38:38.000000000 +0200 +++ new/parsec-0.8.1/.github/workflows/nightly.yml 2021-09-17 12:40:41.000000000 +0200 @@ -12,21 +12,22 @@ default: "" jobs: - dependencies: - name: Check for unused dependencies - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - ref: "${{ github.event.inputs.rev }}" - - name: Install latest Rust - uses: actions-rs/toolchain@v1 - with: - toolchain: nightly - - name: Install cargo udeps - run: cargo install cargo-udeps --locked - - name: Execute cargo udeps - run: cargo +nightly udeps + # Disabled due to the issue discussed in https://github.com/parallaxsecond/parsec/issues/514 + # dependencies: + # name: Check for unused dependencies + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v2 + # with: + # ref: "${{ github.event.inputs.rev }}" + # - name: Install latest Rust + # uses: actions-rs/toolchain@v1 + # with: + # toolchain: nightly + # - name: Install cargo udeps + # run: cargo install cargo-udeps --locked + # - name: Execute cargo udeps + # run: cargo +nightly udeps audit: name: Check for crates with security vulnerabilities diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parsec-0.8.0/CHANGELOG.md new/parsec-0.8.1/CHANGELOG.md --- old/parsec-0.8.0/CHANGELOG.md 2021-08-05 18:38:38.000000000 +0200 +++ new/parsec-0.8.1/CHANGELOG.md 2021-09-17 12:40:41.000000000 +0200 @@ -1,5 +1,123 @@ # Changelog +## [0.8.0](https://github.com/parallaxsecond/parsec/tree/0.8.0) (2021-08-05) + +[Full Changelog](https://github.com/parallaxsecond/parsec/compare/0.7.2...0.8.0) + +**Implemented enhancements:** + +- Add Provider Name Config Option [\#487](https://github.com/parallaxsecond/parsec/issues/487) +- Add PKCS11 provider export-attributes switch [\#462](https://github.com/parallaxsecond/parsec/issues/462) +- Refactor the all-providers workflow [\#455](https://github.com/parallaxsecond/parsec/issues/455) +- Adjust linking for TS provider [\#427](https://github.com/parallaxsecond/parsec/issues/427) +- Allow providers to be optional or conditional depending on platform feature availability [\#401](https://github.com/parallaxsecond/parsec/issues/401) +- Add cross-compilation tests for the TPM provider [\#382](https://github.com/parallaxsecond/parsec/issues/382) +- Make the slot\_number field optional [\#375](https://github.com/parallaxsecond/parsec/issues/375) +- Design workflow and associated APIs for key attestation in Parsec [\#370](https://github.com/parallaxsecond/parsec/issues/370) +- Implement error handling for TS caller errors [\#332](https://github.com/parallaxsecond/parsec/issues/332) +- Add release-build tests to CI [\#163](https://github.com/parallaxsecond/parsec/issues/163) +- Add the possibility of changing key store location of Mbed Crypto provider [\#53](https://github.com/parallaxsecond/parsec/issues/53) +- Add TS provider to all-providers [\#482](https://github.com/parallaxsecond/parsec/pull/482) ([ionut-arm](https://github.com/ionut-arm)) +- Adjust TS provider linking [\#474](https://github.com/parallaxsecond/parsec/pull/474) ([ionut-arm](https://github.com/ionut-arm)) +- Add cargo-audit config [\#473](https://github.com/parallaxsecond/parsec/pull/473) ([ionut-arm](https://github.com/ionut-arm)) +- Update dependency on Trusted Services [\#467](https://github.com/parallaxsecond/parsec/pull/467) ([ionut-arm](https://github.com/ionut-arm)) +- Add import and export support for ECC for PKCS11 [\#452](https://github.com/parallaxsecond/parsec/pull/452) ([ionut-arm](https://github.com/ionut-arm)) +- Add a SPIFFE based authenticator [\#449](https://github.com/parallaxsecond/parsec/pull/449) ([hug-dev](https://github.com/hug-dev)) +- Add ECC functionality to PKCS11 prov [\#446](https://github.com/parallaxsecond/parsec/pull/446) ([ionut-arm](https://github.com/ionut-arm)) +- Enable coverage testing for TS provider [\#434](https://github.com/parallaxsecond/parsec/pull/434) ([ionut-arm](https://github.com/ionut-arm)) +- Create SECURITY.md [\#414](https://github.com/parallaxsecond/parsec/pull/414) ([ionut-arm](https://github.com/ionut-arm)) +- Add TPM provider cross-compilation [\#403](https://github.com/parallaxsecond/parsec/pull/403) ([ionut-arm](https://github.com/ionut-arm)) +- Added Option\<Slot\> to PKCS 11 Provider constructor [\#402](https://github.com/parallaxsecond/parsec/pull/402) ([Sven-bg](https://github.com/Sven-bg)) + +**Fixed bugs:** + +- If a response is an error, log it before sending it [\#417](https://github.com/parallaxsecond/parsec/issues/417) +- Fix ingress/egress trace logs [\#416](https://github.com/parallaxsecond/parsec/issues/416) +- Make `KeyInfo` a private type [\#400](https://github.com/parallaxsecond/parsec/issues/400) +- Unable to build 0.7.2 for i686 \(and ppc64/ppc64le\) [\#379](https://github.com/parallaxsecond/parsec/issues/379) +- Unable to build 0.7.2 for armv7 [\#378](https://github.com/parallaxsecond/parsec/issues/378) +- Document clearly how Mbed Crypto provider keys are stored [\#373](https://github.com/parallaxsecond/parsec/issues/373) +- Fix code coverage reports [\#495](https://github.com/parallaxsecond/parsec/pull/495) ([ionut-arm](https://github.com/ionut-arm)) +- Modify the git submodule command [\#490](https://github.com/parallaxsecond/parsec/pull/490) ([hug-dev](https://github.com/hug-dev)) +- Do not login if no user pin was entered [\#489](https://github.com/parallaxsecond/parsec/pull/489) ([hug-dev](https://github.com/hug-dev)) +- Fix git command and use Arm machine [\#485](https://github.com/parallaxsecond/parsec/pull/485) ([ionut-arm](https://github.com/ionut-arm)) +- Fix CircleCI config format. [\#484](https://github.com/parallaxsecond/parsec/pull/484) ([ionut-arm](https://github.com/ionut-arm)) +- Add submodule initialisation to CircleCI [\#483](https://github.com/parallaxsecond/parsec/pull/483) ([ionut-arm](https://github.com/ionut-arm)) +- Make cross-compilation run on release version [\#454](https://github.com/parallaxsecond/parsec/pull/454) ([ionut-arm](https://github.com/ionut-arm)) +- Bump picky crate versions [\#443](https://github.com/parallaxsecond/parsec/pull/443) ([ionut-arm](https://github.com/ionut-arm)) +- Remove the TS coverage computation [\#436](https://github.com/parallaxsecond/parsec/pull/436) ([ionut-arm](https://github.com/ionut-arm)) +- Fix nightly workflow [\#435](https://github.com/parallaxsecond/parsec/pull/435) ([ionut-arm](https://github.com/ionut-arm)) +- Fix ServiceConfig import in fuzz\_service [\#433](https://github.com/parallaxsecond/parsec/pull/433) ([ionut-arm](https://github.com/ionut-arm)) +- Fix Contributing link [\#415](https://github.com/parallaxsecond/parsec/pull/415) ([ionut-arm](https://github.com/ionut-arm)) +- Fix ownership of ibmtpm folder [\#385](https://github.com/parallaxsecond/parsec/pull/385) ([ionut-arm](https://github.com/ionut-arm)) +- Fix CircleCI config [\#384](https://github.com/parallaxsecond/parsec/pull/384) ([ionut-arm](https://github.com/ionut-arm)) +- Implement a few fixes [\#374](https://github.com/parallaxsecond/parsec/pull/374) ([ionut-arm](https://github.com/ionut-arm)) + +**Security fixes:** + +- Resurrect fuzz testing framework [\#422](https://github.com/parallaxsecond/parsec/issues/422) +- Set up Github security policy [\#398](https://github.com/parallaxsecond/parsec/issues/398) +- Investigate testing of Cryptoauthlib provider [\#315](https://github.com/parallaxsecond/parsec/issues/315) +- rust-spiffe: make sure that the claims returned by the validation operation are as expected [\#290](https://github.com/parallaxsecond/parsec/issues/290) +- rust-spiffe: provide a local validation of the JWT-SVID [\#289](https://github.com/parallaxsecond/parsec/issues/289) +- Revive the fuzz testing framework [\#429](https://github.com/parallaxsecond/parsec/pull/429) ([ionut-arm](https://github.com/ionut-arm)) + +**Closed issues:** + +- NXP PKCS\#11 Parsec integration testing. [\#456](https://github.com/parallaxsecond/parsec/issues/456) +- Split the build tests on a different CI workflow [\#447](https://github.com/parallaxsecond/parsec/issues/447) +- Support ECC signing keys in the PKCS\#11 provider [\#421](https://github.com/parallaxsecond/parsec/issues/421) +- Stability: Communication with backends [\#412](https://github.com/parallaxsecond/parsec/issues/412) +- Adopt CII Best Practices Badge from the LF [\#411](https://github.com/parallaxsecond/parsec/issues/411) +- Unable to build parsec 0.7.2 with rust 1.43.1. Parsec 0.6.0 builds fine. [\#409](https://github.com/parallaxsecond/parsec/issues/409) +- Stability: Build toolchain [\#408](https://github.com/parallaxsecond/parsec/issues/408) +- Stability: Environment variables [\#405](https://github.com/parallaxsecond/parsec/issues/405) +- Stability: Dynamic libraries dependencies [\#397](https://github.com/parallaxsecond/parsec/issues/397) +- Stability: systemd communication [\#396](https://github.com/parallaxsecond/parsec/issues/396) +- Stability: OS signals [\#395](https://github.com/parallaxsecond/parsec/issues/395) +- Stability: Persistent state \(key mappings\) [\#394](https://github.com/parallaxsecond/parsec/issues/394) +- Stability: Configuration file [\#393](https://github.com/parallaxsecond/parsec/issues/393) +- Stability: CLI invocation [\#392](https://github.com/parallaxsecond/parsec/issues/392) +- Stability: Authenticators [\#391](https://github.com/parallaxsecond/parsec/issues/391) +- Stability: Communication with clients \(listeners endpoint\) [\#390](https://github.com/parallaxsecond/parsec/issues/390) +- Stability: Communication with clients \(operation contracts\) [\#389](https://github.com/parallaxsecond/parsec/issues/389) +- Stability: Communication with clients \(requests/responses\) [\#388](https://github.com/parallaxsecond/parsec/issues/388) +- Setup environment stability test [\#386](https://github.com/parallaxsecond/parsec/issues/386) +- Archive for 0.7.0 contains .cargo/ folder [\#377](https://github.com/parallaxsecond/parsec/issues/377) +- Add more Fixed Common header tests [\#351](https://github.com/parallaxsecond/parsec/issues/351) + +**Merged pull requests:** + +- Switch imports to crates.io [\#497](https://github.com/parallaxsecond/parsec/pull/497) ([ionut-arm](https://github.com/ionut-arm)) +- Add the Class attribute when generating key pairs [\#493](https://github.com/parallaxsecond/parsec/pull/493) ([hug-dev](https://github.com/hug-dev)) +- Add tests checking absence of slot\_number [\#492](https://github.com/parallaxsecond/parsec/pull/492) ([hug-dev](https://github.com/hug-dev)) +- Split out the all-providers cargo check into its own CI job. [\#472](https://github.com/parallaxsecond/parsec/pull/472) ([MattDavis00](https://github.com/MattDavis00)) +- Make KeyInfo a private type Fix \#400 [\#469](https://github.com/parallaxsecond/parsec/pull/469) ([Kakemone](https://github.com/Kakemone)) +- Added psa\_export\_key & psa\_generate\_random to TS Provider [\#468](https://github.com/parallaxsecond/parsec/pull/468) ([MattDavis00](https://github.com/MattDavis00)) +- Add a allow\_export flag to restrict exporting [\#466](https://github.com/parallaxsecond/parsec/pull/466) ([hug-dev](https://github.com/hug-dev)) +- Added missing ingress logs to providers. \#416 [\#465](https://github.com/parallaxsecond/parsec/pull/465) ([MattDavis00](https://github.com/MattDavis00)) +- \#417 Added additional error logging to front end handle\_request function. [\#464](https://github.com/parallaxsecond/parsec/pull/464) ([MattDavis00](https://github.com/MattDavis00)) +- Update the TS revision used [\#461](https://github.com/parallaxsecond/parsec/pull/461) ([ionut-arm](https://github.com/ionut-arm)) +- Add a way to allow providers to fail instantiation [\#451](https://github.com/parallaxsecond/parsec/pull/451) ([hug-dev](https://github.com/hug-dev)) +- Randomly select the shutdown signal [\#448](https://github.com/parallaxsecond/parsec/pull/448) ([hug-dev](https://github.com/hug-dev)) +- Execute e2e tests with an old version of client [\#445](https://github.com/parallaxsecond/parsec/pull/445) ([hug-dev](https://github.com/hug-dev)) +- \[CryptoAuthLib provider\] Implementation of export key operation [\#442](https://github.com/parallaxsecond/parsec/pull/442) ([TomaszPawelecGL](https://github.com/TomaszPawelecGL)) +- Move CLI log into its own file [\#441](https://github.com/parallaxsecond/parsec/pull/441) ([hug-dev](https://github.com/hug-dev)) +- Add various tests checking contracts [\#440](https://github.com/parallaxsecond/parsec/pull/440) ([hug-dev](https://github.com/hug-dev)) +- Isolate config logic and add e2e config tests [\#432](https://github.com/parallaxsecond/parsec/pull/432) ([hug-dev](https://github.com/hug-dev)) +- \[CryptoAuthLib provider\] Implementation of psa\_export\_public\_key operation. [\#431](https://github.com/parallaxsecond/parsec/pull/431) ([RobertDrazkowskiGL](https://github.com/RobertDrazkowskiGL)) +- \[CryptoAuthLib provider\] Support for psa\_sign\_message and psa\_verify\_message. [\#425](https://github.com/parallaxsecond/parsec/pull/425) ([RobertDrazkowskiGL](https://github.com/RobertDrazkowskiGL)) +- Replace persistence tests with key mappings tests [\#420](https://github.com/parallaxsecond/parsec/pull/420) ([hug-dev](https://github.com/hug-dev)) +- Add Codecov and cii badges [\#419](https://github.com/parallaxsecond/parsec/pull/419) ([ionut-arm](https://github.com/ionut-arm)) +- CryptoAuthentication Library provider - support for PsaSignHash and PsaVerifyHash operations. [\#413](https://github.com/parallaxsecond/parsec/pull/413) ([RobertDrazkowskiGL](https://github.com/RobertDrazkowskiGL)) +- Make it compile for Rust 1.43.1 [\#410](https://github.com/parallaxsecond/parsec/pull/410) ([hug-dev](https://github.com/hug-dev)) +- PSA\_IMPORT\_KEY introduction. [\#399](https://github.com/parallaxsecond/parsec/pull/399) ([RobertDrazkowskiGL](https://github.com/RobertDrazkowskiGL)) +- CryptoAuthLib provider testability improvements: [\#387](https://github.com/parallaxsecond/parsec/pull/387) ([RobertDrazkowskiGL](https://github.com/RobertDrazkowskiGL)) +- Add CircleCI config [\#383](https://github.com/parallaxsecond/parsec/pull/383) ([ionut-arm](https://github.com/ionut-arm)) +- Import newest versions of cryptoki and tss-esapi [\#381](https://github.com/parallaxsecond/parsec/pull/381) ([hug-dev](https://github.com/hug-dev)) +- Update CHANGELOG [\#367](https://github.com/parallaxsecond/parsec/pull/367) ([hug-dev](https://github.com/hug-dev)) +- Implementation of PsaGenerateKey and PsaDestroyKey operations [\#354](https://github.com/parallaxsecond/parsec/pull/354) ([RobertDrazkowskiGL](https://github.com/RobertDrazkowskiGL)) + ## [0.7.2](https://github.com/parallaxsecond/parsec/tree/0.7.2) (2021-03-25) [Full Changelog](https://github.com/parallaxsecond/parsec/compare/0.7.1...0.7.2) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parsec-0.8.0/Cargo.lock new/parsec-0.8.1/Cargo.lock --- old/parsec-0.8.0/Cargo.lock 2021-08-05 18:38:38.000000000 +0200 +++ new/parsec-0.8.1/Cargo.lock 2021-09-17 12:40:41.000000000 +0200 @@ -607,6 +607,12 @@ ] [[package]] +name = "hamming" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65043da274378d68241eb9a8f8f8aa54e349136f7b8e12f63e3ef44043cc30e1" + +[[package]] name = "hashbrown" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1073,7 +1079,7 @@ [[package]] name = "parsec-service" -version = "0.8.0" +version = "0.8.1" dependencies = [ "anyhow", "base64 0.13.0", @@ -1211,6 +1217,52 @@ checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" [[package]] +name = "primal" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bf9e0aea92a2e2a931fafb1b5d4c6e438197bbca4943a9984b3327fb8e3b5d0" +dependencies = [ + "primal-check", + "primal-estimate", + "primal-sieve", +] + +[[package]] +name = "primal-bit" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2837edc85364907810b0ec880f1010dab1a9cc6e75bacb3655c7fd22e125ec1b" +dependencies = [ + "hamming", +] + +[[package]] +name = "primal-check" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01419cee72c1a1ca944554e23d83e483e1bccf378753344e881de28b5487511d" +dependencies = [ + "num-integer", +] + +[[package]] +name = "primal-estimate" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12e07b550a7cbfcaa567bcd28042919548016ad615b5731633fa5239992d853f" + +[[package]] +name = "primal-sieve" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0113d948c8f955a7ae96520023fe1e730eadbf26e67c4452f801a485e9d357" +dependencies = [ + "primal-bit", + "primal-estimate", + "smallvec", +] + +[[package]] name = "proc-macro-error" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1924,9 +1976,9 @@ [[package]] name = "tss-esapi" -version = "6.1.0" +version = "7.0.0-alpha.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23bb26bea47d9a884f613730d2f68c9aeaef9a6a51ce8277d111042dbb8c5975" +checksum = "d65600c381941a18c1bfbc3f0f65976e34ef5d22b9b6c1d3d256df28c152601b" dependencies = [ "bitfield", "enumflags2", @@ -1935,6 +1987,7 @@ "mbox", "num-derive", "num-traits", + "primal", "regex", "serde", "tss-esapi-sys", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parsec-0.8.0/Cargo.toml new/parsec-0.8.1/Cargo.toml --- old/parsec-0.8.0/Cargo.toml 2021-08-05 18:38:38.000000000 +0200 +++ new/parsec-0.8.1/Cargo.toml 2021-09-17 12:40:41.000000000 +0200 @@ -1,6 +1,6 @@ [package] name = "parsec-service" -version = "0.8.0" +version = "0.8.1" authors = ["Parsec Project Contributors"] description = "A language-agnostic API to secure services in a platform-agnostic way" license = "Apache-2.0" @@ -29,7 +29,7 @@ cryptoki = { version = "0.2.0", optional = true, features = ["psa-crypto-conversions"] } picky-asn1-der = { version = "<=0.2.4", optional = true } picky-asn1 = { version = ">=0.3.1, <=0.3.1", optional = true } -tss-esapi = { version = "6.1.0", optional = true } +tss-esapi = { version = "7.0.0-alpha.1", optional = true } bincode = "1.3.1" structopt = "0.3.21" derivative = "2.2.0" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parsec-0.8.0/ci.sh new/parsec-0.8.1/ci.sh --- old/parsec-0.8.0/ci.sh 2021-08-05 18:38:38.000000000 +0200 +++ new/parsec-0.8.1/ci.sh 2021-09-17 12:40:41.000000000 +0200 @@ -366,4 +366,27 @@ echo "Execute stress tests" RUST_BACKTRACE=1 cargo test $TEST_FEATURES --manifest-path ./e2e_tests/Cargo.toml stress_test fi + + # For the TPM provider we check that keys can still be used after a TPM Reset + if [ "$PROVIDER_NAME" = "tpm" ]; then + # We first create the keys + RUST_BACKTRACE=1 cargo test $TEST_FEATURES --manifest-path ./e2e_tests/Cargo.toml before_tpm_reset + stop_service + + # In order to reset the TPM, we need to restart the TPM server and send a Startup(CLEAR) + pkill tpm_server + sleep 1 + + tpm_server & + TPM_SRV_PID=$! + sleep 5 + + tpm2_startup -c -T mssim + + # We then spin up the service again and check that the keys can still be used + RUST_LOG=error RUST_BACKTRACE=1 cargo run --release $FEATURES -- --config $CONFIG_PATH & + wait_for_service + + RUST_BACKTRACE=1 cargo test $TEST_FEATURES --manifest-path ./e2e_tests/Cargo.toml after_tpm_reset + fi fi diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parsec-0.8.0/e2e_tests/tests/per_provider/mod.rs new/parsec-0.8.1/e2e_tests/tests/per_provider/mod.rs --- old/parsec-0.8.0/e2e_tests/tests/per_provider/mod.rs 2021-08-05 18:38:38.000000000 +0200 +++ new/parsec-0.8.1/e2e_tests/tests/per_provider/mod.rs 2021-09-17 12:40:41.000000000 +0200 @@ -3,3 +3,5 @@ mod key_mappings; mod normal_tests; mod stress_test; +#[cfg(feature = "tpm-provider")] +mod tpm_reset; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parsec-0.8.0/e2e_tests/tests/per_provider/normal_tests/asym_sign_verify.rs new/parsec-0.8.1/e2e_tests/tests/per_provider/normal_tests/asym_sign_verify.rs --- old/parsec-0.8.0/e2e_tests/tests/per_provider/normal_tests/asym_sign_verify.rs 2021-08-05 18:38:38.000000000 +0200 +++ new/parsec-0.8.1/e2e_tests/tests/per_provider/normal_tests/asym_sign_verify.rs 2021-09-17 12:40:41.000000000 +0200 @@ -90,7 +90,7 @@ #[test] fn only_verify_from_internet() -> Result<()> { let mut client = TestClient::new(); - let key_name = String::from("only_verify"); + let key_name = String::from("only_verify_from_internet"); if !client.is_operation_supported(Opcode::PsaImportKey) { return Ok(()); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parsec-0.8.0/e2e_tests/tests/per_provider/normal_tests/import_key.rs new/parsec-0.8.1/e2e_tests/tests/per_provider/normal_tests/import_key.rs --- old/parsec-0.8.0/e2e_tests/tests/per_provider/normal_tests/import_key.rs 2021-08-05 18:38:38.000000000 +0200 +++ new/parsec-0.8.1/e2e_tests/tests/per_provider/normal_tests/import_key.rs 2021-09-17 12:40:41.000000000 +0200 @@ -365,43 +365,43 @@ Ok(()) } -#[cfg(feature = "tpm-provider")] -#[test] -fn import_key_pair() { - let mut client = TestClient::new(); - let key_name = String::from("failed_imported_key_should_be_removed"); +// #[cfg(feature = "tpm-provider")] +// #[test] +// fn import_key_pair() { +// let mut client = TestClient::new(); +// let key_name = String::from("failed_imported_key_should_be_removed"); - client - .import_key( - key_name, - Attributes { - lifetime: Lifetime::Persistent, - key_type: Type::RsaKeyPair, - bits: 1024, - policy: Policy { - usage_flags: UsageFlags { - export: false, - copy: false, - cache: false, - encrypt: false, - decrypt: false, - sign_message: true, - sign_hash: true, - verify_message: true, - verify_hash: true, - derive: false, - }, - permitted_algorithms: Algorithm::AsymmetricSignature( - AsymmetricSignature::RsaPkcs1v15Sign { - hash_alg: Hash::Sha256.into(), - }, - ), - }, - }, - KEY_PAIR_DATA.to_vec(), - ) - .unwrap(); -} +// client +// .import_key( +// key_name, +// Attributes { +// lifetime: Lifetime::Persistent, +// key_type: Type::RsaKeyPair, +// bits: 1024, +// policy: Policy { +// usage_flags: UsageFlags { +// export: false, +// copy: false, +// cache: false, +// encrypt: false, +// decrypt: false, +// sign_message: true, +// sign_hash: true, +// verify_message: true, +// verify_hash: true, +// derive: false, +// }, +// permitted_algorithms: Algorithm::AsymmetricSignature( +// AsymmetricSignature::RsaPkcs1v15Sign { +// hash_alg: Hash::Sha256.into(), +// }, +// ), +// }, +// }, +// KEY_PAIR_DATA.to_vec(), +// ) +// .unwrap(); +// } #[cfg(any(feature = "mbed-crypto-provider", feature = "cryptoauthlib-provider"))] #[test] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parsec-0.8.0/e2e_tests/tests/per_provider/normal_tests/key_attributes.rs new/parsec-0.8.1/e2e_tests/tests/per_provider/normal_tests/key_attributes.rs --- old/parsec-0.8.0/e2e_tests/tests/per_provider/normal_tests/key_attributes.rs 2021-08-05 18:38:38.000000000 +0200 +++ new/parsec-0.8.1/e2e_tests/tests/per_provider/normal_tests/key_attributes.rs 2021-09-17 12:40:41.000000000 +0200 @@ -160,9 +160,10 @@ } let key_type = Type::RsaKeyPair; // Do not permit RSA PKCS 1v15 signing algorithm with SHA-256. + #[allow(deprecated)] let permitted_algorithm = Algorithm::AsymmetricSignature(AsymmetricSignature::RsaPkcs1v15Sign { - hash_alg: Hash::Sha512.into(), + hash_alg: Hash::Sha1.into(), }); let key_attributes = Attributes { lifetime: Lifetime::Persistent, @@ -210,7 +211,7 @@ let key_type = Type::RsaKeyPair; let permitted_algorithm = Algorithm::AsymmetricSignature(AsymmetricSignature::RsaPkcs1v15Sign { - hash_alg: Hash::Sha512.into(), + hash_alg: Hash::Sha256.into(), }); let key_attributes = Attributes { lifetime: Lifetime::Persistent, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parsec-0.8.0/e2e_tests/tests/per_provider/tpm_reset.rs new/parsec-0.8.1/e2e_tests/tests/per_provider/tpm_reset.rs --- old/parsec-0.8.0/e2e_tests/tests/per_provider/tpm_reset.rs 1970-01-01 01:00:00.000000000 +0100 +++ new/parsec-0.8.1/e2e_tests/tests/per_provider/tpm_reset.rs 2021-09-17 12:40:41.000000000 +0200 @@ -0,0 +1,43 @@ +// Copyright 2021 Contributors to the Parsec project. +// SPDX-License-Identifier: Apache-2.0 + +// These tests track a potential regression where the TPM provider +// was unable to handle stored keys after a TPM reset. +// +// `before_tpm_reset` creates keys that should be usable post-TPM-reset, +// in `after_tpm_reset`. +// +// See: https://github.com/parallaxsecond/parsec/issues/504 +use e2e_tests::TestClient; + +const RSA_KEY_NAME: &str = "tpm-reset-rsa"; +const ECC_KEY_NAME: &str = "tpm-reset-ecc"; + +#[test] +fn before_tpm_reset() { + let mut client = TestClient::new(); + client.do_not_destroy_keys(); + + let rsa_key_name = String::from(RSA_KEY_NAME); + let ecc_key_name = String::from(ECC_KEY_NAME); + + client.generate_rsa_sign_key(rsa_key_name.clone()).unwrap(); + client + .generate_ecc_key_pair_secpr1_ecdsa_sha256(ecc_key_name.clone()) + .unwrap(); +} + +#[test] +fn after_tpm_reset() { + let mut client = TestClient::new(); + + let rsa_key_name = String::from(RSA_KEY_NAME); + let ecc_key_name = String::from(ECC_KEY_NAME); + + let _ = client + .sign_with_rsa_sha256(rsa_key_name, vec![0xff; 32]) + .unwrap(); + let _ = client + .sign_with_ecdsa_sha256(ecc_key_name, vec![0xff; 32]) + .unwrap(); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parsec-0.8.0/src/key_info_managers/mod.rs new/parsec-0.8.1/src/key_info_managers/mod.rs --- old/parsec-0.8.0/src/key_info_managers/mod.rs 2021-08-05 18:38:38.000000000 +0200 +++ new/parsec-0.8.1/src/key_info_managers/mod.rs 2021-09-17 12:40:41.000000000 +0200 @@ -261,6 +261,39 @@ } } + /// Replace the key info saved for a given triple + /// + /// # Errors + /// + /// If the key triple doesn't exist in the KIM, PsaErrorDoesNotExist is returned. For + /// any other error occurring in the KIM, KeyInfoManagerError is returned. + pub fn replace_key_info<T: Serialize>( + &self, + key_triple: KeyTriple, + key_id: &T, + attributes: Attributes, + ) -> parsec_interface::requests::Result<()> { + let mut key_info_manager_impl = self + .key_info_manager_impl + .write() + .expect("Key Info Manager lock poisoned"); + let key_info = KeyInfo { + id: bincode::serialize(key_id)?, + attributes, + }; + + match key_info_manager_impl.insert(key_triple.clone(), key_info) { + Ok(None) => { + let _ = key_info_manager_impl + .remove(&key_triple) + .map_err(to_response_status)?; + Err(ResponseStatus::PsaErrorDoesNotExist) + } + Ok(Some(_)) => Ok(()), + Err(string) => Err(to_response_status(string)), + } + } + /// Returns a Vec of ApplicationName of clients having keys in the provider. /// /// # Errors diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parsec-0.8.0/src/providers/tpm/asym_encryption.rs new/parsec-0.8.1/src/providers/tpm/asym_encryption.rs --- old/parsec-0.8.0/src/providers/tpm/asym_encryption.rs 2021-08-05 18:38:38.000000000 +0200 +++ new/parsec-0.8.1/src/providers/tpm/asym_encryption.rs 2021-09-17 12:40:41.000000000 +0200 @@ -1,9 +1,6 @@ // Copyright 2020 Contributors to the Parsec project. // SPDX-License-Identifier: Apache-2.0 -use super::{ - utils::{self, PasswordContext}, - Provider, -}; +use super::{utils, Provider}; use crate::authenticators::ApplicationName; use crate::key_info_managers::KeyTriple; use parsec_interface::operations::{psa_asymmetric_decrypt, psa_asymmetric_encrypt}; @@ -19,21 +16,22 @@ ) -> Result<psa_asymmetric_encrypt::Result> { let key_triple = KeyTriple::new(app_name, ProviderId::Tpm, op.key_name.clone()); + let password_context = self.get_key_ctx(&key_triple)?; + let key_attributes = self.key_info_store.get_key_attributes(&key_triple)?; + let mut esapi_context = self .esapi_context .lock() .expect("ESAPI Context lock poisoned"); - let password_context: PasswordContext = self.key_info_store.get_key_id(&key_triple)?; - let key_attributes = self.key_info_store.get_key_attributes(&key_triple)?; - op.validate(key_attributes)?; match esapi_context.rsa_encrypt( - password_context.context, + password_context.key_material().clone(), + utils::parsec_to_tpm_params(key_attributes)?, Some( password_context - .auth_value + .auth_value() .try_into() .map_err(utils::to_response_status)?, ), @@ -42,7 +40,6 @@ .clone() .try_into() .map_err(utils::to_response_status)?, - utils::convert_asym_scheme_to_tpm(op.alg.into())?, match op.salt { Some(salt) => Some( salt.deref() @@ -71,21 +68,22 @@ ) -> Result<psa_asymmetric_decrypt::Result> { let key_triple = KeyTriple::new(app_name, ProviderId::Tpm, op.key_name.clone()); + let password_context = self.get_key_ctx(&key_triple)?; + let key_attributes = self.key_info_store.get_key_attributes(&key_triple)?; + let mut esapi_context = self .esapi_context .lock() .expect("ESAPI Context lock poisoned"); - let password_context: PasswordContext = self.key_info_store.get_key_id(&key_triple)?; - let key_attributes = self.key_info_store.get_key_attributes(&key_triple)?; - op.validate(key_attributes)?; match esapi_context.rsa_decrypt( - password_context.context, + password_context.key_material().clone(), + utils::parsec_to_tpm_params(key_attributes)?, Some( password_context - .auth_value + .auth_value() .try_into() .map_err(utils::to_response_status)?, ), @@ -94,7 +92,6 @@ .clone() .try_into() .map_err(utils::to_response_status)?, - utils::convert_asym_scheme_to_tpm(op.alg.into())?, match op.salt { Some(salt) => Some( salt.deref() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parsec-0.8.0/src/providers/tpm/asym_sign.rs new/parsec-0.8.1/src/providers/tpm/asym_sign.rs --- old/parsec-0.8.0/src/providers/tpm/asym_sign.rs 2021-08-05 18:38:38.000000000 +0200 +++ new/parsec-0.8.1/src/providers/tpm/asym_sign.rs 2021-09-17 12:40:41.000000000 +0200 @@ -1,9 +1,6 @@ // Copyright 2020 Contributors to the Parsec project. // SPDX-License-Identifier: Apache-2.0 -use super::{ - utils::{self, PasswordContext}, - Provider, -}; +use super::{utils, Provider}; use crate::authenticators::ApplicationName; use crate::key_info_managers::KeyTriple; use log::error; @@ -21,14 +18,14 @@ ) -> Result<psa_sign_hash::Result> { let key_triple = KeyTriple::new(app_name, ProviderId::Tpm, op.key_name.clone()); + let password_context = self.get_key_ctx(&key_triple)?; + let key_attributes = self.key_info_store.get_key_attributes(&key_triple)?; + let mut esapi_context = self .esapi_context .lock() .expect("ESAPI Context lock poisoned"); - let password_context: PasswordContext = self.key_info_store.get_key_id(&key_triple)?; - let key_attributes = self.key_info_store.get_key_attributes(&key_triple)?; - match op.alg { AsymmetricSignature::RsaPkcs1v15Sign { .. } => (), AsymmetricSignature::Ecdsa { .. } => (), @@ -49,9 +46,10 @@ let signature = esapi_context .sign( - password_context.context, + password_context.key_material().clone(), + utils::parsec_to_tpm_params(key_attributes)?, Some( - Auth::try_from(password_context.auth_value) + Auth::try_from(password_context.auth_value()) .map_err(utils::to_response_status)?, ), Digest::try_from((*op.hash).clone()).map_err(utils::to_response_status)?, @@ -64,7 +62,7 @@ })?; Ok(psa_sign_hash::Result { - signature: utils::signature_data_to_bytes(signature.signature, key_attributes)?.into(), + signature: utils::signature_data_to_bytes(signature, key_attributes)?.into(), }) } @@ -75,14 +73,14 @@ ) -> Result<psa_verify_hash::Result> { let key_triple = KeyTriple::new(app_name, ProviderId::Tpm, op.key_name.clone()); + let password_context = self.get_key_ctx(&key_triple)?; + let key_attributes = self.key_info_store.get_key_attributes(&key_triple)?; + let mut esapi_context = self .esapi_context .lock() .expect("ESAPI Context lock poisoned"); - let password_context: PasswordContext = self.key_info_store.get_key_id(&key_triple)?; - let key_attributes = self.key_info_store.get_key_attributes(&key_triple)?; - match op.alg { AsymmetricSignature::RsaPkcs1v15Sign { .. } => (), AsymmetricSignature::Ecdsa { .. } => (), @@ -105,7 +103,8 @@ let _ = esapi_context .verify_signature( - password_context.context, + password_context.key_material().clone(), + utils::parsec_to_tpm_params(key_attributes)?, Digest::try_from((*op.hash).clone()).map_err(utils::to_response_status)?, signature, ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parsec-0.8.0/src/providers/tpm/key_management.rs new/parsec-0.8.1/src/providers/tpm/key_management.rs --- old/parsec-0.8.0/src/providers/tpm/key_management.rs 2021-08-05 18:38:38.000000000 +0200 +++ new/parsec-0.8.1/src/providers/tpm/key_management.rs 2021-09-17 12:40:41.000000000 +0200 @@ -1,8 +1,10 @@ // Copyright 2020 Contributors to the Parsec project. // SPDX-License-Identifier: Apache-2.0 use super::utils; +use super::utils::validate_public_key; +#[allow(deprecated)] +use super::utils::LegacyPasswordContext; use super::utils::PasswordContext; -use super::utils::{validate_private_key, validate_public_key, PUBLIC_EXPONENT}; use super::Provider; use crate::authenticators::ApplicationName; use crate::key_info_managers::KeyTriple; @@ -14,12 +16,60 @@ }; use parsec_interface::requests::{ProviderId, ResponseStatus, Result}; use parsec_interface::secrecy::ExposeSecret; -use picky_asn1_x509::{RSAPrivateKey, RSAPublicKey}; -use tss_esapi::abstraction::transient::RsaExponent; +use picky_asn1_x509::RSAPublicKey; +use std::convert::TryInto; const AUTH_VAL_LEN: usize = 32; impl Provider { + #[allow(deprecated)] + pub(super) fn get_key_ctx(&self, key_triple: &KeyTriple) -> Result<PasswordContext> { + // Try to deserialize into the new format + self.key_info_store + .get_key_id::<PasswordContext>(key_triple) + .or_else(|e| { + // If it failed, check if it was a deserialization error + if let ResponseStatus::InvalidEncoding = e { + // Try to deserialize into legacy format + let legacy_ctx = self + .key_info_store + .get_key_id::<LegacyPasswordContext>(key_triple)?; + + // Try to migrate the key context to the new format + let mut esapi_context = self + .esapi_context + .lock() + .expect("ESAPI Context lock poisoned"); + let password_ctx = PasswordContext::new( + esapi_context + .migrate_key_from_ctx( + legacy_ctx.context, + Some( + legacy_ctx + .auth_value + .clone() + .try_into() + .map_err(utils::to_response_status)?, + ), + ) + .map_err(utils::to_response_status)?, + legacy_ctx.auth_value, + ); + + // Grab key attributes and replace legacy entry with new one + let attributes = self.key_info_store.get_key_attributes(key_triple)?; + let _ = self.key_info_store.replace_key_info( + key_triple.clone(), + &password_ctx, + attributes, + )?; + Ok(password_ctx) + } else { + Err(e) + } + }) + } + pub(super) fn psa_generate_key_internal( &self, app_name: ApplicationName, @@ -41,7 +91,7 @@ .lock() .expect("ESAPI Context lock poisoned"); - let (key_context, auth_value) = esapi_context + let (key_material, auth_value) = esapi_context .create_key(utils::parsec_to_tpm_params(attributes)?, AUTH_VAL_LEN) .map_err(|e| { format_error!("Error creating a RSA signing key", e); @@ -52,10 +102,7 @@ self.key_info_store.insert_key_info( key_triple, - &PasswordContext { - context: key_context, - auth_value: auth_value.value().to_vec(), - }, + &PasswordContext::new(key_material, auth_value.value().to_vec()), attributes, )?; @@ -69,7 +116,6 @@ ) -> Result<psa_import_key::Result> { match op.attributes.key_type { Type::RsaPublicKey => self.psa_import_key_internal_rsa_public(app_name, op), - Type::RsaKeyPair => self.psa_import_key_internal_rsa_keypair(app_name, op), _ => { error!( "The TPM provider does not support importing for the {:?} key type.", @@ -114,7 +160,7 @@ validate_public_key(&public_key, &attributes)?; let key_data = public_key.modulus.as_unsigned_bytes_be(); - let pub_key_context = esapi_context + let key_material = esapi_context .load_external_rsa_public_key(key_data) .map_err(|e| { format_error!("Error creating a RSA signing key", e); @@ -123,73 +169,7 @@ self.key_info_store.insert_key_info( key_triple, - &PasswordContext { - context: pub_key_context, - auth_value: Vec::new(), - }, - attributes, - )?; - - Ok(psa_import_key::Result {}) - } - - pub(super) fn psa_import_key_internal_rsa_keypair( - &self, - app_name: ApplicationName, - op: psa_import_key::Operation, - ) -> Result<psa_import_key::Result> { - // Currently only the RSA PKCS1 v1.5 signature scheme is supported - // by the tss-esapi crate. - if op.attributes.policy.permitted_algorithms - != Algorithm::AsymmetricSignature(AsymmetricSignature::RsaPkcs1v15Sign { - hash_alg: SignHash::Specific(Hash::Sha256), - }) - { - return Err(ResponseStatus::PsaErrorNotSupported); - } - let key_name = op.key_name; - let attributes = op.attributes; - let key_triple = KeyTriple::new(app_name, ProviderId::Tpm, key_name); - let key_data = op.data; - - self.key_info_store.does_not_exist(&key_triple)?; - let mut esapi_context = self - .esapi_context - .lock() - .expect("ESAPI Context lock poisoned"); - - let private_key: RSAPrivateKey = picky_asn1_der::from_bytes(key_data.expose_secret()) - .map_err(|err| { - format_error!("Could not deserialise key elements", err); - ResponseStatus::PsaErrorInvalidArgument - })?; - - // Derive the public key from the keypair. - let public_key = RSAPublicKey { - modulus: private_key.modulus.clone(), - public_exponent: private_key.public_exponent.clone(), - }; - - // Validate the public and the private key. - validate_public_key(&public_key, &attributes)?; - validate_private_key(&private_key, &attributes)?; - - let key_prime = private_key.prime_1.as_unsigned_bytes_be(); - let public_modulus = private_key.modulus.as_unsigned_bytes_be(); - - let keypair_context = esapi_context - .load_external_rsa(key_prime, public_modulus, RsaExponent::new(PUBLIC_EXPONENT)) - .map_err(|e| { - format_error!("Error creating a RSA signing key", e); - utils::to_response_status(e) - })?; - - self.key_info_store.insert_key_info( - key_triple, - &PasswordContext { - context: keypair_context, - auth_value: Vec::new(), - }, + &PasswordContext::new(key_material, Vec::new()), attributes, )?; @@ -204,23 +184,15 @@ let key_name = op.key_name; let key_triple = KeyTriple::new(app_name, ProviderId::Tpm, key_name); - let mut esapi_context = self - .esapi_context - .lock() - .expect("ESAPI Context lock poisoned"); - - let password_context: PasswordContext = self.key_info_store.get_key_id(&key_triple)?; + let password_context = self.get_key_ctx(&key_triple)?; let key_attributes = self.key_info_store.get_key_attributes(&key_triple)?; - let pub_key_data = esapi_context - .read_public_key(password_context.context) - .map_err(|e| { - format_error!("Error reading a public key", e); - utils::to_response_status(e) - })?; - Ok(psa_export_public_key::Result { - data: utils::pub_key_to_bytes(pub_key_data, key_attributes)?.into(), + data: utils::pub_key_to_bytes( + password_context.key_material().public().clone(), + key_attributes, + )? + .into(), }) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parsec-0.8.0/src/providers/tpm/mod.rs new/parsec-0.8.1/src/providers/tpm/mod.rs --- old/parsec-0.8.0/src/providers/tpm/mod.rs 2021-08-05 18:38:38.000000000 +0200 +++ new/parsec-0.8.1/src/providers/tpm/mod.rs 2021-09-17 12:40:41.000000000 +0200 @@ -19,9 +19,9 @@ use std::io::ErrorKind; use std::str::FromStr; use std::sync::Mutex; -use tss_esapi::abstraction::cipher::Cipher; use tss_esapi::interface_types::algorithm::HashingAlgorithm; use tss_esapi::interface_types::resource_handles::Hierarchy; +use tss_esapi::structures::{SymmetricCipherParameters, SymmetricDefinitionObject}; use tss_esapi::Tcti; use uuid::Uuid; use zeroize::Zeroize; @@ -268,9 +268,12 @@ /// /// The method is unsafe because it relies on creating a TSS Context which could cause /// undefined behaviour if multiple such contexts are opened concurrently. - unsafe fn find_default_context_cipher(&self) -> std::io::Result<Cipher> { + unsafe fn find_default_context_cipher(&self) -> std::io::Result<SymmetricDefinitionObject> { info!("Checking for ciphers supported by the TPM."); - let ciphers = [Cipher::aes_256_cfb(), Cipher::aes_128_cfb()]; + let ciphers = [ + SymmetricDefinitionObject::AES_256_CFB, + SymmetricDefinitionObject::AES_128_CFB, + ]; let mut ctx = tss_esapi::Context::new( Tcti::from_str(self.tcti.as_ref().ok_or_else(|| { std::io::Error::new(ErrorKind::InvalidData, "TCTI configuration missing") @@ -285,7 +288,9 @@ })?; for cipher in ciphers.iter() { if ctx - .test_parms(tss_esapi::utils::PublicParmsUnion::SymDetail(*cipher)) + .test_parms(tss_esapi::structures::PublicParameters::SymCipher( + SymmetricCipherParameters::new(*cipher), + )) .is_ok() { return Ok(*cipher); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parsec-0.8.0/src/providers/tpm/utils.rs new/parsec-0.8.1/src/providers/tpm/utils.rs --- old/parsec-0.8.0/src/providers/tpm/utils.rs 2021-08-05 18:38:38.000000000 +0200 +++ new/parsec-0.8.1/src/providers/tpm/utils.rs 2021-09-17 12:40:41.000000000 +0200 @@ -1,24 +1,28 @@ // Copyright 2020 Contributors to the Parsec project. // SPDX-License-Identifier: Apache-2.0 +#![allow(deprecated)] + use log::error; use parsec_interface::operations::psa_algorithm::*; use parsec_interface::operations::psa_key_attributes::*; use parsec_interface::requests::{ResponseStatus, Result}; use picky_asn1::wrapper::IntegerAsn1; -use picky_asn1_x509::{RSAPrivateKey, RSAPublicKey}; +use picky_asn1_x509::RSAPublicKey; use serde::{Deserialize, Serialize}; -use std::convert::TryInto; -use tss_esapi::abstraction::transient::KeyParams; +use std::convert::{TryFrom, TryInto}; +use tss_esapi::abstraction::transient::{KeyMaterial, KeyParams}; use tss_esapi::constants::response_code::Tss2ResponseCodeKind; -use tss_esapi::interface_types::algorithm::HashingAlgorithm; -use tss_esapi::interface_types::ecc::EccCurve; -use tss_esapi::utils::{ - AsymSchemeUnion, PublicKey, Signature, SignatureData, TpmsContext, RSA_KEY_SIZES, +use tss_esapi::interface_types::{ + algorithm::HashingAlgorithm, ecc::EccCurve, key_bits::RsaKeyBits, +}; +use tss_esapi::structures::{ + EccScheme, EccSignature, HashScheme, RsaExponent, RsaScheme, RsaSignature, Signature, }; +use tss_esapi::tss2_esys::TPMS_CONTEXT; +use tss_esapi::utils::{PublicKey, TpmsContext}; use tss_esapi::Error; use zeroize::{Zeroize, Zeroizing}; -pub const PUBLIC_EXPONENT: u32 = 0x10001; const PUBLIC_EXPONENT_BYTES: [u8; 3] = [0x01, 0x00, 0x01]; /// Convert the TSS library specific error values to ResponseStatus values that are returned on @@ -93,6 +97,39 @@ // The PasswordContext is what is stored by the Key Info Manager. #[derive(Serialize, Deserialize, Zeroize)] pub struct PasswordContext { + /// This value is kept for legacy purposes, to aid in the migration process + context: TpmsContext, + /// This value is confidential and needs to be zeroized by its new owner. + auth_value: Vec<u8>, + /// Public and private parts of the key + key_material: KeyMaterial, +} + +impl PasswordContext { + /// Create a new [PasswordContext] + pub fn new(key_material: KeyMaterial, auth_value: Vec<u8>) -> Self { + PasswordContext { + context: TPMS_CONTEXT::default().try_into().unwrap(), // the default value is guaranteed to work + auth_value, + key_material, + } + } + + /// Get a slice of bytes representing the authentication value of the key + pub fn auth_value(&self) -> &[u8] { + &self.auth_value + } + + /// Get reference to the [KeyMaterial] of the key + pub fn key_material(&self) -> &KeyMaterial { + &self.key_material + } +} + +// LegacyPasswordContext that stored key contexts only. +#[deprecated] +#[derive(Serialize, Deserialize, Zeroize)] +pub struct LegacyPasswordContext { pub context: TpmsContext, /// This value is confidential and needs to be zeroized by its new owner. pub auth_value: Vec<u8>, @@ -100,20 +137,41 @@ pub fn parsec_to_tpm_params(attributes: Attributes) -> Result<KeyParams> { match attributes.key_type { - Type::RsaKeyPair => { - let size = match attributes.bits { - x @ 1024 | x @ 2048 | x @ 3072 | x @ 4096 => x.try_into().unwrap(), // will not fail on the matched values - _ => return Err(ResponseStatus::PsaErrorInvalidArgument), - }; + Type::RsaKeyPair | Type::RsaPublicKey => { + let size_u16 = u16::try_from(attributes.bits).map_err(|_| { + error!( + "Requested RSA key size is not supported ({})", + attributes.bits + ); + ResponseStatus::PsaErrorInvalidArgument + })?; + let size = RsaKeyBits::try_from(size_u16).map_err(|_| { + error!("Requested RSA key size is not supported ({})", size_u16); + ResponseStatus::PsaErrorInvalidArgument + })?; match attributes.policy.permitted_algorithms { - Algorithm::AsymmetricSignature(alg) if alg.is_rsa_alg() => Ok(KeyParams::RsaSign { + Algorithm::AsymmetricSignature(alg) if alg.is_rsa_alg() => Ok(KeyParams::Rsa { size, - scheme: convert_asym_scheme_to_tpm(attributes.policy.permitted_algorithms)?, - pub_exponent: 0, + scheme: match alg { + AsymmetricSignature::RsaPkcs1v15Sign { + hash_alg: SignHash::Specific(hash), + } => RsaScheme::RsaSsa(HashScheme::new(convert_hash_to_tpm(hash)?)), + AsymmetricSignature::RsaPss { + hash_alg: SignHash::Specific(hash), + } => RsaScheme::RsaPss(HashScheme::new(convert_hash_to_tpm(hash)?)), + _ => return Err(ResponseStatus::PsaErrorNotSupported), + }, + pub_exponent: RsaExponent::create(0).unwrap(), }), - Algorithm::AsymmetricEncryption(_) => Ok(KeyParams::RsaEncrypt { + Algorithm::AsymmetricEncryption(alg) => Ok(KeyParams::Rsa { size, - pub_exponent: 0, + scheme: match alg { + AsymmetricEncryption::RsaPkcs1v15Crypt => RsaScheme::RsaEs, + AsymmetricEncryption::RsaOaep { hash_alg } => { + RsaScheme::Oaep(HashScheme::new(convert_hash_to_tpm(hash_alg)?)) + } + }, + pub_exponent: RsaExponent::create(0).unwrap(), }), alg => { error!( @@ -124,32 +182,29 @@ } } } - Type::EccKeyPair { .. } => Ok(KeyParams::Ecc { - scheme: convert_asym_scheme_to_tpm(attributes.policy.permitted_algorithms)?, + Type::EccKeyPair { .. } | Type::EccPublicKey { .. } => Ok(KeyParams::Ecc { + scheme: match attributes.policy.permitted_algorithms { + Algorithm::AsymmetricSignature(AsymmetricSignature::Ecdsa { + hash_alg: SignHash::Specific(hash), + }) => EccScheme::EcDsa(HashScheme::new(convert_hash_to_tpm(hash)?)), + Algorithm::AsymmetricSignature(AsymmetricSignature::EcdsaAny) + | Algorithm::AsymmetricSignature(AsymmetricSignature::DeterministicEcdsa { + .. + }) => return Err(ResponseStatus::PsaErrorNotSupported), + _ => { + error!( + "Wrong algorithm provided for ECC key: {:?}", + attributes.policy.permitted_algorithms + ); + return Err(ResponseStatus::PsaErrorInvalidArgument); + } + }, curve: convert_curve_to_tpm(attributes)?, }), _ => Err(ResponseStatus::PsaErrorNotSupported), } } -pub fn convert_asym_scheme_to_tpm(algorithm: Algorithm) -> Result<AsymSchemeUnion> { - match algorithm { - Algorithm::AsymmetricSignature(AsymmetricSignature::RsaPkcs1v15Sign { - hash_alg: SignHash::Specific(hash_alg), - }) => Ok(AsymSchemeUnion::RSASSA(convert_hash_to_tpm(hash_alg)?)), - Algorithm::AsymmetricSignature(AsymmetricSignature::Ecdsa { - hash_alg: SignHash::Specific(hash_alg), - }) => Ok(AsymSchemeUnion::ECDSA(convert_hash_to_tpm(hash_alg)?)), - Algorithm::AsymmetricEncryption(AsymmetricEncryption::RsaPkcs1v15Crypt) => { - Ok(AsymSchemeUnion::RSAES) - } - Algorithm::AsymmetricEncryption(AsymmetricEncryption::RsaOaep { hash_alg }) => { - Ok(AsymSchemeUnion::RSAOAEP(convert_hash_to_tpm(hash_alg)?)) - } - _ => Err(ResponseStatus::PsaErrorNotSupported), - } -} - #[allow(deprecated)] fn convert_hash_to_tpm(hash: Hash) -> Result<HashingAlgorithm> { match hash { @@ -218,20 +273,24 @@ octet_string } -pub fn signature_data_to_bytes(data: SignatureData, key_attributes: Attributes) -> Result<Vec<u8>> { +pub fn signature_data_to_bytes(data: Signature, key_attributes: Attributes) -> Result<Vec<u8>> { match data { - SignatureData::RsaSignature(signature) => Ok(signature), - SignatureData::EcdsaSignature { mut r, mut s } => { + Signature::RsaSsa(rsa_signature) | Signature::RsaPss(rsa_signature) => { + Ok(rsa_signature.signature().value().to_vec()) + } + Signature::EcDsa(ecc_signature) => { // ECDSA signature data is represented the concatenation of the two result values, r and s, // in big endian format, as described here: // https://parallaxsecond.github.io/parsec-book/parsec_client/operations/psa_algorithm.html#asymmetricsignature-algorithm let p_byte_size = key_attributes.bits / 8; // should not fail for valid keys - if r.len() != p_byte_size || s.len() != p_byte_size { + if ecc_signature.signature_r().value().len() != p_byte_size + || ecc_signature.signature_s().value().len() != p_byte_size + { if crate::utils::GlobalConfig::log_error_details() { error!( "Received ECC signature with invalid size: r - {} bytes; s - {} bytes", - r.len(), - s.len() + ecc_signature.signature_r().value().len(), + ecc_signature.signature_s().value().len() ); } else { error!("Received ECC signature with invalid size."); @@ -240,10 +299,14 @@ } let mut signature = vec![]; - signature.append(&mut r); - signature.append(&mut s); + signature.append(&mut ecc_signature.signature_r().value().to_vec()); + signature.append(&mut ecc_signature.signature_s().value().to_vec()); Ok(signature) } + _ => { + error!("Unsupported signature type received from TPM"); + Err(ResponseStatus::PsaErrorGenericError) + } } } @@ -252,9 +315,55 @@ key_attributes: Attributes, signature_alg: AsymmetricSignature, ) -> Result<Signature> { - Ok(Signature { - scheme: convert_asym_scheme_to_tpm(Algorithm::AsymmetricSignature(signature_alg))?, - signature: bytes_to_signature_data(data, key_attributes)?, + // Ok(Signature { + // scheme: convert_asym_scheme_to_tpm(Algorithm::AsymmetricSignature(signature_alg))?, + // signature: bytes_to_signature_data(data, key_attributes)?, + // }) + Ok(match signature_alg { + AsymmetricSignature::RsaPkcs1v15Sign { + hash_alg: SignHash::Specific(hash), + } => Signature::RsaSsa( + RsaSignature::create( + convert_hash_to_tpm(hash)?, + data.to_vec().try_into().map_err(to_response_status)?, + ) + .map_err(to_response_status)?, + ), + AsymmetricSignature::RsaPss { + hash_alg: SignHash::Specific(hash), + } => Signature::RsaPss( + RsaSignature::create( + convert_hash_to_tpm(hash)?, + data.to_vec().try_into().map_err(to_response_status)?, + ) + .map_err(to_response_status)?, + ), + AsymmetricSignature::Ecdsa { + hash_alg: SignHash::Specific(hash), + } => { + // ECDSA signature data is represented the concatenation of the two result values, r and s, + // in big endian format, as described here: + // https://parallaxsecond.github.io/parsec-book/parsec_client/operations/psa_algorithm.html#asymmetricsignature-algorithm + let p_size = key_attributes.bits / 8; + if data.len() != p_size * 2 { + return Err(ResponseStatus::PsaErrorInvalidArgument); + } + + let mut r = data.to_vec(); + let s = r.split_off(p_size); + Signature::EcDsa( + EccSignature::create( + convert_hash_to_tpm(hash)?, + r.try_into().map_err(to_response_status)?, + s.try_into().map_err(to_response_status)?, + ) + .map_err(to_response_status)?, + ) + } + _ => { + error!("Signature type not supported: {:?}", signature_alg); + return Err(ResponseStatus::PsaErrorNotSupported); + } }) } @@ -291,18 +400,15 @@ return Err(ResponseStatus::PsaErrorInvalidArgument); } - let valid_key_sizes_vec = RSA_KEY_SIZES.to_vec(); - if !valid_key_sizes_vec.contains(&((len * 8) as u16)) { + if RsaKeyBits::try_from((len * 8) as u16).is_err() { if crate::utils::GlobalConfig::log_error_details() { error!( - "The TPM provider only supports RSA public keys of size {:?} bits ({} bits given).", - valid_key_sizes_vec, + "The TPM provider only supports RSA public keys of size 1024, 2048, 3072 and 4096 bits ({} bits given).", len * 8, ); } else { error!( - "The TPM provider only supports RSA public keys of size {:?} bits", - valid_key_sizes_vec, + "The TPM provider only supports RSA public keys of size 1024, 2048, 3072 and 4096 bits" ); } return Err(ResponseStatus::PsaErrorNotSupported); @@ -310,66 +416,3 @@ Ok(()) } - -/// Validates an RSAPrivateKey against the attributes we expect. Returns ok on success, otherwise -/// returns an error. -pub fn validate_private_key(private_key: &RSAPrivateKey, attributes: &Attributes) -> Result<()> { - // NOTE: potentially incomplete, but any errors that aren't caught here should be caught - // further down the stack (i.e. in the tss crate). - - // The public exponent must be exactly 0x10001 -- that is the only value supported by the TPM - // provider. Reject everything else. - let given_public_exponent = private_key.public_exponent.as_unsigned_bytes_be(); - if given_public_exponent != PUBLIC_EXPONENT_BYTES { - if crate::utils::GlobalConfig::log_error_details() { - error!( - "Unexpected public exponent in private key (expected: {:?}, got: {:?}).", - PUBLIC_EXPONENT_BYTES, given_public_exponent - ); - } else { - error!("Unexpected public exponent in private key."); - } - return Err(ResponseStatus::PsaErrorInvalidArgument); - } - - // The key prime's length in bits should be exactly half of the size of the size of the key's - // public modulus. - let key_prime = private_key.prime_1.as_unsigned_bytes_be(); - let key_prime_len_bits = key_prime.len() * 8; - if key_prime_len_bits != attributes.bits / 2 { - if crate::utils::GlobalConfig::log_error_details() { - error!( - "The key prime is not of the expected size (expected {}, got {}).", - attributes.bits / 2, - key_prime_len_bits, - ); - } else { - error!("The key prime is not of the expected size.",); - } - return Err(ResponseStatus::PsaErrorInvalidArgument); - } - Ok(()) -} - -fn bytes_to_signature_data( - data: Zeroizing<Vec<u8>>, - key_attributes: Attributes, -) -> Result<SignatureData> { - match key_attributes.key_type { - Type::RsaKeyPair | Type::RsaPublicKey => Ok(SignatureData::RsaSignature(data.to_vec())), - Type::EccKeyPair { .. } | Type::EccPublicKey { .. } => { - // ECDSA signature data is represented the concatenation of the two result values, r and s, - // in big endian format, as described here: - // https://parallaxsecond.github.io/parsec-book/parsec_client/operations/psa_algorithm.html#asymmetricsignature-algorithm - let p_size = key_attributes.bits / 8; - if data.len() != p_size * 2 { - return Err(ResponseStatus::PsaErrorInvalidArgument); - } - - let mut r = data.to_vec(); - let s = r.split_off(p_size); - Ok(SignatureData::EcdsaSignature { r, s }) - } - _ => Err(ResponseStatus::PsaErrorNotSupported), - } -} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parsec-0.8.0/src/providers/trusted_service/context/mod.rs new/parsec-0.8.1/src/providers/trusted_service/context/mod.rs --- old/parsec-0.8.0/src/providers/trusted_service/context/mod.rs 2021-08-05 18:38:38.000000000 +0200 +++ new/parsec-0.8.1/src/providers/trusted_service/context/mod.rs 2021-09-17 12:40:41.000000000 +0200 @@ -74,15 +74,10 @@ info!("Obtaining a crypto Trusted Service context."); let mut status = 0; - let service_context = unsafe { - service_locator_query( - CString::new("sn:trustedfirmware.org:crypto:0") - .unwrap() - .into_raw(), - &mut status, - ) - }; + let service_name = CString::new("sn:trustedfirmware.org:crypto:0").unwrap(); + let service_context = unsafe { service_locator_query(service_name.as_ptr(), &mut status) }; if service_context.is_null() { + error!("Locating crypto Trusted Service failed, status: {}", status); return Err(io::Error::new( io::ErrorKind::Other, "Failed to obtain a Trusted Service context", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parsec-0.8.0/src/utils/service_builder.rs new/parsec-0.8.1/src/utils/service_builder.rs --- old/parsec-0.8.0/src/utils/service_builder.rs 2021-08-05 18:38:38.000000000 +0200 +++ new/parsec-0.8.1/src/utils/service_builder.rs 2021-09-17 12:40:41.000000000 +0200 @@ -370,7 +370,7 @@ } #[cfg(feature = "trusted-service-provider")] ProviderConfig::TrustedService { .. } => { - info!("Creating a TPM Provider."); + info!("Creating a Trusted Service Provider."); Ok(Some(Arc::new( TrustedServiceProviderBuilder::new() .with_key_info_store(kim_factory.build_client(ProviderId::TrustedService)) ++++++ vendor.tar.xz ++++++ /work/SRC/openSUSE:Factory/parsec/vendor.tar.xz /work/SRC/openSUSE:Factory/.parsec.new.1892/vendor.tar.xz differ: char 27, line 1
