diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /third_party/rust/cose | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
32 files changed, 3546 insertions, 0 deletions
diff --git a/third_party/rust/cose-c/.cargo-checksum.json b/third_party/rust/cose-c/.cargo-checksum.json new file mode 100644 index 0000000000..54139175a2 --- /dev/null +++ b/third_party/rust/cose-c/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"6e5aa986e80c9f848f8219f46d5e6d445609a3db70da9793f920c56c18814b7d","LICENSE":"1f256ecad192880510e84ad60474eab7589218784b9a50bc7ceee34c2b91f1d5","include/cosec.h":"0c6ebd84b6e1ee61a710f86416fc9092653292479556c713c83f193f26ac09b9","src/lib.rs":"0fef8341439e55682d7a7e50dead28427832b5fbd28ca48f60b00277c8a4b9b1"},"package":"49726015ab0ca765144fcca61e4a7a543a16b795a777fa53f554da2fffff9a94"}
\ No newline at end of file diff --git a/third_party/rust/cose-c/Cargo.toml b/third_party/rust/cose-c/Cargo.toml new file mode 100644 index 0000000000..fcd8a538d8 --- /dev/null +++ b/third_party/rust/cose-c/Cargo.toml @@ -0,0 +1,26 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g. crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +name = "cose-c" +version = "0.1.5" +authors = ["Franziskus Kiefer <franziskuskiefer@gmail.com>"] +description = "C API for the cose crate" +keywords = ["cose", "jose", "cbor"] +license = "MPL-2.0" +repository = "https://github.com/franziskuskiefer/cose-c-api" + +[lib] +name = "cosec" +path = "src/lib.rs" +[dependencies.cose] +version = "0.1.4" diff --git a/third_party/rust/cose-c/LICENSE b/third_party/rust/cose-c/LICENSE new file mode 100644 index 0000000000..a612ad9813 --- /dev/null +++ b/third_party/rust/cose-c/LICENSE @@ -0,0 +1,373 @@ +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. diff --git a/third_party/rust/cose-c/include/cosec.h b/third_party/rust/cose-c/include/cosec.h new file mode 100644 index 0000000000..6596075e1d --- /dev/null +++ b/third_party/rust/cose-c/include/cosec.h @@ -0,0 +1,34 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include <stdint.h> + +enum CoseSignatureType +{ + ES256 = 0, + ES384 = 1, + ES512 = 2, + PS256 = 3 +}; + +extern "C" { +typedef bool (*cose_verify_callback)(const uint8_t* payload, + size_t payload_len, + const uint8_t** cert_chain, + size_t cert_chain_len, + const size_t* certs_len, + const uint8_t* ee_cert, + size_t ee_cert_len, + const uint8_t* signature, + size_t signature_len, + uint8_t algorithm, + void* ctx); +bool +verify_cose_signature_ffi(const uint8_t* payload, + size_t payload_len, + const uint8_t* signature, + size_t signature_len, + void* ctx, + cose_verify_callback); +} diff --git a/third_party/rust/cose-c/src/lib.rs b/third_party/rust/cose-c/src/lib.rs new file mode 100644 index 0000000000..695d7908f8 --- /dev/null +++ b/third_party/rust/cose-c/src/lib.rs @@ -0,0 +1,89 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +extern crate cose; + +use std::slice; +use cose::decoder::decode_signature; +use cose::SignatureAlgorithm; +use std::os::raw; + +unsafe fn from_raw(ptr: *const u8, len: usize) -> Vec<u8> { + slice::from_raw_parts(ptr, len).to_vec() +} + +type VerifyCallback = extern "C" fn(*const u8, /* payload */ + usize, /* payload len */ + *const *const u8, /* cert_chain */ + usize, /* # certs */ + *const usize, /* cert lengths in cert_chain */ + *const u8, /* signer cert */ + usize, /* signer cert len */ + *const u8, /* signature bytes */ + usize, /* signature len */ + u8, /* signature algorithm */ + *const raw::c_void /* some context of the app */) + -> bool; + +#[no_mangle] +pub extern "C" fn verify_cose_signature_ffi( + payload: *const u8, + payload_len: usize, + cose_signature: *const u8, + cose_signature_len: usize, + ctx: *const raw::c_void, + verify_callback: VerifyCallback, +) -> bool { + if payload.is_null() || cose_signature.is_null() || payload_len == 0 || + cose_signature_len == 0 + { + return false; + } + + // Build Rust variables from C parameters. + let payload = unsafe { from_raw(payload, payload_len) }; + let cose_signature = unsafe { from_raw(cose_signature, cose_signature_len) }; + + // Parse the incoming signature. + let cose_signatures = decode_signature(&cose_signature, &payload); + let cose_signatures = match cose_signatures { + Ok(signatures) => signatures, + Err(_) => Vec::new(), + }; + if cose_signatures.len() == 0 { + return false; + } + + return cose_signatures.into_iter().all(|cose_signature| { + let signature_type = cose_signature.signature_type; + // ES256 = 0, ES384 = 1, ES512 = 2, PS256 = 3 + let signature_type = match signature_type { + SignatureAlgorithm::ES256 => 0, + SignatureAlgorithm::ES384 => 1, + SignatureAlgorithm::ES512 => 2, + SignatureAlgorithm::PS256 => 3, + }; + let signature_bytes = cose_signature.signature; + let real_payload = cose_signature.to_verify; + + // Build cert chain params. + let certs: Vec<_> = cose_signature.certs.iter().map(|c| c.as_ptr()).collect(); + let cert_lens: Vec<_> = cose_signature.certs.iter().map(|c| c.len()).collect(); + + // Call callback to verify the parsed signatures. + verify_callback( + real_payload.as_ptr(), + real_payload.len(), + certs.as_ptr(), + certs.len(), + cert_lens.as_ptr(), + cose_signature.signer_cert.as_ptr(), + cose_signature.signer_cert.len(), + signature_bytes.as_ptr(), + signature_bytes.len(), + signature_type, + ctx, + ) + }); +} diff --git a/third_party/rust/cose/.cargo-checksum.json b/third_party/rust/cose/.cargo-checksum.json new file mode 100644 index 0000000000..61855016bb --- /dev/null +++ b/third_party/rust/cose/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"40534ef8d01b0269e2ca3b00c4d14f7523222bc85611ee07afcffea45a71ef4b","LICENSE":"1f256ecad192880510e84ad60474eab7589218784b9a50bc7ceee34c2b91f1d5","README.md":"7b9676ec9ed5d7ac38f461b1b257eb0bd80568e732994fb26fa929ce5fe503af","build.rs":"a2b798bbeaf8ef19a9bd8c1e24b3fd3899a5b4b3e121e5e09794e4e2b35971dd","examples/sign_verify/main.rs":"fbe4b9c73b23e1ef364126f453f749fefb67ab45703bf809a5eed910a25e461e","examples/sign_verify/nss.rs":"a1d133142efc0ac6564f0b9587890587f1ecaa7404ac0c4c8907de6d43de3267","examples/sign_verify/test_nss.rs":"be41ebe0a82b6172297b10c13767e4768f0b613ac331b554f6e8c2c7a20c0bc8","examples/sign_verify/test_setup.rs":"82330118e4284d9bf788dbec9e637ab4a3b53fd4ec9c7efaed0e996ffa084de4","examples/sign_verify/util_test.rs":"48d52f3ca3e93b670a1d69f8443358260c1ae61d7977a59d922696811320d4c3","rustfmt.toml":"e97717e906fcd3eeb86dcee52ed26f13e1884597b016a27172229d9c78dd3d57","src/cose.rs":"104e06843f4cdffe2ca6f42f46c51c79d685c18d2ad92b65811e3ceffbd90e07","src/decoder.rs":"a4d2dcd44d179fabdac6ce99cc3512ece3164ba48beab9f313ad85db466c3a55","src/test_cose.rs":"849ec936a00eb438a08eb85380b3e4ba8d8c5a5cf674b272e0fd8e671ab6d5ca","src/test_setup.rs":"e26f290831343cbb4e2b2ec7d1be34c7b900eb8c87abd6f40629372a87b6e992","src/util.rs":"8cdcdc8a120e71a772af61fa63ffa2d2d2eb572d8a53da3b5f1ce9da784f2662","tools/certs/certs.md":"7a1acd946f5bb5b9b21ebd7653ef9d5746a1ea237131a69218a91dc26eda545a","tools/certs/certs.sh":"a06e1a7bf99316c7800e388d20c1630da7449937635600d9f21d8d93907011bf","tools/certs/ee-p256.certspec":"5a7246c0abf1ee08edb858ce2fd38010de7785a0e8652f2d9a0b7eee7aa39213","tools/certs/ee-p256.keyspec":"eabd2839f9e57cf2c372e686e5856cf651d7f07d0d396b3699d1d228b5931945","tools/certs/ee-p384.certspec":"d2e4fdd6d8f02f22bffa800ac2b7f899f5d826528e7b7d3248e1abea15cd33bd","tools/certs/ee-p521.certspec":"7ad1fc3cdf024dfa7213f3a2875af0ccfa2bd73fddcfaf73223aa25b24ee2cad","tools/certs/ee-rsa.certspec":"dd69ecbb1cdf322fb8ef6eb50c2f033b62e7983b5448b96f1965eee8f85b7bde","tools/certs/int-p256.certspec":"b42a2286339455626b9a8b6c0811b031bf269440c6fcef7478796d02c5491364","tools/certs/int-rsa.certspec":"a0942438c72a3ce83b54c04e4a5d4bff08036c2c9feb7d75a7105bfa4fdc5499","tools/certs/root-p256.certspec":"99c1bb07505ddfc3ada5737d8a1bf4cff7b1a70a79abda9fd45fc3a6e72061fc","tools/certs/root-rsa.certspec":"67903313b6058aa98be0d98564577b0c878c868b6f2a8758f27bb7af17616d8e"},"package":"72fa26cb151d3ae4b70f63d67d0fed57ce04220feafafbae7f503bef7aae590d"}
\ No newline at end of file diff --git a/third_party/rust/cose/Cargo.toml b/third_party/rust/cose/Cargo.toml new file mode 100644 index 0000000000..5251eac5c2 --- /dev/null +++ b/third_party/rust/cose/Cargo.toml @@ -0,0 +1,32 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g. crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +name = "cose" +version = "0.1.4" +authors = ["Franziskus Kiefer <franziskuskiefer@gmail.com>", "David Keeler <dkeeler@mozilla.com>"] +build = "build.rs" +description = "Library to use COSE (https://tools.ietf.org/html/rfc8152) in Rust" +keywords = ["cose", "jose"] +license = "MPL-2.0" +repository = "https://github.com/franziskuskiefer/cose-rust" + +[lib] +name = "cose" +path = "src/cose.rs" +[dependencies.moz_cbor] +version = "0.1.0" +[dev-dependencies.scopeguard] +version = "0.3" + +[features] +default = [] diff --git a/third_party/rust/cose/LICENSE b/third_party/rust/cose/LICENSE new file mode 100644 index 0000000000..a612ad9813 --- /dev/null +++ b/third_party/rust/cose/LICENSE @@ -0,0 +1,373 @@ +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. diff --git a/third_party/rust/cose/README.md b/third_party/rust/cose/README.md new file mode 100644 index 0000000000..5540371c01 --- /dev/null +++ b/third_party/rust/cose/README.md @@ -0,0 +1,26 @@ +# cose-rust + +A Rust library for [COSE](https://tools.ietf.org/html/rfc8152) using [NSS](https://github.com/nss-dev/nss/). + +[![Build Status](https://travis-ci.org/franziskuskiefer/cose-rust.svg?branch=master)](https://travis-ci.org/franziskuskiefer/cose-rust/) +![Maturity Level](https://img.shields.io/badge/maturity-alpha-red.svg) + +**THIS IS WORK IN PROGRESS. DO NOT USE YET.** + +## Build instructions + +If NSS is not installed in the path, use `NSS_LIB_DIR` to set the library path where +we can find the NSS libraries. + + cargo build + +### Run Tests and Examples + +To run tests and examples you need NSS in your library path. Tests can be run +with + + cargo test + +and examples with + + cargo run --example sign_verify diff --git a/third_party/rust/cose/build.rs b/third_party/rust/cose/build.rs new file mode 100644 index 0000000000..8db7af5ad1 --- /dev/null +++ b/third_party/rust/cose/build.rs @@ -0,0 +1,11 @@ +use std::env; + +fn main() { + // Use NSS_LIB_DIR lazily. If it's not set and we can't find NSS in the path, + // the build will fail. + #[cfg(test)] + let lib_dir = env::var("NSS_LIB_DIR"); + if let Ok(lib_dir) = env::var("NSS_LIB_DIR") { + println!("cargo:rustc-link-search={}", lib_dir); + } +} diff --git a/third_party/rust/cose/examples/sign_verify/main.rs b/third_party/rust/cose/examples/sign_verify/main.rs new file mode 100644 index 0000000000..0b356e41bb --- /dev/null +++ b/third_party/rust/cose/examples/sign_verify/main.rs @@ -0,0 +1,259 @@ +extern crate moz_cbor as cbor; +extern crate cose; + +#[macro_use(defer)] +extern crate scopeguard; + +mod nss; +mod test_nss; +mod test_setup; +mod util_test; + +use util_test::{sign, verify_signature}; +use test_setup as test; +use std::str::FromStr; +use cose::{CoseError, SignatureAlgorithm}; + +// All keys here are from pykey.py/pycert.py from mozilla-central. +// Certificates can be generated with tools/certs/certs.sh and mozilla-central. + +#[derive(Debug)] +pub struct SignatureParameters<'a> { + certificate: &'a [u8], + algorithm: SignatureAlgorithm, + pkcs8: &'a [u8], +} + +#[derive(Debug)] +pub struct Signature<'a> { + parameter: &'a SignatureParameters<'a>, + signature_bytes: Vec<u8>, +} + +const P256_PARAMS: SignatureParameters = SignatureParameters { + certificate: &test::P256_EE, + algorithm: SignatureAlgorithm::ES256, + pkcs8: &test::PKCS8_P256_EE, +}; +const P384_PARAMS: SignatureParameters = SignatureParameters { + certificate: &test::P384_EE, + algorithm: SignatureAlgorithm::ES384, + pkcs8: &test::PKCS8_P384_EE, +}; +const P521_PARAMS: SignatureParameters = SignatureParameters { + certificate: &test::P521_EE, + algorithm: SignatureAlgorithm::ES512, + pkcs8: &test::PKCS8_P521_EE, +}; + +fn test_verify(payload: &[u8], cert_chain: &[&[u8]], params_vec: Vec<SignatureParameters>) { + test::setup(); + let cose_signature = sign(payload, cert_chain, ¶ms_vec); + assert!(cose_signature.is_ok()); + let cose_signature = cose_signature.unwrap(); + + // Verify signature. + assert!(verify_signature(payload, cose_signature).is_ok()); +} + +fn test_verify_modified_payload( + payload: &mut [u8], + cert_chain: &[&[u8]], + params_vec: Vec<SignatureParameters>, +) { + test::setup(); + let cose_signature = sign(payload, cert_chain, ¶ms_vec); + assert!(cose_signature.is_ok()); + let cose_signature = cose_signature.unwrap(); + + // Verify signature. + payload[0] = !payload[0]; + let verify_result = verify_signature(payload, cose_signature); + assert!(verify_result.is_err()); + assert_eq!(verify_result, Err(CoseError::VerificationFailed)); +} + +fn test_verify_modified_signature( + payload: &[u8], + cert_chain: &[&[u8]], + params_vec: Vec<SignatureParameters>, +) { + test::setup(); + let cose_signature = sign(payload, cert_chain, ¶ms_vec); + assert!(cose_signature.is_ok()); + let mut cose_signature = cose_signature.unwrap(); + + // Tamper with the cose signature. + let len = cose_signature.len(); + cose_signature[len - 15] = !cose_signature[len - 15]; + + // Verify signature. + let verify_result = verify_signature(payload, cose_signature); + assert!(verify_result.is_err()); + assert_eq!(verify_result, Err(CoseError::VerificationFailed)); +} + +// This can be used with inconsistent parameters that make the verification fail. +// In particular, the signing key does not match the certificate used to verify. +fn test_verify_verification_fails( + payload: &[u8], + cert_chain: &[&[u8]], + params_vec: Vec<SignatureParameters>, +) { + test::setup(); + let cose_signature = sign(payload, cert_chain, ¶ms_vec); + assert!(cose_signature.is_ok()); + let cose_signature = cose_signature.unwrap(); + + // Verify signature. + let verify_result = verify_signature(payload, cose_signature); + assert!(verify_result.is_err()); + assert_eq!(verify_result, Err(CoseError::VerificationFailed)); +} + +fn test_cose_sign_verify() { + let payload = b"This is the content."; + + // P256 + let certs: [&[u8]; 2] = [&test::P256_ROOT, + &test::P256_INT]; + let params_vec = vec![P256_PARAMS]; + test_verify(payload, &certs, params_vec); + + // P256, no other certs. + let certs: [&[u8]; 0] = []; + let params_vec = vec![P256_PARAMS]; + test_verify(payload, &certs, params_vec); + + // P384 + let params_vec = vec![P384_PARAMS]; + test_verify(payload, &certs, params_vec); + + // P521 + let params_vec = vec![P521_PARAMS]; + test_verify(payload, &certs, params_vec); +} + +fn test_cose_verify_xpi_signature() { + // This signature was created with sign_app.py from m-c. + test::setup(); + assert!(verify_signature(&test::XPI_PAYLOAD, test::XPI_SIGNATURE.to_vec()).is_ok()); +} + +fn test_cose_sign_verify_modified_payload() { + let mut payload = String::from_str("This is the content.") + .unwrap() + .into_bytes(); + let certs: [&[u8]; 2] = [&test::P256_ROOT, + &test::P256_INT]; + let params_vec = vec![P256_PARAMS]; + test_verify_modified_payload(&mut payload, &certs, params_vec); +} + +fn test_cose_sign_verify_wrong_cert() { + let payload = b"This is the content."; + let certs: [&[u8]; 2] = [&test::P256_ROOT, + &test::P256_INT]; + let params = SignatureParameters { + certificate: &test::P384_EE, + algorithm: SignatureAlgorithm::ES256, + pkcs8: &test::PKCS8_P256_EE, + }; + let params_vec = vec![params]; + test_verify_verification_fails(payload, &certs, params_vec); +} + +fn test_cose_sign_verify_tampered_signature() { + let payload = b"This is the content."; + let certs: [&[u8]; 2] = [&test::P256_ROOT, + &test::P256_INT]; + let params_vec = vec![P256_PARAMS]; + test_verify_modified_signature(payload, &certs, params_vec); +} + +const RSA_PARAMS: SignatureParameters = SignatureParameters { + certificate: &test::RSA_EE, + algorithm: SignatureAlgorithm::PS256, + pkcs8: &test::PKCS8_RSA_EE, +}; + +fn test_cose_sign_verify_rsa() { + let payload = b"This is the RSA-signed content."; + let certs: [&[u8]; 2] = [&test::RSA_ROOT, + &test::RSA_INT]; + let params_vec = vec![RSA_PARAMS]; + test_verify(payload, &certs, params_vec); +} + +fn test_cose_sign_verify_rsa_modified_payload() { + let mut payload = String::from_str("This is the RSA-signed content.") + .unwrap() + .into_bytes(); + let certs: [&[u8]; 2] = [&test::RSA_ROOT, + &test::RSA_INT]; + let params_vec = vec![RSA_PARAMS]; + test_verify_modified_payload(&mut payload, &certs, params_vec); +} + +fn test_cose_sign_verify_rsa_tampered_signature() { + let payload = b"This is the RSA-signed content."; + let certs: [&[u8]; 2] = [&test::RSA_ROOT, + &test::RSA_INT]; + let params_vec = vec![RSA_PARAMS]; + test_verify_modified_signature(payload, &certs, params_vec); +} + +fn test_cose_sign_verify_two_signatures() { + let payload = b"This is the content."; + let certs: [&[u8]; 4] = [&test::P256_ROOT, + &test::P256_INT, + &test::RSA_ROOT, + &test::RSA_INT]; + let params_vec = vec![P256_PARAMS, + RSA_PARAMS]; + test_verify(payload, &certs, params_vec); +} + +fn test_cose_sign_verify_two_signatures_tampered_payload() { + let mut payload = String::from_str("This is the content.") + .unwrap() + .into_bytes(); + let certs: [&[u8]; 4] = [&test::P256_ROOT, + &test::P256_INT, + &test::RSA_ROOT, + &test::RSA_INT]; + let params_vec = vec![P256_PARAMS, + RSA_PARAMS]; + test_verify_modified_payload(&mut payload, &certs, params_vec); +} + +fn test_cose_sign_verify_two_signatures_tampered_signature() { + let payload = b"This is the content."; + let certs: [&[u8]; 4] = [&test::P256_ROOT, + &test::P256_INT, + &test::RSA_ROOT, + &test::RSA_INT]; + let params_vec = vec![P256_PARAMS, + RSA_PARAMS]; + test_verify_modified_signature(payload, &certs, params_vec); +} + +fn main() { + // Basic NSS exmaple usage. + test_nss::test_nss_sign_verify(); + test_nss::test_nss_sign_verify_different_payload(); + test_nss::test_nss_sign_verify_wrong_cert(); + + // COSE sign/verify example usages. + test_cose_sign_verify_two_signatures_tampered_signature(); + test_cose_sign_verify_two_signatures_tampered_payload(); + test_cose_sign_verify_two_signatures(); + test_cose_sign_verify_rsa_tampered_signature(); + test_cose_sign_verify_rsa_modified_payload(); + test_cose_sign_verify_rsa(); + test_cose_sign_verify_tampered_signature(); + test_cose_sign_verify_wrong_cert(); + test_cose_sign_verify_modified_payload(); + test_cose_verify_xpi_signature(); + test_cose_sign_verify(); +} diff --git a/third_party/rust/cose/examples/sign_verify/nss.rs b/third_party/rust/cose/examples/sign_verify/nss.rs new file mode 100644 index 0000000000..a5a827ceba --- /dev/null +++ b/third_party/rust/cose/examples/sign_verify/nss.rs @@ -0,0 +1,356 @@ +use std::marker::PhantomData; +use std::{mem, ptr}; +use std::os::raw; +use std::os::raw::c_char; +use cose::SignatureAlgorithm; + +type SECItemType = raw::c_uint; // TODO: actually an enum - is this the right size? +const SI_BUFFER: SECItemType = 0; // called siBuffer in NSS + +#[repr(C)] +struct SECItem { + typ: SECItemType, + data: *const u8, + len: raw::c_uint, +} + +impl SECItem { + fn maybe_new(data: &[u8]) -> Result<SECItem, NSSError> { + if data.len() > u32::max_value() as usize { + return Err(NSSError::InputTooLarge); + } + Ok(SECItem { + typ: SI_BUFFER, + data: data.as_ptr(), + len: data.len() as u32, + }) + } + + fn maybe_from_parts(data: *const u8, len: usize) -> Result<SECItem, NSSError> { + if len > u32::max_value() as usize { + return Err(NSSError::InputTooLarge); + } + Ok(SECItem { + typ: SI_BUFFER, + data: data, + len: len as u32, + }) + } +} + +/// Many NSS APIs take constant data input as SECItems. Some, however, output data as SECItems. +/// To represent this, we define another type of mutable SECItem. +#[repr(C)] +struct SECItemMut<'a> { + typ: SECItemType, + data: *mut u8, + len: raw::c_uint, + _marker: PhantomData<&'a mut Vec<u8>>, +} + +impl<'a> SECItemMut<'a> { + /// Given a mutable reference to a Vec<u8> that has a particular allocated capacity, create a + /// SECItemMut that points to the vec and has the same capacity. + /// The input vec is not expected to have any actual contents, and in any case is cleared. + fn maybe_from_empty_preallocated_vec(vec: &'a mut Vec<u8>) -> Result<SECItemMut<'a>, NSSError> { + if vec.capacity() > u32::max_value() as usize { + return Err(NSSError::InputTooLarge); + } + vec.clear(); + Ok(SECItemMut { + typ: SI_BUFFER, + data: vec.as_mut_ptr(), + len: vec.capacity() as u32, + _marker: PhantomData, + }) + } +} + +#[repr(C)] +struct CkRsaPkcsPssParams { + // Called CK_RSA_PKCS_PSS_PARAMS in NSS + hash_alg: CkMechanismType, // Called hashAlg in NSS + mgf: CkRsaPkcsMgfType, + s_len: raw::c_ulong, // Called sLen in NSS +} + +impl CkRsaPkcsPssParams { + fn new() -> CkRsaPkcsPssParams { + CkRsaPkcsPssParams { + hash_alg: CKM_SHA256, + mgf: CKG_MGF1_SHA256, + s_len: 32, + } + } + + fn get_params_item(&self) -> Result<SECItem, NSSError> { + // This isn't entirely NSS' fault, but it mostly is. + let params_ptr: *const CkRsaPkcsPssParams = self; + let params_ptr: *const u8 = params_ptr as *const u8; + let params_secitem = + SECItem::maybe_from_parts(params_ptr, mem::size_of::<CkRsaPkcsPssParams>())?; + Ok(params_secitem) + } +} + +type CkMechanismType = raw::c_ulong; // called CK_MECHANISM_TYPE in NSS +const CKM_ECDSA: CkMechanismType = 0x0000_1041; +const CKM_RSA_PKCS_PSS: CkMechanismType = 0x0000_000D; +const CKM_SHA256: CkMechanismType = 0x0000_0250; + +type CkRsaPkcsMgfType = raw::c_ulong; // called CK_RSA_PKCS_MGF_TYPE in NSS +const CKG_MGF1_SHA256: CkRsaPkcsMgfType = 0x0000_0002; + +type SECStatus = raw::c_int; // TODO: enum - right size? +const SEC_SUCCESS: SECStatus = 0; // Called SECSuccess in NSS +const SEC_FAILURE: SECStatus = -1; // Called SECFailure in NSS + +enum SECKEYPublicKey {} +enum SECKEYPrivateKey {} +enum PK11SlotInfo {} +enum CERTCertificate {} +enum CERTCertDBHandle {} + +const SHA256_LENGTH: usize = 32; +const SHA384_LENGTH: usize = 48; +const SHA512_LENGTH: usize = 64; + +// TODO: ugh this will probably have a platform-specific name... +#[link(name = "nss3")] +extern "C" { + fn PK11_HashBuf( + hashAlg: HashAlgorithm, + out: *mut u8, + data_in: *const u8, // called "in" in NSS + len: raw::c_int, + ) -> SECStatus; + fn PK11_VerifyWithMechanism( + key: *const SECKEYPublicKey, + mechanism: CkMechanismType, + param: *const SECItem, + sig: *const SECItem, + hash: *const SECItem, + wincx: *const raw::c_void, + ) -> SECStatus; + + fn SECKEY_DestroyPublicKey(pubk: *const SECKEYPublicKey); + + fn CERT_GetDefaultCertDB() -> *const CERTCertDBHandle; + fn CERT_DestroyCertificate(cert: *mut CERTCertificate); + fn CERT_NewTempCertificate( + handle: *const CERTCertDBHandle, + derCert: *const SECItem, + nickname: *const c_char, + isperm: bool, + copyDER: bool, + ) -> *mut CERTCertificate; + fn CERT_ExtractPublicKey(cert: *const CERTCertificate) -> *const SECKEYPublicKey; + + fn PK11_ImportDERPrivateKeyInfoAndReturnKey( + slot: *mut PK11SlotInfo, + derPKI: *const SECItem, + nickname: *const SECItem, + publicValue: *const SECItem, + isPerm: bool, + isPrivate: bool, + keyUsage: u32, + privk: *mut *mut SECKEYPrivateKey, + wincx: *const u8, + ) -> SECStatus; + fn PK11_GetInternalSlot() -> *mut PK11SlotInfo; + fn PK11_FreeSlot(slot: *mut PK11SlotInfo); + fn PK11_SignatureLen(key: *const SECKEYPrivateKey) -> usize; + fn PK11_SignWithMechanism( + key: *const SECKEYPrivateKey, + mech: CkMechanismType, + param: *const SECItem, + sig: *mut SECItemMut, + hash: *const SECItem, + ) -> SECStatus; +} + +/// An error type describing errors that may be encountered during verification. +#[derive(Debug, PartialEq)] +pub enum NSSError { + ImportCertError, + DecodingPKCS8Failed, + InputTooLarge, + LibraryFailure, + SignatureVerificationFailed, + SigningFailed, + ExtractPublicKeyFailed, +} + +// https://searchfox.org/nss/rev/990c2e793aa731cd66238c6c4f00b9473943bc66/lib/util/secoidt.h#274 +#[derive(Debug, PartialEq, Clone)] +#[repr(C)] +enum HashAlgorithm { + SHA256 = 191, + SHA384 = 192, + SHA512 = 193, +} + +fn hash(payload: &[u8], signature_algorithm: &SignatureAlgorithm) -> Result<Vec<u8>, NSSError> { + if payload.len() > raw::c_int::max_value() as usize { + return Err(NSSError::InputTooLarge); + } + let (hash_algorithm, digest_length) = match *signature_algorithm { + SignatureAlgorithm::ES256 => (HashAlgorithm::SHA256, SHA256_LENGTH), + SignatureAlgorithm::ES384 => (HashAlgorithm::SHA384, SHA384_LENGTH), + SignatureAlgorithm::ES512 => (HashAlgorithm::SHA512, SHA512_LENGTH), + SignatureAlgorithm::PS256 => (HashAlgorithm::SHA256, SHA256_LENGTH), + }; + let mut hash_buf = vec![0; digest_length]; + let len: raw::c_int = payload.len() as raw::c_int; + let hash_result = + unsafe { PK11_HashBuf(hash_algorithm, hash_buf.as_mut_ptr(), payload.as_ptr(), len) }; + if hash_result != SEC_SUCCESS { + return Err(NSSError::LibraryFailure); + } + Ok(hash_buf) +} + +/// Main entrypoint for verification. Given a signature algorithm, the bytes of a subject public key +/// info, a payload, and a signature over the payload, returns a result based on the outcome of +/// decoding the subject public key info and running the signature verification algorithm on the +/// signed data. +pub fn verify_signature( + signature_algorithm: &SignatureAlgorithm, + cert: &[u8], + payload: &[u8], + signature: &[u8], +) -> Result<(), NSSError> { + let slot = unsafe { PK11_GetInternalSlot() }; + if slot.is_null() { + return Err(NSSError::LibraryFailure); + } + defer!(unsafe { + PK11_FreeSlot(slot); + }); + + let hash_buf = hash(payload, signature_algorithm).unwrap(); + let hash_item = SECItem::maybe_new(hash_buf.as_slice())?; + + // Import DER cert into NSS. + let der_cert = SECItem::maybe_new(cert)?; + let db_handle = unsafe { CERT_GetDefaultCertDB() }; + if db_handle.is_null() { + // TODO #28 + return Err(NSSError::LibraryFailure); + } + let nss_cert = + unsafe { CERT_NewTempCertificate(db_handle, &der_cert, ptr::null(), false, true) }; + if nss_cert.is_null() { + return Err(NSSError::ImportCertError); + } + defer!(unsafe { + CERT_DestroyCertificate(nss_cert); + }); + + let key = unsafe { CERT_ExtractPublicKey(nss_cert) }; + if key.is_null() { + return Err(NSSError::ExtractPublicKeyFailed); + } + defer!(unsafe { + SECKEY_DestroyPublicKey(key); + }); + let signature_item = SECItem::maybe_new(signature)?; + let mechanism = match *signature_algorithm { + SignatureAlgorithm::ES256 => CKM_ECDSA, + SignatureAlgorithm::ES384 => CKM_ECDSA, + SignatureAlgorithm::ES512 => CKM_ECDSA, + SignatureAlgorithm::PS256 => CKM_RSA_PKCS_PSS, + }; + let rsa_pss_params = CkRsaPkcsPssParams::new(); + let rsa_pss_params_item = rsa_pss_params.get_params_item()?; + let params_item = match *signature_algorithm { + SignatureAlgorithm::ES256 => ptr::null(), + SignatureAlgorithm::ES384 => ptr::null(), + SignatureAlgorithm::ES512 => ptr::null(), + SignatureAlgorithm::PS256 => &rsa_pss_params_item, + }; + let null_cx_ptr: *const raw::c_void = ptr::null(); + let result = unsafe { + PK11_VerifyWithMechanism( + key, + mechanism, + params_item, + &signature_item, + &hash_item, + null_cx_ptr, + ) + }; + match result { + SEC_SUCCESS => Ok(()), + SEC_FAILURE => Err(NSSError::SignatureVerificationFailed), + _ => Err(NSSError::LibraryFailure), + } +} + +pub fn sign( + signature_algorithm: &SignatureAlgorithm, + pk8: &[u8], + payload: &[u8], +) -> Result<Vec<u8>, NSSError> { + let slot = unsafe { PK11_GetInternalSlot() }; + if slot.is_null() { + return Err(NSSError::LibraryFailure); + } + defer!(unsafe { + PK11_FreeSlot(slot); + }); + let pkcs8item = SECItem::maybe_new(pk8)?; + let mut key: *mut SECKEYPrivateKey = ptr::null_mut(); + let ku_all = 0xFF; + let rv = unsafe { + PK11_ImportDERPrivateKeyInfoAndReturnKey( + slot, + &pkcs8item, + ptr::null(), + ptr::null(), + false, + false, + ku_all, + &mut key, + ptr::null(), + ) + }; + if rv != SEC_SUCCESS || key.is_null() { + return Err(NSSError::DecodingPKCS8Failed); + } + let mechanism = match *signature_algorithm { + SignatureAlgorithm::ES256 => CKM_ECDSA, + SignatureAlgorithm::ES384 => CKM_ECDSA, + SignatureAlgorithm::ES512 => CKM_ECDSA, + SignatureAlgorithm::PS256 => CKM_RSA_PKCS_PSS, + }; + let rsa_pss_params = CkRsaPkcsPssParams::new(); + let rsa_pss_params_item = rsa_pss_params.get_params_item()?; + let params_item = match *signature_algorithm { + SignatureAlgorithm::ES256 => ptr::null(), + SignatureAlgorithm::ES384 => ptr::null(), + SignatureAlgorithm::ES512 => ptr::null(), + SignatureAlgorithm::PS256 => &rsa_pss_params_item, + }; + let signature_len = unsafe { PK11_SignatureLen(key) }; + // Allocate enough space for the signature. + let mut signature: Vec<u8> = Vec::with_capacity(signature_len); + let hash_buf = hash(payload, signature_algorithm).unwrap(); + let hash_item = SECItem::maybe_new(hash_buf.as_slice())?; + { + // Get a mutable SECItem on the preallocated signature buffer. PK11_SignWithMechanism will + // fill the SECItem's buf with the bytes of the signature. + let mut signature_item = SECItemMut::maybe_from_empty_preallocated_vec(&mut signature)?; + let rv = unsafe { + PK11_SignWithMechanism(key, mechanism, params_item, &mut signature_item, &hash_item) + }; + if rv != SEC_SUCCESS || signature_item.len as usize != signature_len { + return Err(NSSError::SigningFailed); + } + } + unsafe { + // Now that the bytes of the signature have been filled out, set its length. + signature.set_len(signature_len); + } + Ok(signature) +} diff --git a/third_party/rust/cose/examples/sign_verify/test_nss.rs b/third_party/rust/cose/examples/sign_verify/test_nss.rs new file mode 100644 index 0000000000..5733aa01e2 --- /dev/null +++ b/third_party/rust/cose/examples/sign_verify/test_nss.rs @@ -0,0 +1,65 @@ +use test_setup as test; +use nss; +use nss::NSSError; +use SignatureAlgorithm; + +pub fn test_nss_sign_verify() { + test::setup(); + let payload = b"sample"; + + // Sign. + let signature_result = nss::sign(&SignatureAlgorithm::ES256, &test::PKCS8_P256_EE, payload); + assert!(signature_result.is_ok()); + let signature_result = signature_result.unwrap(); + + // Verify the signature. + assert!( + nss::verify_signature( + &SignatureAlgorithm::ES256, + &test::P256_EE, + payload, + &signature_result, + ).is_ok() + ); +} + +pub fn test_nss_sign_verify_different_payload() { + test::setup(); + let payload = b"sample"; + + // Sign. + let signature_result = nss::sign(&SignatureAlgorithm::ES256, &test::PKCS8_P256_EE, payload); + assert!(signature_result.is_ok()); + let signature_result = signature_result.unwrap(); + + // Verify the signature with a different payload. + let payload = b"sampli"; + let verify_result = nss::verify_signature( + &SignatureAlgorithm::ES256, + &test::P256_EE, + payload, + &signature_result, + ); + assert!(verify_result.is_err()); + assert_eq!(verify_result, Err(NSSError::SignatureVerificationFailed)); +} + +pub fn test_nss_sign_verify_wrong_cert() { + test::setup(); + let payload = b"sample"; + + // Sign. + let signature_result = nss::sign(&SignatureAlgorithm::ES256, &test::PKCS8_P256_EE, payload); + assert!(signature_result.is_ok()); + let signature_result = signature_result.unwrap(); + + // Verify the signature with a wrong cert. + let verify_result = nss::verify_signature( + &SignatureAlgorithm::ES256, + &test::P384_EE, + payload, + &signature_result, + ); + assert!(verify_result.is_err()); + assert_eq!(verify_result, Err(NSSError::SignatureVerificationFailed)); +} diff --git a/third_party/rust/cose/examples/sign_verify/test_setup.rs b/third_party/rust/cose/examples/sign_verify/test_setup.rs new file mode 100644 index 0000000000..28ae3c1e1c --- /dev/null +++ b/third_party/rust/cose/examples/sign_verify/test_setup.rs @@ -0,0 +1,625 @@ +use std::os::raw; +use std::ptr; +use std::sync::{ONCE_INIT, Once}; +static START: Once = ONCE_INIT; + +type SECStatus = raw::c_int; +const SEC_SUCCESS: SECStatus = 0; +// TODO: ugh this will probably have a platform-specific name... +#[link(name = "nss3")] +extern "C" { + fn NSS_NoDB_Init(configdir: *const u8) -> SECStatus; +} + +pub fn setup() { + START.call_once(|| { + let null_ptr: *const u8 = ptr::null(); + unsafe { + assert_eq!(NSS_NoDB_Init(null_ptr), SEC_SUCCESS); + } + }); +} + +#[cfg_attr(rustfmt, rustfmt_skip)] +pub const PKCS8_P256_EE: [u8; 139] = [ + 0x30, 0x81, 0x87, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2a, + 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, + 0xce, 0x3d, 0x03, 0x01, 0x07, 0x04, 0x6d, 0x30, 0x6b, 0x02, 0x01, + 0x01, 0x04, 0x20, 0x21, 0x91, 0x40, 0x3d, 0x57, 0x10, 0xbf, 0x15, + 0xa2, 0x65, 0x81, 0x8c, 0xd4, 0x2e, 0xd6, 0xfe, 0xdf, 0x09, 0xad, + 0xd9, 0x2d, 0x78, 0xb1, 0x8e, 0x7a, 0x1e, 0x9f, 0xeb, 0x95, 0x52, + 0x47, 0x02, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0x4f, 0xbf, 0xbb, + 0xbb, 0x61, 0xe0, 0xf8, 0xf9, 0xb1, 0xa6, 0x0a, 0x59, 0xac, 0x87, + 0x04, 0xe2, 0xec, 0x05, 0x0b, 0x42, 0x3e, 0x3c, 0xf7, 0x2e, 0x92, + 0x3f, 0x2c, 0x4f, 0x79, 0x4b, 0x45, 0x5c, 0x2a, 0x69, 0xd2, 0x33, + 0x45, 0x6c, 0x36, 0xc4, 0x11, 0x9d, 0x07, 0x06, 0xe0, 0x0e, 0xed, + 0xc8, 0xd1, 0x93, 0x90, 0xd7, 0x99, 0x1b, 0x7b, 0x2d, 0x07, 0xa3, + 0x04, 0xea, 0xa0, 0x4a, 0xa6, 0xc0, 0x0a +]; + +#[cfg_attr(rustfmt, rustfmt_skip)] +pub const P256_EE: [u8; 300] = [ + 0x30, 0x82, 0x01, 0x28, 0x30, 0x81, 0xcf, 0xa0, 0x03, 0x02, 0x01, 0x02, + 0x02, 0x14, 0x2f, 0xc3, 0x5f, 0x05, 0x80, 0xb4, 0x49, 0x45, 0x13, 0x92, + 0xd6, 0x93, 0xb7, 0x2d, 0x71, 0x19, 0xc5, 0x8c, 0x40, 0x39, 0x30, 0x0a, + 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x13, + 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x69, + 0x6e, 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x22, 0x18, 0x0f, 0x32, + 0x30, 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, 0x33, 0x31, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x12, 0x31, 0x10, 0x30, + 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x07, 0x65, 0x65, 0x2d, 0x70, + 0x32, 0x35, 0x36, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, + 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, + 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4f, 0xbf, 0xbb, 0xbb, 0x61, 0xe0, + 0xf8, 0xf9, 0xb1, 0xa6, 0x0a, 0x59, 0xac, 0x87, 0x04, 0xe2, 0xec, 0x05, + 0x0b, 0x42, 0x3e, 0x3c, 0xf7, 0x2e, 0x92, 0x3f, 0x2c, 0x4f, 0x79, 0x4b, + 0x45, 0x5c, 0x2a, 0x69, 0xd2, 0x33, 0x45, 0x6c, 0x36, 0xc4, 0x11, 0x9d, + 0x07, 0x06, 0xe0, 0x0e, 0xed, 0xc8, 0xd1, 0x93, 0x90, 0xd7, 0x99, 0x1b, + 0x7b, 0x2d, 0x07, 0xa3, 0x04, 0xea, 0xa0, 0x4a, 0xa6, 0xc0, 0x30, 0x0a, + 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x48, + 0x00, 0x30, 0x45, 0x02, 0x20, 0x5c, 0x75, 0x51, 0x9f, 0x13, 0x11, 0x50, + 0xcd, 0x5d, 0x8a, 0xde, 0x20, 0xa3, 0xbc, 0x06, 0x30, 0x91, 0xff, 0xb2, + 0x73, 0x75, 0x5f, 0x31, 0x64, 0xec, 0xfd, 0xcb, 0x42, 0x80, 0x0a, 0x70, + 0xe6, 0x02, 0x21, 0x00, 0xff, 0x81, 0xbe, 0xa8, 0x0d, 0x03, 0x36, 0x6b, + 0x75, 0xe2, 0x70, 0x6a, 0xac, 0x07, 0x2e, 0x4c, 0xdc, 0xf9, 0xc5, 0x89, + 0xc1, 0xcf, 0x88, 0xc2, 0xc8, 0x2a, 0x32, 0xf5, 0x42, 0x0c, 0xfa, 0x0b +]; + +#[cfg_attr(rustfmt, rustfmt_skip)] +pub const PKCS8_P384_EE: [u8; 185] = [ + 0x30, 0x81, 0xb6, 0x02, 0x01, 0x00, 0x30, 0x10, 0x06, 0x07, 0x2a, 0x86, + 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22, + 0x04, 0x81, 0x9e, 0x30, 0x81, 0x9b, 0x02, 0x01, 0x01, 0x04, 0x30, 0x03, + 0x5c, 0x7a, 0x1b, 0x10, 0xd9, 0xfa, 0xfe, 0x83, 0x7b, 0x64, 0xad, 0x92, + 0xf2, 0x2f, 0x5c, 0xed, 0x07, 0x89, 0x18, 0x65, 0x38, 0x66, 0x9b, 0x5c, + 0x6d, 0x87, 0x2c, 0xec, 0x3d, 0x92, 0x61, 0x22, 0xb3, 0x93, 0x77, 0x2b, + 0x57, 0x60, 0x2f, 0xf3, 0x13, 0x65, 0xef, 0xe1, 0x39, 0x32, 0x46, 0xa1, + 0x64, 0x03, 0x62, 0x00, 0x04, 0xa1, 0x68, 0x72, 0x43, 0x36, 0x2b, 0x5c, + 0x7b, 0x18, 0x89, 0xf3, 0x79, 0x15, 0x46, 0x15, 0xa1, 0xc7, 0x3f, 0xb4, + 0x8d, 0xee, 0x86, 0x3e, 0x02, 0x29, 0x15, 0xdb, 0x60, 0x8e, 0x25, 0x2d, + 0xe4, 0xb7, 0x13, 0x2d, 0xa8, 0xce, 0x98, 0xe8, 0x31, 0x53, 0x4e, 0x6a, + 0x9c, 0x0c, 0x0b, 0x09, 0xc8, 0xd6, 0x39, 0xad, 0xe8, 0x32, 0x06, 0xe5, + 0xba, 0x81, 0x34, 0x73, 0xa1, 0x1f, 0xa3, 0x30, 0xe0, 0x5d, 0xa8, 0xc9, + 0x6e, 0x43, 0x83, 0xfe, 0x27, 0x87, 0x3d, 0xa9, 0x71, 0x03, 0xbe, 0x28, + 0x88, 0xcf, 0xf0, 0x02, 0xf0, 0x5a, 0xf7, 0x1a, 0x1f, 0xdd, 0xcc, 0x83, + 0x74, 0xaa, 0x6e, 0xa9, 0xce +]; + +#[cfg_attr(rustfmt, rustfmt_skip)] +pub const PKCS8_P521_EE: [u8; 240] = [ + 0x30, 0x81, 0xed, 0x02, 0x01, 0x00, 0x30, 0x10, 0x06, 0x07, 0x2a, 0x86, + 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23, + 0x04, 0x81, 0xd5, 0x30, 0x81, 0xd2, 0x02, 0x01, 0x01, 0x04, 0x42, 0x01, + 0x4f, 0x32, 0x84, 0xfa, 0x69, 0x8d, 0xd9, 0xfe, 0x11, 0x18, 0xdd, 0x33, + 0x18, 0x51, 0xcd, 0xfa, 0xac, 0x5a, 0x38, 0x29, 0x27, 0x8e, 0xb8, 0x99, + 0x48, 0x39, 0xde, 0x94, 0x71, 0xc9, 0x40, 0xb8, 0x58, 0xc6, 0x9d, 0x2d, + 0x05, 0xe8, 0xc0, 0x17, 0x88, 0xa7, 0xd0, 0xb6, 0xe2, 0x35, 0xaa, 0x5e, + 0x78, 0x3f, 0xc1, 0xbe, 0xe8, 0x07, 0xdc, 0xc3, 0x86, 0x5f, 0x92, 0x0e, + 0x12, 0xcf, 0x8f, 0x2d, 0x29, 0xa1, 0x81, 0x88, 0x03, 0x81, 0x85, 0x00, + 0x04, 0x18, 0x94, 0x55, 0x0d, 0x07, 0x85, 0x93, 0x2e, 0x00, 0xea, 0xa2, + 0x3b, 0x69, 0x4f, 0x21, 0x3f, 0x8c, 0x31, 0x21, 0xf8, 0x6d, 0xc9, 0x7a, + 0x04, 0xe5, 0xa7, 0x16, 0x7d, 0xb4, 0xe5, 0xbc, 0xd3, 0x71, 0x12, 0x3d, + 0x46, 0xe4, 0x5d, 0xb6, 0xb5, 0xd5, 0x37, 0x0a, 0x7f, 0x20, 0xfb, 0x63, + 0x31, 0x55, 0xd3, 0x8f, 0xfa, 0x16, 0xd2, 0xbd, 0x76, 0x1d, 0xca, 0xc4, + 0x74, 0xb9, 0xa2, 0xf5, 0x02, 0x3a, 0x40, 0x49, 0x31, 0x01, 0xc9, 0x62, + 0xcd, 0x4d, 0x2f, 0xdd, 0xf7, 0x82, 0x28, 0x5e, 0x64, 0x58, 0x41, 0x39, + 0xc2, 0xf9, 0x1b, 0x47, 0xf8, 0x7f, 0xf8, 0x23, 0x54, 0xd6, 0x63, 0x0f, + 0x74, 0x6a, 0x28, 0xa0, 0xdb, 0x25, 0x74, 0x1b, 0x5b, 0x34, 0xa8, 0x28, + 0x00, 0x8b, 0x22, 0xac, 0xc2, 0x3f, 0x92, 0x4f, 0xaa, 0xfb, 0xd4, 0xd3, + 0x3f, 0x81, 0xea, 0x66, 0x95, 0x6d, 0xfe, 0xaa, 0x2b, 0xfd, 0xfc, 0xf5 +]; + +#[cfg_attr(rustfmt, rustfmt_skip)] +pub const P521_EE: [u8; 367] = [ + 0x30, 0x82, 0x01, 0x6b, 0x30, 0x82, 0x01, 0x12, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x14, 0x49, 0xdb, 0x7d, 0xec, 0x87, 0x2b, 0x95, 0xfc, 0xfb, + 0x57, 0xfb, 0xc8, 0xd5, 0x57, 0xb7, 0x3a, 0x10, 0xcc, 0xf1, 0x7a, 0x30, + 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, + 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, + 0x69, 0x6e, 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x22, 0x18, 0x0f, + 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, 0x33, + 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x12, 0x31, 0x10, + 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x07, 0x65, 0x65, 0x2d, + 0x70, 0x35, 0x32, 0x31, 0x30, 0x81, 0x9b, 0x30, 0x10, 0x06, 0x07, 0x2a, + 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, + 0x23, 0x03, 0x81, 0x86, 0x00, 0x04, 0x01, 0x4c, 0xdc, 0x9c, 0xac, 0xc4, + 0x79, 0x41, 0x09, 0x6b, 0xc9, 0xcc, 0x66, 0x75, 0x2e, 0xc2, 0x7f, 0x59, + 0x77, 0x34, 0xfa, 0x66, 0xc6, 0x2b, 0x79, 0x2f, 0x88, 0xc5, 0x19, 0xd6, + 0xd3, 0x7f, 0x0d, 0x16, 0xea, 0x1c, 0x48, 0x3a, 0x18, 0x27, 0xa0, 0x10, + 0xb9, 0x12, 0x8e, 0x3a, 0x08, 0x07, 0x0c, 0xa3, 0x3e, 0xf5, 0xf5, 0x78, + 0x35, 0xb7, 0xc1, 0xba, 0x25, 0x1f, 0x6c, 0xc3, 0x52, 0x1d, 0xc4, 0x2b, + 0x01, 0x06, 0x53, 0x45, 0x19, 0x81, 0xb4, 0x45, 0xd3, 0x43, 0xee, 0xd3, + 0x78, 0x2a, 0x35, 0xd6, 0xcf, 0xf0, 0xff, 0x48, 0x4f, 0x5a, 0x88, 0x3d, + 0x20, 0x9f, 0x1b, 0x90, 0x42, 0xb7, 0x26, 0x70, 0x35, 0x68, 0xb2, 0xf3, + 0x26, 0xe1, 0x8b, 0x83, 0x3b, 0xdd, 0x8a, 0xa0, 0x73, 0x43, 0x92, 0xbc, + 0xd1, 0x95, 0x01, 0xe1, 0x0d, 0x69, 0x8a, 0x79, 0xf5, 0x3e, 0x11, 0xe0, + 0xa2, 0x2b, 0xdd, 0x2a, 0xad, 0x90, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, + 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x47, 0x00, 0x30, 0x44, 0x02, + 0x20, 0x5c, 0x75, 0x51, 0x9f, 0x13, 0x11, 0x50, 0xcd, 0x5d, 0x8a, 0xde, + 0x20, 0xa3, 0xbc, 0x06, 0x30, 0x91, 0xff, 0xb2, 0x73, 0x75, 0x5f, 0x31, + 0x64, 0xec, 0xfd, 0xcb, 0x42, 0x80, 0x0a, 0x70, 0xe6, 0x02, 0x20, 0x35, + 0x20, 0x7c, 0xff, 0x51, 0xf6, 0x68, 0xce, 0x1d, 0x00, 0xf9, 0xcc, 0x7f, + 0xa7, 0xbc, 0x79, 0x52, 0xea, 0x56, 0xdf, 0xc1, 0x46, 0x7c, 0x0c, 0xa1, + 0x2e, 0x32, 0xb1, 0x69, 0x4b, 0x20, 0xc4 +]; + +#[cfg_attr(rustfmt, rustfmt_skip)] +pub const P384_EE: [u8; 329] = [ + 0x30, 0x82, 0x01, 0x45, 0x30, 0x81, 0xec, 0xa0, 0x03, 0x02, 0x01, 0x02, + 0x02, 0x14, 0x79, 0xe3, 0x1c, 0x60, 0x97, 0xa4, 0x3c, 0x3b, 0x82, 0x11, + 0x42, 0x37, 0xaf, 0x57, 0x05, 0xa8, 0xde, 0xd3, 0x40, 0x58, 0x30, 0x0a, + 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x13, + 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x69, + 0x6e, 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x22, 0x18, 0x0f, 0x32, + 0x30, 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, 0x33, 0x31, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x12, 0x31, 0x10, 0x30, + 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x07, 0x65, 0x65, 0x2d, 0x70, + 0x33, 0x38, 0x34, 0x30, 0x76, 0x30, 0x10, 0x06, 0x07, 0x2a, 0x86, 0x48, + 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22, 0x03, + 0x62, 0x00, 0x04, 0xa1, 0x68, 0x72, 0x43, 0x36, 0x2b, 0x5c, 0x7b, 0x18, + 0x89, 0xf3, 0x79, 0x15, 0x46, 0x15, 0xa1, 0xc7, 0x3f, 0xb4, 0x8d, 0xee, + 0x86, 0x3e, 0x02, 0x29, 0x15, 0xdb, 0x60, 0x8e, 0x25, 0x2d, 0xe4, 0xb7, + 0x13, 0x2d, 0xa8, 0xce, 0x98, 0xe8, 0x31, 0x53, 0x4e, 0x6a, 0x9c, 0x0c, + 0x0b, 0x09, 0xc8, 0xd6, 0x39, 0xad, 0xe8, 0x32, 0x06, 0xe5, 0xba, 0x81, + 0x34, 0x73, 0xa1, 0x1f, 0xa3, 0x30, 0xe0, 0x5d, 0xa8, 0xc9, 0x6e, 0x43, + 0x83, 0xfe, 0x27, 0x87, 0x3d, 0xa9, 0x71, 0x03, 0xbe, 0x28, 0x88, 0xcf, + 0xf0, 0x02, 0xf0, 0x5a, 0xf7, 0x1a, 0x1f, 0xdd, 0xcc, 0x83, 0x74, 0xaa, + 0x6e, 0xa9, 0xce, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, + 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x20, 0x5c, 0x75, + 0x51, 0x9f, 0x13, 0x11, 0x50, 0xcd, 0x5d, 0x8a, 0xde, 0x20, 0xa3, 0xbc, + 0x06, 0x30, 0x91, 0xff, 0xb2, 0x73, 0x75, 0x5f, 0x31, 0x64, 0xec, 0xfd, + 0xcb, 0x42, 0x80, 0x0a, 0x70, 0xe6, 0x02, 0x21, 0x00, 0xf3, 0x04, 0x26, + 0xf2, 0xfd, 0xbc, 0x89, 0x3f, 0x29, 0x3b, 0x70, 0xbc, 0x72, 0xa6, 0xc2, + 0x23, 0xcc, 0x43, 0x4d, 0x84, 0x71, 0xaf, 0x53, 0xe4, 0x4b, 0x3e, 0xc0, + 0xbf, 0xe5, 0x68, 0x86, 0x49 +]; + +#[cfg_attr(rustfmt, rustfmt_skip)] +pub const P256_INT: [u8; 332] = [ + 0x30, 0x82, 0x01, 0x48, 0x30, 0x81, 0xf0, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x14, 0x43, 0x63, 0x59, 0xad, 0x04, 0x34, 0x56, 0x80, + 0x43, 0xec, 0x90, 0x6a, 0xd4, 0x10, 0x64, 0x7c, 0x7f, 0x38, 0x32, + 0xe2, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, + 0x03, 0x02, 0x30, 0x14, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0c, 0x09, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x70, 0x32, + 0x35, 0x36, 0x30, 0x22, 0x18, 0x0f, 0x32, 0x30, 0x31, 0x32, 0x30, + 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, + 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, 0x33, 0x31, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x69, 0x6e, 0x74, 0x2d, + 0x70, 0x32, 0x35, 0x36, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, + 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, + 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4f, 0xbf, + 0xbb, 0xbb, 0x61, 0xe0, 0xf8, 0xf9, 0xb1, 0xa6, 0x0a, 0x59, 0xac, + 0x87, 0x04, 0xe2, 0xec, 0x05, 0x0b, 0x42, 0x3e, 0x3c, 0xf7, 0x2e, + 0x92, 0x3f, 0x2c, 0x4f, 0x79, 0x4b, 0x45, 0x5c, 0x2a, 0x69, 0xd2, + 0x33, 0x45, 0x6c, 0x36, 0xc4, 0x11, 0x9d, 0x07, 0x06, 0xe0, 0x0e, + 0xed, 0xc8, 0xd1, 0x93, 0x90, 0xd7, 0x99, 0x1b, 0x7b, 0x2d, 0x07, + 0xa3, 0x04, 0xea, 0xa0, 0x4a, 0xa6, 0xc0, 0xa3, 0x1d, 0x30, 0x1b, + 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, + 0x01, 0x01, 0xff, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, + 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, + 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x47, 0x00, 0x30, 0x44, + 0x02, 0x20, 0x63, 0x59, 0x02, 0x01, 0x89, 0xd7, 0x3e, 0x5b, 0xff, + 0xd1, 0x16, 0x4e, 0xe3, 0xe2, 0x0a, 0xe0, 0x4a, 0xd8, 0x75, 0xaf, + 0x77, 0x5c, 0x93, 0x60, 0xba, 0x10, 0x1f, 0x97, 0xdd, 0x27, 0x2d, + 0x24, 0x02, 0x20, 0x3d, 0x87, 0x0f, 0xac, 0x22, 0x4d, 0x16, 0xd9, + 0xa1, 0x95, 0xbb, 0x56, 0xe0, 0x21, 0x05, 0x93, 0xd1, 0x07, 0xb5, + 0x25, 0x3b, 0xf4, 0x57, 0x20, 0x87, 0x13, 0xa2, 0xf7, 0x78, 0x15, + 0x30, 0xa7 +]; + +#[cfg_attr(rustfmt, rustfmt_skip)] +pub const P256_ROOT: [u8; 334] = [ + 0x30, 0x82, 0x01, 0x4a, 0x30, 0x81, 0xf1, 0xa0, 0x03, 0x02, 0x01, 0x02, + 0x02, 0x14, 0x5f, 0x3f, 0xae, 0x90, 0x49, 0x30, 0x2f, 0x33, 0x6e, 0x95, + 0x23, 0xa7, 0xcb, 0x23, 0xd7, 0x65, 0x4f, 0xea, 0x3c, 0xf7, 0x30, 0x0a, + 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x14, + 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x72, + 0x6f, 0x6f, 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x22, 0x18, 0x0f, + 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, 0x33, + 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x14, 0x31, 0x12, + 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x72, 0x6f, 0x6f, + 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, + 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4f, 0xbf, 0xbb, + 0xbb, 0x61, 0xe0, 0xf8, 0xf9, 0xb1, 0xa6, 0x0a, 0x59, 0xac, 0x87, 0x04, + 0xe2, 0xec, 0x05, 0x0b, 0x42, 0x3e, 0x3c, 0xf7, 0x2e, 0x92, 0x3f, 0x2c, + 0x4f, 0x79, 0x4b, 0x45, 0x5c, 0x2a, 0x69, 0xd2, 0x33, 0x45, 0x6c, 0x36, + 0xc4, 0x11, 0x9d, 0x07, 0x06, 0xe0, 0x0e, 0xed, 0xc8, 0xd1, 0x93, 0x90, + 0xd7, 0x99, 0x1b, 0x7b, 0x2d, 0x07, 0xa3, 0x04, 0xea, 0xa0, 0x4a, 0xa6, + 0xc0, 0xa3, 0x1d, 0x30, 0x1b, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, + 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0b, 0x06, 0x03, 0x55, + 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0a, 0x06, 0x08, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, + 0x45, 0x02, 0x20, 0x5c, 0x75, 0x51, 0x9f, 0x13, 0x11, 0x50, 0xcd, 0x5d, + 0x8a, 0xde, 0x20, 0xa3, 0xbc, 0x06, 0x30, 0x91, 0xff, 0xb2, 0x73, 0x75, + 0x5f, 0x31, 0x64, 0xec, 0xfd, 0xcb, 0x42, 0x80, 0x0a, 0x70, 0xe6, 0x02, + 0x21, 0x00, 0xc2, 0xe4, 0xc1, 0xa8, 0xe2, 0x89, 0xdc, 0xa1, 0xbb, 0xe7, + 0xd5, 0x4f, 0x5c, 0x88, 0xad, 0xeb, 0xa4, 0x78, 0xa1, 0x19, 0xbe, 0x22, + 0x54, 0xc8, 0x9f, 0xef, 0xb8, 0x5d, 0xa2, 0x40, 0xd9, 0x8b +]; + +#[cfg_attr(rustfmt, rustfmt_skip)] +pub const PKCS8_RSA_EE: [u8; 1218] = [ + 0x30, 0x82, 0x04, 0xbe, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, + 0x04, 0xa8, 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, + 0x01, 0x00, 0xba, 0x88, 0x51, 0xa8, 0x44, 0x8e, 0x16, 0xd6, 0x41, 0xfd, + 0x6e, 0xb6, 0x88, 0x06, 0x36, 0x10, 0x3d, 0x3c, 0x13, 0xd9, 0xea, 0xe4, + 0x35, 0x4a, 0xb4, 0xec, 0xf5, 0x68, 0x57, 0x6c, 0x24, 0x7b, 0xc1, 0xc7, + 0x25, 0xa8, 0xe0, 0xd8, 0x1f, 0xbd, 0xb1, 0x9c, 0x06, 0x9b, 0x6e, 0x1a, + 0x86, 0xf2, 0x6b, 0xe2, 0xaf, 0x5a, 0x75, 0x6b, 0x6a, 0x64, 0x71, 0x08, + 0x7a, 0xa5, 0x5a, 0xa7, 0x45, 0x87, 0xf7, 0x1c, 0xd5, 0x24, 0x9c, 0x02, + 0x7e, 0xcd, 0x43, 0xfc, 0x1e, 0x69, 0xd0, 0x38, 0x20, 0x29, 0x93, 0xab, + 0x20, 0xc3, 0x49, 0xe4, 0xdb, 0xb9, 0x4c, 0xc2, 0x6b, 0x6c, 0x0e, 0xed, + 0x15, 0x82, 0x0f, 0xf1, 0x7e, 0xad, 0x69, 0x1a, 0xb1, 0xd3, 0x02, 0x3a, + 0x8b, 0x2a, 0x41, 0xee, 0xa7, 0x70, 0xe0, 0x0f, 0x0d, 0x8d, 0xfd, 0x66, + 0x0b, 0x2b, 0xb0, 0x24, 0x92, 0xa4, 0x7d, 0xb9, 0x88, 0x61, 0x79, 0x90, + 0xb1, 0x57, 0x90, 0x3d, 0xd2, 0x3b, 0xc5, 0xe0, 0xb8, 0x48, 0x1f, 0xa8, + 0x37, 0xd3, 0x88, 0x43, 0xef, 0x27, 0x16, 0xd8, 0x55, 0xb7, 0x66, 0x5a, + 0xaa, 0x7e, 0x02, 0x90, 0x2f, 0x3a, 0x7b, 0x10, 0x80, 0x06, 0x24, 0xcc, + 0x1c, 0x6c, 0x97, 0xad, 0x96, 0x61, 0x5b, 0xb7, 0xe2, 0x96, 0x12, 0xc0, + 0x75, 0x31, 0xa3, 0x0c, 0x91, 0xdd, 0xb4, 0xca, 0xf7, 0xfc, 0xad, 0x1d, + 0x25, 0xd3, 0x09, 0xef, 0xb9, 0x17, 0x0e, 0xa7, 0x68, 0xe1, 0xb3, 0x7b, + 0x2f, 0x22, 0x6f, 0x69, 0xe3, 0xb4, 0x8a, 0x95, 0x61, 0x1d, 0xee, 0x26, + 0xd6, 0x25, 0x9d, 0xab, 0x91, 0x08, 0x4e, 0x36, 0xcb, 0x1c, 0x24, 0x04, + 0x2c, 0xbf, 0x16, 0x8b, 0x2f, 0xe5, 0xf1, 0x8f, 0x99, 0x17, 0x31, 0xb8, + 0xb3, 0xfe, 0x49, 0x23, 0xfa, 0x72, 0x51, 0xc4, 0x31, 0xd5, 0x03, 0xac, + 0xda, 0x18, 0x0a, 0x35, 0xed, 0x8d, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, + 0x82, 0x01, 0x01, 0x00, 0x9e, 0xcb, 0xce, 0x38, 0x61, 0xa4, 0x54, 0xec, + 0xb1, 0xe0, 0xfe, 0x8f, 0x85, 0xdd, 0x43, 0xc9, 0x2f, 0x58, 0x25, 0xce, + 0x2e, 0x99, 0x78, 0x84, 0xd0, 0xe1, 0xa9, 0x49, 0xda, 0xa2, 0xc5, 0xac, + 0x55, 0x9b, 0x24, 0x04, 0x50, 0xe5, 0xac, 0x9f, 0xe0, 0xc3, 0xe3, 0x1c, + 0x0e, 0xef, 0xa6, 0x52, 0x5a, 0x65, 0xf0, 0xc2, 0x21, 0x94, 0x00, 0x4e, + 0xe1, 0xab, 0x46, 0x3d, 0xde, 0x9e, 0xe8, 0x22, 0x87, 0xcc, 0x93, 0xe7, + 0x46, 0xa9, 0x19, 0x29, 0xc5, 0xe6, 0xac, 0x3d, 0x88, 0x75, 0x3f, 0x6c, + 0x25, 0xba, 0x59, 0x79, 0xe7, 0x3e, 0x5d, 0x8f, 0xb2, 0x39, 0x11, 0x1a, + 0x3c, 0xda, 0xb8, 0xa4, 0xb0, 0xcd, 0xf5, 0xf9, 0xca, 0xb0, 0x5f, 0x12, + 0x33, 0xa3, 0x83, 0x35, 0xc6, 0x4b, 0x55, 0x60, 0x52, 0x5e, 0x7e, 0x3b, + 0x92, 0xad, 0x7c, 0x75, 0x04, 0xcf, 0x1d, 0xc7, 0xcb, 0x00, 0x57, 0x88, + 0xaf, 0xcb, 0xe1, 0xe8, 0xf9, 0x5d, 0xf7, 0x40, 0x2a, 0x15, 0x15, 0x30, + 0xd5, 0x80, 0x83, 0x46, 0x86, 0x4e, 0xb3, 0x70, 0xaa, 0x79, 0x95, 0x6a, + 0x58, 0x78, 0x62, 0xcb, 0x53, 0x37, 0x91, 0x30, 0x7f, 0x70, 0xd9, 0x1c, + 0x96, 0xd2, 0x2d, 0x00, 0x1a, 0x69, 0x00, 0x9b, 0x92, 0x3c, 0x68, 0x33, + 0x88, 0xc9, 0xf3, 0x6c, 0xb9, 0xb5, 0xeb, 0xe6, 0x43, 0x02, 0x04, 0x1c, + 0x78, 0xd9, 0x08, 0x20, 0x6b, 0x87, 0x00, 0x9c, 0xb8, 0xca, 0xba, 0xca, + 0xd3, 0xdb, 0xdb, 0x27, 0x92, 0xfb, 0x91, 0x1b, 0x2c, 0xf4, 0xdb, 0x66, + 0x03, 0x58, 0x5b, 0xe9, 0xae, 0x0c, 0xa3, 0xb8, 0xe6, 0x41, 0x7a, 0xa0, + 0x4b, 0x06, 0xe4, 0x70, 0xea, 0x1a, 0x3b, 0x58, 0x1c, 0xa0, 0x3a, 0x67, + 0x81, 0xc9, 0x31, 0x5b, 0x62, 0xb3, 0x0e, 0x60, 0x11, 0xf2, 0x24, 0x72, + 0x59, 0x46, 0xee, 0xc5, 0x7c, 0x6d, 0x94, 0x41, 0x02, 0x81, 0x81, 0x00, + 0xdd, 0x6e, 0x1d, 0x4f, 0xff, 0xeb, 0xf6, 0x8d, 0x88, 0x9c, 0x4d, 0x11, + 0x4c, 0xda, 0xaa, 0x9c, 0xaa, 0x63, 0xa5, 0x93, 0x74, 0x28, 0x6c, 0x8a, + 0x5c, 0x29, 0xa7, 0x17, 0xbb, 0xa6, 0x03, 0x75, 0x64, 0x4d, 0x5c, 0xaa, + 0x67, 0x4c, 0x4b, 0x8b, 0xc7, 0x32, 0x63, 0x58, 0x64, 0x62, 0x20, 0xe4, + 0x55, 0x0d, 0x76, 0x08, 0xac, 0x27, 0xd5, 0x5b, 0x6d, 0xb7, 0x4f, 0x8d, + 0x81, 0x27, 0xef, 0x8f, 0xa0, 0x90, 0x98, 0xb6, 0x91, 0x47, 0xde, 0x06, + 0x55, 0x73, 0x44, 0x7e, 0x18, 0x3d, 0x22, 0xfe, 0x7d, 0x88, 0x5a, 0xce, + 0xb5, 0x13, 0xd9, 0x58, 0x1d, 0xd5, 0xe0, 0x7c, 0x1a, 0x90, 0xf5, 0xce, + 0x08, 0x79, 0xde, 0x13, 0x13, 0x71, 0xec, 0xef, 0xc9, 0xce, 0x72, 0xe9, + 0xc4, 0x3d, 0xc1, 0x27, 0xd2, 0x38, 0x19, 0x0d, 0xe8, 0x11, 0x77, 0x3c, + 0xa5, 0xd1, 0x93, 0x01, 0xf4, 0x8c, 0x74, 0x2b, 0x02, 0x81, 0x81, 0x00, + 0xd7, 0xa7, 0x73, 0xd9, 0xeb, 0xc3, 0x80, 0xa7, 0x67, 0xd2, 0xfe, 0xc0, + 0x93, 0x4a, 0xd4, 0xe8, 0xb5, 0x66, 0x72, 0x40, 0x77, 0x1a, 0xcd, 0xeb, + 0xb5, 0xad, 0x79, 0x6f, 0x47, 0x8f, 0xec, 0x4d, 0x45, 0x98, 0x5e, 0xfb, + 0xc9, 0x53, 0x29, 0x68, 0x28, 0x9c, 0x8d, 0x89, 0x10, 0x2f, 0xad, 0xf2, + 0x1f, 0x34, 0xe2, 0xdd, 0x49, 0x40, 0xeb, 0xa8, 0xc0, 0x9d, 0x6d, 0x1f, + 0x16, 0xdc, 0xc2, 0x97, 0x29, 0x77, 0x4c, 0x43, 0x27, 0x5e, 0x92, 0x51, + 0xdd, 0xbe, 0x49, 0x09, 0xe1, 0xfd, 0x3b, 0xf1, 0xe4, 0xbe, 0xdf, 0x46, + 0xa3, 0x9b, 0x8b, 0x38, 0x33, 0x28, 0xef, 0x4a, 0xe3, 0xb9, 0x5b, 0x92, + 0xf2, 0x07, 0x0a, 0xf2, 0x6c, 0x9e, 0x7c, 0x5c, 0x9b, 0x58, 0x7f, 0xed, + 0xde, 0x05, 0xe8, 0xe7, 0xd8, 0x6c, 0xa5, 0x78, 0x86, 0xfb, 0x16, 0x58, + 0x10, 0xa7, 0x7b, 0x98, 0x45, 0xbc, 0x31, 0x27, 0x02, 0x81, 0x81, 0x00, + 0x96, 0x47, 0x2b, 0x41, 0xa6, 0x10, 0xc0, 0xad, 0xe1, 0xaf, 0x22, 0x66, + 0xc1, 0x60, 0x0e, 0x36, 0x71, 0x35, 0x5b, 0xa4, 0x2d, 0x4b, 0x5a, 0x0e, + 0xb4, 0xe9, 0xd7, 0xeb, 0x35, 0x81, 0x40, 0x0b, 0xa5, 0xdd, 0x13, 0x2c, + 0xdb, 0x1a, 0x5e, 0x93, 0x28, 0xc7, 0xbb, 0xc0, 0xbb, 0xb0, 0x15, 0x5e, + 0xa1, 0x92, 0x97, 0x2e, 0xdf, 0x97, 0xd1, 0x27, 0x51, 0xd8, 0xfc, 0xf6, + 0xae, 0x57, 0x2a, 0x30, 0xb1, 0xea, 0x30, 0x9a, 0x87, 0x12, 0xdd, 0x4e, + 0x33, 0x24, 0x1d, 0xb1, 0xee, 0x45, 0x5f, 0xc0, 0x93, 0xf5, 0xbc, 0x9b, + 0x59, 0x2d, 0x75, 0x6e, 0x66, 0x21, 0x47, 0x4f, 0x32, 0xc0, 0x7a, 0xf2, + 0x2f, 0xb2, 0x75, 0xd3, 0x40, 0x79, 0x2b, 0x32, 0xba, 0x25, 0x90, 0xbb, + 0xb2, 0x61, 0xae, 0xfb, 0x95, 0xa2, 0x58, 0xee, 0xa5, 0x37, 0x65, 0x53, + 0x15, 0xbe, 0x9c, 0x24, 0xd1, 0x91, 0x99, 0x2d, 0x02, 0x81, 0x80, 0x28, + 0xb4, 0x50, 0xa7, 0xa7, 0x5a, 0x85, 0x64, 0x13, 0xb2, 0xbd, 0xa6, 0xf7, + 0xa6, 0x3e, 0x3d, 0x96, 0x4f, 0xb9, 0xec, 0xf5, 0x0e, 0x38, 0x23, 0xef, + 0x6c, 0xc8, 0xe8, 0xfa, 0x26, 0xee, 0x41, 0x3f, 0x8b, 0x9d, 0x12, 0x05, + 0x54, 0x0f, 0x12, 0xbb, 0xe7, 0xa0, 0xc7, 0x68, 0x28, 0xb7, 0xba, 0x65, + 0xad, 0x83, 0xcc, 0xa4, 0xd0, 0xfe, 0x2a, 0x22, 0x01, 0x14, 0xe1, 0xb3, + 0x5d, 0x03, 0xd5, 0xa8, 0x5b, 0xfe, 0x27, 0x06, 0xbd, 0x50, 0xfc, 0xe6, + 0xcf, 0xcd, 0xd5, 0x71, 0xb4, 0x6c, 0xa6, 0x21, 0xb8, 0xed, 0x47, 0xd6, + 0x05, 0xbb, 0xe7, 0x65, 0xb0, 0xaa, 0x4a, 0x06, 0x65, 0xac, 0x25, 0x36, + 0x4d, 0xa2, 0x01, 0x54, 0x03, 0x2e, 0x12, 0x04, 0xb8, 0x55, 0x9d, 0x3e, + 0x34, 0xfb, 0x5b, 0x17, 0x7c, 0x9a, 0x56, 0xff, 0x93, 0x51, 0x0a, 0x5a, + 0x4a, 0x62, 0x87, 0xc1, 0x51, 0xde, 0x2d, 0x02, 0x81, 0x80, 0x28, 0x06, + 0x7b, 0x93, 0x55, 0x80, 0x1d, 0x2e, 0xf5, 0x2d, 0xfa, 0x96, 0xd8, 0xad, + 0xb5, 0x89, 0x67, 0x3c, 0xf8, 0xee, 0x8a, 0x9c, 0x6f, 0xf7, 0x2a, 0xee, + 0xab, 0xe9, 0xef, 0x6b, 0xe5, 0x8a, 0x4f, 0x4a, 0xbf, 0x05, 0xf7, 0x88, + 0x94, 0x7d, 0xc8, 0x51, 0xfd, 0xaa, 0x34, 0x54, 0x21, 0x47, 0xa7, 0x1a, + 0x24, 0x6b, 0xfb, 0x05, 0x4e, 0xe7, 0x6a, 0xa3, 0x46, 0xab, 0xcd, 0x26, + 0x92, 0xcf, 0xc9, 0xe4, 0x4c, 0x51, 0xe6, 0xf0, 0x69, 0xc7, 0x35, 0xe0, + 0x73, 0xba, 0x01, 0x9f, 0x6a, 0x72, 0x14, 0x96, 0x1c, 0x91, 0xb2, 0x68, + 0x71, 0xca, 0xea, 0xbf, 0x8f, 0x06, 0x44, 0x18, 0xa0, 0x26, 0x90, 0xe3, + 0x9a, 0x8d, 0x5f, 0xf3, 0x06, 0x7b, 0x7c, 0xdb, 0x7f, 0x50, 0xb1, 0xf5, + 0x34, 0x18, 0xa7, 0x03, 0x96, 0x6c, 0x4f, 0xc7, 0x74, 0xbf, 0x74, 0x02, + 0xaf, 0x6c, 0x43, 0x24, 0x7f, 0x43 +]; + +#[cfg_attr(rustfmt, rustfmt_skip)] +pub const RSA_EE: [u8; 691] = [ + 0x30, 0x82, 0x02, 0xaf, 0x30, 0x82, 0x01, 0x99, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x14, 0x07, 0x1c, 0x3b, 0x71, 0x08, 0xbe, 0xd7, 0x9f, 0xfd, + 0xaf, 0x26, 0xb6, 0x08, 0xa3, 0x99, 0x06, 0x77, 0x69, 0x32, 0x7e, 0x30, + 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x30, 0x12, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, + 0x07, 0x69, 0x6e, 0x74, 0x2d, 0x72, 0x73, 0x61, 0x30, 0x22, 0x18, 0x0f, + 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, 0x33, + 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x11, 0x31, 0x0f, + 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x06, 0x65, 0x65, 0x2d, + 0x72, 0x73, 0x61, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, + 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, + 0xba, 0x88, 0x51, 0xa8, 0x44, 0x8e, 0x16, 0xd6, 0x41, 0xfd, 0x6e, 0xb6, + 0x88, 0x06, 0x36, 0x10, 0x3d, 0x3c, 0x13, 0xd9, 0xea, 0xe4, 0x35, 0x4a, + 0xb4, 0xec, 0xf5, 0x68, 0x57, 0x6c, 0x24, 0x7b, 0xc1, 0xc7, 0x25, 0xa8, + 0xe0, 0xd8, 0x1f, 0xbd, 0xb1, 0x9c, 0x06, 0x9b, 0x6e, 0x1a, 0x86, 0xf2, + 0x6b, 0xe2, 0xaf, 0x5a, 0x75, 0x6b, 0x6a, 0x64, 0x71, 0x08, 0x7a, 0xa5, + 0x5a, 0xa7, 0x45, 0x87, 0xf7, 0x1c, 0xd5, 0x24, 0x9c, 0x02, 0x7e, 0xcd, + 0x43, 0xfc, 0x1e, 0x69, 0xd0, 0x38, 0x20, 0x29, 0x93, 0xab, 0x20, 0xc3, + 0x49, 0xe4, 0xdb, 0xb9, 0x4c, 0xc2, 0x6b, 0x6c, 0x0e, 0xed, 0x15, 0x82, + 0x0f, 0xf1, 0x7e, 0xad, 0x69, 0x1a, 0xb1, 0xd3, 0x02, 0x3a, 0x8b, 0x2a, + 0x41, 0xee, 0xa7, 0x70, 0xe0, 0x0f, 0x0d, 0x8d, 0xfd, 0x66, 0x0b, 0x2b, + 0xb0, 0x24, 0x92, 0xa4, 0x7d, 0xb9, 0x88, 0x61, 0x79, 0x90, 0xb1, 0x57, + 0x90, 0x3d, 0xd2, 0x3b, 0xc5, 0xe0, 0xb8, 0x48, 0x1f, 0xa8, 0x37, 0xd3, + 0x88, 0x43, 0xef, 0x27, 0x16, 0xd8, 0x55, 0xb7, 0x66, 0x5a, 0xaa, 0x7e, + 0x02, 0x90, 0x2f, 0x3a, 0x7b, 0x10, 0x80, 0x06, 0x24, 0xcc, 0x1c, 0x6c, + 0x97, 0xad, 0x96, 0x61, 0x5b, 0xb7, 0xe2, 0x96, 0x12, 0xc0, 0x75, 0x31, + 0xa3, 0x0c, 0x91, 0xdd, 0xb4, 0xca, 0xf7, 0xfc, 0xad, 0x1d, 0x25, 0xd3, + 0x09, 0xef, 0xb9, 0x17, 0x0e, 0xa7, 0x68, 0xe1, 0xb3, 0x7b, 0x2f, 0x22, + 0x6f, 0x69, 0xe3, 0xb4, 0x8a, 0x95, 0x61, 0x1d, 0xee, 0x26, 0xd6, 0x25, + 0x9d, 0xab, 0x91, 0x08, 0x4e, 0x36, 0xcb, 0x1c, 0x24, 0x04, 0x2c, 0xbf, + 0x16, 0x8b, 0x2f, 0xe5, 0xf1, 0x8f, 0x99, 0x17, 0x31, 0xb8, 0xb3, 0xfe, + 0x49, 0x23, 0xfa, 0x72, 0x51, 0xc4, 0x31, 0xd5, 0x03, 0xac, 0xda, 0x18, + 0x0a, 0x35, 0xed, 0x8d, 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x0b, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x03, 0x82, + 0x01, 0x01, 0x00, 0x44, 0x92, 0xbb, 0x8e, 0x83, 0x58, 0x56, 0x2e, 0x7a, + 0x86, 0xfa, 0x1d, 0x77, 0x50, 0x3f, 0x45, 0x8d, 0x90, 0xc4, 0x62, 0x27, + 0x21, 0x96, 0x5a, 0xef, 0x51, 0x78, 0xd7, 0x7d, 0x0d, 0x02, 0x2d, 0x5a, + 0x0e, 0x3c, 0x82, 0x6f, 0x1d, 0x92, 0x87, 0xd5, 0x1a, 0x44, 0xae, 0xa7, + 0x92, 0xd1, 0x8b, 0xfa, 0x16, 0x53, 0x7f, 0xa3, 0x22, 0x96, 0x1a, 0x51, + 0x8c, 0xeb, 0xa1, 0xe6, 0xf6, 0x37, 0x11, 0xfe, 0x7d, 0x53, 0x3f, 0xae, + 0xf0, 0x6b, 0xb9, 0xb1, 0x7a, 0x73, 0x07, 0x14, 0xcf, 0x04, 0x05, 0x93, + 0x9e, 0xe3, 0xd2, 0x4d, 0x9d, 0x6d, 0x35, 0x68, 0xf9, 0x36, 0xe5, 0x10, + 0x0a, 0x36, 0xd9, 0x48, 0xb0, 0x83, 0xd0, 0xb9, 0x58, 0x74, 0x53, 0xb3, + 0xbc, 0x99, 0xab, 0xe1, 0x3e, 0xd5, 0x01, 0x8e, 0xcf, 0x3a, 0x69, 0x93, + 0x9e, 0xa7, 0x88, 0xd4, 0xad, 0x95, 0xf9, 0x2a, 0xb4, 0x7f, 0x95, 0x97, + 0x86, 0x50, 0x38, 0xb1, 0x04, 0x0a, 0xe4, 0x7a, 0xd5, 0x2d, 0x6c, 0xde, + 0x3e, 0x1a, 0x47, 0x17, 0x88, 0x63, 0x20, 0x9d, 0x21, 0x3e, 0x0c, 0x6f, + 0xfd, 0x20, 0x54, 0xd0, 0x67, 0xd2, 0x6b, 0x06, 0xfe, 0x60, 0x13, 0x42, + 0x3d, 0xb7, 0xca, 0xcb, 0xab, 0x7b, 0x5f, 0x5d, 0x01, 0x56, 0xd3, 0x99, + 0x80, 0x0f, 0xde, 0x7f, 0x3a, 0x61, 0x9c, 0xd3, 0x6b, 0x5e, 0xfe, 0xb5, + 0xfc, 0x39, 0x8b, 0x8e, 0xf0, 0x8c, 0x8b, 0x65, 0x46, 0x45, 0xff, 0x47, + 0x8f, 0xd4, 0xdd, 0xae, 0xc9, 0x72, 0xc7, 0x7f, 0x28, 0x86, 0xf1, 0xf7, + 0x6e, 0xcb, 0x86, 0x03, 0xeb, 0x0c, 0x46, 0xe5, 0xa0, 0x6b, 0xef, 0xd4, + 0x5e, 0xa4, 0x0f, 0x53, 0xe1, 0xbc, 0xb4, 0xc9, 0x37, 0x0e, 0x75, 0xdd, + 0x93, 0xe8, 0x0f, 0x18, 0x0a, 0x02, 0x83, 0x17, 0x74, 0xbb, 0x1a, 0x42, + 0x5b, 0x63, 0x2c, 0x80, 0x80, 0xa6, 0x84 +]; + +#[cfg_attr(rustfmt, rustfmt_skip)] +pub const RSA_INT: [u8; 724] = [ + 0x30, 0x82, 0x02, 0xd0, 0x30, 0x82, 0x01, 0xba, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x14, 0x07, 0x10, 0xaf, 0xc4, 0x1a, 0x3a, 0x56, 0x4f, 0xd8, + 0xc2, 0xcc, 0x46, 0xd7, 0x5b, 0xdf, 0x1c, 0x4e, 0x2f, 0x49, 0x3a, 0x30, + 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, + 0x08, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x72, 0x73, 0x61, 0x30, 0x22, 0x18, + 0x0f, 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, + 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x12, 0x31, + 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x07, 0x69, 0x6e, + 0x74, 0x2d, 0x72, 0x73, 0x61, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, + 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, + 0x01, 0x00, 0xba, 0x88, 0x51, 0xa8, 0x44, 0x8e, 0x16, 0xd6, 0x41, 0xfd, + 0x6e, 0xb6, 0x88, 0x06, 0x36, 0x10, 0x3d, 0x3c, 0x13, 0xd9, 0xea, 0xe4, + 0x35, 0x4a, 0xb4, 0xec, 0xf5, 0x68, 0x57, 0x6c, 0x24, 0x7b, 0xc1, 0xc7, + 0x25, 0xa8, 0xe0, 0xd8, 0x1f, 0xbd, 0xb1, 0x9c, 0x06, 0x9b, 0x6e, 0x1a, + 0x86, 0xf2, 0x6b, 0xe2, 0xaf, 0x5a, 0x75, 0x6b, 0x6a, 0x64, 0x71, 0x08, + 0x7a, 0xa5, 0x5a, 0xa7, 0x45, 0x87, 0xf7, 0x1c, 0xd5, 0x24, 0x9c, 0x02, + 0x7e, 0xcd, 0x43, 0xfc, 0x1e, 0x69, 0xd0, 0x38, 0x20, 0x29, 0x93, 0xab, + 0x20, 0xc3, 0x49, 0xe4, 0xdb, 0xb9, 0x4c, 0xc2, 0x6b, 0x6c, 0x0e, 0xed, + 0x15, 0x82, 0x0f, 0xf1, 0x7e, 0xad, 0x69, 0x1a, 0xb1, 0xd3, 0x02, 0x3a, + 0x8b, 0x2a, 0x41, 0xee, 0xa7, 0x70, 0xe0, 0x0f, 0x0d, 0x8d, 0xfd, 0x66, + 0x0b, 0x2b, 0xb0, 0x24, 0x92, 0xa4, 0x7d, 0xb9, 0x88, 0x61, 0x79, 0x90, + 0xb1, 0x57, 0x90, 0x3d, 0xd2, 0x3b, 0xc5, 0xe0, 0xb8, 0x48, 0x1f, 0xa8, + 0x37, 0xd3, 0x88, 0x43, 0xef, 0x27, 0x16, 0xd8, 0x55, 0xb7, 0x66, 0x5a, + 0xaa, 0x7e, 0x02, 0x90, 0x2f, 0x3a, 0x7b, 0x10, 0x80, 0x06, 0x24, 0xcc, + 0x1c, 0x6c, 0x97, 0xad, 0x96, 0x61, 0x5b, 0xb7, 0xe2, 0x96, 0x12, 0xc0, + 0x75, 0x31, 0xa3, 0x0c, 0x91, 0xdd, 0xb4, 0xca, 0xf7, 0xfc, 0xad, 0x1d, + 0x25, 0xd3, 0x09, 0xef, 0xb9, 0x17, 0x0e, 0xa7, 0x68, 0xe1, 0xb3, 0x7b, + 0x2f, 0x22, 0x6f, 0x69, 0xe3, 0xb4, 0x8a, 0x95, 0x61, 0x1d, 0xee, 0x26, + 0xd6, 0x25, 0x9d, 0xab, 0x91, 0x08, 0x4e, 0x36, 0xcb, 0x1c, 0x24, 0x04, + 0x2c, 0xbf, 0x16, 0x8b, 0x2f, 0xe5, 0xf1, 0x8f, 0x99, 0x17, 0x31, 0xb8, + 0xb3, 0xfe, 0x49, 0x23, 0xfa, 0x72, 0x51, 0xc4, 0x31, 0xd5, 0x03, 0xac, + 0xda, 0x18, 0x0a, 0x35, 0xed, 0x8d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, + 0x1d, 0x30, 0x1b, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, + 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, + 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x03, 0x82, 0x01, 0x01, 0x00, + 0x5e, 0xba, 0x69, 0x55, 0x9f, 0xf8, 0xeb, 0x16, 0x21, 0x98, 0xde, 0xb7, + 0x31, 0x3e, 0x66, 0xe1, 0x3b, 0x0c, 0x29, 0xf7, 0x48, 0x73, 0x05, 0xd9, + 0xce, 0x5e, 0x4c, 0xbe, 0x03, 0xc4, 0x51, 0xd6, 0x21, 0x92, 0x40, 0x38, + 0xaa, 0x5b, 0x28, 0xb5, 0xa1, 0x10, 0x52, 0x57, 0xff, 0x91, 0x54, 0x82, + 0x86, 0x9e, 0x74, 0xd5, 0x3d, 0x82, 0x29, 0xee, 0xd1, 0xcf, 0x93, 0xb1, + 0x24, 0x76, 0xbb, 0x95, 0x41, 0x06, 0x7e, 0x40, 0x9b, 0xb4, 0xab, 0x44, + 0x34, 0x10, 0x8f, 0xb1, 0x51, 0x6f, 0xc0, 0x89, 0xd1, 0xa3, 0xc4, 0x9f, + 0xb3, 0x48, 0xe1, 0xcd, 0x73, 0xad, 0xff, 0x42, 0x5f, 0x76, 0x05, 0x60, + 0xc5, 0xe0, 0x45, 0x79, 0x18, 0xa1, 0x19, 0xb8, 0xa7, 0x3a, 0x64, 0xb3, + 0x19, 0xba, 0x14, 0xa1, 0xb5, 0xdc, 0x32, 0xec, 0x09, 0x39, 0x58, 0x54, + 0x5b, 0x04, 0xdc, 0x1b, 0x66, 0x0d, 0x1d, 0x0d, 0xce, 0x7f, 0xfa, 0x24, + 0x52, 0x6a, 0xad, 0xe2, 0xc8, 0x30, 0xaf, 0xf2, 0xaf, 0x63, 0xc5, 0xe2, + 0xbf, 0xe2, 0x20, 0x1b, 0x9e, 0xf9, 0x3d, 0xbc, 0xfb, 0x04, 0x8e, 0xda, + 0x7a, 0x1a, 0x5d, 0xd3, 0x13, 0xd7, 0x00, 0x8e, 0x9b, 0x5d, 0x85, 0x51, + 0xda, 0xd3, 0x91, 0x25, 0xf5, 0x67, 0x85, 0x3e, 0x25, 0x89, 0x5e, 0xcb, + 0x89, 0x8a, 0xec, 0x8a, 0xde, 0x8b, 0xf4, 0x33, 0x5f, 0x76, 0xdb, 0x3d, + 0xfc, 0x6a, 0x05, 0x21, 0x43, 0xb2, 0x41, 0xd8, 0x33, 0x8d, 0xfd, 0x05, + 0x5c, 0x22, 0x0a, 0xf6, 0x90, 0x65, 0x9c, 0x4f, 0x8c, 0x44, 0x9f, 0x2d, + 0xca, 0xf3, 0x49, 0x9c, 0x3a, 0x14, 0x88, 0xab, 0xe4, 0xce, 0xb7, 0xbc, + 0x95, 0x22, 0x2e, 0xb1, 0x82, 0x4c, 0xbf, 0x83, 0x3e, 0x49, 0x72, 0x03, + 0x2a, 0x68, 0xe7, 0x2d, 0xe5, 0x2d, 0x4b, 0x61, 0xb0, 0x8d, 0x0d, 0x0c, + 0x87, 0xc6, 0x5c, 0x51 +]; + +#[cfg_attr(rustfmt, rustfmt_skip)] +pub const RSA_ROOT: [u8; 725] = [ + 0x30, 0x82, 0x02, 0xd1, 0x30, 0x82, 0x01, 0xbb, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x14, 0x29, 0x6c, 0x1a, 0xd8, 0x20, 0xcd, 0x74, 0x6d, 0x4b, + 0x00, 0xf3, 0x16, 0x88, 0xd9, 0x66, 0x87, 0x5f, 0x28, 0x56, 0x6a, 0x30, + 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, + 0x08, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x72, 0x73, 0x61, 0x30, 0x22, 0x18, + 0x0f, 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, + 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x13, 0x31, + 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x72, 0x6f, + 0x6f, 0x74, 0x2d, 0x72, 0x73, 0x61, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, + 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, + 0x01, 0x01, 0x00, 0xba, 0x88, 0x51, 0xa8, 0x44, 0x8e, 0x16, 0xd6, 0x41, + 0xfd, 0x6e, 0xb6, 0x88, 0x06, 0x36, 0x10, 0x3d, 0x3c, 0x13, 0xd9, 0xea, + 0xe4, 0x35, 0x4a, 0xb4, 0xec, 0xf5, 0x68, 0x57, 0x6c, 0x24, 0x7b, 0xc1, + 0xc7, 0x25, 0xa8, 0xe0, 0xd8, 0x1f, 0xbd, 0xb1, 0x9c, 0x06, 0x9b, 0x6e, + 0x1a, 0x86, 0xf2, 0x6b, 0xe2, 0xaf, 0x5a, 0x75, 0x6b, 0x6a, 0x64, 0x71, + 0x08, 0x7a, 0xa5, 0x5a, 0xa7, 0x45, 0x87, 0xf7, 0x1c, 0xd5, 0x24, 0x9c, + 0x02, 0x7e, 0xcd, 0x43, 0xfc, 0x1e, 0x69, 0xd0, 0x38, 0x20, 0x29, 0x93, + 0xab, 0x20, 0xc3, 0x49, 0xe4, 0xdb, 0xb9, 0x4c, 0xc2, 0x6b, 0x6c, 0x0e, + 0xed, 0x15, 0x82, 0x0f, 0xf1, 0x7e, 0xad, 0x69, 0x1a, 0xb1, 0xd3, 0x02, + 0x3a, 0x8b, 0x2a, 0x41, 0xee, 0xa7, 0x70, 0xe0, 0x0f, 0x0d, 0x8d, 0xfd, + 0x66, 0x0b, 0x2b, 0xb0, 0x24, 0x92, 0xa4, 0x7d, 0xb9, 0x88, 0x61, 0x79, + 0x90, 0xb1, 0x57, 0x90, 0x3d, 0xd2, 0x3b, 0xc5, 0xe0, 0xb8, 0x48, 0x1f, + 0xa8, 0x37, 0xd3, 0x88, 0x43, 0xef, 0x27, 0x16, 0xd8, 0x55, 0xb7, 0x66, + 0x5a, 0xaa, 0x7e, 0x02, 0x90, 0x2f, 0x3a, 0x7b, 0x10, 0x80, 0x06, 0x24, + 0xcc, 0x1c, 0x6c, 0x97, 0xad, 0x96, 0x61, 0x5b, 0xb7, 0xe2, 0x96, 0x12, + 0xc0, 0x75, 0x31, 0xa3, 0x0c, 0x91, 0xdd, 0xb4, 0xca, 0xf7, 0xfc, 0xad, + 0x1d, 0x25, 0xd3, 0x09, 0xef, 0xb9, 0x17, 0x0e, 0xa7, 0x68, 0xe1, 0xb3, + 0x7b, 0x2f, 0x22, 0x6f, 0x69, 0xe3, 0xb4, 0x8a, 0x95, 0x61, 0x1d, 0xee, + 0x26, 0xd6, 0x25, 0x9d, 0xab, 0x91, 0x08, 0x4e, 0x36, 0xcb, 0x1c, 0x24, + 0x04, 0x2c, 0xbf, 0x16, 0x8b, 0x2f, 0xe5, 0xf1, 0x8f, 0x99, 0x17, 0x31, + 0xb8, 0xb3, 0xfe, 0x49, 0x23, 0xfa, 0x72, 0x51, 0xc4, 0x31, 0xd5, 0x03, + 0xac, 0xda, 0x18, 0x0a, 0x35, 0xed, 0x8d, 0x02, 0x03, 0x01, 0x00, 0x01, + 0xa3, 0x1d, 0x30, 0x1b, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, + 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, + 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0b, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x03, 0x82, 0x01, 0x01, + 0x00, 0x23, 0x2f, 0x9f, 0x72, 0xeb, 0x70, 0x6d, 0x9e, 0x3e, 0x9f, 0xd7, + 0x9c, 0xd9, 0x19, 0x7c, 0x99, 0x07, 0xc5, 0x5c, 0x9d, 0xf5, 0x66, 0x9f, + 0x28, 0x8d, 0xfe, 0x0e, 0x3f, 0x38, 0x75, 0xed, 0xee, 0x4e, 0x3f, 0xf6, + 0x6e, 0x35, 0xe0, 0x95, 0x3f, 0x08, 0x4a, 0x71, 0x5a, 0xf2, 0x4f, 0xc9, + 0x96, 0x61, 0x8d, 0x45, 0x4b, 0x97, 0x85, 0xff, 0xb0, 0xe3, 0xbb, 0xb5, + 0xd7, 0x7e, 0xfb, 0xd2, 0xfc, 0xec, 0xfe, 0x42, 0x9f, 0x4e, 0x7b, 0xbf, + 0x97, 0xbb, 0xb4, 0x3a, 0x93, 0x0b, 0x13, 0x61, 0x90, 0x0c, 0x3a, 0xce, + 0xf7, 0x8e, 0xef, 0x80, 0xf5, 0x4a, 0x92, 0xc5, 0xa5, 0x03, 0x78, 0xc2, + 0xee, 0xb8, 0x66, 0x60, 0x6b, 0x76, 0x4f, 0x32, 0x5a, 0x1a, 0xa2, 0x4b, + 0x7e, 0x2b, 0xa6, 0x1a, 0x89, 0x01, 0xe3, 0xbb, 0x55, 0x13, 0x7c, 0x4c, + 0xf4, 0x6a, 0x99, 0x94, 0xd1, 0xa0, 0x84, 0x1c, 0x1a, 0xc2, 0x7b, 0xb4, + 0xa0, 0xb0, 0x3b, 0xdc, 0x5a, 0x7b, 0xc7, 0xe0, 0x44, 0xb2, 0x1f, 0x46, + 0xd5, 0x8b, 0x39, 0x8b, 0xdc, 0x9e, 0xce, 0xa8, 0x7f, 0x85, 0x1d, 0x4b, + 0x63, 0x06, 0x1e, 0x8e, 0xe5, 0xe5, 0x99, 0xd9, 0xf7, 0x4d, 0x89, 0x0b, + 0x1d, 0x5c, 0x27, 0x33, 0x66, 0x21, 0xcf, 0x9a, 0xbd, 0x98, 0x68, 0x23, + 0x3a, 0x66, 0x9d, 0xd4, 0x46, 0xed, 0x63, 0x58, 0xf3, 0x42, 0xe4, 0x1d, + 0xe2, 0x47, 0x65, 0x13, 0x8d, 0xd4, 0x1f, 0x4b, 0x7e, 0xde, 0x11, 0x56, + 0xf8, 0x6d, 0x01, 0x0c, 0x99, 0xbd, 0x8d, 0xca, 0x8a, 0x2e, 0xe3, 0x8a, + 0x9c, 0x3d, 0x83, 0x8d, 0x69, 0x62, 0x8d, 0x05, 0xea, 0xb7, 0xf5, 0xa3, + 0x4b, 0xfc, 0x96, 0xcf, 0x18, 0x21, 0x0a, 0xc7, 0xf3, 0x23, 0x7e, 0x1c, + 0xab, 0xe2, 0xa2, 0xd1, 0x83, 0xc4, 0x25, 0x93, 0x37, 0x80, 0xca, 0xda, + 0xf0, 0xef, 0x7d, 0x94, 0xb5 +]; + +#[cfg_attr(rustfmt, rustfmt_skip)] +pub const XPI_SIGNATURE: [u8; 646] = [ + 0xd8, 0x62, 0x84, 0x43, 0xa1, 0x04, 0x80, 0xa0, 0xf6, 0x81, 0x83, 0x59, + 0x02, 0x35, 0xa2, 0x01, 0x26, 0x04, 0x59, 0x02, 0x2e, 0x30, 0x82, 0x02, + 0x2a, 0x30, 0x82, 0x01, 0x12, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, + 0x17, 0x03, 0x6b, 0xc1, 0xfe, 0xb4, 0x38, 0xe1, 0x83, 0x8f, 0xe5, 0xa7, + 0xca, 0xf1, 0x54, 0x32, 0x4c, 0x8b, 0xf3, 0x05, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, + 0x29, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1e, + 0x78, 0x70, 0x63, 0x73, 0x68, 0x65, 0x6c, 0x6c, 0x20, 0x73, 0x69, 0x67, + 0x6e, 0x65, 0x64, 0x20, 0x61, 0x70, 0x70, 0x73, 0x20, 0x74, 0x65, 0x73, + 0x74, 0x20, 0x72, 0x6f, 0x6f, 0x74, 0x30, 0x22, 0x18, 0x0f, 0x32, 0x30, + 0x31, 0x35, 0x31, 0x31, 0x32, 0x38, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x31, 0x38, 0x30, 0x32, 0x30, 0x35, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x2b, 0x31, 0x29, 0x30, 0x27, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x20, 0x20, 0x78, 0x70, 0x63, 0x73, + 0x68, 0x65, 0x6c, 0x6c, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, + 0x61, 0x70, 0x70, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x73, 0x69, 0x67, + 0x6e, 0x65, 0x72, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, + 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, + 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4f, 0xbf, 0xbb, 0xbb, 0x61, 0xe0, + 0xf8, 0xf9, 0xb1, 0xa6, 0x0a, 0x59, 0xac, 0x87, 0x04, 0xe2, 0xec, 0x05, + 0x0b, 0x42, 0x3e, 0x3c, 0xf7, 0x2e, 0x92, 0x3f, 0x2c, 0x4f, 0x79, 0x4b, + 0x45, 0x5c, 0x2a, 0x69, 0xd2, 0x33, 0x45, 0x6c, 0x36, 0xc4, 0x11, 0x9d, + 0x07, 0x06, 0xe0, 0x0e, 0xed, 0xc8, 0xd1, 0x93, 0x90, 0xd7, 0x99, 0x1b, + 0x7b, 0x2d, 0x07, 0xa3, 0x04, 0xea, 0xa0, 0x4a, 0xa6, 0xc0, 0xa3, 0x0f, + 0x30, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, + 0x02, 0x07, 0x80, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x4f, + 0x5c, 0xcb, 0x1d, 0xea, 0x71, 0x58, 0xfe, 0xe2, 0x49, 0x11, 0x16, 0x65, + 0xbc, 0x23, 0x6d, 0xda, 0x46, 0x7e, 0x98, 0x93, 0x5d, 0x48, 0x2a, 0xa0, + 0xbb, 0x7f, 0x4e, 0xbd, 0x01, 0x0a, 0x1a, 0x30, 0xff, 0xce, 0x03, 0xf5, + 0x9c, 0xd9, 0x84, 0x69, 0x7a, 0x5a, 0xe3, 0x43, 0xd2, 0xd4, 0xbc, 0xab, + 0x4d, 0x17, 0x8f, 0x10, 0x6a, 0xcf, 0xde, 0x17, 0x1d, 0x7d, 0x16, 0x03, + 0x7e, 0x21, 0xf0, 0x32, 0x02, 0x89, 0x67, 0x32, 0x5a, 0xfe, 0xd5, 0xd9, + 0x31, 0x53, 0xdc, 0xd7, 0xba, 0x2a, 0x9f, 0xd3, 0x59, 0x8d, 0x61, 0xb9, + 0x6e, 0xf7, 0x6e, 0x86, 0x61, 0xdd, 0xfd, 0xe1, 0x73, 0xfe, 0xef, 0x9d, + 0xe9, 0x99, 0x9e, 0x51, 0xe8, 0x5d, 0xf7, 0x48, 0x77, 0x8e, 0xc6, 0xe8, + 0x53, 0x05, 0x7b, 0x5c, 0x2c, 0x28, 0xe7, 0x0a, 0x07, 0xbf, 0xea, 0xc1, + 0x06, 0x11, 0x0d, 0xe7, 0x60, 0xd0, 0x79, 0x94, 0xe9, 0x26, 0xf1, 0x93, + 0x71, 0x7b, 0x5b, 0x02, 0x3b, 0x5d, 0x51, 0xb8, 0x19, 0x38, 0x16, 0xab, + 0x48, 0x30, 0xf3, 0xec, 0xd9, 0xd5, 0x8f, 0xc7, 0x9a, 0x02, 0xfd, 0x12, + 0x57, 0x82, 0x0e, 0xde, 0xce, 0xfc, 0x50, 0x42, 0x2a, 0x41, 0xc7, 0xc6, + 0xa8, 0x80, 0x37, 0x7c, 0xc4, 0x47, 0xad, 0xf5, 0xd8, 0xcb, 0xe8, 0xae, + 0x0c, 0x01, 0x80, 0x60, 0x35, 0x93, 0x0a, 0x21, 0x81, 0x33, 0xd1, 0xd6, + 0x6a, 0x1b, 0xe7, 0xb6, 0xd9, 0x91, 0x50, 0xc2, 0xbd, 0x16, 0xda, 0xb7, + 0x68, 0x60, 0xf2, 0x20, 0xaa, 0x72, 0x8c, 0x76, 0x0a, 0x54, 0x7a, 0x05, + 0xd8, 0xa1, 0xcd, 0xe9, 0x07, 0x8a, 0x02, 0x07, 0x4b, 0x87, 0x7d, 0xb5, + 0x27, 0xca, 0x38, 0xb3, 0x30, 0xaf, 0x97, 0xe0, 0xb7, 0x35, 0x14, 0x08, + 0xab, 0x01, 0xb0, 0x14, 0x08, 0x5c, 0x4b, 0xfb, 0x76, 0x0a, 0x95, 0xfc, + 0xb4, 0xb8, 0x34, 0xa0, 0x58, 0x40, 0x5c, 0x75, 0x51, 0x9f, 0x13, 0x11, + 0x50, 0xcd, 0x5d, 0x8a, 0xde, 0x20, 0xa3, 0xbc, 0x06, 0x30, 0x91, 0xff, + 0xb2, 0x73, 0x75, 0x5f, 0x31, 0x64, 0xec, 0xfd, 0xcb, 0x42, 0x80, 0x0a, + 0x70, 0xe6, 0x82, 0x02, 0x0a, 0xe8, 0x69, 0x13, 0xd5, 0xf4, 0x1b, 0xab, + 0xb6, 0xbb, 0x59, 0x93, 0x08, 0x48, 0x68, 0x9c, 0xbd, 0x72, 0xc7, 0xcb, + 0x37, 0xde, 0x26, 0xbc, 0xe9, 0x83, 0x0e, 0xd8, 0x90, 0xa3 +]; + +#[cfg_attr(rustfmt, rustfmt_skip)] +pub const XPI_PAYLOAD: [u8; 236] = [ + 0x4E, 0x61, 0x6D, 0x65, 0x3A, 0x20, 0x6D, 0x61, 0x6E, 0x69, 0x66, 0x65, + 0x73, 0x74, 0x2E, 0x6A, 0x73, 0x6F, 0x6E, 0x0A, 0x53, 0x48, 0x41, 0x32, + 0x35, 0x36, 0x2D, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x3A, 0x20, 0x42, + 0x54, 0x6E, 0x43, 0x70, 0x54, 0x31, 0x35, 0x34, 0x4E, 0x32, 0x36, 0x52, + 0x5A, 0x6D, 0x38, 0x62, 0x68, 0x64, 0x44, 0x34, 0x33, 0x57, 0x58, 0x64, + 0x30, 0x74, 0x6A, 0x35, 0x62, 0x67, 0x36, 0x6F, 0x66, 0x4D, 0x31, 0x39, + 0x4E, 0x4C, 0x49, 0x30, 0x4F, 0x45, 0x3D, 0x0A, 0x0A, 0x4E, 0x61, 0x6D, + 0x65, 0x3A, 0x20, 0x52, 0x45, 0x41, 0x44, 0x4D, 0x45, 0x0A, 0x53, 0x48, + 0x41, 0x32, 0x35, 0x36, 0x2D, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x3A, + 0x20, 0x62, 0x59, 0x30, 0x6C, 0x39, 0x78, 0x71, 0x47, 0x4A, 0x59, 0x43, + 0x70, 0x71, 0x59, 0x65, 0x4A, 0x30, 0x4B, 0x36, 0x71, 0x34, 0x44, 0x57, + 0x55, 0x51, 0x71, 0x75, 0x30, 0x6D, 0x4E, 0x42, 0x46, 0x4D, 0x34, 0x48, + 0x34, 0x65, 0x6D, 0x68, 0x6A, 0x69, 0x4A, 0x67, 0x3D, 0x0A, 0x0A, 0x4E, + 0x61, 0x6D, 0x65, 0x3A, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2F, 0x69, 0x6D, + 0x61, 0x67, 0x65, 0x2E, 0x70, 0x6E, 0x67, 0x0A, 0x53, 0x48, 0x41, 0x32, + 0x35, 0x36, 0x2D, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x3A, 0x20, 0x45, + 0x50, 0x6A, 0x6B, 0x4E, 0x5A, 0x77, 0x79, 0x61, 0x39, 0x58, 0x2B, 0x70, + 0x72, 0x75, 0x4C, 0x6C, 0x78, 0x47, 0x2B, 0x46, 0x41, 0x43, 0x4C, 0x77, + 0x47, 0x43, 0x34, 0x38, 0x58, 0x55, 0x34, 0x53, 0x39, 0x6F, 0x5A, 0x4F, + 0x41, 0x30, 0x6C, 0x56, 0x56, 0x51, 0x3D, 0x0A +]; diff --git a/third_party/rust/cose/examples/sign_verify/util_test.rs b/third_party/rust/cose/examples/sign_verify/util_test.rs new file mode 100644 index 0000000000..c4dd26091a --- /dev/null +++ b/third_party/rust/cose/examples/sign_verify/util_test.rs @@ -0,0 +1,194 @@ +/// We don't need COSE signing at the moment. But we need to generate test files. +/// This module implements basic COSE signing. +use nss; +use {CoseError, Signature, SignatureAlgorithm, SignatureParameters}; +use std::collections::BTreeMap; +use cbor::CborType; +use cose::util::get_sig_struct_bytes; +use cose::decoder::decode_signature; +use cose::decoder::{COSE_TYPE_ES256, COSE_TYPE_ES384, COSE_TYPE_ES512, COSE_TYPE_PS256}; + +/// Converts a `SignatureAlgorithm` to its corresponding `CborType`. +/// See RFC 8152 section 8.1 and RFC 8230 section 5.1. +pub fn signature_type_to_cbor_value(signature_type: &SignatureAlgorithm) -> CborType { + CborType::SignedInteger(match signature_type { + &SignatureAlgorithm::ES256 => COSE_TYPE_ES256, + &SignatureAlgorithm::ES384 => COSE_TYPE_ES384, + &SignatureAlgorithm::ES512 => COSE_TYPE_ES512, + &SignatureAlgorithm::PS256 => COSE_TYPE_PS256, + }) +} + +pub fn build_protected_sig_header(ee_cert: &[u8], alg: &SignatureAlgorithm) -> CborType { + // Protected signature header + let mut header_map: BTreeMap<CborType, CborType> = BTreeMap::new(); + + // Signature type. + let signature_type_value = signature_type_to_cbor_value(alg); + header_map.insert(CborType::Integer(1), signature_type_value); + + // Signer certificate. + header_map.insert(CborType::Integer(4), CborType::Bytes(ee_cert.to_vec())); + + let header_map = CborType::Map(header_map).serialize(); + CborType::Bytes(header_map) +} + +pub fn build_protected_header(cert_chain: &[&[u8]]) -> CborType { + let mut cert_array: Vec<CborType> = Vec::new(); + for cert in cert_chain { + cert_array.push(CborType::Bytes(cert.to_vec())); + } + let mut protected_body_header: BTreeMap<CborType, CborType> = BTreeMap::new(); + protected_body_header.insert(CborType::Integer(4), CborType::Array(cert_array)); + let protected_body_header = CborType::Map(protected_body_header).serialize(); + + CborType::Bytes(protected_body_header) +} + +pub fn build_sig_struct(ee_cert: &[u8], alg: &SignatureAlgorithm, sig_bytes: &Vec<u8>) -> CborType { + // Build the signature item. + let mut signature_item: Vec<CborType> = Vec::new(); + + // Protected signature header + signature_item.push(build_protected_sig_header(ee_cert, alg)); + + // The unprotected signature header is empty. + let empty_map: BTreeMap<CborType, CborType> = BTreeMap::new(); + signature_item.push(CborType::Map(empty_map)); + + // And finally the signature bytes. + signature_item.push(CborType::Bytes(sig_bytes.clone())); + CborType::Array(signature_item) +} + +// 98( +// [ +// / protected / h'..', / { +// \ kid \ 4:'..' \ Array of DER encoded intermediate certificates \ +// } / , +// / unprotected / {}, +// / payload / nil, / The payload is the contents of the manifest file / +// / signatures / [ +// [ +// / protected / h'a2012604..' / { +// \ alg \ 1:-7, \ ECDSA with SHA-256 \ +// \ kid \ 4:'..' \ DER encoded signing certificate \ +// } / , +// / unprotected / {}, +// / signature / h'e2ae..' +// ], +// [ +// / protected / h'a201382404..' / { +// \ alg \ 1:-37, \ RSASSA-PSS with SHA-256 \ +// \ kid \ 4:'..' \ DER encoded signing certificate \ +// } / , +// / unprotected / {}, +// / signature / h'00a2..' +// ] +// ] +// ] +pub fn build_cose_signature(cert_chain: &[&[u8]], signature_vec: &Vec<Signature>) -> Vec<u8> { + // Building the COSE signature content. + let mut cose_signature: Vec<CborType> = Vec::new(); + + // add cert chain as protected header + cose_signature.push(build_protected_header(cert_chain)); + + // Empty map (unprotected header) + let empty_map: BTreeMap<CborType, CborType> = BTreeMap::new(); + cose_signature.push(CborType::Map(empty_map)); + + // No payload (nil). + cose_signature.push(CborType::Null); + + // Create signature items. + let mut signatures: Vec<CborType> = Vec::new(); + for signature in signature_vec { + let signature_item = build_sig_struct( + signature.parameter.certificate, + &signature.parameter.algorithm, + &signature.signature_bytes, + ); + signatures.push(signature_item); + } + + // Pack the signature item and add everything to the cose signature object. + cose_signature.push(CborType::Array(signatures)); + + // A COSE signature is a tagged array (98). + let signature_struct = CborType::Tag(98, Box::new(CborType::Array(cose_signature).clone())); + + return signature_struct.serialize(); +} + +pub fn sign( + payload: &[u8], + cert_chain: &[&[u8]], + parameters: &Vec<SignatureParameters>, +) -> Result<Vec<u8>, CoseError> { + assert!(parameters.len() > 0); + if parameters.len() < 1 { + return Err(CoseError::InvalidArgument); + } + + let mut signatures: Vec<Signature> = Vec::new(); + for param in parameters { + // Build the signature structure containing the protected headers and the + // payload to generate the payload that is actually signed. + let protected_sig_header_serialized = + build_protected_sig_header(param.certificate, ¶m.algorithm); + let protected_header_serialized = build_protected_header(cert_chain); + let payload = get_sig_struct_bytes( + protected_header_serialized, + protected_sig_header_serialized, + payload, + ); + + let signature_bytes = match nss::sign(¶m.algorithm, ¶m.pkcs8, &payload) { + Err(_) => return Err(CoseError::SigningFailed), + Ok(signature) => signature, + }; + let signature = Signature { + parameter: param, + signature_bytes: signature_bytes, + }; + signatures.push(signature); + } + + assert!(signatures.len() > 0); + if signatures.len() < 1 { + return Err(CoseError::MalformedInput); + } + + let cose_signature = build_cose_signature(cert_chain, &signatures); + Ok(cose_signature) +} + +/// Verify a COSE signature. +pub fn verify_signature(payload: &[u8], cose_signature: Vec<u8>) -> Result<(), CoseError> { + // Parse COSE signature. + let cose_signatures = decode_signature(&cose_signature, payload)?; + if cose_signatures.len() < 1 { + return Err(CoseError::MalformedInput); + } + + for signature in cose_signatures { + let signature_algorithm = &signature.signature_type; + let signature_bytes = &signature.signature; + let real_payload = &signature.to_verify; + + // Verify the parsed signatures. + // We ignore the certs field here because we don't verify the certificate. + let verify_result = nss::verify_signature( + &signature_algorithm, + &signature.signer_cert, + real_payload, + signature_bytes, + ); + if !verify_result.is_ok() { + return Err(CoseError::VerificationFailed); + } + } + Ok(()) +} diff --git a/third_party/rust/cose/rustfmt.toml b/third_party/rust/cose/rustfmt.toml new file mode 100644 index 0000000000..a47e18ea00 --- /dev/null +++ b/third_party/rust/cose/rustfmt.toml @@ -0,0 +1,4 @@ +array_layout = "Visual" +array_width = 0 +reorder_imported_names = true +array_horizontal_layout_threshold = 0 diff --git a/third_party/rust/cose/src/cose.rs b/third_party/rust/cose/src/cose.rs new file mode 100644 index 0000000000..d55dda8d16 --- /dev/null +++ b/third_party/rust/cose/src/cose.rs @@ -0,0 +1,72 @@ +//! This crate implements [COSE](https://tools.ietf.org/html/rfc8152) signature +//! parsing. Verification has to be performed by the caller. +//! +//! Example usage: Let `payload` and `cose_signature` be variables holding the +//! signed payload and the COSE signature bytes respectively. +//! Let further `verify_callback` be a function callback that implements +//! signature verification. +//! +//!```rust,ignore +//! use cose::decoder::decode_signature; +//! +//! // Parse the incoming signature. +//! let cose_signatures = decode_signature(cose_signature, &payload); +//! let cose_signatures = match cose_signatures { +//! Ok(signature) => signature, +//! Err(_) => Vec::new(), +//! }; +//! if cose_signatures.len() < 1 { +//! return false; +//! } +//! +//! let mut result = true; +//! for cose_signature in cose_signatures { +//! // Call callback to verify the parsed signatures. +//! result &= verify_callback(cose_signature); +//! +//! // We can stop early. The cose_signature is not valid. +//! if !result { +//! return result; +//! } +//! } +//!``` +extern crate moz_cbor as cbor; + +pub mod decoder; +pub mod util; + +/// Errors that can be returned from COSE functions. +#[derive(Debug, PartialEq)] +pub enum CoseError { + DecodingFailure, + LibraryFailure, + MalformedInput, + MissingHeader, + UnexpectedHeaderValue, + UnexpectedTag, + UnexpectedType, + Unimplemented, + VerificationFailed, + UnknownSignatureScheme, + SigningFailed, + InvalidArgument, +} + +/// An enum identifying supported signature algorithms. +/// Currently ES256 (ECDSA with P256 and SHA256), ES384 (ECDSA with P384 and SHA384) +/// ES512 (ECDSA with P521 and SHA512), and PS256 (RSASSA-PSS with SHA256) +/// are supported. Note that with PS256, the salt length is defined +/// to be 32 bytes. +#[derive(Debug)] +#[derive(PartialEq)] +pub enum SignatureAlgorithm { + ES256, + ES384, + ES512, + PS256, +} + +#[cfg(test)] +mod test_setup; +#[cfg(test)] +mod test_cose; diff --git a/third_party/rust/cose/src/decoder.rs b/third_party/rust/cose/src/decoder.rs new file mode 100644 index 0000000000..90463d5dd2 --- /dev/null +++ b/third_party/rust/cose/src/decoder.rs @@ -0,0 +1,235 @@ +//! Parse and decode COSE signatures. + +use cbor::CborType; +use cbor::decoder::decode; +use {CoseError, SignatureAlgorithm}; +use util::get_sig_struct_bytes; +use std::collections::BTreeMap; + +pub const COSE_SIGN_TAG: u64 = 98; + +/// The result of `decode_signature` holding a decoded COSE signature. +#[derive(Debug)] +pub struct CoseSignature { + pub signature_type: SignatureAlgorithm, + pub signature: Vec<u8>, + pub signer_cert: Vec<u8>, + pub certs: Vec<Vec<u8>>, + pub to_verify: Vec<u8>, +} + +pub const COSE_TYPE_ES256: i64 = -7; +pub const COSE_TYPE_ES384: i64 = -35; +pub const COSE_TYPE_ES512: i64 = -36; +pub const COSE_TYPE_PS256: i64 = -37; + +pub const COSE_HEADER_ALG: u64 = 1; +pub const COSE_HEADER_KID: u64 = 4; + +macro_rules! unpack { + ($to:tt, $var:ident) => ( + match *$var { + CborType::$to(ref cbor_object) => { + cbor_object + } + _ => return Err(CoseError::UnexpectedType), + }; + ) +} + +fn get_map_value( + map: &BTreeMap<CborType, CborType>, + key: &CborType, +) -> Result<CborType, CoseError> { + match map.get(key) { + Some(x) => Ok(x.clone()), + _ => Err(CoseError::MissingHeader), + } +} + +/// Ensure that the referenced `CborType` is an empty map. +fn ensure_empty_map(map: &CborType) -> Result<(), CoseError> { + let unpacked = unpack!(Map, map); + if !unpacked.is_empty() { + return Err(CoseError::MalformedInput); + } + Ok(()) +} + +// This syntax is a little unintuitive. Taken together, the two previous definitions essentially +// mean: +// +// COSE_Sign = [ +// protected : empty_or_serialized_map, +// unprotected : header_map +// payload : bstr / nil, +// signatures : [+ COSE_Signature] +// ] +// +// (COSE_Sign is an array. The first element is an empty or serialized map (in our case, it is +// never expected to be empty). The second element is a map (it is expected to be empty. The third +// element is a bstr or nil (it is expected to be nil). The fourth element is an array of +// COSE_Signature.) +// +// COSE_Signature = [ +// Headers, +// signature : bstr +// ] +// +// but again, unpacking this: +// +// COSE_Signature = [ +// protected : empty_or_serialized_map, +// unprotected : header_map +// signature : bstr +// ] +fn decode_signature_struct( + cose_signature: &CborType, + payload: &[u8], + protected_body_head: &CborType, +) -> Result<CoseSignature, CoseError> { + let cose_signature = unpack!(Array, cose_signature); + if cose_signature.len() != 3 { + return Err(CoseError::MalformedInput); + } + let protected_signature_header_serialized = &cose_signature[0]; + let protected_signature_header_bytes = unpack!(Bytes, protected_signature_header_serialized); + + // Parse the protected signature header. + let protected_signature_header = &match decode(protected_signature_header_bytes) { + Err(_) => return Err(CoseError::DecodingFailure), + Ok(value) => value, + }; + let protected_signature_header = unpack!(Map, protected_signature_header); + if protected_signature_header.len() != 2 { + return Err(CoseError::MalformedInput); + } + let signature_algorithm = get_map_value( + protected_signature_header, + &CborType::Integer(COSE_HEADER_ALG), + )?; + let signature_algorithm = match signature_algorithm { + CborType::SignedInteger(val) => { + match val { + COSE_TYPE_ES256 => SignatureAlgorithm::ES256, + COSE_TYPE_ES384 => SignatureAlgorithm::ES384, + COSE_TYPE_ES512 => SignatureAlgorithm::ES512, + COSE_TYPE_PS256 => SignatureAlgorithm::PS256, + _ => return Err(CoseError::UnexpectedHeaderValue), + } + } + _ => return Err(CoseError::UnexpectedType), + }; + + let ee_cert = &get_map_value( + protected_signature_header, + &CborType::Integer(COSE_HEADER_KID), + )?; + let ee_cert = unpack!(Bytes, ee_cert).clone(); + + // The unprotected header section is expected to be an empty map. + ensure_empty_map(&cose_signature[1])?; + + // Build signature structure to verify. + let signature_bytes = &cose_signature[2]; + let signature_bytes = unpack!(Bytes, signature_bytes).clone(); + let sig_structure_bytes = get_sig_struct_bytes( + protected_body_head.clone(), + protected_signature_header_serialized.clone(), + payload, + ); + + // Read intermediate certificates from protected_body_head. + // Any tampering of the protected header during transport will be detected + // because it is input to the signature verification. + // Note that a protected header has to be present and hold a kid with an + // empty list of intermediate certificates. + let protected_body_head_bytes = unpack!(Bytes, protected_body_head); + let protected_body_head_map = &match decode(protected_body_head_bytes) { + Ok(value) => value, + Err(_) => return Err(CoseError::DecodingFailure), + }; + let protected_body_head_map = unpack!(Map, protected_body_head_map); + if protected_body_head_map.len() != 1 { + return Err(CoseError::MalformedInput); + } + let intermediate_certs_array = + &get_map_value(protected_body_head_map, &CborType::Integer(COSE_HEADER_KID))?; + let intermediate_certs = unpack!(Array, intermediate_certs_array); + let mut certs: Vec<Vec<u8>> = Vec::new(); + for cert in intermediate_certs { + let cert = unpack!(Bytes, cert); + certs.push(cert.clone()); + } + + Ok(CoseSignature { + signature_type: signature_algorithm, + signature: signature_bytes, + signer_cert: ee_cert, + certs: certs, + to_verify: sig_structure_bytes, + }) +} + +/// Decode COSE signature bytes and return a vector of `CoseSignature`. +/// +///```rust,ignore +/// COSE_Sign = [ +/// Headers, +/// payload : bstr / nil, +/// signatures : [+ COSE_Signature] +/// ] +/// +/// Headers = ( +/// protected : empty_or_serialized_map, +/// unprotected : header_map +/// ) +///``` +pub fn decode_signature(bytes: &[u8], payload: &[u8]) -> Result<Vec<CoseSignature>, CoseError> { + // This has to be a COSE_Sign object, which is a tagged array. + let tagged_cose_sign = match decode(bytes) { + Err(_) => return Err(CoseError::DecodingFailure), + Ok(value) => value, + }; + let cose_sign_array = match tagged_cose_sign { + CborType::Tag(tag, cose_sign) => { + if tag != COSE_SIGN_TAG { + return Err(CoseError::UnexpectedTag); + } + match *cose_sign { + CborType::Array(values) => values, + _ => return Err(CoseError::UnexpectedType), + } + } + _ => return Err(CoseError::UnexpectedType), + }; + if cose_sign_array.len() != 4 { + return Err(CoseError::MalformedInput); + } + + // The unprotected header section is expected to be an empty map. + ensure_empty_map(&cose_sign_array[1])?; + + // The payload is expected to be Null (i.e. this is a detached signature). + match cose_sign_array[2] { + CborType::Null => {} + _ => return Err(CoseError::UnexpectedType), + }; + + let signatures = &cose_sign_array[3]; + let signatures = unpack!(Array, signatures); + + // Decode COSE_Signatures. + // There has to be at least one signature to make this a valid COSE signature. + if signatures.len() < 1 { + return Err(CoseError::MalformedInput); + } + let mut result = Vec::new(); + for cose_signature in signatures { + // cose_sign_array[0] holds the protected body header. + let signature = decode_signature_struct(cose_signature, payload, &cose_sign_array[0])?; + result.push(signature); + } + + Ok(result) +} diff --git a/third_party/rust/cose/src/test_cose.rs b/third_party/rust/cose/src/test_cose.rs new file mode 100644 index 0000000000..7c680a879c --- /dev/null +++ b/third_party/rust/cose/src/test_cose.rs @@ -0,0 +1,496 @@ +use test_setup as test; +use {CoseError, SignatureAlgorithm}; +use decoder::{COSE_HEADER_ALG, COSE_HEADER_KID, COSE_SIGN_TAG, COSE_TYPE_ES256, decode_signature}; +use cbor::CborType; +use std::collections::BTreeMap; + +#[test] +fn test_cose_decode() { + let payload = b"This is the content."; + let cose_signatures = decode_signature(&test::COSE_SIGNATURE_BYTES, payload).unwrap(); + assert_eq!(cose_signatures.len(), 1); + assert_eq!(cose_signatures[0].signature_type, SignatureAlgorithm::ES256); + assert_eq!(cose_signatures[0].signature, test::SIGNATURE_BYTES.to_vec()); + assert_eq!(cose_signatures[0].certs[0], test::P256_ROOT.to_vec()); + assert_eq!(cose_signatures[0].certs[1], test::P256_INT.to_vec()); +} + +fn test_cose_format_error(bytes: &[u8], expected_error: CoseError) { + let payload = vec![0]; + let result = decode_signature(bytes, &payload); + assert!(result.is_err()); + assert_eq!(result.err(), Some(expected_error)); +} + +// Helper function to take a `Vec<CborType>`, wrap it in a `CborType::Array`, tag it with the +// COSE_Sign tag (COSE_SIGN_TAG = 98), and serialize it to a `Vec<u8>`. +fn wrap_tag_and_encode_array(array: Vec<CborType>) -> Vec<u8> { + CborType::Tag(COSE_SIGN_TAG, Box::new(CborType::Array(array))).serialize() +} + +// Helper function to create an encoded protected header for a COSE_Sign or COSE_Signature +// structure. +fn encode_test_protected_header(keys: Vec<CborType>, values: Vec<CborType>) -> Vec<u8> { + assert_eq!(keys.len(), values.len()); + let mut map: BTreeMap<CborType, CborType> = BTreeMap::new(); + for (key, value) in keys.iter().zip(values) { + map.insert(key.clone(), value.clone()); + } + CborType::Map(map).serialize() +} + +// Helper function to create a test COSE_Signature structure with the given protected header. +fn build_test_cose_signature(protected_header: Vec<u8>) -> CborType { + CborType::Array(vec![CborType::Bytes(protected_header), + CborType::Map(BTreeMap::new()), + CborType::Bytes(Vec::new())]) +} + +// Helper function to create the minimally-valid COSE_Sign (i.e. "body") protected header. +fn make_minimally_valid_cose_sign_protected_header() -> Vec<u8> { + encode_test_protected_header( + vec![CborType::Integer(COSE_HEADER_KID)], + vec![CborType::Array(Vec::new())], + ) +} + +// Helper function to create a minimally-valid COSE_Signature (i.e. "body"). +fn make_minimally_valid_cose_signature_protected_header() -> Vec<u8> { + encode_test_protected_header( + vec![CborType::Integer(COSE_HEADER_ALG), + CborType::Integer(COSE_HEADER_KID)], + vec![CborType::SignedInteger(COSE_TYPE_ES256), + CborType::Bytes(Vec::new())], + ) +} + +// This tests the minimally-valid COSE_Sign structure according to this implementation. +// The structure must be a CBOR array of length 4 tagged with the integer 98. +// The COSE_Sign protected header must have the `kid` integer key and no others. The value for `kid` +// must be an array (although it may be empty). Each element of the array must be of type bytes. +// The COSE_Sign unprotected header must be an empty map. +// The COSE_Sign payload must be nil. +// The COSE_Sign signatures must be an array with at least one COSE_Signature. +// Each COSE_Signature must be an array of length 3. +// Each COSE_Signature protected header must have the `alg` and `kid` integer keys and no others. +// The value for `alg` must be a valid algorithm identifier. The value for `kid` must be bytes, +// although it may be empty. +// Each COSE_Signature unprotected header must be an empty map. +// Each COSE_Signature signature must be of type bytes (although it may be empty). +#[test] +fn test_cose_sign_minimally_valid() { + let body_protected_header = make_minimally_valid_cose_sign_protected_header(); + let signature_protected_header = make_minimally_valid_cose_signature_protected_header(); + let signature = build_test_cose_signature(signature_protected_header); + let values = vec![CborType::Bytes(body_protected_header), + CborType::Map(BTreeMap::new()), + CborType::Null, + CborType::Array(vec![signature])]; + let bytes = wrap_tag_and_encode_array(values); + let payload = vec![0]; + let result = decode_signature(&bytes, &payload); + assert!(result.is_ok()); + let decoded = result.unwrap(); + assert_eq!(decoded.len(), 1); + assert_eq!(decoded[0].signer_cert.len(), 0); + assert_eq!(decoded[0].certs.len(), 0); +} + +#[test] +fn test_cose_sign_not_tagged() { + let bytes = CborType::Array(vec![CborType::Integer(0)]).serialize(); + test_cose_format_error(&bytes, CoseError::UnexpectedType); +} + +#[test] +fn test_cose_sign_wrong_tag() { + // The expected COSE_Sign tag is 98. + let bytes = CborType::Tag(99, Box::new(CborType::Integer(0))).serialize(); + test_cose_format_error(&bytes, CoseError::UnexpectedTag); +} + +#[test] +fn test_cose_sign_right_tag_wrong_contents() { + // The COSE_Sign tag is 98, but the contents should be an array. + let bytes = CborType::Tag(98, Box::new(CborType::Integer(0))).serialize(); + test_cose_format_error(&bytes, CoseError::UnexpectedType); +} + +#[test] +fn test_cose_sign_too_small() { + let body_protected_header = make_minimally_valid_cose_sign_protected_header(); + let values = vec![CborType::Bytes(body_protected_header), + CborType::Map(BTreeMap::new()), + CborType::Null]; + let bytes = wrap_tag_and_encode_array(values); + test_cose_format_error(&bytes, CoseError::MalformedInput); +} + +#[test] +fn test_cose_sign_too_large() { + let body_protected_header = make_minimally_valid_cose_sign_protected_header(); + let values = vec![CborType::Bytes(body_protected_header), + CborType::Map(BTreeMap::new()), + CborType::Null, + CborType::Array(Vec::new()), + CborType::Array(Vec::new())]; + let bytes = wrap_tag_and_encode_array(values); + test_cose_format_error(&bytes, CoseError::MalformedInput); +} + +#[test] +fn test_cose_sign_protected_header_empty() { + let body_protected_header = encode_test_protected_header(Vec::new(), Vec::new()); + let signature_protected_header = make_minimally_valid_cose_signature_protected_header(); + let signature = build_test_cose_signature(signature_protected_header); + let values = vec![CborType::Bytes(body_protected_header), + CborType::Map(BTreeMap::new()), + CborType::Null, + CborType::Array(vec![signature])]; + let bytes = wrap_tag_and_encode_array(values); + test_cose_format_error(&bytes, CoseError::MalformedInput); +} + +#[test] +fn test_cose_sign_protected_header_missing_kid() { + let body_protected_header = + encode_test_protected_header(vec![CborType::Integer(2)], vec![CborType::Integer(2)]); + let signature_protected_header = make_minimally_valid_cose_signature_protected_header(); + let signature = build_test_cose_signature(signature_protected_header); + let values = vec![CborType::Bytes(body_protected_header), + CborType::Map(BTreeMap::new()), + CborType::Null, + CborType::Array(vec![signature])]; + let bytes = wrap_tag_and_encode_array(values); + test_cose_format_error(&bytes, CoseError::MissingHeader); +} + +#[test] +fn test_cose_sign_protected_header_kid_wrong_type() { + let body_protected_header = encode_test_protected_header( + vec![CborType::Integer(COSE_HEADER_KID)], + vec![CborType::Integer(2)], + ); + let signature_protected_header = make_minimally_valid_cose_signature_protected_header(); + let signature = build_test_cose_signature(signature_protected_header); + let values = vec![CborType::Bytes(body_protected_header), + CborType::Map(BTreeMap::new()), + CborType::Null, + CborType::Array(vec![signature])]; + let bytes = wrap_tag_and_encode_array(values); + test_cose_format_error(&bytes, CoseError::UnexpectedType); +} + +#[test] +fn test_cose_sign_protected_header_extra_header_key() { + let body_protected_header = encode_test_protected_header( + vec![CborType::Integer(COSE_HEADER_KID), + CborType::Integer(2)], + vec![CborType::Bytes(Vec::new()), + CborType::Integer(2)], + ); + let signature_protected_header = make_minimally_valid_cose_signature_protected_header(); + let signature = build_test_cose_signature(signature_protected_header); + let values = vec![CborType::Bytes(body_protected_header), + CborType::Map(BTreeMap::new()), + CborType::Null, + CborType::Array(vec![signature])]; + let bytes = wrap_tag_and_encode_array(values); + test_cose_format_error(&bytes, CoseError::MalformedInput); +} + +#[test] +fn test_cose_sign_unprotected_header_wrong_type() { + let body_protected_header = make_minimally_valid_cose_sign_protected_header(); + let signature_protected_header = make_minimally_valid_cose_signature_protected_header(); + let signature = build_test_cose_signature(signature_protected_header); + let values = vec![CborType::Bytes(body_protected_header), + CborType::Integer(1), + CborType::Null, + CborType::Array(vec![signature])]; + let bytes = wrap_tag_and_encode_array(values); + test_cose_format_error(&bytes, CoseError::UnexpectedType); +} + +#[test] +fn test_cose_sign_unprotected_header_not_empty() { + let body_protected_header = make_minimally_valid_cose_sign_protected_header(); + let signature_protected_header = make_minimally_valid_cose_signature_protected_header(); + let signature = build_test_cose_signature(signature_protected_header); + let mut unprotected_header_map: BTreeMap<CborType, CborType> = BTreeMap::new(); + unprotected_header_map.insert(CborType::Integer(0), CborType::SignedInteger(-1)); + let values = vec![CborType::Bytes(body_protected_header), + CborType::Map(unprotected_header_map), + CborType::Null, + CborType::Array(vec![signature])]; + let bytes = wrap_tag_and_encode_array(values); + test_cose_format_error(&bytes, CoseError::MalformedInput); +} + +#[test] +fn test_cose_sign_payload_not_null() { + let body_protected_header = make_minimally_valid_cose_sign_protected_header(); + let signature_protected_header = make_minimally_valid_cose_signature_protected_header(); + let signature = build_test_cose_signature(signature_protected_header); + let values = vec![CborType::Bytes(body_protected_header), + CborType::Map(BTreeMap::new()), + CborType::Integer(0), + CborType::Array(vec![signature])]; + let bytes = wrap_tag_and_encode_array(values); + test_cose_format_error(&bytes, CoseError::UnexpectedType); +} + +#[test] +fn test_cose_signatures_not_array() { + let body_protected_header = make_minimally_valid_cose_sign_protected_header(); + let values = vec![CborType::Bytes(body_protected_header), + CborType::Map(BTreeMap::new()), + CborType::Null, + CborType::Integer(0)]; + let bytes = wrap_tag_and_encode_array(values); + test_cose_format_error(&bytes, CoseError::UnexpectedType); +} + +#[test] +fn test_cose_signatures_empty() { + let body_protected_header = make_minimally_valid_cose_sign_protected_header(); + let values = vec![CborType::Bytes(body_protected_header), + CborType::Map(BTreeMap::new()), + CborType::Null, + CborType::Array(Vec::new())]; + let bytes = wrap_tag_and_encode_array(values); + test_cose_format_error(&bytes, CoseError::MalformedInput); +} + +#[test] +fn test_cose_signature_protected_header_wrong_type() { + let body_protected_header = make_minimally_valid_cose_sign_protected_header(); + let signature = CborType::Array(vec![CborType::Null, + CborType::Map(BTreeMap::new()), + CborType::SignedInteger(-1)]); + let values = vec![CborType::Bytes(body_protected_header), + CborType::Map(BTreeMap::new()), + CborType::Null, + CborType::Array(vec![signature])]; + let bytes = wrap_tag_and_encode_array(values); + test_cose_format_error(&bytes, CoseError::UnexpectedType); +} + +#[test] +fn test_cose_signature_protected_header_empty() { + let body_protected_header = make_minimally_valid_cose_sign_protected_header(); + let signature_protected_header = encode_test_protected_header(Vec::new(), Vec::new()); + let signature = build_test_cose_signature(signature_protected_header); + let values = vec![CborType::Bytes(body_protected_header), + CborType::Map(BTreeMap::new()), + CborType::Null, + CborType::Array(vec![signature])]; + let bytes = wrap_tag_and_encode_array(values); + test_cose_format_error(&bytes, CoseError::MalformedInput); +} + +#[test] +fn test_cose_signature_protected_header_too_large() { + let body_protected_header = make_minimally_valid_cose_sign_protected_header(); + let signature_protected_header = make_minimally_valid_cose_signature_protected_header(); + let signature = CborType::Array(vec![CborType::Bytes(signature_protected_header), + CborType::Map(BTreeMap::new()), + CborType::Bytes(Vec::new()), + CborType::Null]); + let values = vec![CborType::Bytes(body_protected_header), + CborType::Map(BTreeMap::new()), + CborType::Null, + CborType::Array(vec![signature])]; + let bytes = wrap_tag_and_encode_array(values); + test_cose_format_error(&bytes, CoseError::MalformedInput); +} + +#[test] +fn test_cose_signature_protected_header_bad_encoding() { + let body_protected_header = make_minimally_valid_cose_sign_protected_header(); + // The bytes here are a truncated integer encoding. + let signature = CborType::Array(vec![CborType::Bytes(vec![0x1a, 0x00, 0x00]), + CborType::Map(BTreeMap::new()), + CborType::Bytes(Vec::new())]); + let values = vec![CborType::Bytes(body_protected_header), + CborType::Map(BTreeMap::new()), + CborType::Null, + CborType::Array(vec![signature])]; + let bytes = wrap_tag_and_encode_array(values); + test_cose_format_error(&bytes, CoseError::DecodingFailure); +} + +#[test] +fn test_cose_signature_protected_header_missing_alg() { + let body_protected_header = make_minimally_valid_cose_sign_protected_header(); + let signature_protected_header = encode_test_protected_header( + vec![CborType::Integer(2), + CborType::Integer(COSE_HEADER_KID)], + vec![CborType::SignedInteger(COSE_TYPE_ES256), + CborType::Bytes(Vec::new())], + ); + let signature = build_test_cose_signature(signature_protected_header); + let values = vec![CborType::Bytes(body_protected_header), + CborType::Map(BTreeMap::new()), + CborType::Null, + CborType::Array(vec![signature])]; + let bytes = wrap_tag_and_encode_array(values); + test_cose_format_error(&bytes, CoseError::MissingHeader); +} + +#[test] +fn test_cose_signature_protected_header_missing_kid() { + let body_protected_header = make_minimally_valid_cose_sign_protected_header(); + let signature_protected_header = encode_test_protected_header( + vec![CborType::Integer(COSE_HEADER_ALG), + CborType::Integer(3)], + vec![CborType::SignedInteger(COSE_TYPE_ES256), + CborType::Bytes(Vec::new())], + ); + let signature = build_test_cose_signature(signature_protected_header); + let values = vec![CborType::Bytes(body_protected_header), + CborType::Map(BTreeMap::new()), + CborType::Null, + CborType::Array(vec![signature])]; + let bytes = wrap_tag_and_encode_array(values); + test_cose_format_error(&bytes, CoseError::MissingHeader); +} + +#[test] +fn test_cose_signature_protected_header_wrong_key_types() { + let body_protected_header = make_minimally_valid_cose_sign_protected_header(); + let signature_protected_header = encode_test_protected_header( + vec![CborType::SignedInteger(-1), + CborType::Bytes(vec![0])], + vec![CborType::SignedInteger(COSE_TYPE_ES256), + CborType::Bytes(Vec::new())], + ); + let signature = build_test_cose_signature(signature_protected_header); + let values = vec![CborType::Bytes(body_protected_header), + CborType::Map(BTreeMap::new()), + CborType::Null, + CborType::Array(vec![signature])]; + let bytes = wrap_tag_and_encode_array(values); + test_cose_format_error(&bytes, CoseError::MissingHeader); +} + +#[test] +fn test_cose_signature_protected_header_unexpected_alg_type() { + let body_protected_header = make_minimally_valid_cose_sign_protected_header(); + let signature_protected_header = encode_test_protected_header( + vec![CborType::Integer(COSE_HEADER_ALG), + CborType::Integer(COSE_HEADER_KID)], + vec![CborType::Integer(10), + CborType::Integer(4)], + ); + let signature = build_test_cose_signature(signature_protected_header); + let values = vec![CborType::Bytes(body_protected_header), + CborType::Map(BTreeMap::new()), + CborType::Null, + CborType::Array(vec![signature])]; + let bytes = wrap_tag_and_encode_array(values); + test_cose_format_error(&bytes, CoseError::UnexpectedType); +} + +#[test] +fn test_cose_signature_protected_header_unsupported_alg() { + let body_protected_header = make_minimally_valid_cose_sign_protected_header(); + let signature_protected_header = encode_test_protected_header( + vec![CborType::Integer(COSE_HEADER_ALG), + CborType::Integer(COSE_HEADER_KID)], + vec![CborType::SignedInteger(-10), + CborType::Bytes(Vec::new())], + ); + let signature = build_test_cose_signature(signature_protected_header); + let values = vec![CborType::Bytes(body_protected_header), + CborType::Map(BTreeMap::new()), + CborType::Null, + CborType::Array(vec![signature])]; + let bytes = wrap_tag_and_encode_array(values); + test_cose_format_error(&bytes, CoseError::UnexpectedHeaderValue); +} + +#[test] +fn test_cose_signature_protected_header_unexpected_kid_type() { + let body_protected_header = make_minimally_valid_cose_sign_protected_header(); + let signature_protected_header = encode_test_protected_header( + vec![CborType::Integer(COSE_HEADER_ALG), + CborType::Integer(COSE_HEADER_KID)], + vec![CborType::SignedInteger(COSE_TYPE_ES256), + CborType::Integer(0)], + ); + let signature = build_test_cose_signature(signature_protected_header); + let values = vec![CborType::Bytes(body_protected_header), + CborType::Map(BTreeMap::new()), + CborType::Null, + CborType::Array(vec![signature])]; + let bytes = wrap_tag_and_encode_array(values); + test_cose_format_error(&bytes, CoseError::UnexpectedType); +} + +#[test] +fn test_cose_signature_protected_header_extra_key() { + let body_protected_header = make_minimally_valid_cose_sign_protected_header(); + let signature_protected_header = encode_test_protected_header( + vec![CborType::Integer(COSE_HEADER_ALG), + CborType::Integer(COSE_HEADER_KID), + CborType::Integer(5)], + vec![CborType::SignedInteger(COSE_TYPE_ES256), + CborType::Bytes(Vec::new()), + CborType::Integer(5)], + ); + let signature = build_test_cose_signature(signature_protected_header); + let values = vec![CborType::Bytes(body_protected_header), + CborType::Map(BTreeMap::new()), + CborType::Null, + CborType::Array(vec![signature])]; + let bytes = wrap_tag_and_encode_array(values); + test_cose_format_error(&bytes, CoseError::MalformedInput); +} + +#[test] +fn test_cose_signature_unprotected_header_wrong_type() { + let body_protected_header = make_minimally_valid_cose_sign_protected_header(); + let signature_protected_header = make_minimally_valid_cose_signature_protected_header(); + let signature = CborType::Array(vec![CborType::Bytes(signature_protected_header), + CborType::Integer(1), + CborType::Bytes(Vec::new())]); + let values = vec![CborType::Bytes(body_protected_header), + CborType::Map(BTreeMap::new()), + CborType::Null, + CborType::Array(vec![signature])]; + let bytes = wrap_tag_and_encode_array(values); + test_cose_format_error(&bytes, CoseError::UnexpectedType); +} + +#[test] +fn test_cose_signature_unprotected_header_not_empty() { + let body_protected_header = make_minimally_valid_cose_sign_protected_header(); + let signature_protected_header = make_minimally_valid_cose_signature_protected_header(); + let mut unprotected_header_map: BTreeMap<CborType, CborType> = BTreeMap::new(); + unprotected_header_map.insert(CborType::Integer(0), CborType::SignedInteger(-1)); + let signature = CborType::Array(vec![CborType::Bytes(signature_protected_header), + CborType::Map(unprotected_header_map), + CborType::Bytes(Vec::new())]); + let values = vec![CborType::Bytes(body_protected_header), + CborType::Map(BTreeMap::new()), + CborType::Null, + CborType::Array(vec![signature])]; + let bytes = wrap_tag_and_encode_array(values); + test_cose_format_error(&bytes, CoseError::MalformedInput); +} + +#[test] +fn test_cose_signature_signature_wrong_type() { + let body_protected_header = make_minimally_valid_cose_sign_protected_header(); + let signature_protected_header = make_minimally_valid_cose_signature_protected_header(); + let signature = CborType::Array(vec![CborType::Bytes(signature_protected_header), + CborType::Map(BTreeMap::new()), + CborType::SignedInteger(-1)]); + let values = vec![CborType::Bytes(body_protected_header), + CborType::Map(BTreeMap::new()), + CborType::Null, + CborType::Array(vec![signature])]; + let bytes = wrap_tag_and_encode_array(values); + test_cose_format_error(&bytes, CoseError::UnexpectedType); +} diff --git a/third_party/rust/cose/src/test_setup.rs b/third_party/rust/cose/src/test_setup.rs new file mode 100644 index 0000000000..fce0676a66 --- /dev/null +++ b/third_party/rust/cose/src/test_setup.rs @@ -0,0 +1,169 @@ +#[cfg_attr(rustfmt, rustfmt_skip)] +pub const P256_INT: [u8; 332] = [ + 0x30, 0x82, 0x01, 0x48, 0x30, 0x81, 0xf0, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x14, 0x43, 0x63, 0x59, 0xad, 0x04, 0x34, 0x56, 0x80, + 0x43, 0xec, 0x90, 0x6a, 0xd4, 0x10, 0x64, 0x7c, 0x7f, 0x38, 0x32, + 0xe2, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, + 0x03, 0x02, 0x30, 0x14, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0c, 0x09, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x70, 0x32, + 0x35, 0x36, 0x30, 0x22, 0x18, 0x0f, 0x32, 0x30, 0x31, 0x32, 0x30, + 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, + 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, 0x33, 0x31, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x69, 0x6e, 0x74, 0x2d, + 0x70, 0x32, 0x35, 0x36, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, + 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, + 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4f, 0xbf, + 0xbb, 0xbb, 0x61, 0xe0, 0xf8, 0xf9, 0xb1, 0xa6, 0x0a, 0x59, 0xac, + 0x87, 0x04, 0xe2, 0xec, 0x05, 0x0b, 0x42, 0x3e, 0x3c, 0xf7, 0x2e, + 0x92, 0x3f, 0x2c, 0x4f, 0x79, 0x4b, 0x45, 0x5c, 0x2a, 0x69, 0xd2, + 0x33, 0x45, 0x6c, 0x36, 0xc4, 0x11, 0x9d, 0x07, 0x06, 0xe0, 0x0e, + 0xed, 0xc8, 0xd1, 0x93, 0x90, 0xd7, 0x99, 0x1b, 0x7b, 0x2d, 0x07, + 0xa3, 0x04, 0xea, 0xa0, 0x4a, 0xa6, 0xc0, 0xa3, 0x1d, 0x30, 0x1b, + 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, + 0x01, 0x01, 0xff, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, + 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, + 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x47, 0x00, 0x30, 0x44, + 0x02, 0x20, 0x63, 0x59, 0x02, 0x01, 0x89, 0xd7, 0x3e, 0x5b, 0xff, + 0xd1, 0x16, 0x4e, 0xe3, 0xe2, 0x0a, 0xe0, 0x4a, 0xd8, 0x75, 0xaf, + 0x77, 0x5c, 0x93, 0x60, 0xba, 0x10, 0x1f, 0x97, 0xdd, 0x27, 0x2d, + 0x24, 0x02, 0x20, 0x3d, 0x87, 0x0f, 0xac, 0x22, 0x4d, 0x16, 0xd9, + 0xa1, 0x95, 0xbb, 0x56, 0xe0, 0x21, 0x05, 0x93, 0xd1, 0x07, 0xb5, + 0x25, 0x3b, 0xf4, 0x57, 0x20, 0x87, 0x13, 0xa2, 0xf7, 0x78, 0x15, + 0x30, 0xa7 +]; + +#[cfg_attr(rustfmt, rustfmt_skip)] +pub const P256_ROOT: [u8; 334] = [ + 0x30, 0x82, 0x01, 0x4a, 0x30, 0x81, 0xf1, 0xa0, 0x03, 0x02, 0x01, 0x02, + 0x02, 0x14, 0x5f, 0x3f, 0xae, 0x90, 0x49, 0x30, 0x2f, 0x33, 0x6e, 0x95, + 0x23, 0xa7, 0xcb, 0x23, 0xd7, 0x65, 0x4f, 0xea, 0x3c, 0xf7, 0x30, 0x0a, + 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x14, + 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x72, + 0x6f, 0x6f, 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x22, 0x18, 0x0f, + 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, 0x33, + 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x14, 0x31, 0x12, + 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x72, 0x6f, 0x6f, + 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, + 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4f, 0xbf, 0xbb, + 0xbb, 0x61, 0xe0, 0xf8, 0xf9, 0xb1, 0xa6, 0x0a, 0x59, 0xac, 0x87, 0x04, + 0xe2, 0xec, 0x05, 0x0b, 0x42, 0x3e, 0x3c, 0xf7, 0x2e, 0x92, 0x3f, 0x2c, + 0x4f, 0x79, 0x4b, 0x45, 0x5c, 0x2a, 0x69, 0xd2, 0x33, 0x45, 0x6c, 0x36, + 0xc4, 0x11, 0x9d, 0x07, 0x06, 0xe0, 0x0e, 0xed, 0xc8, 0xd1, 0x93, 0x90, + 0xd7, 0x99, 0x1b, 0x7b, 0x2d, 0x07, 0xa3, 0x04, 0xea, 0xa0, 0x4a, 0xa6, + 0xc0, 0xa3, 0x1d, 0x30, 0x1b, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, + 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0b, 0x06, 0x03, 0x55, + 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0a, 0x06, 0x08, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, + 0x45, 0x02, 0x20, 0x5c, 0x75, 0x51, 0x9f, 0x13, 0x11, 0x50, 0xcd, 0x5d, + 0x8a, 0xde, 0x20, 0xa3, 0xbc, 0x06, 0x30, 0x91, 0xff, 0xb2, 0x73, 0x75, + 0x5f, 0x31, 0x64, 0xec, 0xfd, 0xcb, 0x42, 0x80, 0x0a, 0x70, 0xe6, 0x02, + 0x21, 0x00, 0xc2, 0xe4, 0xc1, 0xa8, 0xe2, 0x89, 0xdc, 0xa1, 0xbb, 0xe7, + 0xd5, 0x4f, 0x5c, 0x88, 0xad, 0xeb, 0xa4, 0x78, 0xa1, 0x19, 0xbe, 0x22, + 0x54, 0xc8, 0x9f, 0xef, 0xb8, 0x5d, 0xa2, 0x40, 0xd9, 0x8b +]; + +#[cfg_attr(rustfmt, rustfmt_skip)] +pub const COSE_SIGNATURE_BYTES: [u8; 1062] = [ + 0xd8, 0x62, 0x84, 0x59, 0x02, 0xa3, 0xa1, 0x04, 0x82, 0x59, 0x01, 0x4e, + 0x30, 0x82, 0x01, 0x4a, 0x30, 0x81, 0xf1, 0xa0, 0x03, 0x02, 0x01, 0x02, + 0x02, 0x14, 0x5f, 0x3f, 0xae, 0x90, 0x49, 0x30, 0x2f, 0x33, 0x6e, 0x95, + 0x23, 0xa7, 0xcb, 0x23, 0xd7, 0x65, 0x4f, 0xea, 0x3c, 0xf7, 0x30, 0x0a, + 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x14, + 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x72, + 0x6f, 0x6f, 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x22, 0x18, 0x0f, + 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, 0x33, + 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x14, 0x31, 0x12, + 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x72, 0x6f, 0x6f, + 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, + 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4f, 0xbf, 0xbb, + 0xbb, 0x61, 0xe0, 0xf8, 0xf9, 0xb1, 0xa6, 0x0a, 0x59, 0xac, 0x87, 0x04, + 0xe2, 0xec, 0x05, 0x0b, 0x42, 0x3e, 0x3c, 0xf7, 0x2e, 0x92, 0x3f, 0x2c, + 0x4f, 0x79, 0x4b, 0x45, 0x5c, 0x2a, 0x69, 0xd2, 0x33, 0x45, 0x6c, 0x36, + 0xc4, 0x11, 0x9d, 0x07, 0x06, 0xe0, 0x0e, 0xed, 0xc8, 0xd1, 0x93, 0x90, + 0xd7, 0x99, 0x1b, 0x7b, 0x2d, 0x07, 0xa3, 0x04, 0xea, 0xa0, 0x4a, 0xa6, + 0xc0, 0xa3, 0x1d, 0x30, 0x1b, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, + 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0b, 0x06, 0x03, 0x55, + 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0a, 0x06, 0x08, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, + 0x45, 0x02, 0x20, 0x5c, 0x75, 0x51, 0x9f, 0x13, 0x11, 0x50, 0xcd, 0x5d, + 0x8a, 0xde, 0x20, 0xa3, 0xbc, 0x06, 0x30, 0x91, 0xff, 0xb2, 0x73, 0x75, + 0x5f, 0x31, 0x64, 0xec, 0xfd, 0xcb, 0x42, 0x80, 0x0a, 0x70, 0xe6, 0x02, + 0x21, 0x00, 0xc2, 0xe4, 0xc1, 0xa8, 0xe2, 0x89, 0xdc, 0xa1, 0xbb, 0xe7, + 0xd5, 0x4f, 0x5c, 0x88, 0xad, 0xeb, 0xa4, 0x78, 0xa1, 0x19, 0xbe, 0x22, + 0x54, 0xc8, 0x9f, 0xef, 0xb8, 0x5d, 0xa2, 0x40, 0xd9, 0x8b, 0x59, 0x01, + 0x4c, 0x30, 0x82, 0x01, 0x48, 0x30, 0x81, 0xf0, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x14, 0x43, 0x63, 0x59, 0xad, 0x04, 0x34, 0x56, 0x80, 0x43, + 0xec, 0x90, 0x6a, 0xd4, 0x10, 0x64, 0x7c, 0x7f, 0x38, 0x32, 0xe2, 0x30, + 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, + 0x14, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, + 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x22, 0x18, + 0x0f, 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, + 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x13, 0x31, + 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x69, 0x6e, + 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, + 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4f, 0xbf, 0xbb, + 0xbb, 0x61, 0xe0, 0xf8, 0xf9, 0xb1, 0xa6, 0x0a, 0x59, 0xac, 0x87, 0x04, + 0xe2, 0xec, 0x05, 0x0b, 0x42, 0x3e, 0x3c, 0xf7, 0x2e, 0x92, 0x3f, 0x2c, + 0x4f, 0x79, 0x4b, 0x45, 0x5c, 0x2a, 0x69, 0xd2, 0x33, 0x45, 0x6c, 0x36, + 0xc4, 0x11, 0x9d, 0x07, 0x06, 0xe0, 0x0e, 0xed, 0xc8, 0xd1, 0x93, 0x90, + 0xd7, 0x99, 0x1b, 0x7b, 0x2d, 0x07, 0xa3, 0x04, 0xea, 0xa0, 0x4a, 0xa6, + 0xc0, 0xa3, 0x1d, 0x30, 0x1b, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, + 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0b, 0x06, 0x03, 0x55, + 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0a, 0x06, 0x08, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x47, 0x00, 0x30, + 0x44, 0x02, 0x20, 0x63, 0x59, 0x02, 0x01, 0x89, 0xd7, 0x3e, 0x5b, 0xff, + 0xd1, 0x16, 0x4e, 0xe3, 0xe2, 0x0a, 0xe0, 0x4a, 0xd8, 0x75, 0xaf, 0x77, + 0x5c, 0x93, 0x60, 0xba, 0x10, 0x1f, 0x97, 0xdd, 0x27, 0x2d, 0x24, 0x02, + 0x20, 0x3d, 0x87, 0x0f, 0xac, 0x22, 0x4d, 0x16, 0xd9, 0xa1, 0x95, 0xbb, + 0x56, 0xe0, 0x21, 0x05, 0x93, 0xd1, 0x07, 0xb5, 0x25, 0x3b, 0xf4, 0x57, + 0x20, 0x87, 0x13, 0xa2, 0xf7, 0x78, 0x15, 0x30, 0xa7, 0xa0, 0xf6, 0x81, + 0x83, 0x59, 0x01, 0x33, 0xa2, 0x01, 0x26, 0x04, 0x59, 0x01, 0x2c, 0x30, + 0x82, 0x01, 0x28, 0x30, 0x81, 0xcf, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, + 0x14, 0x2f, 0xc3, 0x5f, 0x05, 0x80, 0xb4, 0x49, 0x45, 0x13, 0x92, 0xd6, + 0x93, 0xb7, 0x2d, 0x71, 0x19, 0xc5, 0x8c, 0x40, 0x39, 0x30, 0x0a, 0x06, + 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x13, 0x31, + 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x69, 0x6e, + 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x22, 0x18, 0x0f, 0x32, 0x30, + 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, 0x33, 0x31, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x12, 0x31, 0x10, 0x30, 0x0e, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x07, 0x65, 0x65, 0x2d, 0x70, 0x32, + 0x35, 0x36, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, + 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, + 0x07, 0x03, 0x42, 0x00, 0x04, 0x4f, 0xbf, 0xbb, 0xbb, 0x61, 0xe0, 0xf8, + 0xf9, 0xb1, 0xa6, 0x0a, 0x59, 0xac, 0x87, 0x04, 0xe2, 0xec, 0x05, 0x0b, + 0x42, 0x3e, 0x3c, 0xf7, 0x2e, 0x92, 0x3f, 0x2c, 0x4f, 0x79, 0x4b, 0x45, + 0x5c, 0x2a, 0x69, 0xd2, 0x33, 0x45, 0x6c, 0x36, 0xc4, 0x11, 0x9d, 0x07, + 0x06, 0xe0, 0x0e, 0xed, 0xc8, 0xd1, 0x93, 0x90, 0xd7, 0x99, 0x1b, 0x7b, + 0x2d, 0x07, 0xa3, 0x04, 0xea, 0xa0, 0x4a, 0xa6, 0xc0, 0x30, 0x0a, 0x06, + 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, + 0x30, 0x45, 0x02, 0x20, 0x5c, 0x75, 0x51, 0x9f, 0x13, 0x11, 0x50, 0xcd, + 0x5d, 0x8a, 0xde, 0x20, 0xa3, 0xbc, 0x06, 0x30, 0x91, 0xff, 0xb2, 0x73, + 0x75, 0x5f, 0x31, 0x64, 0xec, 0xfd, 0xcb, 0x42, 0x80, 0x0a, 0x70, 0xe6, + 0x02, 0x21, 0x00, 0xff, 0x81, 0xbe, 0xa8, 0x0d, 0x03, 0x36, 0x6b, 0x75, + 0xe2, 0x70, 0x6a, 0xac, 0x07, 0x2e, 0x4c, 0xdc, 0xf9, 0xc5, 0x89, 0xc1, + 0xcf, 0x88, 0xc2, 0xc8, 0x2a, 0x32, 0xf5, 0x42, 0x0c, 0xfa, 0x0b, 0xa0, + 0x58, 0x40, 0x11, 0xe5, 0x73, 0x2c, 0x23, 0x31, 0x6f, 0xb4, 0x17, 0xcf, + 0xa9, 0xee, 0xc5, 0xe3, 0x57, 0xcc, 0x77, 0x82, 0x29, 0x1f, 0xba, 0x97, + 0xbf, 0x32, 0xaf, 0x8d, 0x88, 0x27, 0xde, 0x69, 0xd2, 0xdf, 0xd6, 0xec, + 0x9e, 0x5b, 0xd3, 0x9d, 0xf8, 0x9d, 0x68, 0xc6, 0xce, 0x91, 0x32, 0x41, + 0x50, 0x5f, 0xd8, 0x72, 0xb0, 0x41, 0xb9, 0x39, 0x3d, 0xdf, 0x44, 0xee, + 0x89, 0x74, 0x4d, 0x9e, 0xb4, 0xd7 +]; + +#[cfg_attr(rustfmt, rustfmt_skip)] +pub const SIGNATURE_BYTES: [u8; 64] = [ + 0x11, 0xe5, 0x73, 0x2c, 0x23, 0x31, 0x6f, 0xb4, 0x17, 0xcf, + 0xa9, 0xee, 0xc5, 0xe3, 0x57, 0xcc, 0x77, 0x82, 0x29, 0x1f, 0xba, 0x97, + 0xbf, 0x32, 0xaf, 0x8d, 0x88, 0x27, 0xde, 0x69, 0xd2, 0xdf, 0xd6, 0xec, + 0x9e, 0x5b, 0xd3, 0x9d, 0xf8, 0x9d, 0x68, 0xc6, 0xce, 0x91, 0x32, 0x41, + 0x50, 0x5f, 0xd8, 0x72, 0xb0, 0x41, 0xb9, 0x39, 0x3d, 0xdf, 0x44, 0xee, + 0x89, 0x74, 0x4d, 0x9e, 0xb4, 0xd7 +]; diff --git a/third_party/rust/cose/src/util.rs b/third_party/rust/cose/src/util.rs new file mode 100644 index 0000000000..8f1cf7e954 --- /dev/null +++ b/third_party/rust/cose/src/util.rs @@ -0,0 +1,27 @@ +use cbor::CborType; + +/// Sig_structure is a CBOR array: +/// +/// Sig_structure = [ +/// context : "Signature" / "Signature1" / "CounterSignature", +/// body_protected : empty_or_serialized_map, +/// ? sign_protected : empty_or_serialized_map, +/// external_aad : bstr, +/// payload : bstr +/// ] +/// +/// In this case, the context is "Signature". There is no external_aad, so this defaults to a +/// zero-length bstr. +pub fn get_sig_struct_bytes( + protected_body_header_serialized: CborType, + protected_signature_header_serialized: CborType, + payload: &[u8], +) -> Vec<u8> { + let sig_structure_array: Vec<CborType> = vec![CborType::String(String::from("Signature")), + protected_body_header_serialized, + protected_signature_header_serialized, + CborType::Null, + CborType::Bytes(payload.to_vec())]; + + CborType::Array(sig_structure_array).serialize() +} diff --git a/third_party/rust/cose/tools/certs/certs.md b/third_party/rust/cose/tools/certs/certs.md new file mode 100644 index 0000000000..ef8a53909e --- /dev/null +++ b/third_party/rust/cose/tools/certs/certs.md @@ -0,0 +1,9 @@ +## This folder holds everything to generate certificates and keys for tests + +Scripts in this folder require a copy of [mozilla-central](https://hg.mozilla.org/mozilla-central/) and use scripts from `security/manager/ssl/tests/unit`. The default path for `MOZILLA_CENTRAL` is next to the root of this project. + +The helper script `certs.sh` sets all necessary paths and generates certificates. +The following command generates the end-entity certificate with P256, ECDSA, SHA256. + + MOZILLA_CENTRAL=<path to mc> ./certs.sh < ee-p256.certspec + diff --git a/third_party/rust/cose/tools/certs/certs.sh b/third_party/rust/cose/tools/certs/certs.sh new file mode 100755 index 0000000000..b6f4db679c --- /dev/null +++ b/third_party/rust/cose/tools/certs/certs.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +cwd=$(cd $(dirname $0); pwd -P) +MOZILLA_CENTRAL=${MOZILLA_CENTRAL:-"$cwd/../../../mc"} +script_path="$MOZILLA_CENTRAL/security/manager/ssl/tests/unit" + +python_path="$MOZILLA_CENTRAL/third_party/python/pyasn1/" +python_path="$python_path:$MOZILLA_CENTRAL/third_party/python/pyasn1-modules/" +python_path="$python_path:$MOZILLA_CENTRAL/third_party/python/PyECC/" +python_path="$python_path:$MOZILLA_CENTRAL/third_party/python/mock-1.0.0/" +python_path="$python_path:$MOZILLA_CENTRAL/third_party/python/rsa/" + +gen_cert() { + PYTHONPATH=$python_path "$script_path"/pycert.py "$@" > /tmp/cert.pem + openssl x509 -in /tmp/cert.pem -out /tmp/cert.der -outform DER + xxd -ps /tmp/cert.der | sed 's/\([0-9A-Fa-f]\{2\}\)/0x\1, /g' \ + | tr -d '\n' + echo "" +} + +gen_cert "${@:1}" diff --git a/third_party/rust/cose/tools/certs/ee-p256.certspec b/third_party/rust/cose/tools/certs/ee-p256.certspec new file mode 100644 index 0000000000..59d1312987 --- /dev/null +++ b/third_party/rust/cose/tools/certs/ee-p256.certspec @@ -0,0 +1,6 @@ +issuer:int-p256 +subject:ee-p256 +issuerKey:secp256r1 +subjectKey:secp256r1 +signature:ecdsaWithSHA256 +validity:3650
\ No newline at end of file diff --git a/third_party/rust/cose/tools/certs/ee-p256.keyspec b/third_party/rust/cose/tools/certs/ee-p256.keyspec new file mode 100644 index 0000000000..562d46f945 --- /dev/null +++ b/third_party/rust/cose/tools/certs/ee-p256.keyspec @@ -0,0 +1 @@ +secp256r1
\ No newline at end of file diff --git a/third_party/rust/cose/tools/certs/ee-p384.certspec b/third_party/rust/cose/tools/certs/ee-p384.certspec new file mode 100644 index 0000000000..19be32edb2 --- /dev/null +++ b/third_party/rust/cose/tools/certs/ee-p384.certspec @@ -0,0 +1,6 @@ +issuer:int-p256 +subject:ee-p384 +issuerKey:secp256r1 +subjectKey:secp384r1 +signature:ecdsaWithSHA256 +validity:3650
\ No newline at end of file diff --git a/third_party/rust/cose/tools/certs/ee-p521.certspec b/third_party/rust/cose/tools/certs/ee-p521.certspec new file mode 100644 index 0000000000..b6cec39b08 --- /dev/null +++ b/third_party/rust/cose/tools/certs/ee-p521.certspec @@ -0,0 +1,6 @@ +issuer:int-p256 +subject:ee-p521 +issuerKey:secp256r1 +subjectKey:secp521r1 +signature:ecdsaWithSHA256 +validity:3650
\ No newline at end of file diff --git a/third_party/rust/cose/tools/certs/ee-rsa.certspec b/third_party/rust/cose/tools/certs/ee-rsa.certspec new file mode 100644 index 0000000000..27a0ff3bca --- /dev/null +++ b/third_party/rust/cose/tools/certs/ee-rsa.certspec @@ -0,0 +1,3 @@ +issuer:int-rsa +subject:ee-rsa +validity:3650 diff --git a/third_party/rust/cose/tools/certs/int-p256.certspec b/third_party/rust/cose/tools/certs/int-p256.certspec new file mode 100644 index 0000000000..8fec3584db --- /dev/null +++ b/third_party/rust/cose/tools/certs/int-p256.certspec @@ -0,0 +1,8 @@ +issuer:root-p256 +subject:int-p256 +issuerKey:secp256k1 +subjectKey:secp256r1 +signature:ecdsaWithSHA256 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +validity:3650
\ No newline at end of file diff --git a/third_party/rust/cose/tools/certs/int-rsa.certspec b/third_party/rust/cose/tools/certs/int-rsa.certspec new file mode 100644 index 0000000000..e79c1ecc53 --- /dev/null +++ b/third_party/rust/cose/tools/certs/int-rsa.certspec @@ -0,0 +1,5 @@ +issuer:root-rsa +subject:int-rsa +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +validity:3650 diff --git a/third_party/rust/cose/tools/certs/root-p256.certspec b/third_party/rust/cose/tools/certs/root-p256.certspec new file mode 100644 index 0000000000..e44d96e226 --- /dev/null +++ b/third_party/rust/cose/tools/certs/root-p256.certspec @@ -0,0 +1,8 @@ +issuer:root-p256 +subject:root-p256 +issuerKey:secp256r1 +subjectKey:secp256r1 +signature:ecdsaWithSHA256 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +validity:3650
\ No newline at end of file diff --git a/third_party/rust/cose/tools/certs/root-rsa.certspec b/third_party/rust/cose/tools/certs/root-rsa.certspec new file mode 100644 index 0000000000..39454648fa --- /dev/null +++ b/third_party/rust/cose/tools/certs/root-rsa.certspec @@ -0,0 +1,5 @@ +issuer:root-rsa +subject:root-rsa +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +validity:3650 |