From b3b11ca1ea93cc449823b874451a1dee8f9c2d94 Mon Sep 17 00:00:00 2001 From: Alex Dale Date: Thu, 18 Feb 2021 19:27:28 -0800 Subject: [PATCH 1/4] Added unittests for OEM Certificates. [ Merge of http://go/wvgerrit/115548 ] Create a small set of unittests to verify the functionality of OEM Certificate. This adds a test OEM Public Certificate and OEM Private Key. Bug: 135283522 Test: oemcrypto_unittests Change-Id: Iaa634543d9cb5005d91f1e7c528bf05b2b0c4d68 --- .../oemcrypto/ref/test/oem_cert_test.cpp | 536 ++++++++++++++++++ .../ref/test/oemcrypto_oem_cert_unittest.cpp | 115 ++++ 2 files changed, 651 insertions(+) create mode 100644 libwvdrmengine/oemcrypto/ref/test/oem_cert_test.cpp create mode 100644 libwvdrmengine/oemcrypto/ref/test/oemcrypto_oem_cert_unittest.cpp diff --git a/libwvdrmengine/oemcrypto/ref/test/oem_cert_test.cpp b/libwvdrmengine/oemcrypto/ref/test/oem_cert_test.cpp new file mode 100644 index 00000000..e7e4ffca --- /dev/null +++ b/libwvdrmengine/oemcrypto/ref/test/oem_cert_test.cpp @@ -0,0 +1,536 @@ +// Copyright 2021 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine License +// Agreement. + +#include "oem_cert.h" + +namespace wvoec_ref { +namespace { +const uint32_t kTestOemSystemId = 7913; + +// clang-format off + +// OEM Certificate private key. +// RSA Private-Key: (2048 bit, 2 primes). +const uint8_t kTestOemPrivateKey[] = { + 0x30, 0x82, 0x04, 0xbd, 0x02, 0x01, 0x00, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, + 0x04, 0xa7, 0x30, 0x82, 0x04, 0xa3, 0x02, 0x01, + 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0xa8, 0x75, + 0xd5, 0x3d, 0xd3, 0xf3, 0x59, 0xd1, 0x63, 0x0f, + 0x5d, 0x5f, 0x2c, 0xaf, 0x80, 0x4e, 0x9a, 0xef, + 0x9a, 0x8f, 0x88, 0x37, 0xe5, 0x56, 0xf8, 0x66, + 0xcb, 0xa6, 0x61, 0xab, 0xc1, 0xa9, 0x04, 0xc2, + 0x12, 0x9d, 0xa6, 0x0c, 0x2c, 0xcb, 0x42, 0x09, + 0xd0, 0x36, 0xf0, 0x85, 0x01, 0xdf, 0xd5, 0xbd, + 0xaf, 0x82, 0xbb, 0x25, 0xa1, 0x61, 0x17, 0xfe, + 0xa1, 0x65, 0x34, 0xda, 0x91, 0xee, 0x91, 0x46, + 0xd6, 0x63, 0x47, 0x6a, 0xa5, 0x32, 0x62, 0xe2, + 0x4c, 0x7c, 0xf7, 0x76, 0x59, 0xe1, 0x2b, 0x47, + 0x8d, 0x1c, 0xe6, 0xa0, 0xbd, 0xc3, 0xc9, 0x36, + 0x0e, 0x90, 0x75, 0xba, 0x1c, 0xbd, 0xca, 0x85, + 0x0a, 0x4e, 0xcc, 0xfe, 0x91, 0x3f, 0x22, 0x42, + 0x96, 0xae, 0xa0, 0x87, 0x82, 0x63, 0x3b, 0x22, + 0x54, 0xbc, 0x28, 0xa3, 0x45, 0x4b, 0x34, 0x12, + 0x4e, 0xeb, 0x04, 0x4d, 0x29, 0xb3, 0x05, 0x62, + 0x0d, 0x51, 0x16, 0x46, 0x98, 0x21, 0xc8, 0x59, + 0x96, 0x53, 0x43, 0x38, 0x95, 0x1a, 0x42, 0x94, + 0x8b, 0x49, 0x5d, 0x1b, 0x8a, 0xd5, 0x82, 0x6a, + 0x32, 0x6f, 0x0e, 0x5a, 0x85, 0x3b, 0xd5, 0x42, + 0xc0, 0x4c, 0x34, 0x43, 0x7c, 0x4f, 0xef, 0xca, + 0x02, 0x99, 0x38, 0xf9, 0xa5, 0xc0, 0xd8, 0x1d, + 0xe7, 0x9e, 0x8c, 0x4d, 0x9c, 0x40, 0xcd, 0x4b, + 0x5e, 0x44, 0x37, 0x8d, 0xc5, 0x96, 0xd4, 0xf7, + 0xb3, 0x37, 0x4c, 0x2e, 0x2d, 0x30, 0xca, 0x97, + 0x39, 0xed, 0xe8, 0x73, 0xc5, 0xe7, 0xcb, 0x95, + 0xf0, 0x84, 0x4a, 0x5a, 0x9e, 0x13, 0x19, 0x5f, + 0x98, 0xe5, 0xbe, 0x31, 0x5b, 0xff, 0xed, 0x29, + 0x26, 0xc4, 0x93, 0x54, 0x49, 0x84, 0xd2, 0xeb, + 0x21, 0x40, 0x19, 0x5f, 0xf7, 0x32, 0x67, 0x93, + 0xe0, 0xda, 0x77, 0xfc, 0xda, 0x5e, 0xc4, 0x5b, + 0x95, 0x2e, 0x46, 0xf3, 0xce, 0xfd, 0x02, 0x03, + 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x01, 0x00, + 0x9e, 0x6d, 0x82, 0xc8, 0x0c, 0xc6, 0xb5, 0xd7, + 0xa7, 0xb3, 0xd1, 0x7a, 0x2a, 0x8a, 0x3a, 0xbe, + 0xb2, 0x13, 0x58, 0x66, 0x58, 0x13, 0x49, 0x4a, + 0x0b, 0x7e, 0x91, 0x53, 0xbe, 0x53, 0x4b, 0x63, + 0xeb, 0x27, 0xa1, 0x5e, 0x45, 0xc4, 0xf9, 0x73, + 0x86, 0x7d, 0xb8, 0x25, 0x92, 0xf9, 0x63, 0x93, + 0xe0, 0x6d, 0xed, 0xdb, 0xa2, 0xa9, 0x77, 0x25, + 0xda, 0xed, 0x0b, 0x58, 0x24, 0xe6, 0xd1, 0x8b, + 0x6d, 0x71, 0x13, 0x3a, 0x76, 0xf5, 0xa2, 0xba, + 0xca, 0x28, 0x4d, 0x0a, 0xd1, 0xa7, 0xaa, 0x4b, + 0x8a, 0xea, 0x55, 0x99, 0xb2, 0x83, 0xc5, 0x33, + 0x95, 0xcd, 0x92, 0xd0, 0xe5, 0x06, 0xcc, 0xf4, + 0xe8, 0xbb, 0x49, 0xc0, 0x66, 0x25, 0x9a, 0xef, + 0xa7, 0x06, 0xbc, 0xb3, 0x2a, 0x21, 0x86, 0xcc, + 0x4f, 0xd6, 0xaf, 0x9d, 0xed, 0x11, 0xef, 0x9f, + 0x14, 0x2f, 0x8b, 0xac, 0x96, 0x75, 0x03, 0x1a, + 0xe4, 0x5c, 0x48, 0x81, 0x3a, 0x4b, 0x21, 0x6e, + 0xad, 0xb3, 0x27, 0x51, 0xe9, 0x35, 0xbe, 0xed, + 0x42, 0x5f, 0x8f, 0x83, 0xf0, 0x99, 0xb0, 0xaf, + 0xa9, 0x9c, 0x2f, 0xee, 0x5f, 0xee, 0x39, 0x2b, + 0x1d, 0xb0, 0xb1, 0xf8, 0x7b, 0x69, 0x38, 0x68, + 0xae, 0xa0, 0x36, 0x2a, 0xf5, 0xed, 0x96, 0xfa, + 0x7c, 0x1c, 0x59, 0x29, 0xbf, 0xb3, 0x9e, 0x14, + 0x97, 0x06, 0xc2, 0x40, 0x30, 0x00, 0x6a, 0x95, + 0xd3, 0x86, 0x86, 0xb9, 0x4c, 0xf5, 0x51, 0xa3, + 0x6d, 0x5a, 0xd1, 0x46, 0x43, 0x24, 0xa4, 0xa9, + 0x59, 0xcf, 0xa2, 0xa7, 0x4e, 0x50, 0x7a, 0xa3, + 0x14, 0xe4, 0x4e, 0x32, 0x4d, 0xd4, 0xc2, 0xcf, + 0x2d, 0x74, 0xfb, 0x51, 0x34, 0x98, 0x68, 0xc3, + 0xd2, 0xb1, 0xd9, 0x38, 0x94, 0x91, 0x28, 0xb1, + 0x69, 0x9a, 0xbf, 0xbf, 0x1a, 0xdf, 0xd3, 0xb6, + 0x21, 0x38, 0x94, 0x1b, 0x81, 0x00, 0xb5, 0x39, + 0x02, 0x81, 0x81, 0x00, 0xdb, 0xe4, 0x83, 0xc5, + 0x7a, 0xe0, 0xcf, 0xeb, 0x07, 0x37, 0xfb, 0xf6, + 0xfe, 0xb3, 0x62, 0x72, 0x86, 0xd0, 0x12, 0x96, + 0x9d, 0xf4, 0x93, 0x90, 0xdc, 0xf6, 0xc6, 0x03, + 0x0c, 0x46, 0xb8, 0x66, 0x60, 0xf3, 0x46, 0x5b, + 0xab, 0x9f, 0x9d, 0x81, 0xac, 0x26, 0x8f, 0xd7, + 0xa3, 0xbd, 0x16, 0xbb, 0xb4, 0x4e, 0xf6, 0xc0, + 0x12, 0xb6, 0x99, 0x4a, 0xf5, 0xc1, 0x6c, 0x40, + 0x72, 0x18, 0x71, 0x02, 0x65, 0x77, 0xb1, 0xfb, + 0xec, 0x19, 0xbb, 0x8c, 0x03, 0xea, 0x7b, 0x17, + 0x63, 0xc9, 0xb9, 0x3b, 0x10, 0x56, 0x19, 0xef, + 0x86, 0x69, 0x4d, 0x61, 0x03, 0xac, 0x30, 0x65, + 0x63, 0xe5, 0xe1, 0x0f, 0xd6, 0xf6, 0x5b, 0xc9, + 0x7c, 0xde, 0x9b, 0x26, 0xca, 0x98, 0xda, 0x0c, + 0x5b, 0x6f, 0x91, 0x88, 0xbf, 0x98, 0xc3, 0xbc, + 0x72, 0x21, 0xa0, 0x07, 0x0a, 0x5e, 0xc7, 0x61, + 0x4a, 0xb3, 0x32, 0xc7, 0x02, 0x81, 0x81, 0x00, + 0xc4, 0x1f, 0x4a, 0x23, 0xa6, 0x0b, 0xb9, 0xd5, + 0xc7, 0xe9, 0x1a, 0x24, 0xe8, 0x2b, 0xf2, 0x1f, + 0x17, 0xc3, 0xe6, 0x14, 0x76, 0x71, 0x11, 0x76, + 0x8f, 0xfc, 0x66, 0xb8, 0x8c, 0xe2, 0xf5, 0x46, + 0x89, 0x0d, 0xd7, 0xe3, 0x56, 0x19, 0xd7, 0x1a, + 0xfe, 0x1c, 0xd4, 0x0f, 0x8b, 0x72, 0xd1, 0x20, + 0xb0, 0xa4, 0xbe, 0x6b, 0x6b, 0x01, 0x57, 0xe8, + 0x6b, 0xdf, 0x89, 0x55, 0x3f, 0x10, 0x41, 0x63, + 0xb0, 0x62, 0xa5, 0x7f, 0x4f, 0xe7, 0x42, 0x54, + 0xe4, 0x0e, 0x55, 0xae, 0xa2, 0x53, 0x3d, 0xb8, + 0x4a, 0xff, 0xeb, 0xe2, 0x8a, 0x71, 0x17, 0x54, + 0x20, 0x05, 0x51, 0xed, 0xae, 0xb0, 0xca, 0x7e, + 0xc6, 0xd7, 0x09, 0xa8, 0x39, 0x88, 0xac, 0x7f, + 0x4b, 0xe0, 0x49, 0xd5, 0x6c, 0x89, 0xf0, 0xbc, + 0xe4, 0xe9, 0xb0, 0x29, 0x73, 0x6c, 0x55, 0x7d, + 0x8f, 0xbe, 0x32, 0x31, 0x14, 0xd2, 0xec, 0x1b, + 0x02, 0x81, 0x80, 0x67, 0xf6, 0x55, 0x5a, 0xa3, + 0xaa, 0xf0, 0x82, 0x75, 0x2a, 0x41, 0xe5, 0x58, + 0x2c, 0x65, 0xaa, 0x32, 0x14, 0xe4, 0x04, 0xf3, + 0xef, 0x33, 0x69, 0x75, 0x1e, 0xf3, 0x25, 0x73, + 0xc3, 0x67, 0xe1, 0x77, 0x8a, 0xed, 0x43, 0xe0, + 0x13, 0x99, 0xfb, 0x39, 0xf2, 0x0d, 0x65, 0xed, + 0x93, 0x33, 0xd1, 0x51, 0x01, 0x58, 0x66, 0x1d, + 0x32, 0xd9, 0xac, 0xf8, 0x1e, 0x17, 0xd9, 0x2c, + 0x58, 0x63, 0xed, 0xb7, 0x1d, 0x6d, 0x37, 0xe7, + 0x3b, 0x8f, 0x51, 0x36, 0x74, 0xc0, 0xf7, 0xa1, + 0x05, 0x39, 0x9f, 0x34, 0x2d, 0x11, 0x1c, 0x0e, + 0xd7, 0x70, 0x6f, 0x22, 0xb6, 0x61, 0x37, 0x3e, + 0x90, 0xeb, 0xe4, 0x7a, 0x44, 0x85, 0xc6, 0xf0, + 0x53, 0xaa, 0xd5, 0x1f, 0x4a, 0x3f, 0x25, 0x42, + 0x81, 0xb0, 0x34, 0x10, 0x29, 0xe0, 0xb9, 0x12, + 0xd8, 0xd4, 0xf9, 0x1f, 0x2d, 0x0a, 0x64, 0xf4, + 0x55, 0x5e, 0xf7, 0x02, 0x81, 0x80, 0x3d, 0x06, + 0x1f, 0x63, 0x88, 0x3f, 0x0d, 0xcb, 0xdf, 0x30, + 0x40, 0xda, 0x4b, 0x03, 0xa1, 0x8a, 0xdb, 0x32, + 0x31, 0x5d, 0x1c, 0x9d, 0x81, 0xf9, 0x8a, 0x43, + 0xd7, 0x12, 0x85, 0x83, 0xf9, 0x1d, 0xc1, 0x77, + 0x75, 0x3d, 0x5f, 0x85, 0x1a, 0xd1, 0x63, 0x50, + 0x45, 0x0b, 0xb1, 0x30, 0x40, 0xb2, 0x13, 0x44, + 0xaf, 0x9b, 0x6c, 0xe8, 0x36, 0x1a, 0x33, 0xb6, + 0x92, 0x5c, 0xdc, 0x0a, 0x8a, 0xce, 0x22, 0x0c, + 0x0f, 0xc2, 0xd5, 0x71, 0xf7, 0xc9, 0xc2, 0x4c, + 0x53, 0x8c, 0xcb, 0x25, 0x6b, 0x86, 0xf4, 0x8f, + 0x3d, 0x2e, 0x78, 0x35, 0x48, 0x34, 0xfc, 0xe1, + 0xaa, 0xe4, 0x71, 0xfe, 0xc0, 0x83, 0x42, 0x0b, + 0x97, 0x0d, 0xa9, 0x19, 0x45, 0xd3, 0x36, 0x20, + 0xcb, 0xd8, 0x84, 0xb5, 0x47, 0x1a, 0xff, 0x7f, + 0x57, 0x39, 0x0e, 0x99, 0x1e, 0xe0, 0xba, 0xe1, + 0x4b, 0x6c, 0xca, 0x35, 0xf7, 0x11, 0x02, 0x81, + 0x80, 0x5a, 0x59, 0xf0, 0x8e, 0x07, 0x9c, 0x1a, + 0x83, 0x2b, 0x28, 0xc4, 0x82, 0xcc, 0xb7, 0x9e, + 0x41, 0xa5, 0x15, 0xa2, 0x37, 0xa7, 0x0c, 0x77, + 0x09, 0x73, 0xf5, 0xb1, 0x3f, 0x7a, 0x55, 0x9f, + 0x15, 0x90, 0xa3, 0x5e, 0x6e, 0x19, 0x46, 0x6d, + 0x1f, 0x28, 0x64, 0xad, 0xa0, 0xb5, 0xca, 0x7d, + 0x06, 0x44, 0x88, 0xae, 0x2b, 0x80, 0x21, 0x84, + 0x3d, 0x8d, 0xa5, 0x09, 0x4f, 0xa1, 0xd9, 0x7d, + 0x7c, 0x9a, 0x8b, 0x64, 0x8f, 0xf6, 0xa5, 0xce, + 0x56, 0x65, 0xba, 0xcb, 0x30, 0x38, 0x53, 0xf8, + 0x1b, 0x89, 0x8f, 0xdf, 0xb5, 0xc3, 0x86, 0x3c, + 0x24, 0xef, 0xbc, 0xc0, 0xfc, 0x6c, 0xa4, 0xc6, + 0x74, 0xbb, 0xeb, 0x79, 0xa9, 0x8e, 0xe5, 0x25, + 0xc0, 0x0a, 0xe5, 0x90, 0x08, 0x43, 0x82, 0xec, + 0x17, 0x5e, 0x9e, 0xa2, 0x05, 0xc5, 0x03, 0x20, + 0x12, 0xf7, 0x86, 0x2e, 0x7e, 0x8e, 0x11, 0xf7, + 0x14 +}; + +const size_t kTestOemPrivateKeySize = sizeof(kTestOemPrivateKey); + +// OEM Certificate public cert data. +// Leaf (device) certificate: +// version: 2 +// serialNumber: 61412119066269531030714093834591281593 +// signature algorithm: sha256WithRSAEncryption (1.2.840.113549.1.1.11) +// issuer: +// C=US, ST=WA, L=Kirkland, O=Google, OU=Widevine, CN=system id: 7913 +// validity: +// notBefore: Jan 27 15:55:47 2021 GMT +// notAfter: Jan 25 15:55:47 2031 GMT +// subject: +// CN=7913-leaf, C=US, ST=WA, L=Kirkland, O=Google, OU=Widevine +// key: RSA Public key +// extensions: +// - object: Widevine System Id (1.3.6.1.4.1.11129.4.1.1) +// critical: BOOL ABSENT +// value: 02 02 1e e9 (7913) +// sig_alg: sha256WithRSAEncryption (1.2.840.113549.1.1.11) +// signature: ... +// +// Intermediate (manufacturer) certificate: +// version: 2 +// serialNumber: 4911737327617104025470773024969385060 +// signature: sha256WithRSAEncryption (1.2.840.113549.1.1.11) +// issuer: +// C=US, ST=Washington, L=Kirkland, O=Google, OU=Widevine, +// CN=widevine.com/oem-root-prod +// validity: +// notBefore: Nov 18 01:13:35 2017 GMT +// notAfter: Nov 18 01:13:13 2027 GMT +// subject: +// C=US, ST=WA, L=Kirkland, O=Google, OU=Widevine, CN=system id: 7913 +// key: RSA Public key +// extensions: +// - object: X509v3 Basic Constraints (2.5.29.19) +// critical: TRUE +// value: 30 06 01 01 ff 02 01 00 +// - object: X509v3 Key Usage (2.5.29.15) +// critical: TRUE +// value: 03 02 02 04 +// - object: X509v3 Subject Key Identifier (2.5.29.14) +// critical: BOOL ABSENT +// value: +// 04 14 4b cb df aa 02 de 8d c3 e7 e5 85 db 2e 8a be 75 6b 8a 67-58 +// - object: X509v3 Authority Key Identifier (2.5.29.35) +// critical: BOOL ABSENT +// value: ... +// - object: Widevine System Id (1.3.6.1.4.1.11129.4.1.1) +// critical: BOOL ABSENT +// value: 02 02 1e e9 (7913) +// sig_alg: sha256WithRSAEncryption (1.2.840.113549.1.1.11) +// signature: ... +const uint8_t kTestOemPublicCert[] = { + 0x30, 0x82, 0x09, 0x28, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, + 0x82, 0x09, 0x19, 0x30, 0x82, 0x09, 0x15, 0x02, + 0x01, 0x01, 0x31, 0x00, 0x30, 0x0b, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, + 0x01, 0xa0, 0x82, 0x08, 0xfd, 0x30, 0x82, 0x03, + 0x70, 0x30, 0x82, 0x02, 0x58, 0xa0, 0x03, 0x02, + 0x01, 0x02, 0x02, 0x10, 0x2e, 0x33, 0x8b, 0x3d, + 0x69, 0x18, 0x4c, 0xf7, 0x78, 0x2e, 0x3b, 0x3b, + 0x43, 0xb4, 0x21, 0xb9, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x0b, 0x05, 0x00, 0x30, 0x6b, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x0c, 0x02, 0x57, 0x41, 0x31, + 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0c, 0x08, 0x4b, 0x69, 0x72, 0x6b, 0x6c, 0x61, + 0x6e, 0x64, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, + 0x55, 0x04, 0x0a, 0x0c, 0x06, 0x47, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, + 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x08, 0x57, 0x69, + 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 0x31, 0x18, + 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, + 0x0f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, + 0x69, 0x64, 0x3a, 0x20, 0x37, 0x39, 0x31, 0x33, + 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x31, 0x30, 0x31, + 0x32, 0x37, 0x31, 0x35, 0x35, 0x35, 0x34, 0x37, + 0x5a, 0x17, 0x0d, 0x33, 0x31, 0x30, 0x31, 0x32, + 0x35, 0x31, 0x35, 0x35, 0x35, 0x34, 0x37, 0x5a, + 0x30, 0x65, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0c, 0x09, 0x37, 0x39, 0x31, + 0x33, 0x2d, 0x6c, 0x65, 0x61, 0x66, 0x31, 0x0b, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x57, 0x41, + 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0c, 0x08, 0x4b, 0x69, 0x72, 0x6b, 0x6c, + 0x61, 0x6e, 0x64, 0x31, 0x0f, 0x30, 0x0d, 0x06, + 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x06, 0x47, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x31, 0x11, 0x30, 0x0f, + 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x08, 0x57, + 0x69, 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 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, + 0xa8, 0x75, 0xd5, 0x3d, 0xd3, 0xf3, 0x59, 0xd1, + 0x63, 0x0f, 0x5d, 0x5f, 0x2c, 0xaf, 0x80, 0x4e, + 0x9a, 0xef, 0x9a, 0x8f, 0x88, 0x37, 0xe5, 0x56, + 0xf8, 0x66, 0xcb, 0xa6, 0x61, 0xab, 0xc1, 0xa9, + 0x04, 0xc2, 0x12, 0x9d, 0xa6, 0x0c, 0x2c, 0xcb, + 0x42, 0x09, 0xd0, 0x36, 0xf0, 0x85, 0x01, 0xdf, + 0xd5, 0xbd, 0xaf, 0x82, 0xbb, 0x25, 0xa1, 0x61, + 0x17, 0xfe, 0xa1, 0x65, 0x34, 0xda, 0x91, 0xee, + 0x91, 0x46, 0xd6, 0x63, 0x47, 0x6a, 0xa5, 0x32, + 0x62, 0xe2, 0x4c, 0x7c, 0xf7, 0x76, 0x59, 0xe1, + 0x2b, 0x47, 0x8d, 0x1c, 0xe6, 0xa0, 0xbd, 0xc3, + 0xc9, 0x36, 0x0e, 0x90, 0x75, 0xba, 0x1c, 0xbd, + 0xca, 0x85, 0x0a, 0x4e, 0xcc, 0xfe, 0x91, 0x3f, + 0x22, 0x42, 0x96, 0xae, 0xa0, 0x87, 0x82, 0x63, + 0x3b, 0x22, 0x54, 0xbc, 0x28, 0xa3, 0x45, 0x4b, + 0x34, 0x12, 0x4e, 0xeb, 0x04, 0x4d, 0x29, 0xb3, + 0x05, 0x62, 0x0d, 0x51, 0x16, 0x46, 0x98, 0x21, + 0xc8, 0x59, 0x96, 0x53, 0x43, 0x38, 0x95, 0x1a, + 0x42, 0x94, 0x8b, 0x49, 0x5d, 0x1b, 0x8a, 0xd5, + 0x82, 0x6a, 0x32, 0x6f, 0x0e, 0x5a, 0x85, 0x3b, + 0xd5, 0x42, 0xc0, 0x4c, 0x34, 0x43, 0x7c, 0x4f, + 0xef, 0xca, 0x02, 0x99, 0x38, 0xf9, 0xa5, 0xc0, + 0xd8, 0x1d, 0xe7, 0x9e, 0x8c, 0x4d, 0x9c, 0x40, + 0xcd, 0x4b, 0x5e, 0x44, 0x37, 0x8d, 0xc5, 0x96, + 0xd4, 0xf7, 0xb3, 0x37, 0x4c, 0x2e, 0x2d, 0x30, + 0xca, 0x97, 0x39, 0xed, 0xe8, 0x73, 0xc5, 0xe7, + 0xcb, 0x95, 0xf0, 0x84, 0x4a, 0x5a, 0x9e, 0x13, + 0x19, 0x5f, 0x98, 0xe5, 0xbe, 0x31, 0x5b, 0xff, + 0xed, 0x29, 0x26, 0xc4, 0x93, 0x54, 0x49, 0x84, + 0xd2, 0xeb, 0x21, 0x40, 0x19, 0x5f, 0xf7, 0x32, + 0x67, 0x93, 0xe0, 0xda, 0x77, 0xfc, 0xda, 0x5e, + 0xc4, 0x5b, 0x95, 0x2e, 0x46, 0xf3, 0xce, 0xfd, + 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x16, 0x30, + 0x14, 0x30, 0x12, 0x06, 0x0a, 0x2b, 0x06, 0x01, + 0x04, 0x01, 0xd6, 0x79, 0x04, 0x01, 0x01, 0x04, + 0x04, 0x02, 0x02, 0x1e, 0xe9, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, + 0x00, 0x04, 0x9e, 0xbb, 0x41, 0x3e, 0x1b, 0x35, + 0xca, 0x24, 0xe3, 0xa7, 0x62, 0xf7, 0xbf, 0x54, + 0x88, 0x1d, 0xa3, 0x6c, 0x30, 0x1f, 0xb7, 0xe4, + 0x2b, 0x76, 0x54, 0x4f, 0xb1, 0x30, 0xba, 0x86, + 0x21, 0x12, 0xc3, 0xd9, 0x25, 0xfd, 0x94, 0xab, + 0x3c, 0x9d, 0x4d, 0xbc, 0x2b, 0xdc, 0x68, 0x01, + 0x8d, 0x59, 0x4f, 0x81, 0xe8, 0x87, 0xbe, 0x05, + 0x75, 0x3e, 0x24, 0xd9, 0xf1, 0x55, 0xe3, 0x56, + 0x75, 0xa4, 0x7f, 0xb4, 0x50, 0x41, 0x4b, 0x88, + 0x0e, 0x8f, 0x6e, 0x10, 0x13, 0x25, 0x24, 0xda, + 0x4c, 0x97, 0x0a, 0xdc, 0xbf, 0x2a, 0x1d, 0x4d, + 0x02, 0xb3, 0x4b, 0x6a, 0x96, 0xe6, 0x0e, 0xd1, + 0x61, 0x80, 0x78, 0xab, 0xf0, 0x7b, 0x8b, 0x1e, + 0x99, 0x48, 0x84, 0x31, 0xd2, 0xaf, 0x23, 0x32, + 0x01, 0x5e, 0x11, 0x55, 0x06, 0x6e, 0x0e, 0xed, + 0x69, 0x7b, 0xb8, 0x41, 0x63, 0x3b, 0x30, 0x05, + 0x1e, 0xcd, 0x3e, 0x49, 0xb8, 0x0c, 0x83, 0x50, + 0x26, 0x4e, 0xd8, 0x97, 0x9d, 0x89, 0x30, 0x15, + 0xb9, 0x20, 0x20, 0xba, 0x5d, 0x8b, 0xad, 0x3d, + 0x7f, 0x52, 0xcd, 0x1e, 0xc0, 0x0e, 0xe1, 0xdc, + 0x21, 0x9b, 0xb0, 0x89, 0xa0, 0x20, 0xc6, 0x8c, + 0x56, 0x39, 0xc3, 0x40, 0x30, 0x40, 0x52, 0x2f, + 0x3b, 0x87, 0x96, 0xe2, 0x4d, 0x80, 0x57, 0xb3, + 0xb3, 0xe0, 0xb7, 0x5c, 0x55, 0x6a, 0x0f, 0x44, + 0x91, 0xe8, 0x98, 0xb3, 0xb4, 0xd3, 0x07, 0x8e, + 0x85, 0x8e, 0xc0, 0xcb, 0x85, 0x92, 0x0e, 0xca, + 0x7c, 0x03, 0x23, 0xa0, 0x1f, 0x4e, 0x75, 0x01, + 0x95, 0x61, 0x2c, 0x21, 0x2f, 0x4f, 0x6d, 0x55, + 0xa3, 0xcc, 0x23, 0x62, 0x7f, 0xcb, 0x0a, 0x8a, + 0x8b, 0x82, 0xb5, 0x8c, 0x8a, 0xaa, 0x88, 0xb4, + 0x65, 0x82, 0x6d, 0x12, 0x4a, 0x06, 0xe7, 0xde, + 0xcd, 0x3c, 0xf9, 0x1c, 0x02, 0x9c, 0xf8, 0x21, + 0x20, 0x30, 0x82, 0x05, 0x85, 0x30, 0x82, 0x03, + 0x6d, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, + 0x03, 0xb1, 0xf7, 0x58, 0xdf, 0x1d, 0xe3, 0x25, + 0x00, 0x0b, 0x10, 0x3d, 0xd5, 0xe6, 0xe4, 0x64, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, + 0x7e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, + 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, + 0x74, 0x6f, 0x6e, 0x31, 0x11, 0x30, 0x0f, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0c, 0x08, 0x4b, 0x69, + 0x72, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x0f, + 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, + 0x06, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x31, + 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, + 0x0c, 0x08, 0x57, 0x69, 0x64, 0x65, 0x76, 0x69, + 0x6e, 0x65, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0c, 0x1a, 0x77, 0x69, 0x64, + 0x65, 0x76, 0x69, 0x6e, 0x65, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x6f, 0x65, 0x6d, 0x2d, 0x72, 0x6f, + 0x6f, 0x74, 0x2d, 0x70, 0x72, 0x6f, 0x64, 0x30, + 0x1e, 0x17, 0x0d, 0x31, 0x37, 0x31, 0x31, 0x31, + 0x38, 0x30, 0x31, 0x31, 0x33, 0x33, 0x35, 0x5a, + 0x17, 0x0d, 0x32, 0x37, 0x31, 0x31, 0x31, 0x38, + 0x30, 0x31, 0x31, 0x33, 0x31, 0x33, 0x5a, 0x30, + 0x6b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, + 0x02, 0x57, 0x41, 0x31, 0x11, 0x30, 0x0f, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0c, 0x08, 0x4b, 0x69, + 0x72, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x0f, + 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, + 0x06, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x31, + 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, + 0x0c, 0x08, 0x57, 0x69, 0x64, 0x65, 0x76, 0x69, + 0x6e, 0x65, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x73, 0x79, 0x73, + 0x74, 0x65, 0x6d, 0x20, 0x69, 0x64, 0x3a, 0x20, + 0x37, 0x39, 0x31, 0x33, 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, 0xae, 0xc8, 0x71, + 0xae, 0x08, 0x0c, 0x06, 0x06, 0x2d, 0x81, 0x7c, + 0xa9, 0x8b, 0xb3, 0xd6, 0x66, 0xe4, 0xf6, 0x08, + 0x5e, 0x5a, 0x75, 0xe8, 0x74, 0x61, 0x7a, 0x88, + 0xca, 0x85, 0x14, 0x0d, 0x58, 0xa4, 0x09, 0x19, + 0x6c, 0x60, 0xc9, 0xad, 0x91, 0x1c, 0xbf, 0x04, + 0xb3, 0x47, 0x10, 0x63, 0x7f, 0x02, 0x58, 0xc2, + 0x1e, 0xbd, 0xcc, 0x07, 0x77, 0xaa, 0x7e, 0x14, + 0xa8, 0xc2, 0x01, 0xcd, 0xe8, 0x46, 0x60, 0x53, + 0x6f, 0x2f, 0xda, 0x17, 0x2d, 0x4d, 0x9d, 0x0e, + 0x5d, 0xb5, 0x50, 0x95, 0xae, 0xab, 0x6e, 0x43, + 0xe3, 0xb0, 0x00, 0x12, 0xb4, 0x05, 0x82, 0x4a, + 0x2b, 0x14, 0x63, 0x0d, 0x1f, 0x06, 0x12, 0xaa, + 0xe1, 0x9d, 0xe7, 0xba, 0xda, 0xe3, 0xfc, 0x7c, + 0x6c, 0x73, 0xae, 0x56, 0xf8, 0xab, 0xf7, 0x51, + 0x93, 0x31, 0xef, 0x8f, 0xe4, 0xb6, 0x01, 0x2c, + 0xeb, 0x7b, 0xe4, 0xd8, 0xb3, 0xea, 0x70, 0x37, + 0x89, 0x05, 0xa9, 0x51, 0x57, 0x72, 0x98, 0x9e, + 0xa8, 0x46, 0xdb, 0xeb, 0x7a, 0x38, 0x2b, 0x2f, + 0xc0, 0x27, 0xb7, 0xc2, 0xe1, 0x9a, 0x17, 0xdf, + 0xf5, 0xd6, 0x9c, 0xd5, 0x8c, 0xb8, 0x66, 0x42, + 0xd5, 0x04, 0x1e, 0x7c, 0x36, 0x4c, 0x1e, 0x3e, + 0x45, 0x51, 0x4d, 0x41, 0x72, 0x22, 0x53, 0x3d, + 0xf4, 0x57, 0x7c, 0x6c, 0x33, 0x34, 0x24, 0x45, + 0xdf, 0x84, 0x87, 0x4a, 0xa6, 0xcb, 0x7c, 0x03, + 0xa3, 0xaa, 0x8e, 0x2d, 0x82, 0x01, 0x27, 0x87, + 0x74, 0x82, 0x1a, 0xbc, 0x0f, 0x76, 0x69, 0xab, + 0xe0, 0x4e, 0x70, 0xbe, 0x37, 0xfc, 0xc8, 0x2c, + 0x91, 0x17, 0x4f, 0xd5, 0x26, 0x3b, 0x7b, 0x90, + 0xb5, 0x2d, 0x64, 0xba, 0xf7, 0xd2, 0x8a, 0xb4, + 0x8f, 0x38, 0x9d, 0x8e, 0xba, 0xe7, 0x5c, 0x52, + 0xf1, 0x0a, 0xb8, 0xc0, 0x1b, 0xb6, 0xb1, 0x70, + 0x7e, 0x47, 0x59, 0x94, 0x59, 0x02, 0x03, 0x01, + 0x00, 0x01, 0xa3, 0x82, 0x01, 0x10, 0x30, 0x82, + 0x01, 0x0c, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, + 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, + 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, + 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, + 0x04, 0x04, 0x03, 0x02, 0x02, 0x04, 0x30, 0x1d, + 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, + 0x14, 0x4b, 0xcb, 0xdf, 0xaa, 0x02, 0xde, 0x8d, + 0xc3, 0xe7, 0xe5, 0x85, 0xdb, 0x2e, 0x8a, 0xbe, + 0x75, 0x6b, 0x8a, 0x67, 0x58, 0x30, 0x81, 0xb2, + 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0xaa, + 0x30, 0x81, 0xa7, 0x80, 0x14, 0x04, 0x94, 0x66, + 0xaa, 0xf9, 0x61, 0x89, 0xb6, 0xdb, 0xb5, 0xf7, + 0x13, 0x38, 0x3d, 0x62, 0x84, 0xb8, 0x18, 0x0a, + 0x8f, 0xa1, 0x81, 0x83, 0xa4, 0x81, 0x80, 0x30, + 0x7e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, + 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, + 0x74, 0x6f, 0x6e, 0x31, 0x11, 0x30, 0x0f, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0c, 0x08, 0x4b, 0x69, + 0x72, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x0f, + 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, + 0x06, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x31, + 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, + 0x0c, 0x08, 0x57, 0x69, 0x64, 0x65, 0x76, 0x69, + 0x6e, 0x65, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0c, 0x1a, 0x77, 0x69, 0x64, + 0x65, 0x76, 0x69, 0x6e, 0x65, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x6f, 0x65, 0x6d, 0x2d, 0x72, 0x6f, + 0x6f, 0x74, 0x2d, 0x70, 0x72, 0x6f, 0x64, 0x82, + 0x09, 0x00, 0xdf, 0x86, 0x05, 0x31, 0x01, 0xbe, + 0x9a, 0x9a, 0x30, 0x12, 0x06, 0x0a, 0x2b, 0x06, + 0x01, 0x04, 0x01, 0xd6, 0x79, 0x04, 0x01, 0x01, + 0x04, 0x04, 0x02, 0x02, 0x1e, 0xe9, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, + 0x01, 0x00, 0x61, 0x3f, 0x2f, 0x43, 0xe4, 0xbe, + 0x66, 0x34, 0xef, 0x92, 0x06, 0xe9, 0x88, 0xba, + 0x6a, 0x1d, 0x4f, 0x54, 0x5a, 0x97, 0xb1, 0x75, + 0xd7, 0x93, 0xf8, 0x45, 0xc6, 0x83, 0x92, 0x36, + 0xfd, 0x55, 0xa9, 0x21, 0x0b, 0xdc, 0xf6, 0xae, + 0x11, 0xdc, 0x62, 0x21, 0x44, 0xbd, 0x04, 0x1d, + 0x58, 0x2c, 0x03, 0xf8, 0xe4, 0xe2, 0x1e, 0xba, + 0xe6, 0xdd, 0x19, 0xdd, 0x56, 0xfd, 0xce, 0x06, + 0x73, 0x5f, 0x94, 0x1e, 0xb6, 0x03, 0xdb, 0x3d, + 0x7b, 0xab, 0xab, 0x72, 0x64, 0x7b, 0xde, 0x7d, + 0x4d, 0xcf, 0x7e, 0xf0, 0x91, 0x29, 0xc1, 0x77, + 0x13, 0xc2, 0x6f, 0x80, 0xab, 0x7a, 0xa8, 0xce, + 0xb0, 0x1c, 0x2a, 0xc5, 0x9c, 0xfb, 0x0b, 0xe5, + 0x9f, 0x9c, 0x1b, 0xc9, 0x4b, 0x58, 0xdf, 0x96, + 0x18, 0xf7, 0x67, 0x67, 0x89, 0xa4, 0xe9, 0x14, + 0x48, 0xac, 0xfa, 0x9d, 0x86, 0x2a, 0xeb, 0x75, + 0x2c, 0x2b, 0xbf, 0x63, 0x7d, 0xc7, 0x4e, 0x7e, + 0xad, 0x39, 0x2d, 0xb4, 0x7c, 0x07, 0xa5, 0x5a, + 0xe8, 0x3a, 0xd4, 0xf5, 0x0c, 0x4f, 0xf3, 0xa2, + 0x9c, 0x3c, 0x32, 0xed, 0x9d, 0x4b, 0x49, 0x05, + 0xbc, 0x1f, 0xa0, 0x13, 0xe6, 0xdd, 0x82, 0x79, + 0x06, 0x31, 0x3b, 0xc6, 0x97, 0xec, 0x8d, 0xaa, + 0x4f, 0xef, 0x14, 0x3c, 0x21, 0xf6, 0x72, 0xb2, + 0x09, 0x42, 0xc7, 0x74, 0xfe, 0xef, 0x70, 0xbd, + 0xe9, 0x85, 0x41, 0x30, 0x0b, 0xb3, 0x6b, 0x59, + 0x0c, 0x0f, 0x11, 0x75, 0xd4, 0xbb, 0xb1, 0xdf, + 0xb1, 0xdf, 0xb3, 0xfa, 0xb3, 0x3a, 0x43, 0x17, + 0x7d, 0x8a, 0x82, 0xae, 0xa2, 0x07, 0xf8, 0x83, + 0x51, 0xfb, 0x16, 0xfb, 0x64, 0xb6, 0x46, 0xda, + 0xbe, 0x32, 0x2b, 0xc0, 0xee, 0x78, 0x2a, 0x84, + 0xa9, 0x54, 0x0a, 0xf9, 0x2d, 0x61, 0x65, 0xde, + 0xa5, 0x97, 0x66, 0x79, 0x02, 0xf8, 0x97, 0x17, + 0xe2, 0xd4, 0x9f, 0x9e, 0xac, 0xcc, 0xae, 0x99, + 0x9a, 0x03, 0x04, 0xbb, 0x45, 0xfe, 0xb2, 0xf5, + 0x80, 0xba, 0xbf, 0xdd, 0x24, 0xe5, 0xe6, 0x1e, + 0x5d, 0x36, 0xa5, 0x87, 0x0c, 0xdf, 0x60, 0x81, + 0x6f, 0xb7, 0x5f, 0xb9, 0x1f, 0xca, 0x75, 0x3c, + 0x1a, 0x63, 0xb0, 0xeb, 0xe6, 0x95, 0x86, 0x0d, + 0xae, 0xa6, 0xc9, 0x2a, 0x94, 0xf1, 0xd0, 0xbe, + 0x75, 0xc8, 0xf8, 0x07, 0xd7, 0x88, 0xff, 0xec, + 0xf9, 0xcd, 0x49, 0xc6, 0xfe, 0x4d, 0x7f, 0x44, + 0x1e, 0xd8, 0xaf, 0xa9, 0x72, 0x27, 0x98, 0xe2, + 0x5a, 0x08, 0xea, 0x55, 0xd3, 0xb3, 0xea, 0xdc, + 0x76, 0x69, 0x51, 0x10, 0x01, 0x46, 0x7d, 0x33, + 0x94, 0x9c, 0x94, 0xef, 0xfe, 0x76, 0x1c, 0xc6, + 0xd7, 0x15, 0x53, 0x3e, 0x8d, 0x3d, 0x29, 0x9a, + 0x58, 0x6a, 0xf1, 0x75, 0x9e, 0xea, 0x1b, 0x4c, + 0xf0, 0x47, 0x76, 0xac, 0xc6, 0xa2, 0x32, 0x44, + 0x40, 0xdf, 0xfe, 0xff, 0x9d, 0xf4, 0xe2, 0xc2, + 0xfa, 0xa1, 0x5f, 0x2e, 0x66, 0xe9, 0x97, 0xcb, + 0x27, 0x26, 0x6e, 0x53, 0xe4, 0xe8, 0x86, 0x2c, + 0xea, 0xd3, 0x69, 0x6c, 0x61, 0x4f, 0xfe, 0xc1, + 0xc9, 0x8b, 0x05, 0x92, 0x6f, 0x47, 0x96, 0xce, + 0xf0, 0x33, 0xfa, 0x7c, 0x78, 0x24, 0x9b, 0xd7, + 0x8d, 0x36, 0x56, 0x37, 0x86, 0xbc, 0x72, 0x5a, + 0xf9, 0xb9, 0xb0, 0x93, 0xf0, 0x81, 0x78, 0x10, + 0xf2, 0xb0, 0xc2, 0x79, 0x91, 0x5e, 0xcf, 0xbc, + 0x8c, 0xf2, 0x32, 0x0f, 0xf7, 0x2d, 0x30, 0xd8, + 0x13, 0x77, 0x4f, 0x78, 0x9e, 0x40, 0x8d, 0xe6, + 0x3a, 0x98, 0xb2, 0xaa, 0x13, 0x4d, 0x25, 0x49, + 0x34, 0x6c, 0x80, 0x9e, 0x19, 0x03, 0xdb, 0xcd, + 0xf5, 0xb1, 0x54, 0x74, 0x1b, 0x67, 0x3c, 0x46, + 0xac, 0x3e, 0x5d, 0xa2, 0xd9, 0x13, 0x83, 0x30, + 0xeb, 0x82, 0x3b, 0x06, 0xab, 0x3c, 0x39, 0x7d, + 0xd0, 0x68, 0x31, 0x00 +}; + +// clang-format on + +} // namespace + +const size_t kTestOemPublicCertSize = sizeof(kTestOemPublicCert); + +const uint32_t kOEMSystemId = kTestOemSystemId; + +const uint8_t* kOEMPrivateKey = kTestOemPrivateKey; +const uint8_t* kOEMPublicCert = kTestOemPublicCert; + +const size_t kOEMPrivateKeySize = kTestOemPrivateKeySize; +const size_t kOEMPublicCertSize = kTestOemPublicCertSize; + +} // namespace wvoec_ref diff --git a/libwvdrmengine/oemcrypto/ref/test/oemcrypto_oem_cert_unittest.cpp b/libwvdrmengine/oemcrypto/ref/test/oemcrypto_oem_cert_unittest.cpp new file mode 100644 index 00000000..6afa51d3 --- /dev/null +++ b/libwvdrmengine/oemcrypto/ref/test/oemcrypto_oem_cert_unittest.cpp @@ -0,0 +1,115 @@ +// Copyright 2021 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine License +// Agreement. +// +// Reference implementation of OEMCrypto APIs +// +#include + +#include "OEMCryptoCENCCommon.h" +#include "oem_cert.h" +#include "oemcrypto_oem_cert.h" +#include "oemcrypto_rsa_key.h" + +namespace wvoec_ref { +namespace { +const std::vector kOEMPrivateKeyVector(kOEMPrivateKey, + kOEMPrivateKey + + kOEMPrivateKeySize); + +const std::vector kOEMPublicCertVector(kOEMPublicCert, + kOEMPublicCert + + kOEMPublicCertSize); +} // namespace + +// Creates an OemCertificate wrapper around the built-in reference +// OEM cert. +// Creating the OemCertificate should succeed so long as the data +// is well-formed. +// Validating the OEM cert should succeed (assuming built-in cert+key +// are valid). +TEST(OEMCryptoOemCertTest, CreateFromArray) { + std::unique_ptr oem_cert = OemCertificate::Create( + kOEMPrivateKey, kOEMPrivateKeySize, kOEMPublicCert, kOEMPublicCertSize); + ASSERT_TRUE(oem_cert); + + EXPECT_EQ(OemCertificate::kRsa, oem_cert->key_type()); + + const std::vector private_key = oem_cert->GetPrivateKey(); + EXPECT_EQ(kOEMPrivateKeyVector, private_key); + + size_t public_cert_size = 10; + std::vector public_cert(public_cert_size, 0); + EXPECT_EQ( + OEMCrypto_ERROR_SHORT_BUFFER, + oem_cert->GetPublicCertificate(public_cert.data(), &public_cert_size)); + public_cert.resize(public_cert_size); + EXPECT_EQ(OEMCrypto_SUCCESS, oem_cert->GetPublicCertificate( + public_cert.data(), &public_cert_size)); + EXPECT_EQ(kOEMPublicCertSize, public_cert_size); + EXPECT_EQ(kOEMPublicCertVector, public_cert); + + EXPECT_EQ(OEMCrypto_SUCCESS, oem_cert->IsCertificateValid()); +} + +TEST(OEMCryptoOemCertTest, CreateFromVector) { + std::unique_ptr oem_cert = + OemCertificate::Create(kOEMPrivateKeyVector, kOEMPublicCertVector); + ASSERT_TRUE(oem_cert); + + EXPECT_EQ(OemCertificate::kRsa, oem_cert->key_type()); + + const std::vector private_key = oem_cert->GetPrivateKey(); + EXPECT_EQ(kOEMPrivateKeyVector, private_key); + + const std::vector public_cert = oem_cert->GetPublicCertificate(); + EXPECT_EQ(kOEMPublicCertVector, public_cert); + + EXPECT_EQ(OEMCrypto_SUCCESS, oem_cert->IsCertificateValid()); +} + +// Creation of OemCertificate wrapper should fail if the provided +// key is not well-formed. +TEST(OEMCryptoOemCertTest, CreateWithABadPrivateKey) { + static const uint8_t kBadPrivateKeyData[] = {'n', 'o', 't', ' ', 'a', ' ', + 'p', 'r', 'i', 'v', 'a', 't', + 'e', 'k', 'e', 'y'}; + std::unique_ptr oem_cert = + OemCertificate::Create(kBadPrivateKeyData, sizeof(kBadPrivateKeyData), + kOEMPublicCert, kOEMPublicCertSize); + EXPECT_FALSE(oem_cert); +} + +// Creation of OemCertificate wrapper should fail if the provided +// OEM Public Cert is not well-formed. +TEST(OEMCryptoOemCertTest, CreateWithABadPublicCert) { + static const uint8_t kBadPublicCert[] = {'n', 'o', 't', ' ', 'a', ' ', 'o', + 'e', 'm', ' ', 'p', 'u', 'b', 'l', + 'i', 'c', ' ', 'c', 'e', 'r', 't'}; + std::unique_ptr oem_cert = + OemCertificate::Create(kOEMPrivateKey, kOEMPrivateKeySize, kBadPublicCert, + sizeof(kBadPublicCert)); + EXPECT_FALSE(oem_cert); +} + +// It is possible to create an OEM Certificate using a non-matching +// public-private key pair so long as the key types are the same. +// However, OEM Cert validation should catch the problem. +TEST(OEMCryptoOemCertTest, CreateWithDifferentPrivateRsaKey) { + std::unique_ptr key = RsaPrivateKey::New(kRsa2048Bit); + ASSERT_TRUE(key); + const std::vector private_key = key->Serialize(); + ASSERT_FALSE(private_key.empty()); + + // Creating the OEM Certificate should succeed. + std::unique_ptr oem_cert = + OemCertificate::Create(private_key, kOEMPublicCertVector); + ASSERT_TRUE(oem_cert); + + EXPECT_EQ(OemCertificate::kRsa, oem_cert->key_type()); + + // Validating key should return an error. + EXPECT_EQ(OEMCrypto_ERROR_INVALID_RSA_KEY, oem_cert->IsCertificateValid()); +} + +} // namespace wvoec_ref From b8049e1f20ea30644271a19a5dfbe2715be66f43 Mon Sep 17 00:00:00 2001 From: Rahul Frias Date: Tue, 2 Mar 2021 02:48:10 -0800 Subject: [PATCH 2/4] Log license request and response [ Merge of http://go/wvgerrit/119563 ] This also increases the max log size from 1024 to 5120 Bug: 181642154 Test: WV unit/integration tests Change-Id: Ifae90354dad1165f4d9fa3c9fe33a4dc14df1270 --- libwvdrmengine/cdm/core/src/cdm_engine.cpp | 11 +++++++++++ libwvdrmengine/cdm/util/src/log.cpp | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/libwvdrmengine/cdm/core/src/cdm_engine.cpp b/libwvdrmengine/cdm/core/src/cdm_engine.cpp index 2a71f0d2..aab679e9 100644 --- a/libwvdrmengine/cdm/core/src/cdm_engine.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_engine.cpp @@ -304,6 +304,12 @@ CdmResponseType CdmEngine::GenerateKeyRequest( OnKeyReleaseEvent(key_set_id); } + LOGD( + "key request: (%zu) %s", key_request->message.size(), + wvcdm::Base64SafeEncode(std::vector(key_request->message.begin(), + key_request->message.end())) + .c_str()); + return KEY_MESSAGE; } @@ -339,6 +345,11 @@ CdmResponseType CdmEngine::AddKey(const CdmSessionId& session_id, } id = iter->second.first; + } else { + LOGD("key data: (%zu) %s", key_data.size(), + wvcdm::Base64SafeEncode( + std::vector(key_data.begin(), key_data.end())) + .c_str()); } std::shared_ptr session; diff --git a/libwvdrmengine/cdm/util/src/log.cpp b/libwvdrmengine/cdm/util/src/log.cpp index 830a4dad..fd3c888c 100644 --- a/libwvdrmengine/cdm/util/src/log.cpp +++ b/libwvdrmengine/cdm/util/src/log.cpp @@ -19,7 +19,7 @@ #endif #define LOG_TAG "WVCdm" -#define LOG_BUF_SIZE 1024 +#define LOG_BUF_SIZE 5120 #include "log.h" #include @@ -83,7 +83,7 @@ void Log(const char* file, const char* function, int line, LogPriority level, const char* filename = strrchr(file, '/'); filename = filename == nullptr ? file : filename + 1; - char buf[LOG_BUF_SIZE]; + static thread_local char buf[LOG_BUF_SIZE]; int len = snprintf(buf, LOG_BUF_SIZE, "[%s(%d):%s] ", filename, line, function); if (len < 0) len = 0; From 83a85430e32f23ff5af7941ecfc7bb7bca5c20ae Mon Sep 17 00:00:00 2001 From: Rahul Frias Date: Tue, 23 Feb 2021 12:46:43 -0800 Subject: [PATCH 3/4] Release crypto resources when provisioning fails [ Merge of http://go/wvgerrit/119564 ] This closes a crypto session when the provisioning request fails. We cannot be as eager when handling the response as the app may have multiple simultaneous provisioning attempts in flight. In this case all provisioning responses except the one associated with the last request will fail. If we close the session on error, even the one associated with the last request may fail. Bug: 180986725 Test: WV unit/integration tests Change-Id: Ic3d33a374e442b5bf040e345bed829d91c4ef1dc --- .../core/include/certificate_provisioning.h | 15 ++++++++++++ .../cdm/core/src/certificate_provisioning.cpp | 24 +++++++++++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/libwvdrmengine/cdm/core/include/certificate_provisioning.h b/libwvdrmengine/cdm/core/include/certificate_provisioning.h index 6159fafe..8766de81 100644 --- a/libwvdrmengine/cdm/core/include/certificate_provisioning.h +++ b/libwvdrmengine/cdm/core/include/certificate_provisioning.h @@ -64,6 +64,12 @@ class CertificateProvisioning { const std::string& provisioning_response, std::string* result); private: + CdmResponseType GetProvisioningRequestInternal( + SecurityLevel requested_security_level, CdmCertificateType cert_type, + const std::string& cert_authority, const std::string& origin, + const std::string& spoid, CdmProvisioningRequest* request, + std::string* default_url); + CdmResponseType SetSpoidParameter( const std::string& origin, const std::string& spoid, video_widevine::ProvisioningRequest* request); @@ -71,6 +77,15 @@ class CertificateProvisioning { video_widevine::SignedProvisioningMessage::ProvisioningType GetProvisioningType(); + // Closes crypto session if one is open. Avoid calling this method when + // processing a response. Multiple provisioning responses might be + // simultaneously in flight. Only the response associated with the last + // provisioning request can be processed. All the other responses will + // fail. If the session is closed when these responses fail, even the one + // associated with the last provisioning request may fail. + CdmResponseType CloseSessionOnError(CdmResponseType status); + void CloseSession(); + std::unique_ptr crypto_session_; CdmCertificateType cert_type_; std::unique_ptr service_certificate_; diff --git a/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp b/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp index a957ab95..87fe2180 100644 --- a/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp +++ b/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp @@ -194,6 +194,16 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequest( const std::string& cert_authority, const std::string& origin, const std::string& spoid, CdmProvisioningRequest* request, std::string* default_url) { + return CloseSessionOnError(GetProvisioningRequestInternal( + requested_security_level, cert_type, cert_authority, origin, spoid, + request, default_url)); +} + +CdmResponseType CertificateProvisioning::GetProvisioningRequestInternal( + SecurityLevel requested_security_level, CdmCertificateType cert_type, + const std::string& cert_authority, const std::string& origin, + const std::string& spoid, CdmProvisioningRequest* request, + std::string* default_url) { if (!request || !default_url) { LOGE("Output parameter |%s| is not provided", request ? "default_url" : "request"); @@ -202,7 +212,7 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequest( default_url->assign(kProvisioningServerUrl); - if (crypto_session_->IsOpen()) crypto_session_->Close(); + CloseSession(); CdmResponseType status = crypto_session_->Open(requested_security_level); if (NO_ERROR != status) { LOGE("Failed to create a crypto session: status = %d", @@ -423,7 +433,7 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse( } const CdmSecurityLevel security_level = crypto_session_->GetSecurityLevel(); - crypto_session_->Close(); + CloseSession(); // This is the entire certificate (SignedDrmDeviceCertificate). const std::string& device_cert_data = @@ -521,4 +531,14 @@ bool CertificateProvisioning::ExtractDeviceInfo( return true; } +void CertificateProvisioning::CloseSession() { + if (crypto_session_->IsOpen()) crypto_session_->Close(); +} + +CdmResponseType CertificateProvisioning::CloseSessionOnError( + CdmResponseType status) { + if (status != NO_ERROR) CloseSession(); + return status; +} + } // namespace wvcdm From a828bf5f58982c01c69b8ccf0f2c81eb109071c1 Mon Sep 17 00:00:00 2001 From: Rahul Frias Date: Fri, 12 Mar 2021 00:57:07 -0800 Subject: [PATCH 4/4] Annotate fallthrough in OEC Testbed [ Merge of http://go/wvgerrit/119230 ] This patch adds an annotation to the one place in the codebase where we intentionally fall through between switch statement cases, in order to appease stricter compilers. Bug: 182058081 Test: compile, WV unit/integration tests Change-Id: I004a6a6e61681fcf22c6bf25d9b0284b8b64e776 --- libwvdrmengine/cdm/util/include/util_common.h | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/libwvdrmengine/cdm/util/include/util_common.h b/libwvdrmengine/cdm/util/include/util_common.h index 5e7b1661..7b28c482 100644 --- a/libwvdrmengine/cdm/util/include/util_common.h +++ b/libwvdrmengine/cdm/util/include/util_common.h @@ -5,20 +5,27 @@ #ifndef WVCDM_UTIL_UTIL_COMMON_H_ #define WVCDM_UTIL_UTIL_COMMON_H_ +// This section deals with defines that are platform-specific. + #ifdef _WIN32 + # ifdef CORE_UTIL_IMPLEMENTATION # define CORE_UTIL_EXPORT __declspec(dllexport) # else # define CORE_UTIL_EXPORT __declspec(dllimport) # endif + # define CORE_UTIL_IGNORE_DEPRECATED # define CORE_UTIL_RESTORE_WARNINGS + #else + # ifdef CORE_UTIL_IMPLEMENTATION # define CORE_UTIL_EXPORT __attribute__((visibility("default"))) # else # define CORE_UTIL_EXPORT # endif + # ifdef __GNUC__ # define CORE_UTIL_IGNORE_DEPRECATED \ _Pragma("GCC diagnostic push") \ @@ -28,6 +35,23 @@ # define CORE_UTIL_IGNORE_DEPRECATED # define CORE_UTIL_RESTORE_WARNINGS # endif + +#endif + +// This section deals with attribute-detection and is platform-agnostic. + +#if !defined(__has_cpp_attribute) +# define __has_cpp_attribute(x) 0 +#endif + +#if __has_cpp_attribute(fallthrough) +# define CORE_UTIL_FALLTHROUGH [[fallthrough]] +#elif __has_cpp_attribute(clang::fallthrough) +# define CORE_UTIL_FALLTHROUGH [[clang::fallthrough]] +#elif __has_cpp_attribute(gnu::fallthrough) +# define CORE_UTIL_FALLTHROUGH [[gnu::fallthrough]] +#else +# define CORE_UTIL_FALLTHROUGH #endif #endif // WVCDM_UTIL_UTIL_COMMON_H_