diff --git a/.github/workflows/pkcs7.yml b/.github/workflows/pkcs7.yml deleted file mode 100644 index f129f2796..000000000 --- a/.github/workflows/pkcs7.yml +++ /dev/null @@ -1,64 +0,0 @@ -name: pkcs7 - -on: - pull_request: - paths: - - ".github/workflows/pkcs7.yml" - - "const-oid/**" - - "der/**" - - "pkcs7/**" - - "x509-cert/**" - - "Cargo.*" - push: - branches: master - -defaults: - run: - working-directory: pkcs7 - -env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" - -jobs: - build: - runs-on: ubuntu-latest - strategy: - matrix: - rust: - - 1.65.0 # MSRV - - stable - target: - - thumbv7em-none-eabi - - wasm32-unknown-unknown - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ matrix.rust }} - targets: ${{ matrix.target }} - - uses: RustCrypto/actions/cargo-hack-install@master - - run: cargo hack build --target ${{ matrix.target }} --feature-powerset - - minimal-versions: - uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master - with: - working-directory: ${{ github.workflow }} - # TODO: re-enable benches build when min version of proc-macro2 - # will be updated to 1.0.60+ - nightly-cmd: - - test: - runs-on: ubuntu-latest - strategy: - matrix: - rust: - - 1.65.0 # MSRV - - stable - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ matrix.rust }} - - uses: RustCrypto/actions/cargo-hack-install@master - - run: cargo hack test --feature-powerset diff --git a/Cargo.lock b/Cargo.lock index 605f60863..83b5cc4f1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -997,16 +997,6 @@ dependencies = [ "spki", ] -[[package]] -name = "pkcs7" -version = "0.4.1" -dependencies = [ - "der", - "hex-literal 0.4.1", - "spki", - "x509-cert", -] - [[package]] name = "pkcs8" version = "0.10.2" diff --git a/Cargo.toml b/Cargo.toml index 3d11fa89d..90bb1f46e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,6 @@ members = [ "pem-rfc7468", "pkcs1", "pkcs5", - "pkcs7", "pkcs8", "pkcs12", "sec1", @@ -48,7 +47,6 @@ der_derive = { path = "./der/derive" } pem-rfc7468 = { path = "./pem-rfc7468" } pkcs1 = { path = "./pkcs1" } pkcs5 = { path = "./pkcs5" } -pkcs7 = { path = "./pkcs7" } pkcs8 = { path = "./pkcs8" } pkcs12 = { path = "./pkcs12" } sec1 = { path = "./sec1" } diff --git a/pkcs7/tests/examples/apple_mdm_signature_der.bin b/cms/tests/examples/apple_mdm_signature_der.bin similarity index 100% rename from pkcs7/tests/examples/apple_mdm_signature_der.bin rename to cms/tests/examples/apple_mdm_signature_der.bin diff --git a/pkcs7/tests/examples/cert.pem b/cms/tests/examples/cert.pem similarity index 100% rename from pkcs7/tests/examples/cert.pem rename to cms/tests/examples/cert.pem diff --git a/pkcs7/tests/examples/certData.bin b/cms/tests/examples/certData.bin similarity index 100% rename from pkcs7/tests/examples/certData.bin rename to cms/tests/examples/certData.bin diff --git a/pkcs7/tests/examples/cms_ber.bin b/cms/tests/examples/cms_ber.bin similarity index 100% rename from pkcs7/tests/examples/cms_ber.bin rename to cms/tests/examples/cms_ber.bin diff --git a/pkcs7/tests/examples/cms_der.bin b/cms/tests/examples/cms_der.bin similarity index 100% rename from pkcs7/tests/examples/cms_der.bin rename to cms/tests/examples/cms_der.bin diff --git a/pkcs7/tests/examples/example.pfx b/cms/tests/examples/example.pfx similarity index 100% rename from pkcs7/tests/examples/example.pfx rename to cms/tests/examples/example.pfx diff --git a/pkcs7/tests/examples/examples_notes.txt b/cms/tests/examples/examples_notes.txt similarity index 100% rename from pkcs7/tests/examples/examples_notes.txt rename to cms/tests/examples/examples_notes.txt diff --git a/pkcs7/tests/examples/keyEncryptedData.bin b/cms/tests/examples/keyEncryptedData.bin similarity index 100% rename from pkcs7/tests/examples/keyEncryptedData.bin rename to cms/tests/examples/keyEncryptedData.bin diff --git a/pkcs7/tests/examples/rsa_sk.pkcs1.pem b/cms/tests/examples/rsa_sk.pkcs1.pem similarity index 100% rename from pkcs7/tests/examples/rsa_sk.pkcs1.pem rename to cms/tests/examples/rsa_sk.pkcs1.pem diff --git a/pkcs7/tests/examples/scep_der.bin b/cms/tests/examples/scep_der.bin similarity index 100% rename from pkcs7/tests/examples/scep_der.bin rename to cms/tests/examples/scep_der.bin diff --git a/cms/tests/tests_from_pkcs7_crate.rs b/cms/tests/tests_from_pkcs7_crate.rs index af5c34dc3..75448e6be 100644 --- a/cms/tests/tests_from_pkcs7_crate.rs +++ b/cms/tests/tests_from_pkcs7_crate.rs @@ -9,7 +9,7 @@ use pkcs5::pbes2::Pbkdf2Params; #[test] fn cms_decode_cert_example() { - let enc_ci = include_bytes!("../../pkcs7/tests/examples/certData.bin"); + let enc_ci = include_bytes!("../tests/examples/certData.bin"); let ci = ContentInfo::from_der(enc_ci).unwrap(); assert_eq!(ci.content_type, const_oid::db::rfc5911::ID_DATA); assert_eq!(ci.content.value().len(), 781); @@ -19,7 +19,7 @@ fn cms_decode_cert_example() { #[test] fn cms_decode_encrypted_key_example() { - let enc_ci = include_bytes!("../../pkcs7/tests/examples/keyEncryptedData.bin"); + let enc_ci = include_bytes!("../tests/examples/keyEncryptedData.bin"); let ci = ContentInfo::from_der(enc_ci).unwrap(); assert_eq!(ci.content_type, const_oid::db::rfc5911::ID_ENCRYPTED_DATA); let data = EncryptedData::from_der(ci.content.to_der().unwrap().as_slice()).unwrap(); @@ -54,8 +54,7 @@ fn cms_decode_encrypted_key_example() { #[test] fn cms_decode_signed_mdm_example() { - let der_signed_data_in_ci = - include_bytes!("../../pkcs7/tests/examples/apple_mdm_signature_der.bin"); + let der_signed_data_in_ci = include_bytes!("../tests/examples/apple_mdm_signature_der.bin"); let ci = ContentInfo::from_der(der_signed_data_in_ci).unwrap(); assert_eq!(ci.content_type, const_oid::db::rfc5911::ID_SIGNED_DATA); @@ -81,7 +80,7 @@ fn cms_decode_signed_mdm_example() { #[test] fn cms_decode_signed_scep_example() { - let der_signed_data_in_ci = include_bytes!("../../pkcs7/tests/examples/scep_der.bin"); + let der_signed_data_in_ci = include_bytes!("../tests/examples/scep_der.bin"); let ci = ContentInfo::from_der(der_signed_data_in_ci).unwrap(); assert_eq!(ci.content_type, const_oid::db::rfc5911::ID_SIGNED_DATA); @@ -108,7 +107,7 @@ fn cms_decode_signed_scep_example() { #[test] fn cms_decode_signed_der() { - let der_signed_data_in_ci = include_bytes!("../../pkcs7/tests/examples/cms_der.bin"); + let der_signed_data_in_ci = include_bytes!("../tests/examples/cms_der.bin"); let ci = ContentInfo::from_der(der_signed_data_in_ci).unwrap(); assert_eq!(ci.content_type, const_oid::db::rfc5911::ID_SIGNED_DATA); diff --git a/pkcs7/CHANGELOG.md b/pkcs7/CHANGELOG.md deleted file mode 100644 index 21ad9d241..000000000 --- a/pkcs7/CHANGELOG.md +++ /dev/null @@ -1,40 +0,0 @@ -# Changelog -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## 0.4.1 (2023-05-13) - -🚨 DEPRECATED! 🚨 - -Use the [`cms` crate](https://github.com/RustCrypto/formats/tree/master/cms) instead ([#1062]) - -[#1062]: https://github.com/RustCrypto/formats/pull/1062 - -## 0.4.0 (2023-03-18) -### Added -- `SignedData` type to ([#813]) -- `ValueOrd` impls ([#825]) - -### Changed -- MSRV 1.65 ([#805]) -- Bump `der` to v0.7 ([#899]) -- Bump `spki` to v0.7 ([#900]) -- Make `ContentInfo`'s `contentType` mandatory ([#924]) -- Bump `x509-cert` to v0.2 ([#934]) - -[#805]: https://github.com/RustCrypto/formats/pull/805 -[#813]: https://github.com/RustCrypto/formats/pull/813 -[#825]: https://github.com/RustCrypto/formats/pull/825 -[#899]: https://github.com/RustCrypto/formats/pull/899 -[#900]: https://github.com/RustCrypto/formats/pull/900 -[#924]: https://github.com/RustCrypto/formats/pull/924 -[#934]: https://github.com/RustCrypto/formats/pull/934 - -## 0.3.0 (2021-11-15) -- Initial release: older versions are a pre-RustCrypto crate. - -## 0.2.0 (2016-08-16) - -## 0.1.0 (2016-08-15) diff --git a/pkcs7/Cargo.toml b/pkcs7/Cargo.toml deleted file mode 100644 index 9e2e974f3..000000000 --- a/pkcs7/Cargo.toml +++ /dev/null @@ -1,26 +0,0 @@ -[package] -name = "pkcs7" -version = "0.4.1" -description = "DEPRECATED: use the `cms` crate instead" -authors = ["RustCrypto Developers"] -license = "Apache-2.0 OR MIT" -repository = "https://github.com/RustCrypto/formats/tree/master/pkcs7" -categories = ["cryptography", "data-structures", "encoding", "no-std", "parser-implementations"] -keywords = ["crypto", "pkcs"] -readme = "README.md" -edition = "2021" -rust-version = "1.65" - -[dependencies] -der = { version = "0.7.6", features = ["oid"] } -spki = { version = "0.7" } -x509-cert = { version = "0.2", default-features = false } - -[dev-dependencies] -der = { version = "0.7", features = ["oid", "pem"] } -hex-literal = "0.4" -x509-cert = { version = "0.2", default-features = false, features = ["pem"] } - -[package.metadata.docs.rs] -all-features = true -rustdoc-args = ["--cfg", "docsrs"] diff --git a/pkcs7/LICENSE-APACHE b/pkcs7/LICENSE-APACHE deleted file mode 100644 index 78173fa2e..000000000 --- a/pkcs7/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/pkcs7/LICENSE-MIT b/pkcs7/LICENSE-MIT deleted file mode 100644 index 3294d7434..000000000 --- a/pkcs7/LICENSE-MIT +++ /dev/null @@ -1,25 +0,0 @@ -Copyright (c) 2021-2023 The RustCrypto Project Developers - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/pkcs7/README.md b/pkcs7/README.md index d8855d1f6..5ca42a3c3 100644 --- a/pkcs7/README.md +++ b/pkcs7/README.md @@ -1,17 +1,3 @@ -# [RustCrypto]: PKCS#7 (Cryptographic Messages) - -[![crate][crate-image]][crate-link] -[![Docs][docs-image]][docs-link] -[![Build Status][build-image]][build-link] -![Apache2/MIT licensed][license-image] -![Rust Version][rustc-image] -[![Project Chat][chat-image]][chat-link] - -Pure Rust implementation of Public-Key Cryptography Standards (PKCS) #7: -Cryptographic Message Syntax v1.5 ([RFC 5652] and [RFC 8933]). - -[Documentation][docs-link] - ## 🚨 DEPRECATED! 🚨 The `pkcs7` crate is deprecated and will not receive further releases. @@ -23,44 +9,4 @@ Please migrate to the following instead: See [#1045] for more information. -## Minimum Supported Rust Version - -This crate requires **Rust 1.65** at a minimum. - -We may change the MSRV in the future, but it will be accompanied by a minor -version bump. - -## License - -Licensed under either of: - - * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) - * [MIT license](http://opensource.org/licenses/MIT) - -at your option. - -### Contribution - -Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in the work by you, as defined in the Apache-2.0 license, shall be -dual licensed as above, without any additional terms or conditions. - -[//]: # (badges) - -[crate-image]: https://buildstats.info/crate/pkcs7 -[crate-link]: https://crates.io/crates/pkcs7 -[docs-image]: https://docs.rs/pkcs7/badge.svg -[docs-link]: https://docs.rs/pkcs7/ -[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg -[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg -[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/300570-formats -[build-image]: https://github.com/RustCrypto/formats/workflows/pkcs7/badge.svg?branch=master&event=push -[build-link]: https://github.com/RustCrypto/formats/actions - -[//]: # (links) - -[RustCrypto]: https://github.com/rustcrypto -[RFC 5652]: https://datatracker.ietf.org/doc/html/rfc5652 -[RFC 8933]: https://datatracker.ietf.org/doc/html/rfc8933 [#1045]: https://github.com/RustCrypto/formats/issues/1045 diff --git a/pkcs7/src/algorithm_identifier_types.rs b/pkcs7/src/algorithm_identifier_types.rs deleted file mode 100644 index 3d1cc7d9a..000000000 --- a/pkcs7/src/algorithm_identifier_types.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! `Algorithm Identifier Types` [RFC 5652 § 10.1](https://datatracker.ietf.org/doc/html/rfc5652#section-10.1) - -use der::asn1::SetOfVec; -use spki::AlgorithmIdentifierRef; - -/// ```text -/// DigestAlgorithmIdentifier ::= AlgorithmIdentifier -/// ``` -/// See [RFC 5652 10.1.1](https://datatracker.ietf.org/doc/html/rfc5652#section-10.1.1). -pub type DigestAlgorithmIdentifier<'a> = AlgorithmIdentifierRef<'a>; - -/// ```text -/// DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier -/// ``` -pub type DigestAlgorithmIdentifiers<'a> = SetOfVec>; - -/// ```text -/// SignatureAlgorithmIdentifier ::= AlgorithmIdentifier -/// ``` -/// See [RFC 5652 10.1.2](https://datatracker.ietf.org/doc/html/rfc5652#section-10.1.2). -pub type SignatureAlgorithmIdentifier<'a> = AlgorithmIdentifierRef<'a>; diff --git a/pkcs7/src/certificate_choices.rs b/pkcs7/src/certificate_choices.rs deleted file mode 100644 index f6c370a8c..000000000 --- a/pkcs7/src/certificate_choices.rs +++ /dev/null @@ -1,58 +0,0 @@ -//! `CertificateChoices` [RFC 5652 10.2.2](https://datatracker.ietf.org/doc/html/rfc5652#section-10.2.2) - -use der::{asn1::BitStringRef, AnyRef, Choice, Sequence, ValueOrd}; -use spki::ObjectIdentifier; -use x509_cert::Certificate; - -// TODO (smndtrl): Should come from x509 - for now I haven't found a test case in real world -type AttributeCertificateV1<'a> = BitStringRef<'a>; -type AttributeCertificateV2<'a> = BitStringRef<'a>; -type ExtendedCertificate<'a> = BitStringRef<'a>; - -/// ```text -/// OtherCertificateFormat ::= SEQUENCE { -/// otherCertFormat OBJECT IDENTIFIER, -/// otherCert ANY DEFINED BY otherCertFormat } -/// ``` -#[derive(Clone, Debug, PartialEq, Eq, Sequence, ValueOrd)] -pub struct OtherCertificateFormat<'a> { - other_cert_format: ObjectIdentifier, - other_cert: AnyRef<'a>, -} - -/// ```text -/// CertificateChoices ::= CHOICE { -/// certificate Certificate, -/// extendedCertificate [0] IMPLICIT ExtendedCertificate, -- Obsolete -/// v1AttrCert [1] IMPLICIT AttributeCertificateV1, -- Obsolete -/// v2AttrCert [2] IMPLICIT AttributeCertificateV2, -/// other [3] IMPLICIT OtherCertificateFormat } -/// -/// OtherCertificateFormat ::= SEQUENCE { -/// otherCertFormat OBJECT IDENTIFIER, -/// otherCert ANY DEFINED BY otherCertFormat } -/// ``` -#[derive(Clone, Debug, PartialEq, Eq, Choice, ValueOrd)] -#[allow(clippy::large_enum_variant)] -pub enum CertificateChoices<'a> { - /// X.509 certificate - Certificate(Certificate), - - /// PKCS #6 extended certificate (obsolete) - #[deprecated] - #[asn1(context_specific = "0", tag_mode = "IMPLICIT")] - ExtendedCertificate(ExtendedCertificate<'a>), - - /// version 1 X.509 attribute certificate (ACv1) X.509-97 (obsolete) - #[deprecated] - #[asn1(context_specific = "1", tag_mode = "IMPLICIT")] - V1AttrCert(AttributeCertificateV1<'a>), - - /// version 2 X.509 attribute certificate (ACv2) X.509-00 - #[asn1(context_specific = "2", tag_mode = "IMPLICIT")] - V2AttrCert(AttributeCertificateV2<'a>), - - /// any other certificate forma - #[asn1(context_specific = "3", tag_mode = "IMPLICIT")] - Other(OtherCertificateFormat<'a>), -} diff --git a/pkcs7/src/cms_version.rs b/pkcs7/src/cms_version.rs deleted file mode 100644 index 9655bd0a9..000000000 --- a/pkcs7/src/cms_version.rs +++ /dev/null @@ -1,43 +0,0 @@ -//! `CMSVersion` [RFC 5652 § 10.2.5](https://datatracker.ietf.org/doc/html/rfc5652#section-10.2.5) - -use core::cmp::Ordering; -use der::{Enumerated, ValueOrd}; - -/// The CMSVersion type gives a syntax version number, for compatibility -/// with future revisions of this specification. -/// ```text -/// CMSVersion ::= INTEGER -/// { v0(0), v1(1), v2(2), v3(3), v4(4), v5(5) } -/// ``` -/// -/// See [RFC 5652 10.2.5](https://datatracker.ietf.org/doc/html/rfc5652#section-10.2.5). -#[derive(Clone, Copy, Debug, Enumerated, Eq, PartialEq, PartialOrd, Ord)] -#[asn1(type = "INTEGER")] -#[repr(u8)] -pub enum CmsVersion { - /// syntax version 0 - V0 = 0, - /// syntax version 1 - V1 = 1, - /// syntax version 2 - V2 = 2, - /// syntax version 3 - V3 = 3, - /// syntax version 4 - V4 = 4, - /// syntax version 5 - V5 = 5, -} - -impl From for u8 { - fn from(version: CmsVersion) -> u8 { - version as u8 - } -} - -// TODO(tarcieri): fix `ValueOrd` derive for this case (`asn1` attribute is clashing) -impl ValueOrd for CmsVersion { - fn value_cmp(&self, other: &Self) -> der::Result { - Ok(self.cmp(other)) - } -} diff --git a/pkcs7/src/content_info.rs b/pkcs7/src/content_info.rs deleted file mode 100644 index a36b08ee7..000000000 --- a/pkcs7/src/content_info.rs +++ /dev/null @@ -1,223 +0,0 @@ -use crate::{ - data_content::DataContent, encrypted_data_content::EncryptedDataContent, - signed_data_content::SignedDataContent, ContentType, -}; - -use der::{ - asn1::{ContextSpecific, OctetStringRef}, - Decode, DecodeValue, Encode, EncodeValue, Header, Length, Reader, Sequence, TagMode, TagNumber, - Writer, -}; - -const CONTENT_TAG: TagNumber = TagNumber::new(0); - -/// Content exchanged between entities [RFC 5652 § 3](https://datatracker.ietf.org/doc/html/rfc5652#section-3) -/// -/// ```text -/// ContentInfo ::= SEQUENCE { -/// contentType ContentType, -/// content -/// [0] EXPLICIT ANY DEFINED BY contentType } -/// ``` -/// -/// Note: `content` field was previously optional in [RFC 2315 § 7](https://datatracker.ietf.org/doc/html/rfc2315#section-7). -#[derive(Clone, Debug)] -pub enum ContentInfo<'a> { - /// Content type `data` - Data(DataContent<'a>), - - /// Content type `encrypted-data` - EncryptedData(EncryptedDataContent<'a>), - - /// Content type `signed-data` - SignedData(SignedDataContent<'a>), - - /// Catch-all case for content types that are not explicitly supported - /// - enveloped-data - /// - signed-and-enveloped-data - /// - digested-data - Other((ContentType, OctetStringRef<'a>)), -} - -impl<'a> ContentInfo<'a> { - /// return content type of content info - pub fn content_type(&self) -> ContentType { - match self { - Self::Data(_) => ContentType::Data, - Self::EncryptedData(_) => ContentType::EncryptedData, - Self::SignedData(_) => ContentType::SignedData, - Self::Other((content_type, _)) => *content_type, - } - } -} - -impl<'a> ContentInfo<'a> { - /// new ContentInfo of `data` content type - pub fn new_data(content: &'a [u8]) -> Self { - ContentInfo::Data(content.into()) - } - - /// new Content info of given content type with given raw content - pub fn new_raw(content_type: ContentType, content: &'a [u8]) -> der::Result { - Ok(ContentInfo::Other(( - content_type, - OctetStringRef::new(content)?, - ))) - } -} - -impl<'a> DecodeValue<'a> for ContentInfo<'a> { - fn decode_value>(reader: &mut R, header: Header) -> der::Result> { - #[inline] - fn decode_context_specific<'a, R: Reader<'a>, T: Decode<'a>>( - reader: &mut R, - ) -> der::Result { - Ok(ContextSpecific::::decode_explicit(reader, CONTENT_TAG)? - .ok_or_else(|| { - der::Tag::ContextSpecific { - number: CONTENT_TAG, - constructed: false, - } - .value_error() - })? - .value) - } - - reader.read_nested(header.length, |reader| { - let content_type = reader.decode()?; - match content_type { - ContentType::Data => Ok(ContentInfo::Data(decode_context_specific(reader)?)), - ContentType::EncryptedData => { - Ok(ContentInfo::EncryptedData(decode_context_specific(reader)?)) - } - ContentType::SignedData => { - Ok(ContentInfo::SignedData(decode_context_specific(reader)?)) - } - - _ => Ok(ContentInfo::Other(( - content_type, - decode_context_specific(reader)?, - ))), - } - }) - } -} - -impl EncodeValue for ContentInfo<'_> { - fn value_len(&self) -> der::Result { - self.content_type().encoded_len()? - + match self { - Self::Data(data) => ContextSpecific { - tag_number: CONTENT_TAG, - tag_mode: TagMode::Explicit, - value: *data, - } - .encoded_len(), - Self::EncryptedData(data) => ContextSpecific { - tag_number: CONTENT_TAG, - tag_mode: TagMode::Explicit, - value: *data, - } - .encoded_len(), - Self::SignedData(data) => ContextSpecific { - tag_number: CONTENT_TAG, - tag_mode: TagMode::Explicit, - value: data.clone(), - } - .encoded_len(), - Self::Other((_, oct_str)) => ContextSpecific { - tag_number: CONTENT_TAG, - tag_mode: TagMode::Explicit, - value: *oct_str, - } - .encoded_len(), - }? - } - - fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> { - self.content_type().encode(writer)?; - - match self { - Self::Data(data) => ContextSpecific { - tag_number: CONTENT_TAG, - tag_mode: TagMode::Explicit, - value: *data, - } - .encode(writer)?, - Self::EncryptedData(data) => ContextSpecific { - tag_number: CONTENT_TAG, - tag_mode: TagMode::Explicit, - value: *data, - } - .encode(writer)?, - Self::SignedData(data) => ContextSpecific { - tag_number: CONTENT_TAG, - tag_mode: TagMode::Explicit, - value: data.clone(), - } - .encode(writer)?, - Self::Other((_, oct_str)) => ContextSpecific { - tag_number: CONTENT_TAG, - tag_mode: TagMode::Explicit, - value: *oct_str, - } - .encode(writer)?, - } - - Ok(()) - } -} - -impl<'a> Sequence<'a> for ContentInfo<'a> {} - -#[cfg(test)] -mod tests { - use super::{ContentInfo, DataContent}; - use core::convert::TryFrom; - use der::{asn1::OctetStringRef, Decode, Encode, Length, SliceWriter, TagMode, TagNumber}; - - #[test] - fn simple_data() -> der::Result<()> { - let mut in_buf = [0u8; 32]; - - let hello = "hello".as_bytes(); - assert_eq!(5, hello.len()); - - let hello_len = Length::try_from(hello.len())?.for_tlv()?; - assert_eq!(Length::new(7), hello_len); - - let tagged_hello_len = hello_len.for_tlv()?; - assert_eq!(Length::new(9), tagged_hello_len); - - let oid_len = crate::PKCS_7_DATA_OID.encoded_len()?; - assert_eq!(Length::new(11), oid_len); - - let inner_len = (oid_len + tagged_hello_len)?; - assert_eq!(Length::new(20), inner_len); - - let mut encoder = SliceWriter::new(&mut in_buf); - encoder.sequence(inner_len, |encoder| { - crate::PKCS_7_DATA_OID.encode(encoder)?; - encoder.context_specific( - TagNumber::new(0), - TagMode::Explicit, - &OctetStringRef::new(hello)?, - ) - })?; - let encoded_der = encoder.finish().expect("encoding success"); - assert_eq!(22, encoded_der.len()); - - let info = ContentInfo::from_der(encoded_der)?; - match info { - ContentInfo::Data(DataContent { content }) => assert_eq!(hello, content), - _ => panic!("unexpected case"), - } - - let mut out_buf = [0u8; 32]; - let encoded_der2 = info.encode_to_slice(&mut out_buf)?; - - assert_eq!(encoded_der, encoded_der2); - - Ok(()) - } -} diff --git a/pkcs7/src/content_type.rs b/pkcs7/src/content_type.rs deleted file mode 100644 index c00364846..000000000 --- a/pkcs7/src/content_type.rs +++ /dev/null @@ -1,73 +0,0 @@ -use der::asn1::ObjectIdentifier; -use der::{DecodeValue, EncodeValue, ErrorKind, FixedTag, Header, Length, Reader, Tag, Writer}; - -/// Indicates the type of content. -#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)] -pub enum ContentType { - /// Plain data content type - Data, - - /// Signed-data content type - SignedData, - - /// Enveloped-data content type - EnvelopedData, - - /// Signed-and-enveloped-data content type - SignedAndEnvelopedData, - - /// Digested-data content type - DigestedData, - - /// Encrypted-data content type - EncryptedData, -} - -impl<'a> DecodeValue<'a> for ContentType { - fn decode_value>(reader: &mut R, header: Header) -> der::Result { - ObjectIdentifier::decode_value(reader, header)?.try_into() - } -} - -impl EncodeValue for ContentType { - fn value_len(&self) -> der::Result { - ObjectIdentifier::from(*self).value_len() - } - - fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> { - ObjectIdentifier::from(*self).encode_value(writer) - } -} - -impl FixedTag for ContentType { - const TAG: Tag = Tag::ObjectIdentifier; -} - -impl From for ObjectIdentifier { - fn from(content_type: ContentType) -> ObjectIdentifier { - match content_type { - ContentType::Data => crate::PKCS_7_DATA_OID, - ContentType::SignedData => crate::PKCS_7_SIGNED_DATA_OID, - ContentType::EnvelopedData => crate::PKCS_7_ENVELOPED_DATA_OID, - ContentType::SignedAndEnvelopedData => crate::PKCS_7_SIGNED_AND_ENVELOPED_DATA_OID, - ContentType::DigestedData => crate::PKCS_7_DIGESTED_DATA_OID, - ContentType::EncryptedData => crate::PKCS_7_ENCRYPTED_DATA_OID, - } - } -} - -impl TryFrom for ContentType { - type Error = der::Error; - - fn try_from(oid: ObjectIdentifier) -> der::Result { - match oid { - crate::PKCS_7_DATA_OID => Ok(Self::Data), - crate::PKCS_7_SIGNED_DATA_OID => Ok(Self::SignedData), - crate::PKCS_7_ENVELOPED_DATA_OID => Ok(Self::EnvelopedData), - crate::PKCS_7_SIGNED_AND_ENVELOPED_DATA_OID => Ok(Self::SignedAndEnvelopedData), - crate::PKCS_7_DIGESTED_DATA_OID => Ok(Self::DigestedData), - crate::PKCS_7_ENCRYPTED_DATA_OID => Ok(Self::EncryptedData), - _ => Err(ErrorKind::OidUnknown { oid }.into()), - } - } -} diff --git a/pkcs7/src/data_content.rs b/pkcs7/src/data_content.rs deleted file mode 100644 index e345109e3..000000000 --- a/pkcs7/src/data_content.rs +++ /dev/null @@ -1,53 +0,0 @@ -//! `data` content type [RFC 5652 § 4](https://datatracker.ietf.org/doc/html/rfc5652#section-4) - -use core::convert::{From, TryFrom}; -use der::{ - asn1::OctetStringRef, DecodeValue, EncodeValue, FixedTag, Header, Length, Reader, Tag, Writer, -}; - -/// The content that is just an octet string. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub struct DataContent<'a> { - /// content bytes - pub content: &'a [u8], -} - -impl AsRef<[u8]> for DataContent<'_> { - fn as_ref(&self) -> &[u8] { - self.content - } -} - -impl<'a> From<&'a [u8]> for DataContent<'a> { - fn from(bytes: &'a [u8]) -> DataContent<'a> { - DataContent { content: bytes } - } -} - -impl<'a> From> for &'a [u8] { - fn from(data: DataContent<'a>) -> &'a [u8] { - data.content - } -} - -impl<'a> DecodeValue<'a> for DataContent<'a> { - fn decode_value>(reader: &mut R, header: Header) -> der::Result> { - Ok(OctetStringRef::decode_value(reader, header)? - .as_bytes() - .into()) - } -} - -impl<'a> EncodeValue for DataContent<'a> { - fn value_len(&self) -> der::Result { - Length::try_from(self.content.len()) - } - - fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> { - OctetStringRef::new(self.content)?.encode_value(writer) - } -} - -impl<'a> FixedTag for DataContent<'a> { - const TAG: Tag = Tag::OctetString; -} diff --git a/pkcs7/src/encapsulated_content_info.rs b/pkcs7/src/encapsulated_content_info.rs deleted file mode 100644 index b5b190585..000000000 --- a/pkcs7/src/encapsulated_content_info.rs +++ /dev/null @@ -1,29 +0,0 @@ -//! `encapsulated-data` content type [RFC 5652 § 5.2](https://datatracker.ietf.org/doc/html/rfc5652#section-5.2) - -use der::{AnyRef, Sequence}; -use spki::ObjectIdentifier; - -/// Encapsulated content information [RFC 5652 § 5.2](https://datatracker.ietf.org/doc/html/rfc5652#section-5.2) -/// -/// ```text -/// EncapsulatedContentInfo ::= SEQUENCE { -/// eContentType ContentType, -/// eContent [0] EXPLICIT OCTET STRING OPTIONAL } -/// ``` -/// Due to a difference in PKCS #7 and CMS the contents type can be either -/// ```text -/// content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL -/// ``` -/// or -/// ```text -/// eContent [0] EXPLICIT OCTET STRING OPTIONAL -/// ``` -#[derive(Clone, Copy, Debug, Eq, PartialEq, Sequence)] -pub struct EncapsulatedContentInfo<'a> { - /// indicates the type of content. - pub e_content_type: ObjectIdentifier, - - /// encapsulated content - #[asn1(context_specific = "0", optional = "true", tag_mode = "EXPLICIT")] - pub e_content: Option>, -} diff --git a/pkcs7/src/encrypted_data_content.rs b/pkcs7/src/encrypted_data_content.rs deleted file mode 100644 index 909e08980..000000000 --- a/pkcs7/src/encrypted_data_content.rs +++ /dev/null @@ -1,52 +0,0 @@ -//! `encrypted-data` content type [RFC 5652 § 8](https://datatracker.ietf.org/doc/html/rfc5652#section-8) - -use crate::enveloped_data_content::EncryptedContentInfo; -use der::{Enumerated, Sequence}; - -/// Syntax version of the `encrypted-data` content type. -/// -/// ```text -/// Version ::= Integer -/// ``` -/// -/// The only version supported by this library is `0`. -/// See [RFC 5652 § 8](https://datatracker.ietf.org/doc/html/rfc5652#section-8). -#[derive(Clone, Copy, Debug, Enumerated, Eq, PartialEq)] -#[asn1(type = "INTEGER")] -#[repr(u8)] -pub enum Version { - /// syntax version 0 for [EncryptedDataContent]. - V0 = 0, -} - -impl From for u8 { - fn from(version: Version) -> Self { - version as u8 - } -} - -/// Encrypted-data content type [RFC 5652 § 8](https://datatracker.ietf.org/doc/html/rfc5652#section-8) -/// -/// ```text -/// EncryptedData ::= SEQUENCE { -/// version Version, -/// encryptedContentInfo EncryptedContentInfo } -/// ``` -/// -/// The encrypted-data content type consists of encrypted content of any -/// type. Unlike the enveloped-data content type, the encrypted-data -/// content type has neither recipients nor encrypted content-encryption -/// keys. Keys are assumed to be managed by other means. -/// -/// The fields of type EncryptedData have the following meanings: -/// - [`version`](EncryptedDataContent::version) is the syntax version number. -/// - [`encrypted_content_info`](EncryptedDataContent::encrypted_content_info) is the encrypted content -/// information, as in [EncryptedContentInfo]. -#[derive(Copy, Clone, Debug, Eq, PartialEq, Sequence)] -pub struct EncryptedDataContent<'a> { - /// the syntax version number. - pub version: Version, - - /// the encrypted content information. - pub encrypted_content_info: EncryptedContentInfo<'a>, -} diff --git a/pkcs7/src/enveloped_data_content.rs b/pkcs7/src/enveloped_data_content.rs deleted file mode 100644 index 987995996..000000000 --- a/pkcs7/src/enveloped_data_content.rs +++ /dev/null @@ -1,48 +0,0 @@ -//! `enveloped-data` content type [RFC 5652 § 6](https://datatracker.ietf.org/doc/html/rfc5652#section-6) - -use crate::ContentType; - -use der::{asn1::OctetStringRef, Sequence}; -use spki::AlgorithmIdentifierRef; - -type ContentEncryptionAlgorithmIdentifier<'a> = AlgorithmIdentifierRef<'a>; - -/// Encrypted content information [RFC 5652 § 6](https://datatracker.ietf.org/doc/html/rfc5652#section-6) -/// -/// ```text -/// EncryptedContentInfo ::= SEQUENCE { -/// contentType ContentType, -/// contentEncryptionAlgorithm -/// ContentEncryptionAlgorithmIdentifier, -/// encryptedContent -/// [0] IMPLICIT EncryptedContent OPTIONAL } -/// -/// ContentEncryptionAlgorithmIdentifier ::= -/// AlgorithmIdentifier -/// -/// EncryptedContent ::= OCTET STRING -/// ``` -/// -/// The fields of type `EncryptedContentInfo` have the following meanings: -/// - [`content_type`](EncryptedContentInfo::content_type) indicates the type of content. -/// - [`content_encryption_algorithm`](EncryptedContentInfo::content_encryption_algorithm) -/// identifies the content-encryption algorithm (and any associated parameters) under -/// which the content is encrypted. -/// This algorithm is the same for all recipients. -/// - [`encrypted_content`](EncryptedContentInfo::encrypted_content) is the result of -/// encrypting the content. The field is optional, and if the field is not present, -/// its intended value must be supplied by other means. -#[derive(Clone, Copy, Debug, Eq, PartialEq, Sequence)] -pub struct EncryptedContentInfo<'a> { - /// indicates the type of content. - pub content_type: ContentType, - - /// identifies the content-encryption algorithm (and any associated parameters) under - /// which the content is encrypted. - pub content_encryption_algorithm: ContentEncryptionAlgorithmIdentifier<'a>, - - /// the encrypted contents; - /// when not present, its intended value must be supplied by other means. - #[asn1(context_specific = "0", optional = "true", tag_mode = "IMPLICIT")] - pub encrypted_content: Option>, -} diff --git a/pkcs7/src/lib.rs b/pkcs7/src/lib.rs deleted file mode 100644 index e0beebc58..000000000 --- a/pkcs7/src/lib.rs +++ /dev/null @@ -1,60 +0,0 @@ -#![no_std] -#![cfg_attr(docsrs, feature(doc_auto_cfg))] -#![doc = include_str!("../README.md")] -#![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg" -)] -#![forbid(unsafe_code)] -#![warn( - clippy::mod_module_files, - clippy::unwrap_used, - missing_docs, - rust_2018_idioms, - unused_lifetimes, - unused_qualifications -)] - -pub mod algorithm_identifier_types; -pub mod certificate_choices; -pub mod cms_version; -pub mod data_content; -pub mod encapsulated_content_info; -pub mod encrypted_data_content; -pub mod enveloped_data_content; -pub mod revocation_info_choices; -pub mod signed_data_content; -pub mod signer_info; - -mod content_info; -mod content_type; - -pub use crate::{content_info::ContentInfo, content_type::ContentType}; - -use der::asn1::ObjectIdentifier; - -/// `pkcs-7` Object Identifier (OID). -pub const PKCS_7_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.113549.1.7"); - -/// `pkcs-7 data` Object Identifier (OID). -pub const PKCS_7_DATA_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.113549.1.7.1"); - -/// `pkcs-7 signedData` Object Identifier (OID). -pub const PKCS_7_SIGNED_DATA_OID: ObjectIdentifier = - ObjectIdentifier::new_unwrap("1.2.840.113549.1.7.2"); - -/// `pkcs-7 signedData` Object Identifier (OID). -pub const PKCS_7_ENVELOPED_DATA_OID: ObjectIdentifier = - ObjectIdentifier::new_unwrap("1.2.840.113549.1.7.3"); - -/// `pkcs-7 signedAndEnvelopedData` Object Identifier (OID). -pub const PKCS_7_SIGNED_AND_ENVELOPED_DATA_OID: ObjectIdentifier = - ObjectIdentifier::new_unwrap("1.2.840.113549.1.7.4"); - -/// `pkcs-7 digestedData` Object Identifier (OID). -pub const PKCS_7_DIGESTED_DATA_OID: ObjectIdentifier = - ObjectIdentifier::new_unwrap("1.2.840.113549.1.7.5"); - -/// `pkcs-7 encryptedData` Object Identifier (OID). -pub const PKCS_7_ENCRYPTED_DATA_OID: ObjectIdentifier = - ObjectIdentifier::new_unwrap("1.2.840.113549.1.7.6"); diff --git a/pkcs7/src/revocation_info_choices.rs b/pkcs7/src/revocation_info_choices.rs deleted file mode 100644 index 232a5acbc..000000000 --- a/pkcs7/src/revocation_info_choices.rs +++ /dev/null @@ -1,52 +0,0 @@ -//! `RevocationInfoChoices` [RFC 5652 10.2.1](https://datatracker.ietf.org/doc/html/rfc5652#section-10.2.1) - -use core::cmp::Ordering; - -use der::{asn1::SetOfVec, AnyRef, Choice, Sequence, ValueOrd}; -use spki::ObjectIdentifier; -use x509_cert::crl::CertificateList; - -/// ```text -/// RevocationInfoChoices ::= SET OF RevocationInfoChoice -/// RevocationInfoChoice ::= CHOICE { -/// crl CertificateList, -/// other [1] IMPLICIT OtherRevocationInfoFormat } -/// OtherRevocationInfoFormat ::= SEQUENCE { -/// otherRevInfoFormat OBJECT IDENTIFIER, -/// otherRevInfo ANY DEFINED BY otherRevInfoFormat } -/// ``` -#[derive(Clone, Debug, PartialEq, Eq, Choice)] -#[allow(clippy::large_enum_variant)] -pub enum RevocationInfoChoice<'a> { - /// The CertificateList type gives a certificate revocation list (CRL). - Crl(CertificateList), - - /// The OtherRevocationInfoFormat alternative is provided to support any - /// other revocation information format without further modifications to - /// the CMS. - #[asn1(context_specific = "1", tag_mode = "IMPLICIT", constructed = "true")] - Other(OtherRevocationInfoFormat<'a>), -} - -/// ```text -/// RevocationInfoChoices ::= SET OF RevocationInfoChoice -/// ``` -pub type RevocationInfoChoices<'a> = SetOfVec>; - -/// ```text -/// OtherRevocationInfoFormat ::= SEQUENCE { -/// otherRevInfoFormat OBJECT IDENTIFIER, -/// otherRevInfo ANY DEFINED BY otherRevInfoFormat } -/// ``` -#[derive(Clone, Debug, PartialEq, Eq, Sequence)] -pub struct OtherRevocationInfoFormat<'a> { - other_rev_info_format: ObjectIdentifier, - other_rev_info: AnyRef<'a>, -} - -// TODO: figure out what ordering makes sense - if any -impl ValueOrd for RevocationInfoChoice<'_> { - fn value_cmp(&self, _other: &Self) -> der::Result { - Ok(Ordering::Equal) - } -} diff --git a/pkcs7/src/signed_data_content.rs b/pkcs7/src/signed_data_content.rs deleted file mode 100644 index 43ccf170c..000000000 --- a/pkcs7/src/signed_data_content.rs +++ /dev/null @@ -1,48 +0,0 @@ -//! `signed-data` content type [RFC 5652 § 5](https://datatracker.ietf.org/doc/html/rfc5652#section-5) - -use crate::{ - algorithm_identifier_types::DigestAlgorithmIdentifiers, - certificate_choices::CertificateChoices, cms_version::CmsVersion, - encapsulated_content_info::EncapsulatedContentInfo, - revocation_info_choices::RevocationInfoChoices, signer_info::SignerInfos, -}; -use der::{asn1::SetOfVec, Sequence}; - -/// ```text -/// CertificateSet ::= SET OF CertificateChoices -/// ``` -pub type CertificateSet<'a> = SetOfVec>; - -/// Signed-data content type [RFC 5652 § 5](https://datatracker.ietf.org/doc/html/rfc5652#section-5) -/// -/// ```text -/// SignedData ::= SEQUENCE { -/// version CMSVersion, -/// digestAlgorithms DigestAlgorithmIdentifiers, -/// encapContentInfo EncapsulatedContentInfo, -/// certificates [0] IMPLICIT CertificateSet OPTIONAL, -/// crls [1] IMPLICIT RevocationInfoChoices OPTIONAL, -/// signerInfos SignerInfos } -/// ``` -#[derive(Clone, Debug, Eq, PartialEq, Sequence)] -pub struct SignedDataContent<'a> { - /// the syntax version number. - pub version: CmsVersion, - - /// digest algorithm - pub digest_algorithms: DigestAlgorithmIdentifiers<'a>, - - /// content - pub encap_content_info: EncapsulatedContentInfo<'a>, - - /// certs - #[asn1(context_specific = "0", optional = "true", tag_mode = "IMPLICIT")] - pub certificates: Option>, - - /// crls - #[asn1(context_specific = "1", optional = "true", tag_mode = "IMPLICIT")] - pub crls: Option>, - - /// signer info - pub signer_infos: SignerInfos<'a>, -} diff --git a/pkcs7/src/signer_info.rs b/pkcs7/src/signer_info.rs deleted file mode 100644 index fc53f09f1..000000000 --- a/pkcs7/src/signer_info.rs +++ /dev/null @@ -1,88 +0,0 @@ -//! `SignerInfo` data type [RFC 5652 § 5.3](https://datatracker.ietf.org/doc/html/rfc5652#section-5.3) - -use crate::{ - algorithm_identifier_types::{DigestAlgorithmIdentifier, SignatureAlgorithmIdentifier}, - cms_version::CmsVersion, -}; -use der::{ - asn1::{OctetStringRef, SetOfVec}, - Choice, Sequence, ValueOrd, -}; -use x509_cert::{ - attr::Attribute, ext::pkix::SubjectKeyIdentifier, name::Name, serial_number::SerialNumber, -}; - -/// ```text -/// SignedAttributes ::= SET SIZE (1..MAX) OF Attribute -/// ``` -type SignedAttributes<'a> = SetOfVec; - -/// ```text -/// UnsignedAttributes ::= SET SIZE (1..MAX) OF Attribute -/// ``` -type UnsignedAttributes<'a> = SetOfVec; - -/// ```text -/// SignerIdentifier ::= CHOICE { -// issuerAndSerialNumber IssuerAndSerialNumber, -// subjectKeyIdentifier [0] SubjectKeyIdentifier } -/// ``` -#[derive(Clone, Debug, PartialEq, Eq, Choice, ValueOrd)] -pub enum SignerIdentifier { - /// issuer and serial number - IssuerAndSerialNumber(IssuerAndSerialNumber), - - /// subject key identifier - #[asn1(context_specific = "0")] - SubjectKeyIdentifier(SubjectKeyIdentifier), -} - -#[derive(Clone, Debug, Eq, PartialEq, Sequence, ValueOrd)] -#[allow(missing_docs)] -pub struct IssuerAndSerialNumber { - pub name: Name, - pub serial_number: SerialNumber, -} - -/// ```text -/// SignerInfos ::= SET OF SignerInfo -/// ``` -pub type SignerInfos<'a> = SetOfVec>; - -/// `SignerInfo` data type [RFC 5652 § 5.3](https://datatracker.ietf.org/doc/html/rfc5652#section-5.3) -/// -/// ```text -/// SignerInfo ::= SEQUENCE { -/// version CMSVersion, -/// sid SignerIdentifier, -/// digestAlgorithm DigestAlgorithmIdentifier, -/// signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL, -/// signatureAlgorithm SignatureAlgorithmIdentifier, -/// signature SignatureValue, -/// unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL } -/// ``` -#[derive(Clone, Debug, Eq, PartialEq, Sequence, ValueOrd)] -pub struct SignerInfo<'a> { - /// the syntax version number. - pub version: CmsVersion, - - /// the signer identifier - pub sid: SignerIdentifier, - - /// the message digest algorithm - pub digest_algorithm: DigestAlgorithmIdentifier<'a>, - - /// the signed attributes - #[asn1(context_specific = "0", tag_mode = "IMPLICIT", optional = "true")] - pub signed_attributes: Option>, - - /// the signature algorithm - pub signature_algorithm: SignatureAlgorithmIdentifier<'a>, - - /// the signature for content or detached - pub signature: OctetStringRef<'a>, - - /// the unsigned attributes - #[asn1(context_specific = "1", tag_mode = "IMPLICIT", optional = "true")] - pub unsigned_attributes: Option>, -} diff --git a/pkcs7/tests/content_tests.rs b/pkcs7/tests/content_tests.rs deleted file mode 100644 index 7623525dd..000000000 --- a/pkcs7/tests/content_tests.rs +++ /dev/null @@ -1,245 +0,0 @@ -//! PKCS#7 example tests - -use der::{ - asn1::{ObjectIdentifier, OctetStringRef, SequenceRef}, - Decode, DecodePem, SliceWriter, -}; -use hex_literal::hex; -use pkcs7::algorithm_identifier_types::{DigestAlgorithmIdentifier, DigestAlgorithmIdentifiers}; -use pkcs7::certificate_choices::CertificateChoices; -use pkcs7::signed_data_content::CertificateSet; -use pkcs7::signer_info::SignerInfos; -use pkcs7::{ - cms_version::CmsVersion, encapsulated_content_info::EncapsulatedContentInfo, - encrypted_data_content::EncryptedDataContent, enveloped_data_content::EncryptedContentInfo, - signed_data_content::SignedDataContent, ContentInfo, ContentType, -}; -use spki::AlgorithmIdentifierRef; -use std::fs; - -fn encode_content_info<'a>(content_info: &ContentInfo<'a>, buf: &'a mut [u8]) -> &'a [u8] { - let mut encoder = SliceWriter::new(buf); - encoder.encode(content_info).expect("encoded content info"); - encoder.finish().expect("encoding success") -} - -#[test] -fn decode_cert_example() { - let path = "./tests/examples/certData.bin"; - let bytes = fs::read(path).unwrap_or_else(|_| panic!("Failed to read from {}", &path)); - - let content = ContentInfo::from_der(&bytes).expect("expected valid data"); - - match content { - ContentInfo::Data(data) => assert_eq!(data.content.len(), 781), - _ => panic!("expected ContentInfo::Data(Some(_))"), - } - - let mut buf = vec![0u8; bytes.len()]; - let encoded_content = encode_content_info(&content, &mut buf); - - assert_eq!(encoded_content, bytes); -} - -#[test] -fn decode_encrypted_key_example() { - let path = "./tests/examples/keyEncryptedData.bin"; - let bytes = fs::read(path).unwrap_or_else(|_| panic!("Failed to read from {}", &path)); - - let content = ContentInfo::from_der(&bytes).expect("expected valid data"); - - let expected_oid = ObjectIdentifier::new("1.2.840.113549.1.12.1.6").unwrap(); - let expected_salt = &hex!("ad2d4b4e87b34d67"); - match content { - ContentInfo::EncryptedData(EncryptedDataContent { - version: _, - encrypted_content_info: - EncryptedContentInfo { - content_type: ContentType::Data, - content_encryption_algorithm: - AlgorithmIdentifierRef { - oid, - parameters: Some(any), - }, - encrypted_content: Some(bytes), - }, - }) => { - assert_eq!(oid, expected_oid); - - let (salt, iter) = any - .sequence(|decoder| { - let salt = OctetStringRef::decode(decoder)?; - let iter = u16::decode(decoder)?; - Ok((salt, iter)) - }) - .expect("salt and iters parameters"); - assert_eq!(salt.as_bytes(), expected_salt); - assert_eq!(iter, 2048); - - assert_eq!(552u32, bytes.len().into()) - } - _ => panic!("expected ContentInfo::Data(Some(_))"), - } - - let mut buf = vec![0u8; bytes.len()]; - let encoded_content = encode_content_info(&content, &mut buf); - - assert_eq!(encoded_content, bytes) -} - -#[test] -fn decode_signed_mdm_example() { - let path = "./tests/examples/apple_mdm_signature_der.bin"; - let bytes = fs::read(path).unwrap_or_else(|_| panic!("Failed to read from {}", &path)); - - let content = ContentInfo::from_der(&bytes).expect("expected valid data"); - - match content { - ContentInfo::SignedData(SignedDataContent { - version: _, - digest_algorithms: _, - encap_content_info: - EncapsulatedContentInfo { - e_content_type: _, - e_content: Some(content), - }, - certificates: _, - crls: _, - signer_infos: _, - }) => { - let _content = content - .decode_as::() - .expect("Content should be in the correct format: SequenceRef"); - } - _ => panic!("expected ContentInfo::SignedData(Some(_))"), - } -} - -#[test] -fn decode_signed_scep_example() { - let path = "./tests/examples/scep_der.bin"; - let bytes = fs::read(path).unwrap_or_else(|_| panic!("Failed to read from {}", &path)); - - let content = ContentInfo::from_der(&bytes).expect("expected valid data"); - - match content { - ContentInfo::SignedData(SignedDataContent { - version: ver, - digest_algorithms: _, - encap_content_info: - EncapsulatedContentInfo { - e_content_type: _, - e_content: Some(content), - }, - certificates: _, - crls: _, - signer_infos: _, - }) => { - let _content = content - .decode_as::() - .expect("Content should be in the correct format: OctetStringRef"); - - assert_eq!(ver, CmsVersion::V1) - } - _ => panic!("expected ContentInfo::SignedData(Some(_))"), - } - - let mut buf = vec![0u8; bytes.len()]; - encode_content_info(&content, &mut buf); -} - -// TODO(tarcieri): BER support -#[test] -#[ignore] -fn decode_signed_ber() { - let bytes = include_bytes!("examples/cms_ber.bin"); - - let content = match ContentInfo::from_der(bytes) { - Ok(ContentInfo::SignedData(data)) => data, - other => panic!("unexpected result: {:?}", other), - }; - - assert_eq!( - content - .encap_content_info - .e_content - .unwrap() - .decode_as::() - .unwrap() - .as_bytes() - .len(), - 10034 - ); -} - -#[test] -fn decode_signed_der() { - let bytes = include_bytes!("examples/cms_der.bin"); - - let content = match ContentInfo::from_der(bytes) { - Ok(ContentInfo::SignedData(data)) => data, - other => panic!("unexpected result: {:?}", other), - }; - - assert_eq!( - content - .encap_content_info - .e_content - .unwrap() - .decode_as::() - .unwrap() - .as_bytes() - .len(), - 10034 - ); -} - -#[test] -fn create_pkcs7_signed_data() { - // {iso(1) identified-organization(3) thawte(101) id-Ed25519(112)} - const OID_ED25519: &str = "1.3.101.112"; - // {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-7(7) signedData(2)} - const OID_PKCS7_SIGNED_DATA: &str = "1.2.840.113549.1.7.2"; - - let digest_algorithms = { - let digest_algorithm = DigestAlgorithmIdentifier { - oid: der::asn1::ObjectIdentifier::new(OID_ED25519).unwrap(), - parameters: None, - }; - let mut digest_algorithms = DigestAlgorithmIdentifiers::new(); - digest_algorithms.insert(digest_algorithm).unwrap(); - digest_algorithms - }; - - let encap_content_info = { - EncapsulatedContentInfo { - e_content_type: der::asn1::ObjectIdentifier::new(OID_PKCS7_SIGNED_DATA).unwrap(), - e_content: None, - } - }; - - let certificates = { - let cert_pem = include_bytes!("../tests/examples/cert.pem"); - let cert: x509_cert::Certificate = x509_cert::Certificate::from_pem(cert_pem).unwrap(); - let cert_choice = CertificateChoices::Certificate(cert); - let mut certs = CertificateSet::new(); - certs.insert(cert_choice).unwrap(); - Some(certs) - }; - - fn get_signer_infos<'a>() -> SignerInfos<'a> { - SignerInfos::new() - } - - let content_info = ContentInfo::SignedData(SignedDataContent { - version: pkcs7::cms_version::CmsVersion::V1, - digest_algorithms, - encap_content_info, - certificates, - crls: None, - signer_infos: get_signer_infos(), - }); - - let mut buf = vec![0u8; 10000]; // buffer length must be guessed in advance :| - encode_content_info(&content_info, &mut buf); -}