From 7b10164f9fd61bb610af276aace06106a045fa9d Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Wed, 22 Nov 2017 16:37:15 +0100 Subject: [PATCH] Bug 1403840 - add cose rust lib with a test, r=keeler,ttaubert Summary: This adds the COSE rust library from https://github.com/franziskuskiefer/cose-rust with its C API from https://github.com/franziskuskiefer/cose-c-api to gecko with a basic test. The COSE library will be used for verifying add-on signatures in future. Reviewers: keeler, ttaubert Reviewed By: keeler Bug #: 1403840 Differential Revision: https://phabricator.services.mozilla.com/D232 --HG-- extra : rebase_source : 433ca6894d88ccda333bfac53507eba4e84924fb --- security/manager/ssl/tests/gtest/CoseTest.cpp | 738 ++++++++++++++++++ security/manager/ssl/tests/gtest/moz.build | 2 + third_party/rust/cose-c/.cargo-checksum.json | 1 + third_party/rust/cose-c/Cargo.toml | 26 + third_party/rust/cose-c/LICENSE | 373 +++++++++ third_party/rust/cose-c/include/cosec.h | 32 + third_party/rust/cose-c/src/lib.rs | 85 ++ third_party/rust/cose/.cargo-checksum.json | 1 + third_party/rust/cose/.travis.yml | 31 + third_party/rust/cose/Cargo.toml | 30 + third_party/rust/cose/LICENSE | 373 +++++++++ third_party/rust/cose/README.md | 15 + third_party/rust/cose/build.rs | 11 + third_party/rust/cose/rustfmt.toml | 4 + third_party/rust/cose/src/cbor/decoder.rs | 150 ++++ third_party/rust/cose/src/cbor/mod.rs | 56 ++ third_party/rust/cose/src/cbor/serializer.rs | 121 +++ .../rust/cose/src/cbor/test_decoder.rs | 405 ++++++++++ .../rust/cose/src/cbor/test_serializer.rs | 310 ++++++++ third_party/rust/cose/src/cose.rs | 98 +++ third_party/rust/cose/src/decoder.rs | 192 +++++ third_party/rust/cose/src/nss.rs | 356 +++++++++ third_party/rust/cose/src/test_cose.rs | 230 ++++++ third_party/rust/cose/src/test_nss.rs | 68 ++ third_party/rust/cose/src/test_setup.rs | 646 +++++++++++++++ third_party/rust/cose/src/util.rs | 27 + third_party/rust/cose/src/util_test.rs | 194 +++++ third_party/rust/cose/tools/certs/certs.md | 9 + third_party/rust/cose/tools/certs/certs.sh | 21 + .../rust/cose/tools/certs/ee-p256.certspec | 6 + .../rust/cose/tools/certs/ee-p256.keyspec | 1 + .../rust/cose/tools/certs/ee-p384.certspec | 6 + .../rust/cose/tools/certs/ee-p521.certspec | 6 + .../rust/cose/tools/certs/ee-rsa.certspec | 3 + .../rust/cose/tools/certs/int-p256.certspec | 8 + .../rust/cose/tools/certs/int-rsa.certspec | 5 + .../rust/cose/tools/certs/root-p256.certspec | 8 + .../rust/cose/tools/certs/root-rsa.certspec | 5 + toolkit/library/gtest/rust/Cargo.lock | 16 + toolkit/library/rust/Cargo.lock | 16 + toolkit/library/rust/shared/Cargo.toml | 1 + toolkit/library/rust/shared/lib.rs | 1 + 42 files changed, 4687 insertions(+) create mode 100644 security/manager/ssl/tests/gtest/CoseTest.cpp create mode 100644 third_party/rust/cose-c/.cargo-checksum.json create mode 100644 third_party/rust/cose-c/Cargo.toml create mode 100644 third_party/rust/cose-c/LICENSE create mode 100644 third_party/rust/cose-c/include/cosec.h create mode 100644 third_party/rust/cose-c/src/lib.rs create mode 100644 third_party/rust/cose/.cargo-checksum.json create mode 100644 third_party/rust/cose/.travis.yml create mode 100644 third_party/rust/cose/Cargo.toml create mode 100644 third_party/rust/cose/LICENSE create mode 100644 third_party/rust/cose/README.md create mode 100644 third_party/rust/cose/build.rs create mode 100644 third_party/rust/cose/rustfmt.toml create mode 100644 third_party/rust/cose/src/cbor/decoder.rs create mode 100644 third_party/rust/cose/src/cbor/mod.rs create mode 100644 third_party/rust/cose/src/cbor/serializer.rs create mode 100644 third_party/rust/cose/src/cbor/test_decoder.rs create mode 100644 third_party/rust/cose/src/cbor/test_serializer.rs create mode 100644 third_party/rust/cose/src/cose.rs create mode 100644 third_party/rust/cose/src/decoder.rs create mode 100644 third_party/rust/cose/src/nss.rs create mode 100644 third_party/rust/cose/src/test_cose.rs create mode 100644 third_party/rust/cose/src/test_nss.rs create mode 100644 third_party/rust/cose/src/test_setup.rs create mode 100644 third_party/rust/cose/src/util.rs create mode 100644 third_party/rust/cose/src/util_test.rs create mode 100644 third_party/rust/cose/tools/certs/certs.md create mode 100755 third_party/rust/cose/tools/certs/certs.sh create mode 100644 third_party/rust/cose/tools/certs/ee-p256.certspec create mode 100644 third_party/rust/cose/tools/certs/ee-p256.keyspec create mode 100644 third_party/rust/cose/tools/certs/ee-p384.certspec create mode 100644 third_party/rust/cose/tools/certs/ee-p521.certspec create mode 100644 third_party/rust/cose/tools/certs/ee-rsa.certspec create mode 100644 third_party/rust/cose/tools/certs/int-p256.certspec create mode 100644 third_party/rust/cose/tools/certs/int-rsa.certspec create mode 100644 third_party/rust/cose/tools/certs/root-p256.certspec create mode 100644 third_party/rust/cose/tools/certs/root-rsa.certspec diff --git a/security/manager/ssl/tests/gtest/CoseTest.cpp b/security/manager/ssl/tests/gtest/CoseTest.cpp new file mode 100644 index 000000000000..64d7825e1418 --- /dev/null +++ b/security/manager/ssl/tests/gtest/CoseTest.cpp @@ -0,0 +1,738 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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 "gtest/gtest.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "ScopedNSSTypes.h" +#include "cosec.h" + +namespace mozilla { + +// "This is the content." +const uint8_t PAYLOAD[] = { 84, 104, 105, 115, 32, 105, 115, 32, 116, 104, + 101, 32, 99, 111, 110, 116, 101, 110, 116, 46 }; + +// This is a COSE signature generated with the cose rust library (see +// third-party/rust/cose). The payload is signed with the P256 key from +// pykey.py. +const uint8_t SIGNATURE[] = { + 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, 0xb7, 0x50, 0xae, + 0x12, 0x41, 0xb2, 0x62, 0x28, 0x80, 0x0b, 0xaa, 0x99, 0xec, 0x5f, 0x1c, 0x91, + 0x2f, 0xd8, 0x65, 0xd0, 0x1c, 0x38, 0x7c, 0x37, 0x63, 0x6d, 0xfa, 0x67, 0x9d, + 0x21, 0xff, 0x54, 0x98, 0xf8, 0x97, 0x63, 0xc2, 0x2e, 0x3c, 0xfa, 0x25, 0x28, + 0xec, 0x2c, 0x96, 0x8c, 0xca, 0xfc, 0x94, 0xd0, 0xc2, 0x19, 0x28, 0x28, 0x43, + 0xe6, 0x64, 0xd4, 0x09, 0x2b, 0x0f, 0x01, 0xc3, 0x6e +}; + +// This is a COSE signature generated with the cose rust library (see +// third-party/rust/cose). The payload is signed twice; with the P256 and the +// RSA key from pykey.py. +const uint8_t SIGNATURE_ES256_PS256[] = { + 0xd8, 0x62, 0x84, 0x59, 0x08, 0x52, 0xa1, 0x04, 0x84, 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, 0x59, 0x02, 0xd5, 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, 0x59, 0x02, 0xd4, 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, 0xa0, 0xf6, 0x82, 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, 0xfa, 0xc6, 0xb7, 0xae, + 0xec, 0x0b, 0x0b, 0xe2, 0xef, 0xae, 0xf7, 0x9d, 0x64, 0xe5, 0xaf, 0xbb, 0x2c, + 0x4b, 0xe8, 0x7c, 0x61, 0xa9, 0x1e, 0xb9, 0x6d, 0x9c, 0xfa, 0xe3, 0x11, 0x77, + 0xaf, 0x44, 0x9d, 0xc3, 0xa8, 0xa9, 0xbc, 0x58, 0xed, 0xc5, 0xe5, 0xa1, 0x92, + 0x3b, 0x89, 0xa3, 0x3b, 0x1e, 0xbf, 0x6e, 0x33, 0x64, 0x21, 0x0b, 0x97, 0xee, + 0xb7, 0xae, 0x84, 0x17, 0x5c, 0xff, 0x27, 0xa0, 0x83, 0x59, 0x02, 0xbb, 0xa2, + 0x01, 0x38, 0x24, 0x04, 0x59, 0x02, 0xb3, 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, 0xa0, 0x59, 0x01, 0x00, + 0x67, 0xbe, 0xe4, 0x81, 0xed, 0x1e, 0xce, 0x7d, 0x18, 0xf5, 0x85, 0xa2, 0xcb, + 0x1d, 0x75, 0x6f, 0x8a, 0x34, 0xaa, 0x6b, 0x58, 0x91, 0xd2, 0xa4, 0x58, 0x4f, + 0xe1, 0x8b, 0x6a, 0x36, 0xe1, 0x67, 0x23, 0x2c, 0x5d, 0x7e, 0x05, 0xe2, 0xa0, + 0x18, 0xa8, 0x78, 0x7d, 0x85, 0xda, 0x07, 0x60, 0xc6, 0x8e, 0x44, 0x14, 0xad, + 0xbc, 0x35, 0x2f, 0xf3, 0xd8, 0xda, 0x34, 0x65, 0x12, 0x45, 0x6a, 0xbe, 0x46, + 0x53, 0x09, 0xc8, 0xcc, 0x96, 0x6b, 0x07, 0xd4, 0xc3, 0x4f, 0xd2, 0x7b, 0x88, + 0xad, 0x10, 0x3b, 0x93, 0x3c, 0x9a, 0xc4, 0x1a, 0x98, 0x12, 0x2f, 0xf9, 0xc9, + 0xb9, 0xd2, 0xda, 0x40, 0xe9, 0x9e, 0xd8, 0x74, 0x2f, 0x02, 0xf1, 0xf0, 0x9a, + 0x31, 0x99, 0xb4, 0x82, 0xe1, 0x25, 0xee, 0x3f, 0xf9, 0xd5, 0xbb, 0x10, 0x8b, + 0xff, 0x03, 0x0f, 0xcb, 0x96, 0x8f, 0x29, 0x51, 0x71, 0xfc, 0xe2, 0x0e, 0x9c, + 0xf7, 0x3d, 0xc0, 0x95, 0xc6, 0x70, 0xfd, 0x8c, 0xb7, 0xf6, 0xa7, 0xfa, 0x7d, + 0xd6, 0x44, 0x0b, 0xa3, 0xd3, 0x97, 0xf5, 0xcd, 0x6d, 0xc9, 0x17, 0xc6, 0xcb, + 0xd5, 0x82, 0x01, 0x0e, 0xef, 0xb3, 0xbd, 0x33, 0x6e, 0x49, 0x57, 0xb1, 0x38, + 0x57, 0x27, 0x91, 0x22, 0x5a, 0xeb, 0x02, 0x97, 0x53, 0xeb, 0x56, 0x01, 0xdc, + 0xf9, 0xe9, 0x6c, 0x38, 0x7c, 0x0b, 0x1c, 0x7e, 0x19, 0xc7, 0x4b, 0x9d, 0x30, + 0xad, 0x14, 0x2a, 0xb2, 0x07, 0x99, 0x80, 0x40, 0x42, 0x82, 0x49, 0x4e, 0xb5, + 0x1a, 0x49, 0xa3, 0x31, 0x7f, 0xd9, 0x78, 0xd1, 0x08, 0x39, 0xaf, 0x0d, 0xeb, + 0x8a, 0x93, 0x43, 0xab, 0x3d, 0x3f, 0x9b, 0xe3, 0x25, 0x3b, 0x09, 0xa9, 0x00, + 0xfc, 0x98, 0xb9, 0xdc, 0x73, 0x91, 0x87, 0x58, 0x53, 0xd4, 0xc1, 0x8b, 0x05, + 0xe6, 0x85, 0xc8, 0x48, 0xb8, 0x7e, 0x23, 0xcf, 0x12 +}; + +// The RSA intermediate certificate that issued the EE cert used in the +// signature above. The certificate was generated with pycert.py +const uint8_t RSA_INT[] = { + 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 +}; + +// The RSA root certificate that issued the RSA intermediate certificate above. +// The certificate was generated with pycert.py +const uint8_t RSA_ROOT[] = { + 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 +}; + +// The P256 intermediate certificate that issued the EE cert used in the +// signatures above. The certificate was generated with pycert.py +const uint8_t P256_INT[] = { + 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 +}; + +// The P256 root certificate that issued the P256 intermediate certificate +// above. The certificate was generated with pycert.py +const uint8_t P256_ROOT[] = { + 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 +}; + +void +check_hard_coded_certs(const uint8_t** cert_chain, + size_t cert_chain_len, + const size_t* certs_len) +{ + // Very hacky and fragile check that the intermediate certs are correct. + switch (cert_chain_len) { + case 2: { + const uint8_t* cert = cert_chain[0]; + size_t cert_len = certs_len[0]; + ASSERT_EQ(cert_len, sizeof(P256_ROOT)); + ASSERT_EQ(0, memcmp(cert, P256_ROOT, cert_len)); + cert = cert_chain[1]; + cert_len = certs_len[1]; + ASSERT_EQ(cert_len, sizeof(P256_INT)); + ASSERT_EQ(0, memcmp(cert, P256_INT, cert_len)); + break; + } + case 4: { + const uint8_t* cert = cert_chain[0]; + size_t cert_len = certs_len[0]; + ASSERT_EQ(cert_len, sizeof(P256_ROOT)); + ASSERT_EQ(0, memcmp(cert, P256_ROOT, cert_len)); + cert = cert_chain[1]; + cert_len = certs_len[1]; + ASSERT_EQ(cert_len, sizeof(P256_INT)); + ASSERT_EQ(0, memcmp(cert, P256_INT, cert_len)); + cert = cert_chain[2]; + cert_len = certs_len[2]; + ASSERT_EQ(cert_len, sizeof(RSA_ROOT)); + ASSERT_EQ(0, memcmp(cert, RSA_ROOT, cert_len)); + cert = cert_chain[3]; + cert_len = certs_len[3]; + ASSERT_EQ(cert_len, sizeof(RSA_INT)); + ASSERT_EQ(0, memcmp(cert, RSA_INT, cert_len)); + break; + } + default: + // In this case something went wrong. + ASSERT_EQ(true, false); + } +} + +/* Verification function called from cose-rust. + * Returns true if everything goes well and the signature is good, false in any + * other case. */ +bool +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 signature_algorithm) +{ + UniquePK11SlotInfo slot(PK11_GetInternalSlot()); + if (!slot) { + return false; + } + + CK_MECHANISM_TYPE mechanism; + SECOidTag oid; + uint32_t hash_length; + SECItem param = { siBuffer, nullptr, 0 }; + CK_RSA_PKCS_PSS_PARAMS rsa_pss_params = { CKM_SHA256, CKG_MGF1_SHA256, SHA256_LENGTH }; + switch (signature_algorithm) { + case (ES256): + mechanism = CKM_ECDSA; + oid = SEC_OID_SHA256; + hash_length = SHA256_LENGTH; + break; + case (PS256): + mechanism = CKM_RSA_PKCS_PSS; + oid = SEC_OID_SHA256; + hash_length = SHA256_LENGTH; + param = { siBuffer, + reinterpret_cast(&rsa_pss_params), + sizeof(rsa_pss_params) }; + break; + default: + return false; + } + check_hard_coded_certs(cert_chain, cert_chain_len, certs_len); + + uint8_t hash_buf[HASH_LENGTH_MAX]; + SECStatus rv = PK11_HashBuf(oid, hash_buf, payload, payload_len); + if (rv != SECSuccess) { + return false; + } + SECItem hash_item = { siBuffer, hash_buf, hash_length }; + CERTCertDBHandle* db_handle = CERT_GetDefaultCertDB(); + if (!db_handle) { + return false; + } + SECItem der_cert = { siBuffer, + const_cast(ee_cert), + static_cast(ee_cert_len) }; + UniqueCERTCertificate cert( + CERT_NewTempCertificate(db_handle, &der_cert, nullptr, false, true)); + if (!cert) { + return false; + } + UniqueSECKEYPublicKey key(CERT_ExtractPublicKey(cert.get())); + if (!key) { + return false; + } + SECItem signature_item = { siBuffer, + const_cast(signature), + static_cast(signature_len) }; + rv = PK11_VerifyWithMechanism( + key.get(), mechanism, ¶m, &signature_item, &hash_item, nullptr); + if (rv != SECSuccess) { + return false; + } + + return true; +} + +class psm_COSE : public ::testing::Test +{ +}; + +TEST_F(psm_COSE, CoseTestingSingleSignature) +{ + SECStatus rv = NSS_NoDB_Init(nullptr); + ASSERT_EQ(SECSuccess, rv); + bool result = verify_cose_signature_ffi( + PAYLOAD, sizeof(PAYLOAD), SIGNATURE, sizeof(SIGNATURE), verify_callback); + ASSERT_TRUE(result); +} + +TEST_F(psm_COSE, CoseTestingTwoSignatures) +{ + SECStatus rv = NSS_NoDB_Init(nullptr); + ASSERT_EQ(SECSuccess, rv); + bool result = verify_cose_signature_ffi(PAYLOAD, + sizeof(PAYLOAD), + SIGNATURE_ES256_PS256, + sizeof(SIGNATURE_ES256_PS256), + verify_callback); + ASSERT_TRUE(result); +} + +TEST_F(psm_COSE, CoseTestingAlteredPayload) +{ + SECStatus rv = NSS_NoDB_Init(nullptr); + ASSERT_EQ(SECSuccess, rv); + uint8_t altered_payload[20] = { 84, 104, 105, 115, 32, 104, 115, + 32, 116, 104, 101, 32, 99, 111, + 110, 116, 101, 110, 116, 46 }; + bool result = verify_cose_signature_ffi(altered_payload, + sizeof(altered_payload), + SIGNATURE_ES256_PS256, + sizeof(SIGNATURE_ES256_PS256), + verify_callback); + ASSERT_FALSE(result); +} + +} // namespace mozilla diff --git a/security/manager/ssl/tests/gtest/moz.build b/security/manager/ssl/tests/gtest/moz.build index 72b965fbf034..12b9e671ab30 100644 --- a/security/manager/ssl/tests/gtest/moz.build +++ b/security/manager/ssl/tests/gtest/moz.build @@ -7,6 +7,7 @@ SOURCES += [ 'CertDBTest.cpp', 'CertListTest.cpp', + 'CoseTest.cpp', 'DataStorageTest.cpp', 'DeserializeCertTest.cpp', 'MD4Test.cpp', @@ -19,6 +20,7 @@ LOCAL_INCLUDES += [ '/security/manager/ssl', '/security/pkix/include', '/security/pkix/test/lib', + '/third_party/rust/cose-c/include', ] include('/ipc/chromium/chromium-config.mozbuild') 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 000000000000..b6dac98cddaf --- /dev/null +++ b/third_party/rust/cose-c/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"6689411cf004e6ebc4645105de26492adbea6f690f9184119cf1689829ff098a","LICENSE":"1f256ecad192880510e84ad60474eab7589218784b9a50bc7ceee34c2b91f1d5","include/cosec.h":"9e952f6bf578c812e67a93c3c810f4aaa57d365932fe8d01f36f587e8aa32538","src/lib.rs":"d10a17e4840187711d85058bf4afdbfbda88c74a9483921ee48a1bfc0cc5ff70"},"package":"07cc8bb85ec2e93541ef9369b85a4b6fb7732bc7f4854d317eab20e726b0fc2f"} \ 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 000000000000..caa174f30e23 --- /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.1" +authors = ["Franziskus Kiefer "] +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.2" diff --git a/third_party/rust/cose-c/LICENSE b/third_party/rust/cose-c/LICENSE new file mode 100644 index 000000000000..a612ad9813b0 --- /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 000000000000..ee96cdfc2f6e --- /dev/null +++ b/third_party/rust/cose-c/include/cosec.h @@ -0,0 +1,32 @@ +/* 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 + +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); +bool +verify_cose_signature_ffi(const uint8_t* payload, + size_t payload_len, + const uint8_t* signature, + size_t signature_len, + 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 000000000000..526889154909 --- /dev/null +++ b/third_party/rust/cose-c/src/lib.rs @@ -0,0 +1,85 @@ +/* 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; + +unsafe fn from_raw(ptr: *const u8, len: usize) -> Vec { + 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 */) + -> 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, + 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, + ) + }); +} diff --git a/third_party/rust/cose/.cargo-checksum.json b/third_party/rust/cose/.cargo-checksum.json new file mode 100644 index 000000000000..2aef910f1af7 --- /dev/null +++ b/third_party/rust/cose/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{".travis.yml":"be3532bc6d5d823090206ad957c8705436960d1918a2c577342f6914a233ca98","Cargo.toml":"5eb5257aced25840b3af43757478e4dfa38e2f222cb25794ffeeb681b6a46ce2","LICENSE":"1f256ecad192880510e84ad60474eab7589218784b9a50bc7ceee34c2b91f1d5","README.md":"42a12b9a8944a2888ce2622bb03c06850163ab738917414e3413b63be9257a8a","build.rs":"a2b798bbeaf8ef19a9bd8c1e24b3fd3899a5b4b3e121e5e09794e4e2b35971dd","rustfmt.toml":"e97717e906fcd3eeb86dcee52ed26f13e1884597b016a27172229d9c78dd3d57","src/cbor/decoder.rs":"b9e375489131aea75fb461c9ee96e45595e08957c90179f2c449226a31b7e4c5","src/cbor/mod.rs":"f5b767eedbee01b3f697afb2dce777c6043e6fea6f9a7eab8387560caaa40100","src/cbor/serializer.rs":"d86f0123f364046c8c18b45e109437b16c24d29bc7ef01c12a7c465e89878836","src/cbor/test_decoder.rs":"6a47f0f98f54a343f12c78033c94c5892b0a5b5e62de251bef3a722f358978ab","src/cbor/test_serializer.rs":"984fbe0520e77d078fb2e2c60e4e0df077d40ede644b1b92651f3a0696377511","src/cose.rs":"1a5c23f31863c58838f4aa94c2940e9f18252929c990d2a9522490e56593710e","src/decoder.rs":"ce86fd2f72cf02185ea724d63e5cb24aaea9ff6a2f3137c20322764a3ea9d15e","src/nss.rs":"e17101aa957367ee025afd5af37d72a955d9b79098ab7db1631f93b6479230a3","src/test_cose.rs":"35798ef9ee5849204b36a69b07969c0b4f3976d0e44ccfff6f413a2e3684f76b","src/test_nss.rs":"51ececb4a8fd8ddba7e1af179b9326e38a838d4693998092f842db5f30e75703","src/test_setup.rs":"b2c8d5b4a20013fd89bcc9d5732af509331a648a1163a9e44b47e51dde2b6308","src/util.rs":"fbc1a2051230156c2504efcff5044fbf54a6f925aa7dfb97c211208348364425","src/util_test.rs":"49dde5be7202aa2fa3f7ac6d36de189739cd5538e378f5c0a27161b9185e9ca6","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":"ec10816629f38fa557f08e199a3474fab954f4c8d2645550367235afa6e5646b"} \ No newline at end of file diff --git a/third_party/rust/cose/.travis.yml b/third_party/rust/cose/.travis.yml new file mode 100644 index 000000000000..5e165342024b --- /dev/null +++ b/third_party/rust/cose/.travis.yml @@ -0,0 +1,31 @@ +sudo: true +language: rust +cache: cargo +rust: + - stable + - beta + - nightly + +addons: + apt: + packages: + - build-essential + - libnss3-dev + +install: +# Apparently cargo install returns a nonzero exit status if +# caching succeeds, so just make this always "succeed". + - (cargo install rustfmt || true) + +script: +# The NSS version in Ubuntu is too old. Get a newer one. +- | + wget http://de.archive.ubuntu.com/ubuntu/pool/main/n/nss/libnss3_3.32-1ubuntu3_amd64.deb + wget http://de.archive.ubuntu.com/ubuntu/pool/main/n/nspr/libnspr4_4.16-1ubuntu2_amd64.deb + sudo dpkg -i libnspr4_4.16-1ubuntu2_amd64.deb + sudo dpkg -i libnss3_3.32-1ubuntu3_amd64.deb +- | + cargo fmt -- --write-mode=diff +- | + cargo build --features "$FEATURES" && + cargo test diff --git a/third_party/rust/cose/Cargo.toml b/third_party/rust/cose/Cargo.toml new file mode 100644 index 000000000000..711785e49fbd --- /dev/null +++ b/third_party/rust/cose/Cargo.toml @@ -0,0 +1,30 @@ +# 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.2" +authors = ["Franziskus Kiefer ", "David Keeler "] +build = "build.rs" +description = "Library to use COSE (https://tools.ietf.org/html/rfc8152) in Rust" +keywords = ["cose", "jose", "cbor"] +license = "MPL-2.0" +repository = "https://github.com/franziskuskiefer/cose-rust" + +[lib] +name = "cose" +path = "src/cose.rs" +[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 000000000000..a612ad9813b0 --- /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 000000000000..0547779eb0ef --- /dev/null +++ b/third_party/rust/cose/README.md @@ -0,0 +1,15 @@ +# 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 diff --git a/third_party/rust/cose/build.rs b/third_party/rust/cose/build.rs new file mode 100644 index 000000000000..8db7af5ad197 --- /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/rustfmt.toml b/third_party/rust/cose/rustfmt.toml new file mode 100644 index 000000000000..a47e18ea00a9 --- /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/cbor/decoder.rs b/third_party/rust/cose/src/cbor/decoder.rs new file mode 100644 index 000000000000..bb980737e37d --- /dev/null +++ b/third_party/rust/cose/src/cbor/decoder.rs @@ -0,0 +1,150 @@ +use std::collections::BTreeMap; +use std::io::{Cursor, Read, Seek, SeekFrom}; +use cbor::{CborError, CborType}; + +// We limit the length of any cbor byte array to 128MiB. This is a somewhat +// arbitrary limit that should work on all platforms and is large enough for +// any benign data. +pub const MAX_ARRAY_SIZE: usize = 134_217_728; + +/// Struct holding a cursor and additional information for decoding. +#[derive(Debug)] +struct DecoderCursor<'a> { + cursor: Cursor<&'a [u8]>, +} + +/// Apply this mask (with &) to get the value part of the initial byte of a CBOR item. +const INITIAL_VALUE_MASK: u64 = 0b0001_1111; + +impl<'a> DecoderCursor<'a> { + /// Read and return the given number of bytes from the cursor. Advances the cursor. + fn read_bytes(&mut self, len: usize) -> Result, CborError> { + if len > MAX_ARRAY_SIZE { + return Err(CborError::InputTooLarge); + } + let mut buf: Vec = vec![0; len]; + if self.cursor.read_exact(&mut buf).is_err() { + Err(CborError::TruncatedInput) + } else { + Ok(buf) + } + } + + /// Convert num bytes to a u64 + fn read_uint_from_bytes(&mut self, num: usize) -> Result { + let x = self.read_bytes(num)?; + let mut result: u64 = 0; + for i in (0..num).rev() { + result += u64::from(x[num - 1 - i]) << (i * 8); + } + Ok(result) + } + + /// Read an integer and return it as u64. + fn read_int(&mut self) -> Result { + let first_value = self.read_uint_from_bytes(1)? & INITIAL_VALUE_MASK; + match first_value { + 0...23 => Ok(first_value), + 24 => self.read_uint_from_bytes(1), + 25 => self.read_uint_from_bytes(2), + 26 => self.read_uint_from_bytes(4), + 27 => self.read_uint_from_bytes(8), + _ => Err(CborError::MalformedInput), + } + } + + fn read_negative_int(&mut self) -> Result { + let uint = self.read_int()?; + if uint > i64::max_value() as u64 { + return Err(CborError::InputValueOutOfRange); + } + let result: i64 = -1 - uint as i64; + Ok(CborType::SignedInteger(result)) + } + + /// Read an array of data items and return it. + fn read_array(&mut self) -> Result { + // Create a new array. + let mut array: Vec = Vec::new(); + // Read the length of the array. + let num_items = self.read_int()?; + // Decode each of the num_items data items. + for _ in 0..num_items { + let new_item = self.decode_item()?; + array.push(new_item); + } + Ok(CborType::Array(array)) + } + + /// Read a byte string and return it. + fn read_byte_string(&mut self) -> Result { + let length = self.read_int()?; + if length > MAX_ARRAY_SIZE as u64 { + return Err(CborError::InputTooLarge); + } + let byte_string = self.read_bytes(length as usize)?; + Ok(CborType::Bytes(byte_string)) + } + + /// Read a map. + fn read_map(&mut self) -> Result { + let num_items = self.read_int()?; + // Create a new array. + let mut map: BTreeMap = BTreeMap::new(); + // Decode each of the num_items (key, data item) pairs. + for _ in 0..num_items { + let key_val = self.decode_item()?; + let item_value = self.decode_item()?; + if map.insert(key_val, item_value).is_some() { + return Err(CborError::DuplicateMapKey); + } + } + Ok(CborType::Map(map)) + } + + fn read_null(&mut self) -> Result { + let value = self.read_uint_from_bytes(1)? & INITIAL_VALUE_MASK; + if value != 22 { + return Err(CborError::UnsupportedType); + } + Ok(CborType::Null) + } + + /// Peeks at the next byte in the cursor, but does not change the position. + fn peek_byte(&mut self) -> Result { + let x = self.read_bytes(1)?; + if self.cursor.seek(SeekFrom::Current(-1)).is_err() { + return Err(CborError::LibraryError); + }; + Ok(x[0]) + } + + /// Decodes the next CBOR item. + pub fn decode_item(&mut self) -> Result { + let major_type = self.peek_byte()? >> 5; + match major_type { + 0 => { + let value = self.read_int()?; + Ok(CborType::Integer(value)) + } + 1 => self.read_negative_int(), + 2 => self.read_byte_string(), + 4 => self.read_array(), + 5 => self.read_map(), + 6 => { + let tag = self.read_int()?; + let item = self.decode_item()?; + Ok(CborType::Tag(tag, Box::new(item))) + } + 7 => self.read_null(), + _ => Err(CborError::UnsupportedType), + } + } +} + +/// Read the CBOR structure in bytes and return it as a `CborType`. +pub fn decode(bytes: &[u8]) -> Result { + let mut decoder_cursor = DecoderCursor { cursor: Cursor::new(bytes) }; + decoder_cursor.decode_item() + // TODO: check cursor at end? +} diff --git a/third_party/rust/cose/src/cbor/mod.rs b/third_party/rust/cose/src/cbor/mod.rs new file mode 100644 index 000000000000..b796f1a53eae --- /dev/null +++ b/third_party/rust/cose/src/cbor/mod.rs @@ -0,0 +1,56 @@ +pub mod decoder; +pub mod serializer; +#[cfg(test)] +mod test_decoder; +#[cfg(test)] +mod test_serializer; + +use std::collections::BTreeMap; +use std::cmp::Ordering; + +#[derive(Debug)] +#[derive(Clone)] +#[derive(PartialEq)] +#[derive(PartialOrd)] +#[derive(Eq)] +pub enum CborType { + Integer(u64), + SignedInteger(i64), + Tag(u64, Box), + Bytes(Vec), + String(String), + Array(Vec), + Map(BTreeMap), + Null, +} + +#[derive(Debug)] +#[derive(PartialEq)] +pub enum CborError { + DuplicateMapKey, + InputTooLarge, + InputValueOutOfRange, + LibraryError, + MalformedInput, + TruncatedInput, + UnsupportedType, +} + +impl Ord for CborType { + /// Sorting for maps: RFC 7049 Section 3.9 + /// + /// The keys in every map must be sorted lowest value to highest. + /// * If two keys have different lengths, the shorter one sorts + /// earlier; + /// + /// * If two keys have the same length, the one with the lower value + /// in (byte-wise) lexical order sorts earlier. + fn cmp(&self, other: &Self) -> Ordering { + let self_bytes = self.serialize(); + let other_bytes = other.serialize(); + if self_bytes.len() == other_bytes.len() { + return self_bytes.cmp(&other_bytes); + } + self_bytes.len().cmp(&other_bytes.len()) + } +} diff --git a/third_party/rust/cose/src/cbor/serializer.rs b/third_party/rust/cose/src/cbor/serializer.rs new file mode 100644 index 000000000000..70877bbd3710 --- /dev/null +++ b/third_party/rust/cose/src/cbor/serializer.rs @@ -0,0 +1,121 @@ +use std::collections::BTreeMap; +use cbor::CborType; + +/// Given a vector of bytes to append to, a tag to use, and an unsigned value to encode, uses the +/// CBOR unsigned integer encoding to represent the given value. +fn common_encode_unsigned(output: &mut Vec, tag: u8, value: u64) { + assert!(tag < 8); + let shifted_tag = tag << 5; + match value { + 0...23 => { + output.push(shifted_tag | (value as u8)); + } + 24...255 => { + output.push(shifted_tag | 24); + output.push(value as u8); + } + 256...65_535 => { + output.push(shifted_tag | 25); + output.push((value >> 8) as u8); + output.push((value & 255) as u8); + } + 65_536...4_294_967_295 => { + output.push(shifted_tag | 26); + output.push((value >> 24) as u8); + output.push(((value >> 16) & 255) as u8); + output.push(((value >> 8) & 255) as u8); + output.push((value & 255) as u8); + } + _ => { + output.push(shifted_tag | 27); + output.push((value >> 56) as u8); + output.push(((value >> 48) & 255) as u8); + output.push(((value >> 40) & 255) as u8); + output.push(((value >> 32) & 255) as u8); + output.push(((value >> 24) & 255) as u8); + output.push(((value >> 16) & 255) as u8); + output.push(((value >> 8) & 255) as u8); + output.push((value & 255) as u8); + } + }; +} + +/// The major type is 0. For values 0 through 23, the 5 bits of additional information is just the +/// value of the unsigned number. For values representable in one byte, the additional information +/// has the value 24. If two bytes are necessary, the value is 25. If four bytes are necessary, the +/// value is 26. If 8 bytes are necessary, the value is 27. The following bytes are the value of the +/// unsigned number in as many bytes were indicated in network byte order (big endian). +fn encode_unsigned(output: &mut Vec, unsigned: u64) { + common_encode_unsigned(output, 0, unsigned); +} + +/// The major type is 1. The encoding is the same as for positive (i.e. unsigned) integers, except +/// the value encoded is -1 minus the value of the negative number. +fn encode_negative(output: &mut Vec, negative: i64) { + assert!(negative < 0); + let value_to_encode: u64 = (-1 - negative) as u64; + common_encode_unsigned(output, 1, value_to_encode); +} + +/// The major type is 2. The length of the data is encoded as with positive integers, followed by +/// the actual data. +fn encode_bytes(output: &mut Vec, bstr: &[u8]) { + common_encode_unsigned(output, 2, bstr.len() as u64); + output.extend_from_slice(bstr); +} + +/// The major type is 3. The length is as with bstr. The UTF-8-encoded bytes of the string follow. +fn encode_string(output: &mut Vec, tstr: &str) { + let utf8_bytes = tstr.as_bytes(); + common_encode_unsigned(output, 3, utf8_bytes.len() as u64); + output.extend_from_slice(utf8_bytes); +} + +/// The major type is 4. The number of items is encoded as with positive integers. Then follows the +/// encodings of the items themselves. +fn encode_array(output: &mut Vec, array: &[CborType]) { + common_encode_unsigned(output, 4, array.len() as u64); + for element in array { + output.append(&mut element.serialize()); + } +} + +/// The major type is 5. The number of pairs is encoded as with positive integers. Then follows the +/// encodings of each key, value pair. In Canonical CBOR, the keys must be sorted lowest value to +/// highest. +fn encode_map(output: &mut Vec, map: &BTreeMap) { + common_encode_unsigned(output, 5, map.len() as u64); + for (key, value) in map { + output.append(&mut key.serialize()); + output.append(&mut value.serialize()); + } +} + +fn encode_tag(output: &mut Vec, tag: &u64, val: &CborType) { + common_encode_unsigned(output, 6, *tag); + output.append(&mut val.serialize()); +} + +/// The major type is 7. The only supported value for this type is 22, which is Null. +/// This makes the encoded value 246, or 0xf6. +fn encode_null(output: &mut Vec) { + output.push(0xf6); +} + +impl CborType { + /// Serialize a Cbor object. + pub fn serialize(&self) -> Vec { + let mut bytes: Vec = Vec::new(); + match *self { + CborType::Integer(ref unsigned) => encode_unsigned(&mut bytes, *unsigned), + CborType::SignedInteger(ref negative) => encode_negative(&mut bytes, *negative), + CborType::Bytes(ref bstr) => encode_bytes(&mut bytes, bstr), + CborType::String(ref tstr) => encode_string(&mut bytes, tstr), + CborType::Array(ref arr) => encode_array(&mut bytes, arr), + CborType::Map(ref map) => encode_map(&mut bytes, map), + CborType::Tag(ref t, ref val) => encode_tag(&mut bytes, t, val), + CborType::Null => encode_null(&mut bytes), + }; + bytes + } +} diff --git a/third_party/rust/cose/src/cbor/test_decoder.rs b/third_party/rust/cose/src/cbor/test_decoder.rs new file mode 100644 index 000000000000..3392926256b7 --- /dev/null +++ b/third_party/rust/cose/src/cbor/test_decoder.rs @@ -0,0 +1,405 @@ +use cbor::decoder::*; +use cbor::*; +use std::collections::BTreeMap; + +// First test all the basic types +fn test_decoder(bytes: Vec, expected: CborType) { + let result = decode(&bytes); + assert!(result.is_ok()); + assert_eq!(result.unwrap(), expected); +} + +fn test_decoder_error(bytes: Vec, expected_error: CborError) { + let result = decode(&bytes); + assert!(result.is_err()); + assert_eq!(result.unwrap_err(), expected_error); +} + +fn test_integer(bytes: Vec, expected: u64) { + let decoded = decode(&bytes).unwrap(); + match decoded { + CborType::Integer(val) => assert_eq!(val, expected), + _ => assert_eq!(1, 0), + } +} + +fn test_integer_all(bytes: Vec, expected_value: u64) { + let expected = CborType::Integer(expected_value); + test_decoder(bytes.clone(), expected); + test_integer(bytes, expected_value); +} + +#[test] +fn test_integer_objects() { + let bytes: Vec = vec![0x00]; + test_integer_all(bytes, 0); + + let bytes = vec![0x01]; + test_integer_all(bytes, 1); + + let bytes = vec![0x0A]; + test_integer_all(bytes, 10); + + let bytes = vec![0x17]; + test_integer_all(bytes, 23); + + let bytes = vec![0x18, 0x18]; + test_integer_all(bytes, 24); + + let bytes = vec![0x18, 0x19]; + test_integer_all(bytes, 25); + + let bytes = vec![0x18, 0x64]; + test_integer_all(bytes, 100); + + let bytes = vec![0x19, 0x03, 0xe8]; + test_integer_all(bytes, 1000); + + let bytes = vec![0x1a, 0x00, 0x0f, 0x42, 0x40]; + test_integer_all(bytes, 1000000); + + let bytes = vec![0x1b, 0x00, 0x00, 0x00, 0xe8, 0xd4, 0xa5, 0x10, 0x00]; + test_integer_all(bytes, 1000000000000); + + let bytes = vec![0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]; + test_integer_all(bytes, 18446744073709551615); +} + +#[cfg(test)] +fn test_tag(bytes: Vec, expected_tag: u64, expected_value: CborType) { + let decoded = decode(&bytes).unwrap(); + match decoded { + CborType::Tag(tag, value) => { + assert_eq!(expected_tag, tag); + assert_eq!(expected_value, *value); + } + _ => assert_eq!(1, 0), + } +} + +#[test] +fn test_tagged_objects() { + let bytes: Vec = vec![0xD2, 0x02]; + let expected_tag_value = 0x12; + let expected_value = CborType::Integer(2); + let expected = CborType::Tag(expected_tag_value, Box::new(expected_value.clone())); + test_decoder(bytes.clone(), expected); + test_tag(bytes, expected_tag_value, expected_value); +} + +#[test] +#[cfg_attr(rustfmt, rustfmt_skip)] +fn test_arrays() { + // [] + let bytes: Vec = vec![0x80]; + let expected = CborType::Array(vec![]); + test_decoder(bytes, expected); + + // [1, 2, 3] + let bytes: Vec = vec![0x83, 0x01, 0x02, 0x03]; + let tmp = vec![ + CborType::Integer(1), + CborType::Integer(2), + CborType::Integer(3), + ]; + let expected = CborType::Array(tmp); + test_decoder(bytes, expected); + + // [1, [2, 3], [4, 5]] + let bytes: Vec = vec![0x83, 0x01, 0x82, 0x02, 0x03, 0x82, 0x04, 0x05]; + let tmp1 = vec![CborType::Integer(2), CborType::Integer(3)]; + let tmp2 = vec![CborType::Integer(4), CborType::Integer(5)]; + let tmp = vec![ + CborType::Integer(1), + CborType::Array(tmp1), + CborType::Array(tmp2), + ]; + let expected = CborType::Array(tmp); + test_decoder(bytes, expected); + + // [1, [[[[1]]]], [1]] + let bytes: Vec = vec![0x83, 0x01, 0x81, 0x81, 0x81, 0x81, 0x01, 0x81, 0x02]; + let tmp = vec![ + CborType::Integer(1), + CborType::Array(vec![ + CborType::Array(vec![ + CborType::Array(vec![ + CborType::Array(vec![ + CborType::Integer(1)])])])]), + CborType::Array(vec![CborType::Integer(2)]), + ]; + let expected = CborType::Array(tmp); + test_decoder(bytes, expected); + + let bytes: Vec = vec![0x98, 0x1A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x18, 0x18, 0x19, 0x82, 0x81, 0x81, + 0x81, 0x05, 0x81, 0x1A, 0x49, 0x96, 0x02, 0xD2]; + // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + // 21, 22, 23, 24, 25, [[[[5]]], [1234567890]]] + let tmp = vec![ + CborType::Integer(1), + CborType::Integer(2), + CborType::Integer(3), + CborType::Integer(4), + CborType::Integer(5), + CborType::Integer(6), + CborType::Integer(7), + CborType::Integer(8), + CborType::Integer(9), + CborType::Integer(10), + CborType::Integer(11), + CborType::Integer(12), + CborType::Integer(13), + CborType::Integer(14), + CborType::Integer(15), + CborType::Integer(16), + CborType::Integer(17), + CborType::Integer(18), + CborType::Integer(19), + CborType::Integer(20), + CborType::Integer(21), + CborType::Integer(22), + CborType::Integer(23), + CborType::Integer(24), + CborType::Integer(25), + CborType::Array(vec![ + CborType::Array(vec![ + CborType::Array(vec![ + CborType::Array(vec![ + CborType::Integer(5)])])]), + CborType::Array(vec![CborType::Integer(1234567890)])]) + ]; + let expected = CborType::Array(tmp); + test_decoder(bytes, expected); +} + +#[test] +fn test_signed_integer() { + let bytes: Vec = vec![0x20]; + let expected = CborType::SignedInteger(-1); + test_decoder(bytes, expected); + + let bytes = vec![0x29]; + let expected = CborType::SignedInteger(-10); + test_decoder(bytes, expected); + + let bytes = vec![0x38, 0x63]; + let expected = CborType::SignedInteger(-100); + test_decoder(bytes, expected); + + let bytes = vec![0x39, 0x03, 0xe7]; + let expected = CborType::SignedInteger(-1000); + test_decoder(bytes, expected); + + let bytes = vec![0x39, 0x27, 0x0F]; + let expected = CborType::SignedInteger(-10000); + test_decoder(bytes, expected); + + let bytes = vec![0x3A, 0x00, 0x01, 0x86, 0x9F]; + let expected = CborType::SignedInteger(-100000); + test_decoder(bytes, expected); + + let bytes = vec![0x3B, 0x00, 0x00, 0x00, 0xE8, 0xD4, 0xA5, 0x0F, 0xFF]; + let expected = CborType::SignedInteger(-1000000000000); + test_decoder(bytes, expected); +} + +#[test] +fn test_byte_strings() { + let bytes: Vec = vec![0x40]; + let expected = CborType::Bytes(vec![]); + test_decoder(bytes, expected); + + // 01020304 + let bytes: Vec = vec![0x44, 0x01, 0x02, 0x03, 0x04]; + let expected = CborType::Bytes(vec![0x01, 0x02, 0x03, 0x04]); + test_decoder(bytes, expected); + + // 0102030405060708090A0B0C0D0E0F10203040506070 + let bytes: Vec = vec![0x56, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, + 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, + 0x70]; + let expected = CborType::Bytes(vec![0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x20, 0x30, + 0x40, 0x50, 0x60, 0x70]); + test_decoder(bytes, expected); + + let bytes: Vec = + vec![0x59, 0x01, 0x0E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]; + let expected = CborType::Bytes(vec![0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]); + test_decoder(bytes, expected); +} + +#[test] +fn test_maps() { + // {} + let bytes: Vec = vec![0xa0]; + let expected: BTreeMap = BTreeMap::new(); + test_decoder(bytes, CborType::Map(expected)); + + // {1: 2, 3: 4} + let bytes: Vec = vec![0xa2, 0x01, 0x02, 0x03, 0x04]; + let mut expected: BTreeMap = BTreeMap::new(); + expected.insert(CborType::Integer(1), CborType::Integer(2)); + expected.insert(CborType::Integer(3), CborType::Integer(4)); + test_decoder(bytes, CborType::Map(expected)); + + // TODO: strings aren't properly supported as keys yet. + // {"a": 1, "b": [2, 3]} + // let bytes: Vec = vec![0xa2, 0x61, 0x61, 0x01, 0x61, 0x62, 0x82, 0x02, 0x03]; + // let expected = + // CborType::Map(vec![ + // CborMap{key: CborType::Integer(1), value: CborType::Integer(2)}, + // CborMap{key: CborType::Integer(3), value: CborType::Integer(4)}]); + // test_decoder(bytes, expected); + + // let bytes: Vec = vec![0x82, 0x61, 0x61, 0xa1, 0x61, 0x62, 0x61, 0x63]; + // test_decoder(bytes, "[a, {b: c}]"); + + // let bytes: Vec = vec![0xa5, 0x61, 0x61, 0x61, 0x41, 0x61, 0x62, 0x61, + // 0x42, 0x61, 0x63, 0x61, 0x43, 0x61, 0x64, 0x61, + // 0x44, 0x61, 0x65, 0x61, 0x45]; + // test_decoder(bytes, "{a: A, b: B, c: C, d: D, e: E}"); +} + +#[test] +fn test_map_duplicate_keys() { + let bytes: Vec = vec![0xa4, 0x01, 0x02, 0x02, 0x03, 0x01, 0x03, 0x04, 0x04]; + test_decoder_error(bytes, CborError::DuplicateMapKey); +} + +#[test] +fn test_tag_with_no_value() { + let bytes: Vec = vec![0xc0]; + test_decoder_error(bytes, CborError::TruncatedInput); +} + +#[test] +fn test_truncated_int() { + let bytes: Vec = vec![0x19, 0x03]; + test_decoder_error(bytes, CborError::TruncatedInput); +} + +#[test] +fn test_truncated_array() { + let bytes: Vec = vec![0x83, 0x01, 0x02]; + test_decoder_error(bytes, CborError::TruncatedInput); +} + +#[test] +fn test_truncated_map() { + let bytes: Vec = vec![0xa2, 0x01, 0x02, 0x00]; + test_decoder_error(bytes, CborError::TruncatedInput); +} + +#[test] +fn test_malformed_integer() { + let bytes: Vec = vec![0x1c]; + test_decoder_error(bytes, CborError::MalformedInput); +} + +#[test] +fn test_signed_integer_too_large() { + let bytes = vec![0x3b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]; + test_decoder_error(bytes, CborError::InputValueOutOfRange); +} + +#[test] +fn test_null() { + let bytes = vec![0xf6]; + test_decoder(bytes, CborType::Null); +} + +#[test] +fn test_null_in_array() { + let bytes = vec![0x82, 0xf6, 0xf6]; + test_decoder( + bytes, + CborType::Array(vec![CborType::Null, + CborType::Null]), + ); +} + +#[test] +fn test_major_type_7() { + for i in 0..0x20 { + if i != 22 { + let bytes = vec![0xe0 | i]; + test_decoder_error(bytes, CborError::UnsupportedType); + } + } +} + +#[test] +fn test_large_input() { + let array = vec![0xFF; MAX_ARRAY_SIZE]; + let expected = CborType::Bytes(array.clone()); + let mut bytes = vec![0x5A, 0x08, 0x00, 0x00, 0x00]; + bytes.extend_from_slice(&array); + test_decoder(bytes, expected); +} + +#[test] +fn test_too_large_input() { + let array = vec![0xFF; MAX_ARRAY_SIZE + 1]; + let mut bytes = vec![0x5A, 0x08, 0x00, 0x00, 0x01]; + bytes.extend_from_slice(&array); + test_decoder_error(bytes, CborError::InputTooLarge); +} + +// We currently don't support CBOR strings (issue #39). +#[test] +fn test_invalid_input() { + let bytes = vec![0x60]; + test_decoder_error(bytes, CborError::UnsupportedType); +} diff --git a/third_party/rust/cose/src/cbor/test_serializer.rs b/third_party/rust/cose/src/cbor/test_serializer.rs new file mode 100644 index 000000000000..dc662128a715 --- /dev/null +++ b/third_party/rust/cose/src/cbor/test_serializer.rs @@ -0,0 +1,310 @@ +use cbor::CborType; +use std::collections::BTreeMap; + +#[test] +fn test_nint() { + struct Testcase { + value: i64, + expected: Vec, + } + let testcases: Vec = vec![Testcase { + value: -1, + expected: vec![0x20], + }, + Testcase { + value: -10, + expected: vec![0x29], + }, + Testcase { + value: -100, + expected: vec![0x38, 0x63], + }, + Testcase { + value: -1000, + expected: vec![0x39, 0x03, 0xe7], + }, + Testcase { + value: -1000000, + expected: vec![0x3a, 0x00, 0x0f, 0x42, 0x3f], + }, + Testcase { + value: -4611686018427387903, + expected: vec![0x3b, 0x3f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfe], + }]; + for testcase in testcases { + let cbor = CborType::SignedInteger(testcase.value); + assert_eq!(testcase.expected, cbor.serialize()); + } +} + +#[test] +fn test_bstr() { + struct Testcase { + value: Vec, + expected: Vec, + } + let testcases: Vec = + vec![Testcase { + value: vec![], + expected: vec![0x40], + }, + Testcase { + value: vec![0x01, 0x02, 0x03, 0x04], + expected: vec![0x44, 0x01, 0x02, 0x03, 0x04], + }, + Testcase { + value: vec![0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, + 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, + 0xaf, 0xaf, 0xaf], + expected: vec![0x58, 0x19, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, + 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, + 0xaf, 0xaf, 0xaf, 0xaf, 0xaf], + }]; + for testcase in testcases { + let cbor = CborType::Bytes(testcase.value); + assert_eq!(testcase.expected, cbor.serialize()); + } +} + +#[test] +fn test_tstr() { + struct Testcase { + value: String, + expected: Vec, + } + let testcases: Vec = vec![Testcase { + value: String::new(), + expected: vec![0x60], + }, + Testcase { + value: String::from("a"), + expected: vec![0x61, 0x61], + }, + Testcase { + value: String::from("IETF"), + expected: vec![0x64, 0x49, 0x45, 0x54, 0x46], + }, + Testcase { + value: String::from("\"\\"), + expected: vec![0x62, 0x22, 0x5c], + }, + Testcase { + value: String::from("æ°´"), + expected: vec![0x63, 0xe6, 0xb0, 0xb4], + }]; + for testcase in testcases { + let cbor = CborType::String(testcase.value); + assert_eq!(testcase.expected, cbor.serialize()); + } +} + +#[test] +fn test_arr() { + struct Testcase { + value: Vec, + expected: Vec, + } + let nested_arr_1 = vec![CborType::Integer(2), + CborType::Integer(3)]; + let nested_arr_2 = vec![CborType::Integer(4), + CborType::Integer(5)]; + let testcases: Vec = + vec![Testcase { + value: vec![], + expected: vec![0x80], + }, + Testcase { + value: vec![CborType::Integer(1), + CborType::Integer(2), + CborType::Integer(3)], + expected: vec![0x83, 0x01, 0x02, 0x03], + }, + Testcase { + value: vec![CborType::Integer(1), + CborType::Array(nested_arr_1), + CborType::Array(nested_arr_2)], + expected: vec![0x83, 0x01, 0x82, 0x02, 0x03, 0x82, 0x04, 0x05], + }, + Testcase { + value: vec![CborType::Integer(1), + CborType::Integer(2), + CborType::Integer(3), + CborType::Integer(4), + CborType::Integer(5), + CborType::Integer(6), + CborType::Integer(7), + CborType::Integer(8), + CborType::Integer(9), + CborType::Integer(10), + CborType::Integer(11), + CborType::Integer(12), + CborType::Integer(13), + CborType::Integer(14), + CborType::Integer(15), + CborType::Integer(16), + CborType::Integer(17), + CborType::Integer(18), + CborType::Integer(19), + CborType::Integer(20), + CborType::Integer(21), + CborType::Integer(22), + CborType::Integer(23), + CborType::Integer(24), + CborType::Integer(25)], + expected: vec![0x98, 0x19, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16, 0x17, 0x18, 0x18, 0x18, 0x19], + }]; + for testcase in testcases { + let cbor = CborType::Array(testcase.value); + assert_eq!(testcase.expected, cbor.serialize()); + } +} + +#[test] +fn test_map() { + let empty_map: BTreeMap = BTreeMap::new(); + assert_eq!(vec![0xa0], CborType::Map(empty_map).serialize()); + + let mut positive_map: BTreeMap = BTreeMap::new(); + positive_map.insert(CborType::Integer(20), CborType::Integer(10)); + positive_map.insert(CborType::Integer(10), CborType::Integer(20)); + positive_map.insert(CborType::Integer(15), CborType::Integer(15)); + assert_eq!( + vec![0xa3, 0x0a, 0x14, 0x0f, 0x0f, 0x14, 0x0a], + CborType::Map(positive_map).serialize() + ); + + let mut negative_map: BTreeMap = BTreeMap::new(); + negative_map.insert(CborType::SignedInteger(-4), CborType::Integer(10)); + negative_map.insert(CborType::SignedInteger(-1), CborType::Integer(20)); + negative_map.insert(CborType::SignedInteger(-5), CborType::Integer(15)); + negative_map.insert(CborType::SignedInteger(-6), CborType::Integer(10)); + assert_eq!( + vec![0xa4, 0x20, 0x14, 0x23, 0x0a, 0x24, 0x0f, 0x25, 0x0a], + CborType::Map(negative_map).serialize() + ); + + let mut mixed_map: BTreeMap = BTreeMap::new(); + mixed_map.insert(CborType::Integer(0), CborType::Integer(10)); + mixed_map.insert(CborType::SignedInteger(-10), CborType::Integer(20)); + mixed_map.insert(CborType::Integer(15), CborType::Integer(15)); + assert_eq!( + vec![0xa3, 0x00, 0x0a, 0x0f, 0x0f, 0x29, 0x14], + CborType::Map(mixed_map).serialize() + ); + + let mut very_mixed_map: BTreeMap = BTreeMap::new(); + very_mixed_map.insert(CborType::Integer(0), CborType::Integer(10)); + very_mixed_map.insert( + CborType::SignedInteger(-10000), + CborType::String("low".to_string()), + ); + very_mixed_map.insert(CborType::SignedInteger(-10), CborType::Integer(20)); + very_mixed_map.insert( + CborType::Integer(10001), + CborType::String("high".to_string()), + ); + very_mixed_map.insert( + CborType::Integer(10000), + CborType::String("high".to_string()), + ); + very_mixed_map.insert(CborType::Integer(15), CborType::Integer(15)); + let expected = vec![0xa6, 0x00, 0x0a, 0x0f, 0x0f, 0x29, 0x14, 0x19, 0x27, 0x10, 0x64, 0x68, + 0x69, 0x67, 0x68, 0x19, 0x27, 0x11, 0x64, 0x68, 0x69, 0x67, 0x68, 0x39, + 0x27, 0x0F, 0x63, 0x6C, 0x6F, 0x77]; + assert_eq!(expected, CborType::Map(very_mixed_map).serialize()); +} + +#[test] +#[ignore] +// XXX: The string isn't put into the map at the moment, so we can't actually +// test this. +fn test_invalid_map() { + let mut invalid_map: BTreeMap = BTreeMap::new(); + invalid_map.insert(CborType::SignedInteger(-10), CborType::Integer(20)); + invalid_map.insert(CborType::String("0".to_string()), CborType::Integer(10)); + invalid_map.insert(CborType::Integer(15), CborType::Integer(15)); + let expected: Vec = vec![]; + assert_eq!(expected, CborType::Map(invalid_map).serialize()); +} + +#[test] +fn test_integer() { + struct Testcase { + value: u64, + expected: Vec, + } + let testcases: Vec = + vec![Testcase { + value: 0, + expected: vec![0], + }, + Testcase { + value: 1, + expected: vec![1], + }, + Testcase { + value: 10, + expected: vec![0x0a], + }, + Testcase { + value: 23, + expected: vec![0x17], + }, + Testcase { + value: 24, + expected: vec![0x18, 0x18], + }, + Testcase { + value: 25, + expected: vec![0x18, 0x19], + }, + Testcase { + value: 100, + expected: vec![0x18, 0x64], + }, + Testcase { + value: 1000, + expected: vec![0x19, 0x03, 0xe8], + }, + Testcase { + value: 1000000, + expected: vec![0x1a, 0x00, 0x0f, 0x42, 0x40], + }, + Testcase { + value: 1000000000000, + expected: vec![0x1b, 0x00, 0x00, 0x00, 0xe8, 0xd4, 0xa5, 0x10, 0x00], + }, + Testcase { + value: 18446744073709551615, + expected: vec![0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff], + }]; + for testcase in testcases { + let cbor = CborType::Integer(testcase.value); + assert_eq!(testcase.expected, cbor.serialize()); + } +} + +#[test] +fn test_tagged_item() { + let cbor = CborType::Tag(0x12, Box::new(CborType::Integer(2).clone())); + assert_eq!(vec![0xD2, 0x02], cbor.serialize()); + + let cbor = CborType::Tag(0x62, Box::new(CborType::Array(vec![]).clone())); + assert_eq!(vec![0xD8, 0x62, 0x80], cbor.serialize()); +} + +#[test] +fn test_null() { + let cbor = CborType::Null; + assert_eq!(vec![0xf6], cbor.serialize()); +} + +#[test] +fn test_null_in_array() { + let cbor = CborType::Array(vec![CborType::Null, + CborType::Null]); + assert_eq!(vec![0x82, 0xf6, 0xf6], cbor.serialize()); +} diff --git a/third_party/rust/cose/src/cose.rs b/third_party/rust/cose/src/cose.rs new file mode 100644 index 000000000000..3d03c7bb63d7 --- /dev/null +++ b/third_party/rust/cose/src/cose.rs @@ -0,0 +1,98 @@ +//! 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; +//! } +//! } +//!``` + +#[macro_use] +pub mod decoder; +mod cbor; +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)] +#[macro_use(defer)] +extern crate scopeguard; + +#[cfg(test)] +mod nss; +#[cfg(test)] +mod test_setup; +#[cfg(test)] +mod test_nss; +#[cfg(test)] +mod util_test; +#[cfg(test)] +mod test_cose; + +#[derive(Debug)] +#[cfg(test)] +pub struct SignatureParameters<'a> { + certificate: &'a [u8], + algorithm: SignatureAlgorithm, + pkcs8: &'a [u8], +} + +#[derive(Debug)] +#[cfg(test)] +pub struct Signature<'a> { + parameter: &'a SignatureParameters<'a>, + signature_bytes: Vec, +} diff --git a/third_party/rust/cose/src/decoder.rs b/third_party/rust/cose/src/decoder.rs new file mode 100644 index 000000000000..b66e98031dab --- /dev/null +++ b/third_party/rust/cose/src/decoder.rs @@ -0,0 +1,192 @@ +//! Parse and decode COSE signatures. + +use cbor::CborType; +use cbor::decoder::decode; +use {CoseError, SignatureAlgorithm}; +use util::get_sig_struct_bytes; + +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, + pub signer_cert: Vec, + pub certs: Vec>, + pub to_verify: Vec, +} + +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; + +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: &CborType, key: &CborType) -> Result { + match *map { + CborType::Map(ref values) => { + match values.get(key) { + Some(x) => Ok(x.clone()), + _ => Err(CoseError::MissingHeader), + } + } + _ => Err(CoseError::UnexpectedType), + } +} + +// 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 { + 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 signature_algorithm = get_map_value(&protected_signature_header, &CborType::Integer(1))?; + 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(4))?; + let ee_cert = unpack!(Bytes, ee_cert).clone(); + + // 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. + let protected_body_head = unpack!(Bytes, protected_body_head); + let protected_body_head_map = match decode(protected_body_head) { + Ok(value) => value, + Err(_) => return Err(CoseError::DecodingFailure), + }; + let intermediate_certs_array = &get_map_value(&protected_body_head_map, &CborType::Integer(4))?; + let intermediate_certs = unpack!(Array, intermediate_certs_array); + let mut certs: Vec> = 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, 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); + } + 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 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/nss.rs b/third_party/rust/cose/src/nss.rs new file mode 100644 index 000000000000..ddeee16e35c5 --- /dev/null +++ b/third_party/rust/cose/src/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 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 { + 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 { + 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>, +} + +impl<'a> SECItemMut<'a> { + /// Given a mutable reference to a Vec 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) -> Result, 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 { + // 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::())?; + 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, 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, 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 = 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/src/test_cose.rs b/third_party/rust/cose/src/test_cose.rs new file mode 100644 index 000000000000..cdf70a2714e7 --- /dev/null +++ b/third_party/rust/cose/src/test_cose.rs @@ -0,0 +1,230 @@ +use test_setup as test; +use util_test::{sign, verify_signature}; +use {CoseError, SignatureAlgorithm, SignatureParameters}; +use std::str::FromStr; +use decoder::decode_signature; + +#[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()); +} + +// All keys here are from pykey.py/pycert.py from mozilla-central. +// Certificates can be generated with tools/certs/certs.sh and mozilla-central. + +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, +}; + +#[cfg(test)] +fn test_verify(payload: &[u8], cert_chain: &[&[u8]], params_vec: Vec) { + 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()); +} + +#[cfg(test)] +fn test_verify_modified_payload( + payload: &mut [u8], + cert_chain: &[&[u8]], + params_vec: Vec, +) { + 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)); +} + +#[cfg(test)] +fn test_verify_modified_signature( + payload: &[u8], + cert_chain: &[&[u8]], + params_vec: Vec, +) { + 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. +#[cfg(test)] +fn test_verify_verification_fails( + payload: &[u8], + cert_chain: &[&[u8]], + params_vec: Vec, +) { + 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)); +} + +#[test] +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); + + // 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); +} + +#[test] +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); +} + +#[test] +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); +} + +#[test] +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, +}; + +#[test] +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); +} + +#[test] +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); +} + +#[test] +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); +} + +#[test] +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); +} + +#[test] +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); +} + +#[test] +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); +} diff --git a/third_party/rust/cose/src/test_nss.rs b/third_party/rust/cose/src/test_nss.rs new file mode 100644 index 000000000000..a759e0b10334 --- /dev/null +++ b/third_party/rust/cose/src/test_nss.rs @@ -0,0 +1,68 @@ +use test_setup as test; +use nss; +use nss::NSSError; +use SignatureAlgorithm; + +#[test] +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() + ); +} + +#[test] +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)); +} + +#[test] +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/src/test_setup.rs b/third_party/rust/cose/src/test_setup.rs new file mode 100644 index 000000000000..befad9746a59 --- /dev/null +++ b/third_party/rust/cose/src/test_setup.rs @@ -0,0 +1,646 @@ +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 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 000000000000..8767f1ca2966 --- /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 { + let sig_structure_array: Vec = vec![CborType::String(String::from("Signature")), + protected_body_header_serialized, + protected_signature_header_serialized, + CborType::Bytes(Vec::new()), + CborType::Bytes(payload.to_vec())]; + + CborType::Array(sig_structure_array).serialize() +} diff --git a/third_party/rust/cose/src/util_test.rs b/third_party/rust/cose/src/util_test.rs new file mode 100644 index 000000000000..19a7a98d1850 --- /dev/null +++ b/third_party/rust/cose/src/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 util::get_sig_struct_bytes; +use decoder::decode_signature; +use 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 = 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 = Vec::new(); + for cert in cert_chain { + cert_array.push(CborType::Bytes(cert.to_vec())); + } + let mut protected_body_header: BTreeMap = 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) -> CborType { + // Build the signature item. + let mut signature_item: Vec = 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 = 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) -> Vec { + // Building the COSE signature content. + let mut cose_signature: Vec = Vec::new(); + + // add cert chain as protected header + cose_signature.push(build_protected_header(cert_chain)); + + // Empty map (unprotected header) + let empty_map: BTreeMap = BTreeMap::new(); + cose_signature.push(CborType::Map(empty_map)); + + // No payload (nil). + cose_signature.push(CborType::Null); + + // Create signature items. + let mut signatures: Vec = 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, +) -> Result, CoseError> { + assert!(parameters.len() > 0); + if parameters.len() < 1 { + return Err(CoseError::InvalidArgument); + } + + let mut signatures: Vec = 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) -> 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/tools/certs/certs.md b/third_party/rust/cose/tools/certs/certs.md new file mode 100644 index 000000000000..ef8a53909efc --- /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= ./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 000000000000..b6f4db679c6c --- /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 000000000000..59d1312987ee --- /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 000000000000..562d46f94574 --- /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 000000000000..19be32edb256 --- /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 000000000000..b6cec39b08b3 --- /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 000000000000..27a0ff3bcafc --- /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 000000000000..8fec3584db3b --- /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 000000000000..e79c1ecc53bd --- /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 000000000000..e44d96e22691 --- /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 000000000000..39454648fac2 --- /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 diff --git a/toolkit/library/gtest/rust/Cargo.lock b/toolkit/library/gtest/rust/Cargo.lock index b6ef8d05bbe6..590ee68775d0 100644 --- a/toolkit/library/gtest/rust/Cargo.lock +++ b/toolkit/library/gtest/rust/Cargo.lock @@ -267,6 +267,19 @@ dependencies = [ "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "cose" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cose-c" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cose 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "cssparser" version = "0.22.0" @@ -554,6 +567,7 @@ version = "0.1.0" dependencies = [ "audioipc-client 0.1.0", "audioipc-server 0.1.0", + "cose-c 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "cubeb 0.3.0", "cubeb-backend 0.2.0", "cubeb-core 0.1.0", @@ -1601,6 +1615,8 @@ dependencies = [ "checksum core-foundation-sys 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bc9fb3d6cb663e6fd7cf1c63f9b144ee2b1e4a78595a0451dd34bff85b9a3387" "checksum core-graphics 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5dc0a78ab2ac23b6ea7b3fe5fe93b227900dc0956979735b8f68032417976dd4" "checksum core-text 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bcad23756dd1dc4b47bf6a914ace27aadb8fa68889db5837af2308d018d0467c" +"checksum cose 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ec10816629f38fa557f08e199a3474fab954f4c8d2645550367235afa6e5646b" +"checksum cose-c 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "07cc8bb85ec2e93541ef9369b85a4b6fb7732bc7f4854d317eab20e726b0fc2f" "checksum cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44313341610282488e1156ad1fedebca51c54766c87a041d0287b10499c04ba1" "checksum cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "079adec4af52bb5275eadd004292028c79eb3c5f5b4ee8086a36d4197032f6df" "checksum darling 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9861a8495606435477df581bc858ccf15a3469747edf175b94a4704fd9aaedac" diff --git a/toolkit/library/rust/Cargo.lock b/toolkit/library/rust/Cargo.lock index eb599622341c..2d78c2d9e946 100644 --- a/toolkit/library/rust/Cargo.lock +++ b/toolkit/library/rust/Cargo.lock @@ -267,6 +267,19 @@ dependencies = [ "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "cose" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cose-c" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cose 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "cssparser" version = "0.22.0" @@ -553,6 +566,7 @@ version = "0.1.0" dependencies = [ "audioipc-client 0.1.0", "audioipc-server 0.1.0", + "cose-c 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "cubeb 0.3.0", "cubeb-backend 0.2.0", "cubeb-core 0.1.0", @@ -1613,6 +1627,8 @@ dependencies = [ "checksum core-foundation-sys 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bc9fb3d6cb663e6fd7cf1c63f9b144ee2b1e4a78595a0451dd34bff85b9a3387" "checksum core-graphics 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5dc0a78ab2ac23b6ea7b3fe5fe93b227900dc0956979735b8f68032417976dd4" "checksum core-text 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bcad23756dd1dc4b47bf6a914ace27aadb8fa68889db5837af2308d018d0467c" +"checksum cose 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ec10816629f38fa557f08e199a3474fab954f4c8d2645550367235afa6e5646b" +"checksum cose-c 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "07cc8bb85ec2e93541ef9369b85a4b6fb7732bc7f4854d317eab20e726b0fc2f" "checksum cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44313341610282488e1156ad1fedebca51c54766c87a041d0287b10499c04ba1" "checksum cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "079adec4af52bb5275eadd004292028c79eb3c5f5b4ee8086a36d4197032f6df" "checksum darling 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9861a8495606435477df581bc858ccf15a3469747edf175b94a4704fd9aaedac" diff --git a/toolkit/library/rust/shared/Cargo.toml b/toolkit/library/rust/shared/Cargo.toml index 73659d4fc182..ad5485c93c15 100644 --- a/toolkit/library/rust/shared/Cargo.toml +++ b/toolkit/library/rust/shared/Cargo.toml @@ -25,6 +25,7 @@ u2fhid = { path = "../../../../dom/webauthn/u2f-hid-rs" } # We have these to enforce common feature sets for said crates. log = {version = "0.3", features = ["release_max_level_info"]} syn = { version = "0.11", features = ["full", "visit", "parsing"] } +cose-c = { version = "0.1.1" } [features] default = [] diff --git a/toolkit/library/rust/shared/lib.rs b/toolkit/library/rust/shared/lib.rs index 91c54564f003..465c314c77ee 100644 --- a/toolkit/library/rust/shared/lib.rs +++ b/toolkit/library/rust/shared/lib.rs @@ -23,6 +23,7 @@ extern crate audioipc_server; extern crate u2fhid; extern crate log; extern crate syn; +extern crate cosec; use std::boxed::Box; use std::ffi::CStr;