Export provisioning sdk
Change-Id: I4d47d80444c9507f84896767dc676112ca11e901
This commit is contained in:
164
common/BUILD
Normal file
164
common/BUILD
Normal file
@@ -0,0 +1,164 @@
|
||||
################################################################################
|
||||
# Copyright 2016 Google Inc.
|
||||
#
|
||||
# This software is licensed under the terms defined in the Widevine Master
|
||||
# License Agreement. For a copy of this agreement, please contact
|
||||
# widevine-licensing@google.com.
|
||||
################################################################################
|
||||
|
||||
#
|
||||
# Description:
|
||||
# Build file for code common to multiple Widevine services.
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
cc_library(
|
||||
name = "rsa_util",
|
||||
srcs = ["rsa_util.cc"],
|
||||
hdrs = ["rsa_util.h"],
|
||||
deps = [
|
||||
"//base",
|
||||
"//external:openssl",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "rsa_util_test",
|
||||
size = "medium",
|
||||
timeout = "short",
|
||||
srcs = ["rsa_util_test.cc"],
|
||||
deps = [
|
||||
":rsa_test_keys",
|
||||
":rsa_util",
|
||||
"//external:gtest",
|
||||
"//external:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "openssl_util",
|
||||
hdrs = ["openssl_util.h"],
|
||||
deps = [
|
||||
"//external:openssl",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "rsa_key",
|
||||
srcs = ["rsa_key.cc"],
|
||||
hdrs = ["rsa_key.h"],
|
||||
deps = [
|
||||
":rsa_util",
|
||||
":sha_util",
|
||||
"//base",
|
||||
"//external:openssl",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "rsa_key_test",
|
||||
size = "medium",
|
||||
timeout = "short",
|
||||
srcs = ["rsa_key_test.cc"],
|
||||
deps = [
|
||||
":rsa_key",
|
||||
":rsa_test_keys",
|
||||
"//external:gtest",
|
||||
"//external:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "rsa_test_keys",
|
||||
testonly = 1,
|
||||
srcs = ["rsa_test_keys.cc"],
|
||||
hdrs = ["rsa_test_keys.h"],
|
||||
deps = [
|
||||
"//base",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "mock_rsa_key",
|
||||
testonly = 1,
|
||||
hdrs = ["mock_rsa_key.h"],
|
||||
deps = [
|
||||
":rsa_key",
|
||||
"//external:gtest",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "aes_cbc_util",
|
||||
srcs = ["aes_cbc_util.cc"],
|
||||
hdrs = ["aes_cbc_util.h"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//base",
|
||||
"//external:openssl",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "aes_cbc_util_test",
|
||||
srcs = ["aes_cbc_util_test.cc"],
|
||||
deps = [
|
||||
":aes_cbc_util",
|
||||
"//external:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "random_util",
|
||||
srcs = ["random_util.cc"],
|
||||
hdrs = ["random_util.h"],
|
||||
deps = [
|
||||
"//base",
|
||||
"//external:openssl",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "random_util_test",
|
||||
srcs = ["random_util_test.cc"],
|
||||
deps = [
|
||||
":random_util",
|
||||
"//external:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "sha_util",
|
||||
srcs = ["sha_util.cc"],
|
||||
hdrs = ["sha_util.h"],
|
||||
deps = [
|
||||
"//external:openssl",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "sha_util_test",
|
||||
srcs = ["sha_util_test.cc"],
|
||||
deps = [
|
||||
":sha_util",
|
||||
"//external:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "file_util",
|
||||
srcs = ["file_util.cc"],
|
||||
hdrs = ["file_util.h"],
|
||||
deps = [
|
||||
"//base",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "file_util_test",
|
||||
srcs = ["file_util_test.cc"],
|
||||
deps = [
|
||||
":file_util",
|
||||
"//external:gtest_main",
|
||||
],
|
||||
)
|
||||
93
common/aes_cbc_util.cc
Normal file
93
common/aes_cbc_util.cc
Normal file
@@ -0,0 +1,93 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2016 Google Inc.
|
||||
//
|
||||
// This software is licensed under the terms defined in the Widevine Master
|
||||
// License Agreement. For a copy of this agreement, please contact
|
||||
// widevine-licensing@google.com.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "common/aes_cbc_util.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "glog/logging.h"
|
||||
#include "openssl/aes.h"
|
||||
|
||||
namespace widevine {
|
||||
namespace crypto_util {
|
||||
|
||||
// Encrypts the provided plantext std::string using AES-CBC encryption.
|
||||
std::string EncryptAesCbc(const std::string& key, const std::string& iv,
|
||||
const std::string& plaintext) {
|
||||
if (iv.size() != AES_BLOCK_SIZE) return "";
|
||||
|
||||
const size_t num_padding_bytes =
|
||||
AES_BLOCK_SIZE - (plaintext.size() % AES_BLOCK_SIZE);
|
||||
std::string padded_text = plaintext;
|
||||
padded_text.append(num_padding_bytes, static_cast<char>(num_padding_bytes));
|
||||
|
||||
AES_KEY aes_key;
|
||||
if (AES_set_encrypt_key(reinterpret_cast<const uint8_t*>(&key[0]),
|
||||
key.size() * 8, &aes_key) != 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string encrypted(padded_text);
|
||||
std::vector<uint8_t> local_iv(iv.begin(), iv.end());
|
||||
AES_cbc_encrypt(reinterpret_cast<const uint8_t*>(padded_text.data()),
|
||||
reinterpret_cast<uint8_t*>(&encrypted[0]), padded_text.size(),
|
||||
&aes_key, &local_iv[0], AES_ENCRYPT);
|
||||
return encrypted;
|
||||
}
|
||||
|
||||
// Decrypts the AES-CBC encrypted text. Returns an empty std::string on error or
|
||||
// the plaintext on success.
|
||||
std::string DecryptAesCbc(const std::string& key, const std::string& iv,
|
||||
const std::string& ciphertext) {
|
||||
if (ciphertext.empty()) return "";
|
||||
if (iv.size() != AES_BLOCK_SIZE) return "";
|
||||
if ((ciphertext.size() % AES_BLOCK_SIZE) != 0) return "";
|
||||
|
||||
AES_KEY aes_key;
|
||||
if (AES_set_decrypt_key(reinterpret_cast<const uint8_t*>(&key[0]),
|
||||
key.size() * 8, &aes_key) != 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string cleartext(ciphertext);
|
||||
std::vector<uint8_t> local_iv(iv.begin(), iv.end());
|
||||
AES_cbc_encrypt(reinterpret_cast<const uint8_t*>(ciphertext.data()),
|
||||
reinterpret_cast<uint8_t*>(&cleartext[0]), ciphertext.size(),
|
||||
&aes_key, &local_iv[0], AES_DECRYPT);
|
||||
|
||||
const uint8_t num_padding_bytes = cleartext[cleartext.size() - 1];
|
||||
if (num_padding_bytes > AES_BLOCK_SIZE) return "";
|
||||
for (uint8_t i = 0; i < num_padding_bytes; ++i) {
|
||||
if (cleartext[cleartext.size() - 1 - i] != num_padding_bytes) return "";
|
||||
}
|
||||
cleartext.resize(cleartext.size() - num_padding_bytes);
|
||||
return cleartext;
|
||||
}
|
||||
|
||||
std::string DecryptAesCbcNoPad(const std::string& key, const std::string& iv,
|
||||
const std::string& ciphertext) {
|
||||
std::vector<uint8_t> local_iv(iv.begin(), iv.end());
|
||||
if (local_iv.empty()) local_iv.resize(AES_BLOCK_SIZE, '\0');
|
||||
else if (local_iv.size() != AES_BLOCK_SIZE) return "";
|
||||
if ((ciphertext.size() % AES_BLOCK_SIZE) != 0) return "";
|
||||
|
||||
AES_KEY aes_key;
|
||||
if (AES_set_decrypt_key(reinterpret_cast<const uint8_t*>(&key[0]),
|
||||
key.size() * 8, &aes_key) != 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string cleartext(ciphertext);
|
||||
AES_cbc_encrypt(reinterpret_cast<const uint8_t*>(ciphertext.data()),
|
||||
reinterpret_cast<uint8_t*>(&cleartext[0]), ciphertext.size(),
|
||||
&aes_key, &local_iv[0], AES_DECRYPT);
|
||||
return cleartext;
|
||||
}
|
||||
|
||||
} // namespace crypto_util
|
||||
} // namespace widevine
|
||||
38
common/aes_cbc_util.h
Normal file
38
common/aes_cbc_util.h
Normal file
@@ -0,0 +1,38 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2016 Google Inc.
|
||||
//
|
||||
// This software is licensed under the terms defined in the Widevine Master
|
||||
// License Agreement. For a copy of this agreement, please contact
|
||||
// widevine-licensing@google.com.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef COMMON_AES_CBC_UTIL_H_
|
||||
#define COMMON_AES_CBC_UTIL_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace widevine {
|
||||
namespace crypto_util {
|
||||
|
||||
// Helper for wrapping AES CBC encryption. Uses PKCS5 padding.
|
||||
std::string EncryptAesCbc(const std::string& key, const std::string& iv,
|
||||
const std::string& plaintext);
|
||||
|
||||
// Helper for common Keybox decrypt operations; wraps AES-CBC. Returns an
|
||||
// empty std::string on error or the plaintext on success. Uses PKCS5 padding.
|
||||
std::string DecryptAesCbc(const std::string& key, const std::string& iv,
|
||||
const std::string& ciphertext);
|
||||
|
||||
// Helper for common Keybox decrypt operations; wraps AES-CBC. Returns an
|
||||
// empty std::string on error or the plaintext on success.
|
||||
// Uses no padding; fails if the ciphertext is not a multiple of 16 bytes.
|
||||
// This is used to decrypt the encrypted blob in the WVM keyboxes, with
|
||||
// a zero iv.
|
||||
std::string DecryptAesCbcNoPad(const std::string& key, const std::string& iv,
|
||||
const std::string& ciphertext);
|
||||
|
||||
} // namespace crypto_util
|
||||
} // namespace widevine
|
||||
|
||||
#endif // COMMON_AES_CBC_UTIL_H_
|
||||
|
||||
137
common/aes_cbc_util_test.cc
Normal file
137
common/aes_cbc_util_test.cc
Normal file
@@ -0,0 +1,137 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2016 Google Inc.
|
||||
//
|
||||
// This software is licensed under the terms defined in the Widevine Master
|
||||
// License Agreement. For a copy of this agreement, please contact
|
||||
// widevine-licensing@google.com.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "common/aes_cbc_util.h"
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace {
|
||||
|
||||
const uint8_t kKey[] = {
|
||||
0x87, 0x27, 0xa4, 0x0e, 0xbd, 0x82, 0x32, 0x9e,
|
||||
0x6b, 0x3b, 0x4e, 0x29, 0xfa, 0x3b, 0x00, 0x4b,
|
||||
};
|
||||
|
||||
const uint8_t kIv[] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace widevine {
|
||||
namespace crypto_util {
|
||||
|
||||
TEST(CryptoUtilTest, EncryptAndDecryptAesCbc) {
|
||||
std::string plain_text("Foo");
|
||||
std::string ciphertext = EncryptAesCbc(std::string(kKey, kKey + sizeof(kKey)),
|
||||
std::string(kIv, kIv + sizeof(kIv)), plain_text);
|
||||
std::string expected_ciphertext(
|
||||
"\xCF\x1A\x3\x1C\x9C\x8C\xB9Z\xEC\xC0\x17\xDCRxX\xD7");
|
||||
ASSERT_EQ(0, ciphertext.size() % 16);
|
||||
ASSERT_GT(ciphertext.size(), plain_text.size());
|
||||
ASSERT_EQ(expected_ciphertext, ciphertext);
|
||||
|
||||
std::string decrypted = DecryptAesCbc(std::string(kKey, kKey + sizeof(kKey)),
|
||||
std::string(kIv, kIv + sizeof(kIv)), ciphertext);
|
||||
ASSERT_EQ(plain_text, decrypted);
|
||||
}
|
||||
|
||||
TEST(CryptoUtilTest, DecryptAesCbcNoPad) {
|
||||
const uint8_t kKey[] = {
|
||||
0xdd, 0x71, 0x39, 0xea, 0xfa, 0xce, 0xed, 0x7c,
|
||||
0xda, 0x9f, 0x25, 0xda, 0x8a, 0xa9, 0x15, 0xea,
|
||||
};
|
||||
const uint8_t kIv[] = {
|
||||
0x5d, 0x16, 0x44, 0xea, 0xec, 0x11, 0xf9, 0x83,
|
||||
0x14, 0x75, 0x41, 0xe4, 0x6e, 0xeb, 0x27, 0x74,
|
||||
};
|
||||
const uint8_t kCiphertext[] = {
|
||||
0x6d, 0xa6, 0xda, 0xe4, 0xee, 0x40, 0x09, 0x17,
|
||||
0x54, 0x7b, 0xba, 0xa5, 0x27, 0xb8, 0x82, 0x1b,
|
||||
};
|
||||
const uint8_t kExpectedPlaintext[] = {
|
||||
0xb3, 0x49, 0xd4, 0x80, 0x9e, 0x91, 0x06, 0x87,
|
||||
0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x10,
|
||||
};
|
||||
const uint8_t kExpectedPlaintextEmptyIv[] = {
|
||||
0xee, 0x5f, 0x90, 0x6a, 0x72, 0x80, 0xff, 0x04,
|
||||
0x14, 0x75, 0x41, 0xa4, 0x6e, 0xeb, 0x27, 0x64,
|
||||
};
|
||||
|
||||
std::string decrypted = DecryptAesCbcNoPad(
|
||||
std::string(kKey, kKey + sizeof(kKey)), std::string(kIv, kIv + sizeof(kIv)),
|
||||
std::string(kCiphertext, kCiphertext + sizeof(kCiphertext)));
|
||||
ASSERT_EQ(std::string(kExpectedPlaintext,
|
||||
kExpectedPlaintext + sizeof(kExpectedPlaintext)),
|
||||
decrypted);
|
||||
|
||||
std::string dummy_iv;
|
||||
decrypted = DecryptAesCbcNoPad(
|
||||
std::string(kKey, kKey + sizeof(kKey)), dummy_iv,
|
||||
std::string(kCiphertext, kCiphertext + sizeof(kCiphertext)));
|
||||
ASSERT_EQ(
|
||||
std::string(kExpectedPlaintextEmptyIv,
|
||||
kExpectedPlaintextEmptyIv + sizeof(kExpectedPlaintextEmptyIv)),
|
||||
decrypted);
|
||||
}
|
||||
|
||||
TEST(CryptoUtilTest, TestFailedEncrypt) {
|
||||
// Test with bogus initialization vector.
|
||||
std::string plain_text("Foo");
|
||||
std::string bogus_iv("bogus");
|
||||
std::string ciphertext =
|
||||
EncryptAesCbc(std::string(kKey, kKey + sizeof(kKey)), bogus_iv, plain_text);
|
||||
ASSERT_EQ(ciphertext.size(), 0);
|
||||
|
||||
// Test with bogus key.
|
||||
std::string bogus_key("bogus");
|
||||
ciphertext =
|
||||
EncryptAesCbc(bogus_key, std::string(kIv, kIv + sizeof(kIv)), plain_text);
|
||||
ASSERT_EQ(ciphertext.size(), 0);
|
||||
}
|
||||
|
||||
TEST(CryptoUtilTest, TestFailedDecrypt) {
|
||||
// First, encrypt the data.
|
||||
std::string plain_text("Foo");
|
||||
std::string ciphertext = EncryptAesCbc(std::string(kKey, kKey + sizeof(kKey)),
|
||||
std::string(kIv, kIv + sizeof(kIv)), plain_text);
|
||||
ASSERT_NE(ciphertext.size(), 0);
|
||||
|
||||
// Test Decrypt with bogus iv.
|
||||
std::string bogus_iv("bogus");
|
||||
plain_text =
|
||||
DecryptAesCbc(std::string(kKey, kKey + sizeof(kKey)), bogus_iv, ciphertext);
|
||||
ASSERT_EQ(plain_text.size(), 0);
|
||||
|
||||
// Test Decrypt with bogus key.
|
||||
std::string bogus_key("bogus");
|
||||
plain_text =
|
||||
DecryptAesCbc(bogus_key, std::string(kIv, kIv + sizeof(kIv)), ciphertext);
|
||||
ASSERT_EQ(plain_text.size(), 0);
|
||||
}
|
||||
|
||||
TEST(CryptoUtilTest, TestEmptyEncrypt) {
|
||||
EXPECT_EQ("\xDBx\xD9\x91\xE8\x1D\xD9\x19\x80r\x12\x89\xD7Kp\xEB",
|
||||
EncryptAesCbc(std::string(kKey, kKey + sizeof(kKey)),
|
||||
std::string(kIv, kIv + sizeof(kIv)), ""));
|
||||
}
|
||||
|
||||
TEST(CryptoUtilTest, TestEmptyDecryptAesCbc) {
|
||||
EXPECT_EQ("", DecryptAesCbc(std::string(kKey, kKey + sizeof(kKey)),
|
||||
std::string(kIv, kIv + sizeof(kIv)), ""));
|
||||
}
|
||||
|
||||
TEST(CryptoUtilTest, TestEmptyDecryptAesCbcNoPad) {
|
||||
EXPECT_EQ("", DecryptAesCbcNoPad(std::string(kKey, kKey + sizeof(kKey)),
|
||||
std::string(kIv, kIv + sizeof(kIv)), ""));
|
||||
}
|
||||
|
||||
} // namespace crypto_util
|
||||
} // namespace widevine
|
||||
63
common/file_util.cc
Normal file
63
common/file_util.cc
Normal file
@@ -0,0 +1,63 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2016 Google Inc.
|
||||
//
|
||||
// This software is licensed under the terms defined in the Widevine Master
|
||||
// License Agreement. For a copy of this agreement, please contact
|
||||
// widevine-licensing@google.com.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "common/file_util.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "glog/logging.h"
|
||||
|
||||
namespace widevine {
|
||||
|
||||
bool GetContents(const std::string& file_name, std::string* contents) {
|
||||
if (file_name.empty()) {
|
||||
LOG(WARNING) << "File name is empty.";
|
||||
return false;
|
||||
}
|
||||
FILE* file = fopen(file_name.c_str(), "r");
|
||||
if (!file) {
|
||||
LOG(WARNING) << "Unable to open file " << file_name;
|
||||
return false;
|
||||
}
|
||||
contents->clear();
|
||||
const size_t kReadSize = 0x1000;
|
||||
char buffer[kReadSize];
|
||||
while (true) {
|
||||
size_t size_read = fread(buffer, sizeof(char), kReadSize, file);
|
||||
if (size_read == 0) break;
|
||||
contents->append(buffer, size_read);
|
||||
}
|
||||
const bool eof = feof(file);
|
||||
fclose(file);
|
||||
if (!eof) {
|
||||
LOG(WARNING) << "Failed to read all file contents.";
|
||||
return false;
|
||||
}
|
||||
return true;;
|
||||
}
|
||||
|
||||
bool SetContents(const std::string& file_name, const std::string& contents) {
|
||||
if (file_name.empty()) {
|
||||
LOG(WARNING) << "File name is empty.";
|
||||
return false;
|
||||
}
|
||||
FILE* file = fopen(file_name.c_str(), "w");
|
||||
if (!file) {
|
||||
LOG(WARNING) << "Unable to open file " << file_name;
|
||||
return false;
|
||||
}
|
||||
const size_t size_written =
|
||||
fwrite(contents.data(), sizeof(char), contents.size(), file);
|
||||
if (size_written != contents.size())
|
||||
LOG(WARNING) << "Failed to write to " << file_name;
|
||||
fclose(file);
|
||||
return size_written == contents.size();
|
||||
}
|
||||
|
||||
} // namespace widevine
|
||||
27
common/file_util.h
Normal file
27
common/file_util.h
Normal file
@@ -0,0 +1,27 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2016 Google Inc.
|
||||
//
|
||||
// This software is licensed under the terms defined in the Widevine Master
|
||||
// License Agreement. For a copy of this agreement, please contact
|
||||
// widevine-licensing@google.com.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// File util wrapper to be used in partner sdks. Implemented using generic file
|
||||
// apis.
|
||||
|
||||
#ifndef COMMON_FILE_UTIL_H_
|
||||
#define COMMON_FILE_UTIL_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace widevine {
|
||||
|
||||
// Read file to string.
|
||||
bool GetContents(const std::string& file_name, std::string* contents);
|
||||
|
||||
// Write file.
|
||||
bool SetContents(const std::string& file_name, const std::string& contents);
|
||||
|
||||
} // namespace widevine
|
||||
|
||||
#endif // COMMON_FILE_UTIL_H_
|
||||
29
common/file_util_test.cc
Normal file
29
common/file_util_test.cc
Normal file
@@ -0,0 +1,29 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2016 Google Inc.
|
||||
//
|
||||
// This software is licensed under the terms defined in the Widevine Master
|
||||
// License Agreement. For a copy of this agreement, please contact
|
||||
// widevine-licensing@google.com.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "common/file_util.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace widevine {
|
||||
|
||||
TEST(FileUtilTest, EmptyFileName) {
|
||||
std::string contents;
|
||||
EXPECT_FALSE(GetContents("", &contents));
|
||||
EXPECT_FALSE(SetContents("", "test content"));
|
||||
}
|
||||
|
||||
TEST(FileUtilTest, BasicTest) {
|
||||
const std::string file_path = FLAGS_test_tmpdir + "/file_util_test";
|
||||
EXPECT_TRUE(SetContents(file_path, "test content"));
|
||||
std::string contents;
|
||||
EXPECT_TRUE(GetContents(file_path, &contents));
|
||||
EXPECT_EQ("test content", contents);
|
||||
}
|
||||
|
||||
} // namespace widevine
|
||||
71
common/mock_rsa_key.h
Normal file
71
common/mock_rsa_key.h
Normal file
@@ -0,0 +1,71 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2016 Google Inc.
|
||||
//
|
||||
// This software is licensed under the terms defined in the Widevine Master
|
||||
// License Agreement. For a copy of this agreement, please contact
|
||||
// widevine-licensing@google.com.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef COMMON_MOCK_RSA_KEY_H_
|
||||
#define COMMON_MOCK_RSA_KEY_H_
|
||||
|
||||
#include "common/rsa_key.h"
|
||||
|
||||
namespace widevine {
|
||||
|
||||
class MockRsaPrivateKey : public RsaPrivateKey {
|
||||
public:
|
||||
MockRsaPrivateKey() : RsaPrivateKey(RSA_new()) {}
|
||||
~MockRsaPrivateKey() override {}
|
||||
|
||||
MOCK_CONST_METHOD2(Decrypt, bool(const std::string& encrypted_message,
|
||||
std::string* decrypted_message));
|
||||
MOCK_CONST_METHOD2(GenerateSignature,
|
||||
bool(const std::string& message, std::string* signature));
|
||||
MOCK_CONST_METHOD1(MatchesPrivateKey, bool(const RsaPrivateKey& private_key));
|
||||
MOCK_CONST_METHOD1(MatchesPublicKey, bool(const RsaPublicKey& public_key));
|
||||
|
||||
private:
|
||||
MockRsaPrivateKey(const MockRsaPrivateKey&) = delete;
|
||||
MockRsaPrivateKey& operator=(const MockRsaPrivateKey&) = delete;
|
||||
};
|
||||
|
||||
class MockRsaPublicKey : public RsaPublicKey {
|
||||
public:
|
||||
MockRsaPublicKey() : RsaPublicKey(RSA_new()) {}
|
||||
~MockRsaPublicKey() override {}
|
||||
|
||||
MOCK_CONST_METHOD2(Encrypt, bool(const std::string& clear_message,
|
||||
std::string* encrypted_message));
|
||||
MOCK_CONST_METHOD2(VerifySignature, bool(const std::string& message,
|
||||
const std::string& signature));
|
||||
MOCK_CONST_METHOD1(MatchesPrivateKey, bool(const RsaPrivateKey& private_key));
|
||||
MOCK_CONST_METHOD1(MatchesPublicKey, bool(const RsaPublicKey& public_key));
|
||||
|
||||
private:
|
||||
MockRsaPublicKey(const MockRsaPublicKey&) = delete;
|
||||
MockRsaPublicKey& operator=(const MockRsaPublicKey&) = delete;
|
||||
};
|
||||
|
||||
class MockRsaKeyFactory : public RsaKeyFactory{
|
||||
public:
|
||||
MockRsaKeyFactory() {}
|
||||
~MockRsaKeyFactory() override {}
|
||||
|
||||
MOCK_METHOD1(CreateFromPkcs1PrivateKey,
|
||||
std::unique_ptr<RsaPrivateKey>(const std::string& private_key));
|
||||
MOCK_METHOD2(
|
||||
CreateFromPkcs8PrivateKey,
|
||||
std::unique_ptr<RsaPrivateKey>(const std::string& private_key,
|
||||
const std::string& private_key_passphrase));
|
||||
MOCK_METHOD1(CreateFromPkcs1PublicKey,
|
||||
std::unique_ptr<RsaPublicKey>(const std::string& public_key));
|
||||
|
||||
private:
|
||||
MockRsaKeyFactory(const MockRsaKeyFactory&) = delete;
|
||||
MockRsaKeyFactory& operator=(const MockRsaKeyFactory&) = delete;
|
||||
};
|
||||
|
||||
} // namespace widevine
|
||||
|
||||
#endif // COMMON_MOCK_RSA_KEY_H_
|
||||
70
common/openssl_util.h
Normal file
70
common/openssl_util.h
Normal file
@@ -0,0 +1,70 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2016 Google Inc.
|
||||
//
|
||||
// This software is licensed under the terms defined in the Widevine Master
|
||||
// License Agreement. For a copy of this agreement, please contact
|
||||
// widevine-licensing@google.com.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#ifndef COMMON_OPENSSL_UTIL_H__
|
||||
#define COMMON_OPENSSL_UTIL_H__
|
||||
|
||||
#include "openssl/bio.h"
|
||||
#include "openssl/evp.h"
|
||||
#include "openssl/rsa.h"
|
||||
#include "openssl/x509v3.h"
|
||||
|
||||
template <typename T, void (*func)(T *)>
|
||||
struct OpenSSLDeleter {
|
||||
void operator()(T *obj) { func(obj); }
|
||||
};
|
||||
|
||||
template <typename StackType, typename T, void (*func)(T *)>
|
||||
struct OpenSSLStackDeleter {
|
||||
void operator()(StackType *obj) {
|
||||
sk_pop_free(reinterpret_cast<_STACK *>(obj),
|
||||
reinterpret_cast<void (*)(void *)>(func));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename StackType>
|
||||
struct OpenSSLStackOnlyDeleter {
|
||||
void operator()(StackType *obj) { sk_free(reinterpret_cast<_STACK *>(obj)); }
|
||||
};
|
||||
|
||||
template <typename T, void (*func)(T *)>
|
||||
using ScopedOpenSSLType = std::unique_ptr<T, OpenSSLDeleter<T, func>>;
|
||||
template <typename StackType, typename T, void (*func)(T *)>
|
||||
using ScopedOpenSSLStack =
|
||||
std::unique_ptr<StackType, OpenSSLStackDeleter<StackType, T, func>>;
|
||||
template <typename StackType>
|
||||
using ScopedOpenSSLStackOnly =
|
||||
std::unique_ptr<StackType, OpenSSLStackOnlyDeleter<StackType>>;
|
||||
|
||||
using ScopedBIO = ScopedOpenSSLType<BIO, BIO_vfree>;
|
||||
using ScopedPKEY = ScopedOpenSSLType<EVP_PKEY, EVP_PKEY_free>;
|
||||
using ScopedRSA = ScopedOpenSSLType<RSA, RSA_free>;
|
||||
using ScopedX509 = ScopedOpenSSLType<X509, X509_free>;
|
||||
using ScopedX509Extension =
|
||||
ScopedOpenSSLType<X509_EXTENSION, X509_EXTENSION_free>;
|
||||
using ScopedX509Name = ScopedOpenSSLType<X509_NAME, X509_NAME_free>;
|
||||
using ScopedX509NameEntry =
|
||||
ScopedOpenSSLType<X509_NAME_ENTRY, X509_NAME_ENTRY_free>;
|
||||
using ScopedX509Store = ScopedOpenSSLType<X509_STORE, X509_STORE_free>;
|
||||
using ScopedX509StoreCtx =
|
||||
ScopedOpenSSLType<X509_STORE_CTX, X509_STORE_CTX_free>;
|
||||
using ScopedAsn1UtcTime = ScopedOpenSSLType<ASN1_UTCTIME, ASN1_UTCTIME_free>;
|
||||
using ScopedAsn1Utc8String =
|
||||
ScopedOpenSSLType<ASN1_UTF8STRING, ASN1_UTF8STRING_free>;
|
||||
using ScopedAsn1Integer = ScopedOpenSSLType<ASN1_INTEGER, ASN1_INTEGER_free>;
|
||||
|
||||
// XxxStack deallocates the stack and its members while XxxStackOnly deallocates
|
||||
// the stack only.
|
||||
using ScopedX509Stack = ScopedOpenSSLStack<STACK_OF(X509), X509, X509_free>;
|
||||
using ScopedX509StackOnly = ScopedOpenSSLStackOnly<STACK_OF(X509)>;
|
||||
using ScopedX509InfoStack =
|
||||
ScopedOpenSSLStack<STACK_OF(X509_INFO), X509_INFO, X509_INFO_free>;
|
||||
using ScopedX509InfoStackOnly = ScopedOpenSSLStackOnly<STACK_OF(X509_INFO)>;
|
||||
|
||||
#endif // COMMON_OPENSSL_UTIL_H__
|
||||
22
common/random_util.cc
Normal file
22
common/random_util.cc
Normal file
@@ -0,0 +1,22 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2016 Google Inc.
|
||||
//
|
||||
// This software is licensed under the terms defined in the Widevine Master
|
||||
// License Agreement. For a copy of this agreement, please contact
|
||||
// widevine-licensing@google.com.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "common/random_util.h"
|
||||
|
||||
#include "glog/logging.h"
|
||||
#include "openssl/rand.h"
|
||||
|
||||
namespace widevine {
|
||||
|
||||
bool RandomBytes(size_t num_bytes, std::string* output) {
|
||||
DCHECK(output);
|
||||
output->resize(num_bytes);
|
||||
return RAND_bytes(reinterpret_cast<uint8_t*>(&(*output)[0]), num_bytes);
|
||||
}
|
||||
|
||||
} // namespace widevine
|
||||
22
common/random_util.h
Normal file
22
common/random_util.h
Normal file
@@ -0,0 +1,22 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2016 Google Inc.
|
||||
//
|
||||
// This software is licensed under the terms defined in the Widevine Master
|
||||
// License Agreement. For a copy of this agreement, please contact
|
||||
// widevine-licensing@google.com.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef COMMON_RANDOM_UTIL_H_
|
||||
#define COMMON_RANDOM_UTIL_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace widevine {
|
||||
|
||||
// Generates a random string.
|
||||
// Return true on success, false otherwise.
|
||||
bool RandomBytes(size_t num_bytes, std::string* output);
|
||||
|
||||
} // namespace widevine
|
||||
|
||||
#endif // COMMON_RANDOM_UTIL_H_
|
||||
29
common/random_util_test.cc
Normal file
29
common/random_util_test.cc
Normal file
@@ -0,0 +1,29 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2016 Google Inc.
|
||||
//
|
||||
// This software is licensed under the terms defined in the Widevine Master
|
||||
// License Agreement. For a copy of this agreement, please contact
|
||||
// widevine-licensing@google.com.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "common/random_util.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace widevine {
|
||||
|
||||
TEST(RandomUtilTest, Test) {
|
||||
std::string output;
|
||||
ASSERT_TRUE(RandomBytes(16u, &output));
|
||||
EXPECT_EQ(16u, output.size());
|
||||
|
||||
std::string output2;
|
||||
ASSERT_TRUE(RandomBytes(16u, &output2));
|
||||
EXPECT_EQ(16u, output2.size());
|
||||
EXPECT_NE(output, output2);
|
||||
|
||||
ASSERT_TRUE(RandomBytes(10u, &output2));
|
||||
EXPECT_EQ(10u, output2.size());
|
||||
}
|
||||
|
||||
} // namespace widevine
|
||||
296
common/rsa_key.cc
Normal file
296
common/rsa_key.cc
Normal file
@@ -0,0 +1,296 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2016 Google Inc.
|
||||
//
|
||||
// This software is licensed under the terms defined in the Widevine Master
|
||||
// License Agreement. For a copy of this agreement, please contact
|
||||
// widevine-licensing@google.com.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
// Description:
|
||||
// Definition of classes representing RSA private and public keys used
|
||||
// for message signing, signature verification, encryption and decryption.
|
||||
//
|
||||
// RSA signature details:
|
||||
// Algorithm: RSASSA-PSS
|
||||
// Hash algorithm: SHA1
|
||||
// Mask generation function: mgf1SHA1
|
||||
// Salt length: 20 bytes
|
||||
// Trailer field: 0xbc
|
||||
//
|
||||
// RSA encryption details:
|
||||
// Algorithm: RSA-OAEP
|
||||
// Mask generation function: mgf1SHA1
|
||||
// Label (encoding paramter): empty std::string
|
||||
|
||||
#include "common/rsa_key.h"
|
||||
|
||||
#include "glog/logging.h"
|
||||
#include "openssl/bn.h"
|
||||
#include "openssl/err.h"
|
||||
#include "openssl/evp.h"
|
||||
#include "openssl/rsa.h"
|
||||
#include "openssl/sha.h"
|
||||
#include "common/rsa_util.h"
|
||||
#include "common/sha_util.h"
|
||||
|
||||
static const int kPssSaltLength = 20;
|
||||
|
||||
namespace {
|
||||
|
||||
// Check if two RSA keys match. If matches, they are either a public-private key
|
||||
// pair or the same public key or the same private key.
|
||||
bool RsaKeyMatch(const RSA* key1, const RSA* key2) {
|
||||
if (!key1 || !key2) return false;
|
||||
return BN_cmp(key1->n, key2->n) == 0;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace widevine {
|
||||
|
||||
RsaPrivateKey::RsaPrivateKey(RSA* key) : key_(CHECK_NOTNULL(key)) {}
|
||||
|
||||
RsaPrivateKey::~RsaPrivateKey() { RSA_free(key_); }
|
||||
|
||||
RsaPrivateKey* RsaPrivateKey::Create(const std::string& serialized_key) {
|
||||
RSA* key;
|
||||
if (!rsa_util::DeserializeRsaPrivateKey(serialized_key, &key)) return nullptr;
|
||||
if (RSA_check_key(key) != 1) {
|
||||
LOG(ERROR) << "Invalid private RSA key: "
|
||||
<< ERR_error_string(ERR_get_error(), nullptr);
|
||||
RSA_free(key);
|
||||
}
|
||||
return new RsaPrivateKey(key);
|
||||
}
|
||||
|
||||
bool RsaPrivateKey::Decrypt(const std::string& encrypted_message,
|
||||
std::string* decrypted_message) const {
|
||||
DCHECK(decrypted_message);
|
||||
|
||||
size_t rsa_size = RSA_size(key_);
|
||||
if (encrypted_message.size() != rsa_size) {
|
||||
LOG(ERROR) << "Encrypted RSA message has the wrong size (expected "
|
||||
<< rsa_size << ", actual " << encrypted_message.size() << ")";
|
||||
return false;
|
||||
}
|
||||
decrypted_message->assign(rsa_size, 0);
|
||||
int decrypted_size = RSA_private_decrypt(
|
||||
rsa_size,
|
||||
const_cast<unsigned char*>(
|
||||
reinterpret_cast<const unsigned char*>(encrypted_message.data())),
|
||||
reinterpret_cast<unsigned char*>(&(*decrypted_message)[0]), key_,
|
||||
RSA_PKCS1_OAEP_PADDING);
|
||||
if (decrypted_size == -1) {
|
||||
LOG(ERROR) << "RSA private decrypt failure: "
|
||||
<< ERR_error_string(ERR_get_error(), nullptr);
|
||||
return false;
|
||||
}
|
||||
decrypted_message->resize(decrypted_size);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RsaPrivateKey::GenerateSignature(const std::string& message,
|
||||
std::string* signature) const {
|
||||
DCHECK(signature);
|
||||
|
||||
if (message.empty()) {
|
||||
LOG(ERROR) << "Message to be signed is empty";
|
||||
return false;
|
||||
}
|
||||
// Hash the message using SHA1.
|
||||
std::string message_digest = Sha1_Hash(message);
|
||||
|
||||
// Add PSS padding.
|
||||
size_t rsa_size = RSA_size(key_);
|
||||
std::string padded_digest(rsa_size, 0);
|
||||
if (!RSA_padding_add_PKCS1_PSS_mgf1(
|
||||
key_, reinterpret_cast<unsigned char*>(&padded_digest[0]),
|
||||
reinterpret_cast<unsigned char*>(&message_digest[0]), EVP_sha1(),
|
||||
EVP_sha1(), kPssSaltLength)) {
|
||||
LOG(ERROR) << "RSA padding failure: "
|
||||
<< ERR_error_string(ERR_get_error(), nullptr);
|
||||
return false;
|
||||
}
|
||||
// Encrypt PSS padded digest.
|
||||
signature->assign(rsa_size, 0);
|
||||
if (RSA_private_encrypt(padded_digest.size(),
|
||||
reinterpret_cast<unsigned char*>(&padded_digest[0]),
|
||||
reinterpret_cast<unsigned char*>(&(*signature)[0]),
|
||||
key_, RSA_NO_PADDING) !=
|
||||
static_cast<int>(signature->size())) {
|
||||
LOG(ERROR) << "RSA private encrypt failure: "
|
||||
<< ERR_error_string(ERR_get_error(), nullptr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RsaPrivateKey::GenerateSignatureSha256Pkcs7(const std::string& message,
|
||||
std::string* signature) const {
|
||||
DCHECK(signature);
|
||||
if (message.empty()) {
|
||||
LOG(ERROR) << "Empty signature verification message";
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned char digest[SHA256_DIGEST_LENGTH];
|
||||
SHA256(reinterpret_cast<const unsigned char*>(message.data()),
|
||||
message.size(),
|
||||
digest);
|
||||
unsigned int sig_len = RSA_size(key_);
|
||||
signature->resize(sig_len);
|
||||
return RSA_sign(NID_sha256,
|
||||
digest,
|
||||
sizeof(digest),
|
||||
reinterpret_cast<unsigned char*>(&(*signature)[0]),
|
||||
&sig_len,
|
||||
key_) == 1;
|
||||
}
|
||||
|
||||
bool RsaPrivateKey::MatchesPrivateKey(const RsaPrivateKey& private_key) const {
|
||||
return RsaKeyMatch(key(), private_key.key());
|
||||
}
|
||||
|
||||
bool RsaPrivateKey::MatchesPublicKey(const RsaPublicKey& public_key) const {
|
||||
return RsaKeyMatch(key(), public_key.key());
|
||||
}
|
||||
|
||||
RsaPublicKey::RsaPublicKey(RSA* key) : key_(CHECK_NOTNULL(key)) {}
|
||||
|
||||
RsaPublicKey::~RsaPublicKey() { RSA_free(key_); }
|
||||
|
||||
RsaPublicKey* RsaPublicKey::Create(const std::string& serialized_key) {
|
||||
RSA* key;
|
||||
if (!rsa_util::DeserializeRsaPublicKey(serialized_key, &key)) return nullptr;
|
||||
if (RSA_size(key) == 0) {
|
||||
LOG(ERROR) << "Invalid public RSA key: "
|
||||
<< ERR_error_string(ERR_get_error(), nullptr);
|
||||
RSA_free(key);
|
||||
}
|
||||
return new RsaPublicKey(key);
|
||||
}
|
||||
|
||||
bool RsaPublicKey::Encrypt(const std::string& clear_message,
|
||||
std::string* encrypted_message) const {
|
||||
DCHECK(encrypted_message);
|
||||
|
||||
if (clear_message.empty()) {
|
||||
LOG(ERROR) << "Message to be encrypted is empty";
|
||||
return false;
|
||||
}
|
||||
size_t rsa_size = RSA_size(key_);
|
||||
encrypted_message->assign(rsa_size, 0);
|
||||
if (RSA_public_encrypt(
|
||||
clear_message.size(),
|
||||
const_cast<unsigned char*>(
|
||||
reinterpret_cast<const unsigned char*>(clear_message.data())),
|
||||
reinterpret_cast<unsigned char*>(&(*encrypted_message)[0]), key_,
|
||||
RSA_PKCS1_OAEP_PADDING) != static_cast<int>(rsa_size)) {
|
||||
LOG(ERROR) << "RSA public encrypt failure: "
|
||||
<< ERR_error_string(ERR_get_error(), nullptr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RsaPublicKey::VerifySignature(const std::string& message,
|
||||
const std::string& signature) const {
|
||||
if (message.empty()) {
|
||||
LOG(ERROR) << "Signed message is empty";
|
||||
return false;
|
||||
}
|
||||
size_t rsa_size = RSA_size(key_);
|
||||
if (signature.size() != rsa_size) {
|
||||
LOG(ERROR) << "Message signature is of the wrong size (expected "
|
||||
<< rsa_size << ", actual " << signature.size() << ")";
|
||||
return false;
|
||||
}
|
||||
// Decrypt the signature.
|
||||
std::string padded_digest(signature.size(), 0);
|
||||
if (RSA_public_decrypt(
|
||||
signature.size(),
|
||||
const_cast<unsigned char*>(
|
||||
reinterpret_cast<const unsigned char*>(signature.data())),
|
||||
reinterpret_cast<unsigned char*>(&padded_digest[0]), key_,
|
||||
RSA_NO_PADDING) != static_cast<int>(rsa_size)) {
|
||||
LOG(ERROR) << "RSA public decrypt failure: "
|
||||
<< ERR_error_string(ERR_get_error(), nullptr);
|
||||
return false;
|
||||
}
|
||||
// Hash the message using SHA1.
|
||||
std::string message_digest = Sha1_Hash(message);
|
||||
|
||||
// Verify PSS padding.
|
||||
return RSA_verify_PKCS1_PSS_mgf1(
|
||||
key_, reinterpret_cast<unsigned char*>(&message_digest[0]),
|
||||
EVP_sha1(), EVP_sha1(),
|
||||
reinterpret_cast<unsigned char*>(&padded_digest[0]),
|
||||
kPssSaltLength) != 0;
|
||||
}
|
||||
|
||||
bool RsaPublicKey::VerifySignatureSha256Pkcs7(
|
||||
const std::string& message, const std::string& signature) const {
|
||||
if (message.empty()) {
|
||||
LOG(ERROR) << "Empty signature verification message";
|
||||
return false;
|
||||
}
|
||||
if (signature.empty()) {
|
||||
LOG(ERROR) << "Empty signature";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (signature.size() != RSA_size(key_)) {
|
||||
LOG(ERROR) << "RSA signature has the wrong size";
|
||||
return false;
|
||||
}
|
||||
unsigned char digest[SHA256_DIGEST_LENGTH];
|
||||
SHA256(reinterpret_cast<const unsigned char*>(message.data()),
|
||||
message.size(),
|
||||
digest);
|
||||
return RSA_verify(NID_sha256,
|
||||
digest,
|
||||
sizeof(digest),
|
||||
reinterpret_cast<const unsigned char*>(signature.data()),
|
||||
signature.size(),
|
||||
key_) == 1;
|
||||
}
|
||||
|
||||
bool RsaPublicKey::MatchesPrivateKey(const RsaPrivateKey& private_key) const {
|
||||
return RsaKeyMatch(key(), private_key.key());
|
||||
}
|
||||
|
||||
bool RsaPublicKey::MatchesPublicKey(const RsaPublicKey& public_key) const {
|
||||
return RsaKeyMatch(key(), public_key.key());
|
||||
}
|
||||
|
||||
RsaKeyFactory::RsaKeyFactory() {}
|
||||
|
||||
RsaKeyFactory::~RsaKeyFactory() {}
|
||||
|
||||
std::unique_ptr<RsaPrivateKey> RsaKeyFactory::CreateFromPkcs1PrivateKey(
|
||||
const std::string& private_key) {
|
||||
return std::unique_ptr<RsaPrivateKey>(RsaPrivateKey::Create(private_key));
|
||||
}
|
||||
|
||||
std::unique_ptr<RsaPrivateKey> RsaKeyFactory::CreateFromPkcs8PrivateKey(
|
||||
const std::string& private_key, const std::string& private_key_passphrase) {
|
||||
std::string pkcs1_key;
|
||||
const bool result =
|
||||
private_key_passphrase.empty()
|
||||
? rsa_util::PrivateKeyInfoToRsaPrivateKey(private_key, &pkcs1_key)
|
||||
: rsa_util::EncryptedPrivateKeyInfoToRsaPrivateKey(
|
||||
private_key, private_key_passphrase, &pkcs1_key);
|
||||
if (!result) {
|
||||
LOG(WARNING) << "Failed to get pkcs1_key.";
|
||||
return std::unique_ptr<RsaPrivateKey>();
|
||||
}
|
||||
return std::unique_ptr<RsaPrivateKey>(RsaPrivateKey::Create(pkcs1_key));
|
||||
}
|
||||
|
||||
std::unique_ptr<RsaPublicKey> RsaKeyFactory::CreateFromPkcs1PublicKey(
|
||||
const std::string& public_key) {
|
||||
return std::unique_ptr<RsaPublicKey>(RsaPublicKey::Create(public_key));
|
||||
}
|
||||
|
||||
} // namespace widevine
|
||||
131
common/rsa_key.h
Normal file
131
common/rsa_key.h
Normal file
@@ -0,0 +1,131 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2016 Google Inc.
|
||||
//
|
||||
// This software is licensed under the terms defined in the Widevine Master
|
||||
// License Agreement. For a copy of this agreement, please contact
|
||||
// widevine-licensing@google.com.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
// Description:
|
||||
// Declaration of classes representing RSA private and public keys used
|
||||
// for message signing, signature verification, encryption and decryption.
|
||||
|
||||
#ifndef COMMON_RSA_KEY_H_
|
||||
#define COMMON_RSA_KEY_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "openssl/rsa.h"
|
||||
|
||||
namespace widevine {
|
||||
|
||||
class RsaPublicKey;
|
||||
|
||||
class RsaPrivateKey {
|
||||
public:
|
||||
explicit RsaPrivateKey(RSA* key);
|
||||
virtual ~RsaPrivateKey();
|
||||
|
||||
// Create an RsaPrivateKey object using a DER encoded PKCS#1 RSAPrivateKey.
|
||||
// Returns NULL on failure.
|
||||
static RsaPrivateKey* Create(const std::string& serialized_key);
|
||||
|
||||
// Decrypt a message using RSA-OAEP. Caller retains ownership of all
|
||||
// parameters. Returns true if successful, false otherwise.
|
||||
virtual bool Decrypt(const std::string& encrypted_message,
|
||||
std::string* decrypted_message) const;
|
||||
|
||||
// Generate RSSASSA-PSS signature. Caller retains ownership of all parameters.
|
||||
// Returns true if successful, false otherwise.
|
||||
virtual bool GenerateSignature(const std::string& message,
|
||||
std::string* signature) const;
|
||||
|
||||
// Generate SHA256 digest, PKCS#7 padded signature. Caller retains ownership
|
||||
// of all parameters. Returns true if successful, false otherwise.
|
||||
virtual bool GenerateSignatureSha256Pkcs7(const std::string& message,
|
||||
std::string* signature) const;
|
||||
|
||||
// Return true if the underlying key matches with |private_key|.
|
||||
virtual bool MatchesPrivateKey(const RsaPrivateKey& private_key) const;
|
||||
|
||||
// Return true if the underlying key is a public-private key pair with
|
||||
// |public_key|.
|
||||
virtual bool MatchesPublicKey(const RsaPublicKey& public_key) const;
|
||||
|
||||
const RSA* key() const { return key_; }
|
||||
|
||||
private:
|
||||
RSA* key_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(RsaPrivateKey);
|
||||
};
|
||||
|
||||
class RsaPublicKey {
|
||||
public:
|
||||
explicit RsaPublicKey(RSA* key);
|
||||
virtual ~RsaPublicKey();
|
||||
|
||||
// Create an RsaPublicKey object using a DER encoded PKCS#1 RSAPublicKey.
|
||||
// Returns NULL on failure.
|
||||
static RsaPublicKey* Create(const std::string& serialized_key);
|
||||
|
||||
// Encrypt a message using RSA-OAEP. Caller retains ownership of all
|
||||
// parameters. Returns true if successful, false otherwise.
|
||||
virtual bool Encrypt(const std::string& clear_message,
|
||||
std::string* encrypted_message) const;
|
||||
|
||||
// Verify RSSASSA-PSS signature. Caller retains ownership of all parameters.
|
||||
// Returns true if validation succeeds, false otherwise.
|
||||
virtual bool VerifySignature(const std::string& message,
|
||||
const std::string& signature) const;
|
||||
|
||||
|
||||
// Verify a signature. This method takes two parameters: |message| which is a
|
||||
// std::string containing the data which was signed, and |signature| which is a
|
||||
// std::string containing the message SHA256 digest signature with PKCS#7
|
||||
// padding. Returns true if verification succeeds, false otherwise.
|
||||
virtual bool VerifySignatureSha256Pkcs7(const std::string& message,
|
||||
const std::string& signature) const;
|
||||
|
||||
// Return true if the underlying key is a public-private key pair with
|
||||
// |private_key|.
|
||||
virtual bool MatchesPrivateKey(const RsaPrivateKey& private_key) const;
|
||||
|
||||
// Return true if the underlying key matches with |public_key|.
|
||||
virtual bool MatchesPublicKey(const RsaPublicKey& public_key) const;
|
||||
|
||||
const RSA* key() const { return key_; }
|
||||
|
||||
private:
|
||||
RSA* key_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(RsaPublicKey);
|
||||
};
|
||||
|
||||
class RsaKeyFactory {
|
||||
public:
|
||||
RsaKeyFactory();
|
||||
virtual ~RsaKeyFactory();
|
||||
|
||||
// Create an RsaPrivateKey object using a DER encoded PKCS#1 RSAPrivateKey.
|
||||
virtual std::unique_ptr<RsaPrivateKey> CreateFromPkcs1PrivateKey(
|
||||
const std::string& private_key);
|
||||
|
||||
// Create an RsaPrivateKey object using an encrypted PKCS#8 RSAPrivateKey.
|
||||
virtual std::unique_ptr<RsaPrivateKey> CreateFromPkcs8PrivateKey(
|
||||
const std::string& private_key, const std::string& private_key_passphrase);
|
||||
|
||||
// Create an RsaPublicKey object using a DER encoded PKCS#1 RSAPublicKey.
|
||||
virtual std::unique_ptr<RsaPublicKey> CreateFromPkcs1PublicKey(
|
||||
const std::string& public_key);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(RsaKeyFactory);
|
||||
};
|
||||
|
||||
} // namespace widevine
|
||||
|
||||
#endif // COMMON_RSA_KEY_H_
|
||||
227
common/rsa_key_test.cc
Normal file
227
common/rsa_key_test.cc
Normal file
@@ -0,0 +1,227 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2016 Google Inc.
|
||||
//
|
||||
// This software is licensed under the terms defined in the Widevine Master
|
||||
// License Agreement. For a copy of this agreement, please contact
|
||||
// widevine-licensing@google.com.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
// Description:
|
||||
// Unit test for rsa_key RSA encryption and signing.
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "common/rsa_key.h"
|
||||
#include "common/rsa_test_keys.h"
|
||||
#include "common/rsa_util.h"
|
||||
|
||||
namespace widevine {
|
||||
|
||||
static const char kTestMessage[] =
|
||||
"A fool thinks himself to be wise, but a wise man knows himself to be a "
|
||||
"fool.";
|
||||
|
||||
class RsaKeyTest : public ::testing::Test {
|
||||
protected:
|
||||
void TestEncryption(std::unique_ptr<RsaPrivateKey> private_key,
|
||||
std::unique_ptr<RsaPublicKey> public_key);
|
||||
|
||||
void TestSigning(std::unique_ptr<RsaPrivateKey> private_key,
|
||||
std::unique_ptr<RsaPublicKey> public_key);
|
||||
|
||||
void TestSigningSha256Pkcs7(std::unique_ptr<RsaPrivateKey> private_key,
|
||||
std::unique_ptr<RsaPublicKey> public_key);
|
||||
|
||||
RsaTestKeys test_keys_;
|
||||
RsaKeyFactory factory_;
|
||||
};
|
||||
|
||||
void RsaKeyTest::TestEncryption(std::unique_ptr<RsaPrivateKey> private_key,
|
||||
std::unique_ptr<RsaPublicKey> public_key) {
|
||||
ASSERT_TRUE(private_key);
|
||||
ASSERT_TRUE(public_key);
|
||||
std::string encrypted_message;
|
||||
EXPECT_TRUE(public_key->Encrypt(kTestMessage, &encrypted_message));
|
||||
std::string decrypted_message;
|
||||
EXPECT_TRUE(private_key->Decrypt(encrypted_message, &decrypted_message));
|
||||
EXPECT_EQ(kTestMessage, decrypted_message);
|
||||
// Add a byte to the encrypted message.
|
||||
std::string bad_enc_message(encrypted_message);
|
||||
bad_enc_message += '\0';
|
||||
EXPECT_FALSE(private_key->Decrypt(bad_enc_message, &decrypted_message));
|
||||
// Remove a byte from the encrypted message.
|
||||
bad_enc_message = encrypted_message.substr(0, encrypted_message.size() - 1);
|
||||
EXPECT_FALSE(private_key->Decrypt(bad_enc_message, &decrypted_message));
|
||||
// Change a byte in the encrypted message.
|
||||
bad_enc_message = encrypted_message;
|
||||
bad_enc_message[128] ^= 0x55;
|
||||
EXPECT_FALSE(private_key->Decrypt(bad_enc_message, &decrypted_message));
|
||||
}
|
||||
|
||||
void RsaKeyTest::TestSigning(std::unique_ptr<RsaPrivateKey> private_key,
|
||||
std::unique_ptr<RsaPublicKey> public_key) {
|
||||
ASSERT_TRUE(private_key);
|
||||
ASSERT_TRUE(public_key);
|
||||
std::string signature;
|
||||
EXPECT_TRUE(private_key->GenerateSignature(kTestMessage, &signature));
|
||||
EXPECT_TRUE(public_key->VerifySignature(kTestMessage, signature));
|
||||
// Add a byte to the signature.
|
||||
std::string bad_signature(signature);
|
||||
bad_signature += '\0';
|
||||
EXPECT_FALSE(public_key->VerifySignature(kTestMessage, bad_signature));
|
||||
// Remove a byte from the signature.
|
||||
bad_signature = signature.substr(0, signature.size() - 1);
|
||||
EXPECT_FALSE(public_key->VerifySignature(kTestMessage, bad_signature));
|
||||
// Change a byte in the signature.
|
||||
bad_signature = signature;
|
||||
bad_signature[32] ^= 0x55;
|
||||
EXPECT_FALSE(public_key->VerifySignature(kTestMessage, bad_signature));
|
||||
}
|
||||
|
||||
void RsaKeyTest::TestSigningSha256Pkcs7(
|
||||
std::unique_ptr<RsaPrivateKey> private_key,
|
||||
std::unique_ptr<RsaPublicKey> public_key) {
|
||||
ASSERT_TRUE(private_key);
|
||||
ASSERT_TRUE(public_key);
|
||||
std::string signature;
|
||||
EXPECT_TRUE(
|
||||
private_key->GenerateSignatureSha256Pkcs7(kTestMessage, &signature));
|
||||
EXPECT_TRUE(public_key->VerifySignatureSha256Pkcs7(kTestMessage, signature));
|
||||
// Add a byte to the signature.
|
||||
std::string bad_signature(signature);
|
||||
bad_signature += '\0';
|
||||
EXPECT_FALSE(
|
||||
public_key->VerifySignatureSha256Pkcs7(kTestMessage, bad_signature));
|
||||
// Remove a byte from the signature.
|
||||
bad_signature = signature.substr(0, signature.size() - 1);
|
||||
EXPECT_FALSE(
|
||||
public_key->VerifySignatureSha256Pkcs7(kTestMessage, bad_signature));
|
||||
// Change a byte in the signature.
|
||||
bad_signature = signature;
|
||||
bad_signature[32] ^= 0x55;
|
||||
EXPECT_FALSE(
|
||||
public_key->VerifySignatureSha256Pkcs7(kTestMessage, bad_signature));
|
||||
}
|
||||
|
||||
TEST_F(RsaKeyTest, BadKey) {
|
||||
std::unique_ptr<RsaPrivateKey> private_key(
|
||||
RsaPrivateKey::Create("bad_private_key"));
|
||||
EXPECT_TRUE(!private_key);
|
||||
std::unique_ptr<RsaPublicKey> public_key(
|
||||
RsaPublicKey::Create("bad_public_key"));
|
||||
EXPECT_TRUE(!public_key);
|
||||
}
|
||||
|
||||
TEST_F(RsaKeyTest, EncryptAndDecrypt_3072) {
|
||||
const std::string& private_key = test_keys_.private_test_key_1_3072_bits();
|
||||
const std::string& public_key = test_keys_.public_test_key_1_3072_bits();
|
||||
TestEncryption(
|
||||
std::unique_ptr<RsaPrivateKey>(RsaPrivateKey::Create(private_key)),
|
||||
std::unique_ptr<RsaPublicKey>(RsaPublicKey::Create(public_key)));
|
||||
TestEncryption(factory_.CreateFromPkcs1PrivateKey(private_key),
|
||||
factory_.CreateFromPkcs1PublicKey(public_key));
|
||||
}
|
||||
|
||||
TEST_F(RsaKeyTest, EncryptAndDecrypt_2048) {
|
||||
const std::string& private_key = test_keys_.private_test_key_2_2048_bits();
|
||||
const std::string& public_key = test_keys_.public_test_key_2_2048_bits();
|
||||
TestEncryption(
|
||||
std::unique_ptr<RsaPrivateKey>(RsaPrivateKey::Create(private_key)),
|
||||
std::unique_ptr<RsaPublicKey>(RsaPublicKey::Create(public_key)));
|
||||
|
||||
std::string pkcs8_key;
|
||||
std::string passphrase("passphrase");
|
||||
ASSERT_TRUE(rsa_util::RsaPrivateKeyToEncryptedPrivateKeyInfo(
|
||||
private_key, passphrase, &pkcs8_key));
|
||||
TestEncryption(factory_.CreateFromPkcs8PrivateKey(pkcs8_key, passphrase),
|
||||
factory_.CreateFromPkcs1PublicKey(public_key));
|
||||
|
||||
ASSERT_TRUE(rsa_util::RsaPrivateKeyToPrivateKeyInfo(private_key, &pkcs8_key));
|
||||
TestEncryption(factory_.CreateFromPkcs8PrivateKey(pkcs8_key, std::string()),
|
||||
factory_.CreateFromPkcs1PublicKey(public_key));
|
||||
}
|
||||
|
||||
TEST_F(RsaKeyTest, SignAndVerify_3072) {
|
||||
const std::string& private_key = test_keys_.private_test_key_1_3072_bits();
|
||||
const std::string& public_key = test_keys_.public_test_key_1_3072_bits();
|
||||
TestSigning(
|
||||
std::unique_ptr<RsaPrivateKey>(RsaPrivateKey::Create(private_key)),
|
||||
std::unique_ptr<RsaPublicKey>(RsaPublicKey::Create(public_key)));
|
||||
TestSigning(factory_.CreateFromPkcs1PrivateKey(private_key),
|
||||
factory_.CreateFromPkcs1PublicKey(public_key));
|
||||
}
|
||||
|
||||
TEST_F(RsaKeyTest, SignAndVerify_2048) {
|
||||
const std::string& private_key = test_keys_.private_test_key_2_2048_bits();
|
||||
const std::string& public_key = test_keys_.public_test_key_2_2048_bits();
|
||||
TestSigning(
|
||||
std::unique_ptr<RsaPrivateKey>(RsaPrivateKey::Create(private_key)),
|
||||
std::unique_ptr<RsaPublicKey>(RsaPublicKey::Create(public_key)));
|
||||
|
||||
std::string pkcs8_key;
|
||||
std::string passphrase("passphrase");
|
||||
ASSERT_TRUE(rsa_util::RsaPrivateKeyToEncryptedPrivateKeyInfo(
|
||||
private_key, passphrase, &pkcs8_key));
|
||||
TestSigning(factory_.CreateFromPkcs8PrivateKey(pkcs8_key, passphrase),
|
||||
factory_.CreateFromPkcs1PublicKey(public_key));
|
||||
|
||||
ASSERT_TRUE(rsa_util::RsaPrivateKeyToPrivateKeyInfo(private_key, &pkcs8_key));
|
||||
TestSigning(factory_.CreateFromPkcs8PrivateKey(pkcs8_key, std::string()),
|
||||
factory_.CreateFromPkcs1PublicKey(public_key));
|
||||
}
|
||||
|
||||
TEST_F(RsaKeyTest, SignAndVerifySha256Pkcs7_3072) {
|
||||
const std::string& private_key = test_keys_.private_test_key_1_3072_bits();
|
||||
const std::string& public_key = test_keys_.public_test_key_1_3072_bits();
|
||||
TestSigningSha256Pkcs7(
|
||||
std::unique_ptr<RsaPrivateKey>(RsaPrivateKey::Create(private_key)),
|
||||
std::unique_ptr<RsaPublicKey>(RsaPublicKey::Create(public_key)));
|
||||
TestSigningSha256Pkcs7(factory_.CreateFromPkcs1PrivateKey(private_key),
|
||||
factory_.CreateFromPkcs1PublicKey(public_key));
|
||||
}
|
||||
|
||||
TEST_F(RsaKeyTest, SignAndVerifySha256Pkcs7_2048) {
|
||||
const std::string& private_key = test_keys_.private_test_key_2_2048_bits();
|
||||
const std::string& public_key = test_keys_.public_test_key_2_2048_bits();
|
||||
TestSigningSha256Pkcs7(
|
||||
std::unique_ptr<RsaPrivateKey>(RsaPrivateKey::Create(private_key)),
|
||||
std::unique_ptr<RsaPublicKey>(RsaPublicKey::Create(public_key)));
|
||||
|
||||
std::string pkcs8_key;
|
||||
std::string passphrase("passphrase");
|
||||
ASSERT_TRUE(rsa_util::RsaPrivateKeyToEncryptedPrivateKeyInfo(
|
||||
private_key, passphrase, &pkcs8_key));
|
||||
TestSigningSha256Pkcs7(
|
||||
factory_.CreateFromPkcs8PrivateKey(pkcs8_key, passphrase),
|
||||
factory_.CreateFromPkcs1PublicKey(public_key));
|
||||
|
||||
ASSERT_TRUE(rsa_util::RsaPrivateKeyToPrivateKeyInfo(private_key, &pkcs8_key));
|
||||
TestSigningSha256Pkcs7(
|
||||
factory_.CreateFromPkcs8PrivateKey(pkcs8_key, std::string()),
|
||||
factory_.CreateFromPkcs1PublicKey(public_key));
|
||||
}
|
||||
|
||||
TEST_F(RsaKeyTest, RsaKeyMatch) {
|
||||
std::unique_ptr<RsaPrivateKey> private_key2(
|
||||
RsaPrivateKey::Create(test_keys_.private_test_key_2_2048_bits()));
|
||||
std::unique_ptr<RsaPrivateKey> private_key3(
|
||||
RsaPrivateKey::Create(test_keys_.private_test_key_3_2048_bits()));
|
||||
std::unique_ptr<RsaPublicKey> public_key2(
|
||||
RsaPublicKey::Create(test_keys_.public_test_key_2_2048_bits()));
|
||||
std::unique_ptr<RsaPublicKey> public_key3(
|
||||
RsaPublicKey::Create(test_keys_.public_test_key_3_2048_bits()));
|
||||
|
||||
EXPECT_TRUE(public_key2->MatchesPublicKey(*public_key2));
|
||||
EXPECT_FALSE(public_key2->MatchesPublicKey(*public_key3));
|
||||
EXPECT_TRUE(public_key2->MatchesPrivateKey(*private_key2));
|
||||
EXPECT_FALSE(public_key2->MatchesPrivateKey(*private_key3));
|
||||
|
||||
EXPECT_TRUE(private_key2->MatchesPublicKey(*public_key2));
|
||||
EXPECT_FALSE(private_key2->MatchesPublicKey(*public_key3));
|
||||
EXPECT_TRUE(private_key2->MatchesPrivateKey(*private_key2));
|
||||
EXPECT_FALSE(private_key2->MatchesPrivateKey(*private_key3));
|
||||
}
|
||||
|
||||
} // namespace widevine
|
||||
682
common/rsa_test_keys.cc
Normal file
682
common/rsa_test_keys.cc
Normal file
@@ -0,0 +1,682 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2016 Google Inc.
|
||||
//
|
||||
// This software is licensed under the terms defined in the Widevine Master
|
||||
// License Agreement. For a copy of this agreement, please contact
|
||||
// widevine-licensing@google.com.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
// Description:
|
||||
// RSA keys generated using fake_prng for purposes of testing.
|
||||
|
||||
#include "common/rsa_test_keys.h"
|
||||
|
||||
|
||||
namespace widevine {
|
||||
|
||||
static const unsigned char kTestRsaPrivateKey1_3072[] = {
|
||||
0x30, 0x82, 0x06, 0xe3, 0x02, 0x01, 0x00, 0x02,
|
||||
0x82, 0x01, 0x81, 0x00, 0xa5, 0x62, 0x07, 0xdf,
|
||||
0xc8, 0x84, 0x74, 0xe1, 0x2a, 0xb7, 0xbb, 0xc0,
|
||||
0x78, 0x76, 0xbe, 0x13, 0x3b, 0xe6, 0x2c, 0x09,
|
||||
0x9d, 0x35, 0x3f, 0xf3, 0x0f, 0xe9, 0x61, 0x96,
|
||||
0x20, 0x53, 0x6e, 0x78, 0x62, 0xe0, 0x10, 0xd2,
|
||||
0xca, 0xe4, 0xdd, 0xd5, 0x96, 0xaf, 0x9a, 0xd7,
|
||||
0x08, 0x47, 0xe4, 0x55, 0x1b, 0x83, 0xbe, 0x10,
|
||||
0x66, 0x74, 0x08, 0xf2, 0x49, 0x79, 0xea, 0x29,
|
||||
0x46, 0xc2, 0x65, 0x97, 0xa6, 0xcc, 0x4b, 0xa4,
|
||||
0x08, 0xc3, 0x04, 0x17, 0x01, 0xb5, 0x11, 0x53,
|
||||
0xe9, 0x68, 0x34, 0x3c, 0x26, 0x56, 0x44, 0x37,
|
||||
0x5c, 0xb4, 0x7a, 0x1d, 0x5d, 0x6c, 0x58, 0xc2,
|
||||
0x82, 0xa0, 0x92, 0xf1, 0x14, 0xf1, 0x22, 0xff,
|
||||
0x64, 0xde, 0xdf, 0xb3, 0x3d, 0x9d, 0xa5, 0x86,
|
||||
0xcd, 0xa0, 0x0a, 0x63, 0x08, 0xdd, 0x60, 0x5d,
|
||||
0xfd, 0xa4, 0x01, 0xe3, 0xb6, 0x0e, 0x85, 0xe4,
|
||||
0xc3, 0x37, 0x61, 0xd0, 0xe7, 0x12, 0xe9, 0xc4,
|
||||
0xde, 0xf2, 0x59, 0x11, 0xe3, 0x5b, 0x02, 0x9f,
|
||||
0x24, 0xb9, 0xb0, 0xbb, 0x31, 0xa0, 0xee, 0x6a,
|
||||
0x2c, 0xb4, 0x30, 0xff, 0xe0, 0xf0, 0x93, 0xee,
|
||||
0x3a, 0xae, 0xb2, 0x2e, 0x84, 0xa0, 0x47, 0x42,
|
||||
0x51, 0xbb, 0xfa, 0xbb, 0x90, 0x97, 0x2c, 0x77,
|
||||
0x45, 0xee, 0x2c, 0xfb, 0xec, 0x5d, 0xd8, 0xca,
|
||||
0x49, 0x94, 0x53, 0x5d, 0x37, 0xaf, 0x86, 0x47,
|
||||
0xda, 0xe2, 0xbd, 0xf0, 0x5f, 0x07, 0x53, 0x8a,
|
||||
0x10, 0xd0, 0x9a, 0xd0, 0x7f, 0xe9, 0xef, 0xf6,
|
||||
0xda, 0xea, 0x1e, 0x2e, 0x54, 0xec, 0x44, 0xde,
|
||||
0x3a, 0xe1, 0xc8, 0xdb, 0x17, 0xe8, 0xc9, 0x3a,
|
||||
0x81, 0x11, 0x4d, 0xb7, 0x2d, 0x09, 0x83, 0xab,
|
||||
0x30, 0xb7, 0xf5, 0x1b, 0x03, 0x86, 0x21, 0xa9,
|
||||
0xf5, 0xca, 0x15, 0x26, 0xaf, 0x39, 0xf3, 0x5d,
|
||||
0x01, 0x7d, 0xe3, 0x19, 0x54, 0xd1, 0x2e, 0x10,
|
||||
0x16, 0x9c, 0xee, 0xc3, 0xbd, 0xcc, 0xdb, 0x02,
|
||||
0x82, 0xd0, 0x60, 0x0b, 0x42, 0x72, 0x85, 0xec,
|
||||
0xdc, 0x41, 0x7c, 0xf1, 0x34, 0xd8, 0x27, 0x21,
|
||||
0xf9, 0xa6, 0x82, 0x40, 0xd3, 0xc5, 0xc9, 0xf9,
|
||||
0x6b, 0xc9, 0x12, 0x64, 0xe4, 0x3a, 0x3b, 0xc9,
|
||||
0x8f, 0x3c, 0xd0, 0x2c, 0xb8, 0xb8, 0xf3, 0x05,
|
||||
0x4a, 0xe9, 0x4c, 0x46, 0x2b, 0xb6, 0xe1, 0xed,
|
||||
0x82, 0xb2, 0xf0, 0xd1, 0x72, 0x71, 0x04, 0x35,
|
||||
0x19, 0xc1, 0x16, 0x17, 0xd6, 0x75, 0xe0, 0xab,
|
||||
0xde, 0x8f, 0xe1, 0xc1, 0x49, 0x68, 0x0c, 0xc8,
|
||||
0xce, 0x6d, 0x87, 0x50, 0x04, 0xb5, 0xd7, 0x24,
|
||||
0xf4, 0x2e, 0x0c, 0x11, 0x35, 0xb2, 0x67, 0x85,
|
||||
0x1b, 0x38, 0xff, 0x2f, 0x71, 0xf5, 0x30, 0x18,
|
||||
0x1e, 0x6f, 0xd7, 0xf0, 0x33, 0x61, 0x53, 0x7e,
|
||||
0x55, 0x7f, 0x0d, 0x60, 0x83, 0xf3, 0x8a, 0x2b,
|
||||
0x67, 0xd5, 0xf0, 0x2e, 0x23, 0x23, 0x60, 0x0b,
|
||||
0x83, 0x9c, 0xc2, 0x87, 0x02, 0x03, 0x01, 0x00,
|
||||
0x01, 0x02, 0x82, 0x01, 0x80, 0x5a, 0x09, 0x3f,
|
||||
0x9e, 0x2e, 0x4d, 0x26, 0x50, 0x7b, 0x70, 0x21,
|
||||
0xb0, 0x0c, 0x25, 0x21, 0x1f, 0xd9, 0x89, 0x5a,
|
||||
0xca, 0x35, 0x23, 0x0b, 0x58, 0xa9, 0x7d, 0xf6,
|
||||
0x19, 0xc4, 0x29, 0x87, 0xc7, 0xd4, 0x94, 0x85,
|
||||
0xb4, 0x2c, 0xaf, 0x62, 0xb1, 0xe8, 0x62, 0x5b,
|
||||
0xda, 0xdb, 0x70, 0x40, 0x37, 0xb1, 0x4e, 0x0c,
|
||||
0xc8, 0x62, 0xee, 0xa2, 0xfc, 0x3c, 0xd2, 0x39,
|
||||
0x90, 0x15, 0x2c, 0xba, 0x20, 0x50, 0xb7, 0x82,
|
||||
0x2a, 0xa0, 0x76, 0x83, 0x20, 0x7f, 0x56, 0x73,
|
||||
0x43, 0x8a, 0x9b, 0xa7, 0x6c, 0x63, 0xb6, 0xad,
|
||||
0x56, 0xb2, 0x8a, 0xb2, 0xbc, 0x8f, 0xe2, 0xef,
|
||||
0x83, 0x9d, 0x98, 0x0b, 0xc7, 0x62, 0x0e, 0x51,
|
||||
0x6e, 0x57, 0x1d, 0x1b, 0x0e, 0x3a, 0xea, 0x3b,
|
||||
0x76, 0x63, 0x35, 0xd0, 0xd1, 0xcf, 0xbe, 0xad,
|
||||
0xbb, 0x1d, 0xde, 0x0f, 0x05, 0x48, 0x55, 0x29,
|
||||
0xc1, 0xbc, 0x21, 0xc7, 0x87, 0xf2, 0x75, 0x12,
|
||||
0x7d, 0x92, 0x9e, 0xbf, 0xad, 0x04, 0x68, 0xc4,
|
||||
0xc9, 0x9d, 0x35, 0xd6, 0xa8, 0x62, 0xc1, 0x69,
|
||||
0x6a, 0xb6, 0x41, 0xb7, 0x37, 0x66, 0xdf, 0xb2,
|
||||
0xb9, 0x8c, 0x8b, 0x15, 0x08, 0x4c, 0x3d, 0xf1,
|
||||
0xed, 0x82, 0x0f, 0xe3, 0xd5, 0xff, 0x46, 0xbd,
|
||||
0xf7, 0x85, 0x43, 0xc0, 0x8b, 0xba, 0x47, 0xf1,
|
||||
0x41, 0x57, 0xc3, 0x7f, 0x8b, 0x0d, 0x48, 0xea,
|
||||
0xc2, 0xed, 0xc0, 0x69, 0x84, 0xb6, 0x32, 0x08,
|
||||
0x49, 0x74, 0x14, 0x84, 0xa4, 0x1b, 0x48, 0x5b,
|
||||
0xec, 0xd3, 0x0b, 0x12, 0x2b, 0x4c, 0x9e, 0x5c,
|
||||
0x01, 0x60, 0xad, 0xef, 0xcb, 0x2b, 0x56, 0x84,
|
||||
0x07, 0xfa, 0x62, 0xc6, 0x08, 0x92, 0x98, 0x70,
|
||||
0xc9, 0x5b, 0x18, 0xc8, 0xfa, 0x27, 0x0c, 0xe2,
|
||||
0xbd, 0xfb, 0x3e, 0x43, 0xa5, 0xb7, 0x06, 0x2c,
|
||||
0x4e, 0xf1, 0x07, 0x5d, 0x8d, 0xdd, 0x53, 0xc5,
|
||||
0x8c, 0x4a, 0xf2, 0x2f, 0x8e, 0x80, 0x96, 0x16,
|
||||
0xc0, 0xfc, 0xf9, 0x20, 0x4f, 0x35, 0xc7, 0x53,
|
||||
0x8b, 0x2d, 0x37, 0x43, 0x93, 0x3d, 0x74, 0x3f,
|
||||
0x63, 0xf7, 0x0b, 0xbd, 0x46, 0xe4, 0x51, 0x67,
|
||||
0x33, 0x57, 0x15, 0xf5, 0x59, 0x27, 0x66, 0xe8,
|
||||
0xe2, 0x4b, 0xa3, 0x93, 0x03, 0x8a, 0x9c, 0x05,
|
||||
0x13, 0xf2, 0xcb, 0xf7, 0x9c, 0x68, 0xe7, 0x16,
|
||||
0x4b, 0x8e, 0x59, 0x71, 0x2b, 0x73, 0x9b, 0xb9,
|
||||
0xae, 0x50, 0xfa, 0xd7, 0xd3, 0x34, 0x17, 0x1d,
|
||||
0x62, 0x88, 0xbd, 0x8c, 0xba, 0x5a, 0x6b, 0x6a,
|
||||
0x5e, 0xb3, 0xa5, 0x80, 0xca, 0xbb, 0xb9, 0xb5,
|
||||
0xa8, 0x2e, 0xb1, 0x61, 0x6e, 0xd5, 0xd6, 0x62,
|
||||
0x98, 0x4a, 0xb0, 0xb8, 0x76, 0xa9, 0x19, 0x5c,
|
||||
0xe2, 0xbe, 0xb3, 0x9b, 0x4a, 0x39, 0xf5, 0xe6,
|
||||
0xbb, 0x11, 0x6e, 0x13, 0x13, 0x38, 0xb8, 0x1f,
|
||||
0x21, 0x19, 0xf5, 0xa7, 0x76, 0x93, 0xb3, 0x56,
|
||||
0xfa, 0xcc, 0x74, 0xbc, 0x19, 0x02, 0x81, 0xc1,
|
||||
0x00, 0xd1, 0xd1, 0x72, 0x57, 0xe5, 0xb0, 0x1c,
|
||||
0x09, 0x05, 0xbb, 0x55, 0x89, 0x3c, 0x4a, 0x81,
|
||||
0x90, 0x9a, 0xf9, 0x32, 0x63, 0x41, 0xad, 0x6a,
|
||||
0x5f, 0x65, 0x94, 0x92, 0xcc, 0xf7, 0xc7, 0x53,
|
||||
0x93, 0xa0, 0xf7, 0xbe, 0x48, 0x82, 0x63, 0x31,
|
||||
0x7b, 0xd0, 0x82, 0x09, 0xbb, 0x0a, 0xbc, 0x60,
|
||||
0xc9, 0x4d, 0x83, 0xe4, 0x5d, 0x50, 0xe6, 0x5f,
|
||||
0x8b, 0x47, 0x07, 0xa3, 0x3a, 0x36, 0x97, 0xaa,
|
||||
0x21, 0x70, 0x7f, 0xd5, 0x6c, 0xb0, 0x56, 0xf5,
|
||||
0x5c, 0x48, 0x74, 0x2a, 0xdd, 0xfe, 0x94, 0x83,
|
||||
0x05, 0xe0, 0x3d, 0x5d, 0xdd, 0x5a, 0x05, 0xcb,
|
||||
0x47, 0xd7, 0xf9, 0x89, 0x55, 0xaa, 0x0b, 0x21,
|
||||
0xc0, 0x71, 0x5d, 0xe1, 0x4c, 0x6a, 0x45, 0x86,
|
||||
0x86, 0xf2, 0xb9, 0x38, 0x6a, 0x56, 0x51, 0x0d,
|
||||
0x7d, 0xac, 0x30, 0x31, 0xca, 0x2d, 0xaa, 0xaa,
|
||||
0xba, 0xcc, 0x12, 0x40, 0xc1, 0x0d, 0xa6, 0xc1,
|
||||
0x7d, 0x22, 0xec, 0xb6, 0x51, 0x45, 0xfe, 0x4e,
|
||||
0xbb, 0x4a, 0xd2, 0xba, 0x9b, 0xa2, 0xcc, 0x28,
|
||||
0x2b, 0x01, 0x53, 0x53, 0xf3, 0xa9, 0x5a, 0x8f,
|
||||
0xeb, 0xb7, 0xb8, 0x62, 0x6b, 0x8a, 0x79, 0x24,
|
||||
0xcc, 0x86, 0x34, 0x45, 0xe2, 0xad, 0x1d, 0xd0,
|
||||
0x4c, 0xc9, 0x77, 0x2a, 0xf9, 0x1a, 0xe8, 0x58,
|
||||
0x78, 0x51, 0x8a, 0xea, 0x3f, 0x90, 0x36, 0x46,
|
||||
0x2a, 0xc0, 0x71, 0x41, 0x83, 0x2c, 0x48, 0xee,
|
||||
0xc5, 0x02, 0x81, 0xc1, 0x00, 0xc9, 0xc8, 0xce,
|
||||
0xc4, 0x50, 0xb2, 0x26, 0xcb, 0x35, 0x78, 0x55,
|
||||
0x3c, 0xcc, 0xf0, 0x7e, 0xba, 0xad, 0xeb, 0x58,
|
||||
0xe9, 0xb5, 0x78, 0x2f, 0x43, 0x5f, 0x07, 0x47,
|
||||
0x56, 0x05, 0x41, 0x38, 0x71, 0xe1, 0x58, 0x62,
|
||||
0xb1, 0x8e, 0xbc, 0xf9, 0x80, 0x04, 0x22, 0x39,
|
||||
0x22, 0x24, 0x28, 0x86, 0x9c, 0x00, 0x44, 0x5f,
|
||||
0xc4, 0x97, 0xe6, 0x71, 0x5f, 0x1f, 0x58, 0xea,
|
||||
0x75, 0x18, 0x0c, 0x23, 0x63, 0x09, 0xc5, 0x98,
|
||||
0xc4, 0x6d, 0x23, 0xc2, 0x2c, 0x93, 0x6a, 0x26,
|
||||
0xe4, 0x3d, 0x8d, 0xa1, 0x39, 0x70, 0x34, 0x25,
|
||||
0xcd, 0xbc, 0x82, 0x78, 0x2b, 0xf3, 0x7e, 0x81,
|
||||
0xb6, 0x5f, 0xc5, 0x69, 0xd0, 0x81, 0x69, 0x50,
|
||||
0x2f, 0x17, 0x0c, 0x17, 0x3c, 0x0b, 0x45, 0x38,
|
||||
0xce, 0xe3, 0xbf, 0x8a, 0x50, 0x0a, 0x00, 0x74,
|
||||
0x7e, 0x7a, 0xd8, 0x55, 0x52, 0x6b, 0x82, 0xfb,
|
||||
0x34, 0x15, 0x73, 0x6a, 0xf4, 0x51, 0x9b, 0x9f,
|
||||
0xa0, 0x45, 0xb9, 0x76, 0xe5, 0xd3, 0xd5, 0xf4,
|
||||
0xa9, 0xa4, 0xcd, 0x42, 0x2f, 0x29, 0x89, 0xec,
|
||||
0x28, 0x5f, 0x03, 0x45, 0x27, 0xaf, 0x8c, 0x39,
|
||||
0x3e, 0x59, 0x9d, 0xaf, 0x27, 0x5d, 0x17, 0x53,
|
||||
0x17, 0xeb, 0x8d, 0x7f, 0x3d, 0xb8, 0x2a, 0x50,
|
||||
0x1e, 0xb5, 0xc5, 0x04, 0xab, 0x9c, 0xa7, 0xaa,
|
||||
0x86, 0x41, 0xb9, 0x36, 0x29, 0x9e, 0xd2, 0xd8,
|
||||
0xde, 0x5f, 0xde, 0x80, 0xdb, 0x02, 0x81, 0xc0,
|
||||
0x03, 0xf3, 0x5f, 0xa5, 0xcc, 0x0b, 0x5e, 0xdb,
|
||||
0xc4, 0xa1, 0xdc, 0x60, 0x73, 0x24, 0x2c, 0x00,
|
||||
0x5f, 0x0a, 0xa6, 0x2a, 0x3c, 0x48, 0x59, 0xa2,
|
||||
0x66, 0x35, 0x3f, 0xf6, 0x60, 0x0b, 0xfe, 0xc4,
|
||||
0xde, 0xd9, 0x0b, 0x5a, 0x2e, 0x2a, 0x53, 0xfa,
|
||||
0x32, 0xd8, 0xdf, 0xfa, 0x07, 0x9f, 0xb8, 0x6a,
|
||||
0xd1, 0xec, 0xd3, 0xd5, 0xf5, 0xfa, 0x00, 0x7e,
|
||||
0x8c, 0xdd, 0xd5, 0xf2, 0xf8, 0xa8, 0x2e, 0x69,
|
||||
0xe6, 0xc6, 0x61, 0x6c, 0x64, 0x7d, 0x9e, 0xad,
|
||||
0x18, 0x28, 0x27, 0xce, 0x7a, 0x46, 0xad, 0x98,
|
||||
0xe4, 0xba, 0x03, 0x14, 0x71, 0xe7, 0x7e, 0x06,
|
||||
0x62, 0x48, 0xae, 0x8f, 0x50, 0x5e, 0x59, 0x4a,
|
||||
0x58, 0x58, 0x1e, 0x2f, 0xe4, 0x28, 0x5e, 0xfa,
|
||||
0x17, 0x83, 0xe9, 0x4e, 0x07, 0x46, 0x0b, 0x6c,
|
||||
0xfc, 0x5b, 0x03, 0xf4, 0xfc, 0x9b, 0x24, 0x0f,
|
||||
0xd4, 0x5b, 0xdb, 0xa0, 0x46, 0xf3, 0x86, 0xdd,
|
||||
0x26, 0x55, 0x32, 0xb1, 0xa1, 0x11, 0xc2, 0xc5,
|
||||
0xc0, 0x08, 0xeb, 0xbe, 0x96, 0x78, 0x25, 0xa1,
|
||||
0x79, 0xaa, 0xe9, 0xff, 0xc2, 0x86, 0x94, 0x03,
|
||||
0x2a, 0x38, 0x6c, 0x91, 0xfd, 0xcf, 0x7e, 0x23,
|
||||
0xe3, 0xbb, 0x04, 0x3d, 0xda, 0x68, 0x9f, 0x4d,
|
||||
0x72, 0xd5, 0xad, 0x97, 0x77, 0x2c, 0x3c, 0xce,
|
||||
0x37, 0x2a, 0xd8, 0x72, 0x4d, 0xf2, 0xd7, 0xab,
|
||||
0x62, 0x68, 0x3f, 0x85, 0x8a, 0xc5, 0xec, 0xc9,
|
||||
0x02, 0x81, 0xc1, 0x00, 0x92, 0x43, 0x0c, 0x1d,
|
||||
0x20, 0xa1, 0x01, 0x9d, 0xaa, 0x54, 0x5e, 0xf4,
|
||||
0x83, 0x58, 0x8f, 0x83, 0xa1, 0x2d, 0x46, 0x75,
|
||||
0xa1, 0x24, 0x4c, 0x9d, 0xf8, 0xf3, 0xbd, 0xb1,
|
||||
0x8c, 0x7d, 0x89, 0xfc, 0x81, 0xeb, 0x1f, 0x1e,
|
||||
0xb4, 0xe8, 0x25, 0xb1, 0xb5, 0x4d, 0x59, 0x3c,
|
||||
0x76, 0x19, 0x29, 0xf9, 0x49, 0xf8, 0x45, 0xb2,
|
||||
0xaa, 0xa8, 0x4e, 0xe5, 0x34, 0x43, 0xaf, 0x2e,
|
||||
0xd1, 0x0f, 0x7b, 0x56, 0xfe, 0x6e, 0x4c, 0x1d,
|
||||
0x95, 0x3e, 0xa6, 0x30, 0xc9, 0x69, 0xd8, 0x66,
|
||||
0xf8, 0x77, 0x00, 0xb6, 0x31, 0xae, 0x9a, 0xf8,
|
||||
0x55, 0xfb, 0xfc, 0x3f, 0x5f, 0x70, 0x03, 0x75,
|
||||
0xbe, 0x55, 0xca, 0x2d, 0x68, 0xa0, 0x7d, 0x8e,
|
||||
0xa4, 0x96, 0x0f, 0x01, 0x66, 0xe9, 0xf6, 0x13,
|
||||
0x80, 0xe2, 0x05, 0xcf, 0x9e, 0x70, 0x56, 0x00,
|
||||
0x97, 0xea, 0xd7, 0x6d, 0xb6, 0xa0, 0x6a, 0x95,
|
||||
0x86, 0x36, 0xf2, 0xff, 0xc5, 0x67, 0x98, 0x7d,
|
||||
0x04, 0x0d, 0x3b, 0x31, 0xbc, 0x2b, 0x09, 0xfd,
|
||||
0x2d, 0x87, 0xda, 0xc1, 0x74, 0xca, 0x94, 0x73,
|
||||
0x6e, 0xeb, 0x5f, 0xe5, 0x34, 0x49, 0xdf, 0xf4,
|
||||
0x61, 0xe0, 0xfa, 0x64, 0xfe, 0x05, 0x3a, 0x25,
|
||||
0xcc, 0x87, 0xf4, 0x03, 0x38, 0xca, 0xf2, 0xe8,
|
||||
0x4f, 0xb9, 0x4f, 0x79, 0x55, 0x43, 0xf3, 0x46,
|
||||
0xfd, 0xbc, 0xd2, 0x95, 0xb8, 0x99, 0xfc, 0xb8,
|
||||
0xb3, 0xa5, 0x04, 0xa1, 0x02, 0x81, 0xc0, 0x47,
|
||||
0xc6, 0x9c, 0x18, 0x54, 0xe5, 0xbb, 0xf9, 0xf4,
|
||||
0x38, 0xd2, 0xc0, 0xd1, 0x1a, 0xcc, 0xdb, 0x06,
|
||||
0x87, 0x75, 0x1f, 0x13, 0xa2, 0x7f, 0x8b, 0x45,
|
||||
0x54, 0xcb, 0x43, 0xf8, 0xbb, 0x94, 0xd6, 0x2e,
|
||||
0x56, 0x5c, 0x69, 0x6d, 0x83, 0xb5, 0x45, 0x46,
|
||||
0x68, 0x5c, 0x76, 0x1e, 0x6c, 0x0c, 0x53, 0x59,
|
||||
0xcc, 0x19, 0xc7, 0x81, 0x62, 0x66, 0x92, 0x02,
|
||||
0x8f, 0xa6, 0xdb, 0x50, 0x1c, 0x67, 0xfc, 0x82,
|
||||
0x56, 0x2b, 0x4b, 0x1f, 0x97, 0x87, 0xc4, 0x7d,
|
||||
0x20, 0xda, 0xd3, 0x3f, 0x28, 0xf9, 0x55, 0xfe,
|
||||
0x84, 0x50, 0xc5, 0x3b, 0xd4, 0xaf, 0xf5, 0x3d,
|
||||
0x43, 0xce, 0xdc, 0x55, 0x11, 0x87, 0xdb, 0x72,
|
||||
0x66, 0xcc, 0x83, 0xc4, 0x8b, 0x20, 0xae, 0x59,
|
||||
0x4d, 0xeb, 0xac, 0xb5, 0x4a, 0xec, 0x66, 0x09,
|
||||
0x37, 0x55, 0x14, 0x21, 0x57, 0xff, 0x0a, 0xac,
|
||||
0xda, 0xb1, 0xae, 0x31, 0xab, 0x41, 0x30, 0x65,
|
||||
0x02, 0x83, 0xd1, 0xdb, 0x65, 0xb7, 0x52, 0xa7,
|
||||
0x21, 0x9f, 0x1f, 0x8f, 0x69, 0x23, 0x3b, 0xb8,
|
||||
0xf9, 0x6d, 0xe7, 0xc1, 0x53, 0x9f, 0x8f, 0x67,
|
||||
0xfc, 0x6e, 0x20, 0x18, 0x31, 0x89, 0xe7, 0xbb,
|
||||
0xd4, 0xc1, 0x03, 0x67, 0xd6, 0xa5, 0x76, 0xc9,
|
||||
0xea, 0x97, 0x93, 0x02, 0xca, 0x44, 0x52, 0x55,
|
||||
0x0f, 0xed, 0x55, 0xb5, 0x49, 0xd6, 0x94, 0x59,
|
||||
0xee, 0xcc, 0x1b, 0x5a, 0x00, 0x3d, 0xcd };
|
||||
|
||||
static const unsigned char kTestRsaPublicKey1_3072[] = {
|
||||
0x30, 0x82, 0x01, 0x8a, 0x02, 0x82, 0x01, 0x81,
|
||||
0x00, 0xa5, 0x62, 0x07, 0xdf, 0xc8, 0x84, 0x74,
|
||||
0xe1, 0x2a, 0xb7, 0xbb, 0xc0, 0x78, 0x76, 0xbe,
|
||||
0x13, 0x3b, 0xe6, 0x2c, 0x09, 0x9d, 0x35, 0x3f,
|
||||
0xf3, 0x0f, 0xe9, 0x61, 0x96, 0x20, 0x53, 0x6e,
|
||||
0x78, 0x62, 0xe0, 0x10, 0xd2, 0xca, 0xe4, 0xdd,
|
||||
0xd5, 0x96, 0xaf, 0x9a, 0xd7, 0x08, 0x47, 0xe4,
|
||||
0x55, 0x1b, 0x83, 0xbe, 0x10, 0x66, 0x74, 0x08,
|
||||
0xf2, 0x49, 0x79, 0xea, 0x29, 0x46, 0xc2, 0x65,
|
||||
0x97, 0xa6, 0xcc, 0x4b, 0xa4, 0x08, 0xc3, 0x04,
|
||||
0x17, 0x01, 0xb5, 0x11, 0x53, 0xe9, 0x68, 0x34,
|
||||
0x3c, 0x26, 0x56, 0x44, 0x37, 0x5c, 0xb4, 0x7a,
|
||||
0x1d, 0x5d, 0x6c, 0x58, 0xc2, 0x82, 0xa0, 0x92,
|
||||
0xf1, 0x14, 0xf1, 0x22, 0xff, 0x64, 0xde, 0xdf,
|
||||
0xb3, 0x3d, 0x9d, 0xa5, 0x86, 0xcd, 0xa0, 0x0a,
|
||||
0x63, 0x08, 0xdd, 0x60, 0x5d, 0xfd, 0xa4, 0x01,
|
||||
0xe3, 0xb6, 0x0e, 0x85, 0xe4, 0xc3, 0x37, 0x61,
|
||||
0xd0, 0xe7, 0x12, 0xe9, 0xc4, 0xde, 0xf2, 0x59,
|
||||
0x11, 0xe3, 0x5b, 0x02, 0x9f, 0x24, 0xb9, 0xb0,
|
||||
0xbb, 0x31, 0xa0, 0xee, 0x6a, 0x2c, 0xb4, 0x30,
|
||||
0xff, 0xe0, 0xf0, 0x93, 0xee, 0x3a, 0xae, 0xb2,
|
||||
0x2e, 0x84, 0xa0, 0x47, 0x42, 0x51, 0xbb, 0xfa,
|
||||
0xbb, 0x90, 0x97, 0x2c, 0x77, 0x45, 0xee, 0x2c,
|
||||
0xfb, 0xec, 0x5d, 0xd8, 0xca, 0x49, 0x94, 0x53,
|
||||
0x5d, 0x37, 0xaf, 0x86, 0x47, 0xda, 0xe2, 0xbd,
|
||||
0xf0, 0x5f, 0x07, 0x53, 0x8a, 0x10, 0xd0, 0x9a,
|
||||
0xd0, 0x7f, 0xe9, 0xef, 0xf6, 0xda, 0xea, 0x1e,
|
||||
0x2e, 0x54, 0xec, 0x44, 0xde, 0x3a, 0xe1, 0xc8,
|
||||
0xdb, 0x17, 0xe8, 0xc9, 0x3a, 0x81, 0x11, 0x4d,
|
||||
0xb7, 0x2d, 0x09, 0x83, 0xab, 0x30, 0xb7, 0xf5,
|
||||
0x1b, 0x03, 0x86, 0x21, 0xa9, 0xf5, 0xca, 0x15,
|
||||
0x26, 0xaf, 0x39, 0xf3, 0x5d, 0x01, 0x7d, 0xe3,
|
||||
0x19, 0x54, 0xd1, 0x2e, 0x10, 0x16, 0x9c, 0xee,
|
||||
0xc3, 0xbd, 0xcc, 0xdb, 0x02, 0x82, 0xd0, 0x60,
|
||||
0x0b, 0x42, 0x72, 0x85, 0xec, 0xdc, 0x41, 0x7c,
|
||||
0xf1, 0x34, 0xd8, 0x27, 0x21, 0xf9, 0xa6, 0x82,
|
||||
0x40, 0xd3, 0xc5, 0xc9, 0xf9, 0x6b, 0xc9, 0x12,
|
||||
0x64, 0xe4, 0x3a, 0x3b, 0xc9, 0x8f, 0x3c, 0xd0,
|
||||
0x2c, 0xb8, 0xb8, 0xf3, 0x05, 0x4a, 0xe9, 0x4c,
|
||||
0x46, 0x2b, 0xb6, 0xe1, 0xed, 0x82, 0xb2, 0xf0,
|
||||
0xd1, 0x72, 0x71, 0x04, 0x35, 0x19, 0xc1, 0x16,
|
||||
0x17, 0xd6, 0x75, 0xe0, 0xab, 0xde, 0x8f, 0xe1,
|
||||
0xc1, 0x49, 0x68, 0x0c, 0xc8, 0xce, 0x6d, 0x87,
|
||||
0x50, 0x04, 0xb5, 0xd7, 0x24, 0xf4, 0x2e, 0x0c,
|
||||
0x11, 0x35, 0xb2, 0x67, 0x85, 0x1b, 0x38, 0xff,
|
||||
0x2f, 0x71, 0xf5, 0x30, 0x18, 0x1e, 0x6f, 0xd7,
|
||||
0xf0, 0x33, 0x61, 0x53, 0x7e, 0x55, 0x7f, 0x0d,
|
||||
0x60, 0x83, 0xf3, 0x8a, 0x2b, 0x67, 0xd5, 0xf0,
|
||||
0x2e, 0x23, 0x23, 0x60, 0x0b, 0x83, 0x9c, 0xc2,
|
||||
0x87, 0x02, 0x03, 0x01, 0x00, 0x01 };
|
||||
|
||||
static const unsigned char kTestRsaPrivateKey2_2048[] = {
|
||||
0x30, 0x82, 0x04, 0xa2, 0x02, 0x01, 0x00, 0x02,
|
||||
0x82, 0x01, 0x01, 0x00, 0xa7, 0x00, 0x36, 0x60,
|
||||
0x65, 0xdc, 0xbd, 0x54, 0x5a, 0x2a, 0x40, 0xb4,
|
||||
0xe1, 0x15, 0x94, 0x58, 0x11, 0x4f, 0x94, 0x58,
|
||||
0xdd, 0xde, 0xa7, 0x1f, 0x3c, 0x2c, 0xe0, 0x88,
|
||||
0x09, 0x29, 0x61, 0x57, 0x67, 0x5e, 0x56, 0x7e,
|
||||
0xee, 0x27, 0x8f, 0x59, 0x34, 0x9a, 0x2a, 0xaa,
|
||||
0x9d, 0xb4, 0x4e, 0xfa, 0xa7, 0x6a, 0xd4, 0xc9,
|
||||
0x7a, 0x53, 0xc1, 0x4e, 0x9f, 0xe3, 0x34, 0xf7,
|
||||
0x3d, 0xb7, 0xc9, 0x10, 0x47, 0x4f, 0x28, 0xda,
|
||||
0x3f, 0xce, 0x31, 0x7b, 0xfd, 0x06, 0x10, 0xeb,
|
||||
0xf7, 0xbe, 0x92, 0xf9, 0xaf, 0xfb, 0x3e, 0x68,
|
||||
0xda, 0xee, 0x1a, 0x64, 0x4c, 0xf3, 0x29, 0xf2,
|
||||
0x73, 0x9e, 0x39, 0xd8, 0xf6, 0x6f, 0xd8, 0xb2,
|
||||
0x80, 0x82, 0x71, 0x8e, 0xb5, 0xa4, 0xf2, 0xc2,
|
||||
0x3e, 0xcd, 0x0a, 0xca, 0xb6, 0x04, 0xcd, 0x9a,
|
||||
0x13, 0x8b, 0x54, 0x73, 0x54, 0x25, 0x54, 0x8c,
|
||||
0xbe, 0x98, 0x7a, 0x67, 0xad, 0xda, 0xb3, 0x4e,
|
||||
0xb3, 0xfa, 0x82, 0xa8, 0x4a, 0x67, 0x98, 0x56,
|
||||
0x57, 0x54, 0x71, 0xcd, 0x12, 0x7f, 0xed, 0xa3,
|
||||
0x01, 0xc0, 0x6a, 0x8b, 0x24, 0x03, 0x96, 0x88,
|
||||
0xbe, 0x97, 0x66, 0x2a, 0xbc, 0x53, 0xc9, 0x83,
|
||||
0x06, 0x51, 0x5a, 0x88, 0x65, 0x13, 0x18, 0xe4,
|
||||
0x3a, 0xed, 0x6b, 0xf1, 0x61, 0x5b, 0x4c, 0xc8,
|
||||
0x1e, 0xf4, 0xc2, 0xae, 0x08, 0x5e, 0x2d, 0x5f,
|
||||
0xf8, 0x12, 0x7f, 0xa2, 0xfc, 0xbb, 0x21, 0x18,
|
||||
0x30, 0xda, 0xfe, 0x40, 0xfb, 0x01, 0xca, 0x2e,
|
||||
0x37, 0x0e, 0xce, 0xdd, 0x76, 0x87, 0x82, 0x46,
|
||||
0x0b, 0x3a, 0x77, 0x8f, 0xc0, 0x72, 0x07, 0x2c,
|
||||
0x7f, 0x9d, 0x1e, 0x86, 0x5b, 0xed, 0x27, 0x29,
|
||||
0xdf, 0x03, 0x97, 0x62, 0xef, 0x44, 0xd3, 0x5b,
|
||||
0x3d, 0xdb, 0x9c, 0x5e, 0x1b, 0x7b, 0x39, 0xb4,
|
||||
0x0b, 0x6d, 0x04, 0x6b, 0xbb, 0xbb, 0x2c, 0x5f,
|
||||
0xcf, 0xb3, 0x7a, 0x05, 0x02, 0x03, 0x01, 0x00,
|
||||
0x01, 0x02, 0x82, 0x01, 0x00, 0x5e, 0x79, 0x65,
|
||||
0x49, 0xa5, 0x76, 0x79, 0xf9, 0x05, 0x45, 0x0f,
|
||||
0xf4, 0x03, 0xbd, 0xa4, 0x7d, 0x29, 0xd5, 0xde,
|
||||
0x33, 0x63, 0xd8, 0xb8, 0xac, 0x97, 0xeb, 0x3f,
|
||||
0x5e, 0x55, 0xe8, 0x7d, 0xf3, 0xe7, 0x3b, 0x5c,
|
||||
0x2d, 0x54, 0x67, 0x36, 0xd6, 0x1d, 0x46, 0xf5,
|
||||
0xca, 0x2d, 0x8b, 0x3a, 0x7e, 0xdc, 0x45, 0x38,
|
||||
0x79, 0x7e, 0x65, 0x71, 0x5f, 0x1c, 0x5e, 0x79,
|
||||
0xb1, 0x40, 0xcd, 0xfe, 0xc5, 0xe1, 0xc1, 0x6b,
|
||||
0x78, 0x04, 0x4e, 0x8e, 0x79, 0xf9, 0x0a, 0xfc,
|
||||
0x79, 0xb1, 0x5e, 0xb3, 0x60, 0xe3, 0x68, 0x7b,
|
||||
0xc6, 0xef, 0xcb, 0x71, 0x4c, 0xba, 0xa7, 0x79,
|
||||
0x5c, 0x7a, 0x81, 0xd1, 0x71, 0xe7, 0x00, 0x21,
|
||||
0x13, 0xe2, 0x55, 0x69, 0x0e, 0x75, 0xbe, 0x09,
|
||||
0xc3, 0x4f, 0xa9, 0xc9, 0x68, 0x22, 0x0e, 0x97,
|
||||
0x8d, 0x89, 0x6e, 0xf1, 0xe8, 0x88, 0x7a, 0xd1,
|
||||
0xd9, 0x09, 0x5d, 0xd3, 0x28, 0x78, 0x25, 0x0b,
|
||||
0x1c, 0x47, 0x73, 0x25, 0xcc, 0x21, 0xb6, 0xda,
|
||||
0xc6, 0x24, 0x5a, 0xd0, 0x37, 0x14, 0x46, 0xc7,
|
||||
0x94, 0x69, 0xe4, 0x43, 0x6f, 0x47, 0xde, 0x00,
|
||||
0x33, 0x4d, 0x8f, 0x95, 0x72, 0xfa, 0x68, 0x71,
|
||||
0x17, 0x66, 0x12, 0x1a, 0x87, 0x27, 0xf7, 0xef,
|
||||
0x7e, 0xe0, 0x35, 0x58, 0xf2, 0x4d, 0x6f, 0x35,
|
||||
0x01, 0xaa, 0x96, 0xe2, 0x3d, 0x51, 0x13, 0x86,
|
||||
0x9c, 0x79, 0xd0, 0xb7, 0xb6, 0x64, 0xe8, 0x86,
|
||||
0x65, 0x50, 0xbf, 0xcc, 0x27, 0x53, 0x1f, 0x51,
|
||||
0xd4, 0xca, 0xbe, 0xf5, 0xdd, 0x77, 0x70, 0x98,
|
||||
0x0f, 0xee, 0xa8, 0x96, 0x07, 0x5f, 0x45, 0x6a,
|
||||
0x7a, 0x0d, 0x03, 0x9c, 0x4f, 0x29, 0xf6, 0x06,
|
||||
0xf3, 0x5d, 0x58, 0x6c, 0x47, 0xd0, 0x96, 0xa9,
|
||||
0x03, 0x17, 0xbb, 0x4e, 0xc9, 0x21, 0xe0, 0xac,
|
||||
0xcd, 0x78, 0x78, 0xb2, 0xfe, 0x81, 0xb2, 0x51,
|
||||
0x53, 0xa6, 0x1f, 0x98, 0x45, 0x02, 0x81, 0x81,
|
||||
0x00, 0xcf, 0x73, 0x8c, 0xbe, 0x6d, 0x45, 0x2d,
|
||||
0x0c, 0x0b, 0x5d, 0x5c, 0x6c, 0x75, 0x78, 0xcc,
|
||||
0x35, 0x48, 0xb6, 0x98, 0xf1, 0xb9, 0x64, 0x60,
|
||||
0x8c, 0x43, 0xeb, 0x85, 0xab, 0x04, 0xb6, 0x7d,
|
||||
0x1b, 0x71, 0x75, 0x06, 0xe2, 0xda, 0x84, 0x68,
|
||||
0x2e, 0x7f, 0x4c, 0xe3, 0x73, 0xb4, 0xde, 0x51,
|
||||
0x4b, 0xb6, 0x51, 0x86, 0x7b, 0xd0, 0xe6, 0x4d,
|
||||
0xf3, 0xd1, 0xcf, 0x1a, 0xfe, 0x7f, 0x3a, 0x83,
|
||||
0xba, 0xb3, 0xe1, 0xff, 0x54, 0x13, 0x93, 0xd7,
|
||||
0x9c, 0x27, 0x80, 0xb7, 0x1e, 0x64, 0x9e, 0xf7,
|
||||
0x32, 0x2b, 0x46, 0x29, 0xf7, 0xf8, 0x18, 0x6c,
|
||||
0xf7, 0x4a, 0xbe, 0x4b, 0xee, 0x96, 0x90, 0x8f,
|
||||
0xa2, 0x16, 0x22, 0x6a, 0xcc, 0x48, 0x06, 0x74,
|
||||
0x63, 0x43, 0x7f, 0x27, 0x22, 0x44, 0x3c, 0x2d,
|
||||
0x3b, 0x62, 0xf1, 0x1c, 0xb4, 0x27, 0x33, 0x85,
|
||||
0x26, 0x60, 0x48, 0x16, 0xcb, 0xef, 0xf8, 0xcd,
|
||||
0x37, 0x02, 0x81, 0x81, 0x00, 0xce, 0x15, 0x43,
|
||||
0x6e, 0x4b, 0x0f, 0xf9, 0x3f, 0x87, 0xc3, 0x41,
|
||||
0x45, 0x97, 0xb1, 0x49, 0xc2, 0x19, 0x23, 0x87,
|
||||
0xe4, 0x24, 0x1c, 0x64, 0xe5, 0x28, 0xcb, 0x43,
|
||||
0x10, 0x14, 0x14, 0x0e, 0x19, 0xcb, 0xbb, 0xdb,
|
||||
0xfd, 0x11, 0x9d, 0x17, 0x68, 0x78, 0x6d, 0x61,
|
||||
0x70, 0x63, 0x3a, 0xa1, 0xb3, 0xf3, 0xa7, 0x5b,
|
||||
0x0e, 0xff, 0xb7, 0x61, 0x11, 0x54, 0x91, 0x99,
|
||||
0xe5, 0x91, 0x32, 0x2d, 0xeb, 0x3f, 0xd8, 0x3e,
|
||||
0xf7, 0xd4, 0xcb, 0xd2, 0xa3, 0x41, 0xc1, 0xee,
|
||||
0xc6, 0x92, 0x13, 0xeb, 0x7f, 0x42, 0x58, 0xf4,
|
||||
0xd0, 0xb2, 0x74, 0x1d, 0x8e, 0x87, 0x46, 0xcd,
|
||||
0x14, 0xb8, 0x16, 0xad, 0xb5, 0xbd, 0x0d, 0x6c,
|
||||
0x95, 0x5a, 0x16, 0xbf, 0xe9, 0x53, 0xda, 0xfb,
|
||||
0xed, 0x83, 0x51, 0x67, 0xa9, 0x55, 0xab, 0x54,
|
||||
0x02, 0x95, 0x20, 0xa6, 0x68, 0x17, 0x53, 0xa8,
|
||||
0xea, 0x43, 0xe5, 0xb0, 0xa3, 0x02, 0x81, 0x80,
|
||||
0x67, 0x9c, 0x32, 0x83, 0x39, 0x57, 0xff, 0x73,
|
||||
0xb0, 0x89, 0x64, 0x8b, 0xd6, 0xf0, 0x0a, 0x2d,
|
||||
0xe2, 0xaf, 0x30, 0x1c, 0x2a, 0x97, 0xf3, 0x90,
|
||||
0x9a, 0xab, 0x9b, 0x0b, 0x1b, 0x43, 0x79, 0xa0,
|
||||
0xa7, 0x3d, 0xe7, 0xbe, 0x8d, 0x9c, 0xeb, 0xdb,
|
||||
0xad, 0x40, 0xdd, 0xa9, 0x00, 0x80, 0xb8, 0xe1,
|
||||
0xb3, 0xa1, 0x6c, 0x25, 0x92, 0xe4, 0x33, 0xb2,
|
||||
0xbe, 0xeb, 0x4d, 0x74, 0x26, 0x5f, 0x37, 0x43,
|
||||
0x9c, 0x6c, 0x17, 0x76, 0x0a, 0x81, 0x20, 0x82,
|
||||
0xa1, 0x48, 0x2c, 0x2d, 0x45, 0xdc, 0x0f, 0x62,
|
||||
0x43, 0x32, 0xbb, 0xeb, 0x59, 0x41, 0xf9, 0xca,
|
||||
0x58, 0xce, 0x4a, 0x66, 0x53, 0x54, 0xc8, 0x28,
|
||||
0x10, 0x1e, 0x08, 0x71, 0x16, 0xd8, 0x02, 0x71,
|
||||
0x41, 0x58, 0xd4, 0x56, 0xcc, 0xf5, 0xb1, 0x31,
|
||||
0xa3, 0xed, 0x00, 0x85, 0x09, 0xbf, 0x35, 0x95,
|
||||
0x41, 0x29, 0x40, 0x19, 0x83, 0x35, 0x24, 0x69,
|
||||
0x02, 0x81, 0x80, 0x55, 0x10, 0x0b, 0xcc, 0x3b,
|
||||
0xa9, 0x75, 0x3d, 0x16, 0xe1, 0xae, 0x50, 0x76,
|
||||
0x63, 0x94, 0x49, 0x4c, 0xad, 0x10, 0xcb, 0x47,
|
||||
0x68, 0x7c, 0xf0, 0xe5, 0xdc, 0xb8, 0x6a, 0xab,
|
||||
0x8e, 0xf7, 0x9f, 0x08, 0x2c, 0x1b, 0x8a, 0xa2,
|
||||
0xb9, 0x8f, 0xce, 0xec, 0x5e, 0x61, 0xa8, 0xcd,
|
||||
0x1c, 0x87, 0x60, 0x4a, 0xc3, 0x1a, 0x5f, 0xdf,
|
||||
0x87, 0x26, 0xc6, 0xcb, 0x7c, 0x69, 0xe4, 0x8b,
|
||||
0x01, 0x06, 0x59, 0x22, 0xfa, 0x34, 0x4b, 0x81,
|
||||
0x87, 0x3c, 0x03, 0x6d, 0x02, 0x0a, 0x77, 0xe6,
|
||||
0x15, 0xd8, 0xcf, 0xa7, 0x68, 0x26, 0x6c, 0xfa,
|
||||
0x2b, 0xd9, 0x83, 0x5a, 0x2d, 0x0c, 0x3b, 0x70,
|
||||
0x1c, 0xd4, 0x48, 0xbe, 0xa7, 0x0a, 0xd9, 0xbe,
|
||||
0xdc, 0xc3, 0x0c, 0x21, 0x33, 0xb3, 0x66, 0xff,
|
||||
0x1c, 0x1b, 0xc8, 0x96, 0x76, 0xe8, 0x6f, 0x44,
|
||||
0x74, 0xbc, 0x9b, 0x1c, 0x7d, 0xc8, 0xac, 0x21,
|
||||
0xa8, 0x6e, 0x37, 0x02, 0x81, 0x80, 0x2c, 0x7c,
|
||||
0xad, 0x1e, 0x75, 0xf6, 0x69, 0x1d, 0xe7, 0xa6,
|
||||
0xca, 0x74, 0x7d, 0x67, 0xc8, 0x65, 0x28, 0x66,
|
||||
0xc4, 0x43, 0xa6, 0xbd, 0x40, 0x57, 0xae, 0xb7,
|
||||
0x65, 0x2c, 0x52, 0xf9, 0xe4, 0xc7, 0x81, 0x7b,
|
||||
0x56, 0xa3, 0xd2, 0x0d, 0xe8, 0x33, 0x70, 0xcf,
|
||||
0x06, 0x84, 0xb3, 0x4e, 0x44, 0x50, 0x75, 0x61,
|
||||
0x96, 0x86, 0x4b, 0xb6, 0x2b, 0xad, 0xf0, 0xad,
|
||||
0x57, 0xd0, 0x37, 0x0d, 0x1d, 0x35, 0x50, 0xcb,
|
||||
0x69, 0x22, 0x39, 0x29, 0xb9, 0x3a, 0xd3, 0x29,
|
||||
0x23, 0x02, 0x60, 0xf7, 0xab, 0x30, 0x40, 0xda,
|
||||
0x8e, 0x4d, 0x45, 0x70, 0x26, 0xf4, 0xa2, 0x0d,
|
||||
0xd0, 0x64, 0x5d, 0x47, 0x3c, 0x18, 0xf4, 0xd4,
|
||||
0x52, 0x95, 0x00, 0xae, 0x84, 0x6b, 0x47, 0xb2,
|
||||
0x3c, 0x82, 0xd3, 0x72, 0x53, 0xde, 0x72, 0x2c,
|
||||
0xf7, 0xc1, 0x22, 0x36, 0xd9, 0x18, 0x56, 0xfe,
|
||||
0x39, 0x28, 0x33, 0xe0, 0xdb, 0x03 };
|
||||
|
||||
static const unsigned char kTestRsaPublicKey2_2048[] = {
|
||||
0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
|
||||
0x00, 0xa7, 0x00, 0x36, 0x60, 0x65, 0xdc, 0xbd,
|
||||
0x54, 0x5a, 0x2a, 0x40, 0xb4, 0xe1, 0x15, 0x94,
|
||||
0x58, 0x11, 0x4f, 0x94, 0x58, 0xdd, 0xde, 0xa7,
|
||||
0x1f, 0x3c, 0x2c, 0xe0, 0x88, 0x09, 0x29, 0x61,
|
||||
0x57, 0x67, 0x5e, 0x56, 0x7e, 0xee, 0x27, 0x8f,
|
||||
0x59, 0x34, 0x9a, 0x2a, 0xaa, 0x9d, 0xb4, 0x4e,
|
||||
0xfa, 0xa7, 0x6a, 0xd4, 0xc9, 0x7a, 0x53, 0xc1,
|
||||
0x4e, 0x9f, 0xe3, 0x34, 0xf7, 0x3d, 0xb7, 0xc9,
|
||||
0x10, 0x47, 0x4f, 0x28, 0xda, 0x3f, 0xce, 0x31,
|
||||
0x7b, 0xfd, 0x06, 0x10, 0xeb, 0xf7, 0xbe, 0x92,
|
||||
0xf9, 0xaf, 0xfb, 0x3e, 0x68, 0xda, 0xee, 0x1a,
|
||||
0x64, 0x4c, 0xf3, 0x29, 0xf2, 0x73, 0x9e, 0x39,
|
||||
0xd8, 0xf6, 0x6f, 0xd8, 0xb2, 0x80, 0x82, 0x71,
|
||||
0x8e, 0xb5, 0xa4, 0xf2, 0xc2, 0x3e, 0xcd, 0x0a,
|
||||
0xca, 0xb6, 0x04, 0xcd, 0x9a, 0x13, 0x8b, 0x54,
|
||||
0x73, 0x54, 0x25, 0x54, 0x8c, 0xbe, 0x98, 0x7a,
|
||||
0x67, 0xad, 0xda, 0xb3, 0x4e, 0xb3, 0xfa, 0x82,
|
||||
0xa8, 0x4a, 0x67, 0x98, 0x56, 0x57, 0x54, 0x71,
|
||||
0xcd, 0x12, 0x7f, 0xed, 0xa3, 0x01, 0xc0, 0x6a,
|
||||
0x8b, 0x24, 0x03, 0x96, 0x88, 0xbe, 0x97, 0x66,
|
||||
0x2a, 0xbc, 0x53, 0xc9, 0x83, 0x06, 0x51, 0x5a,
|
||||
0x88, 0x65, 0x13, 0x18, 0xe4, 0x3a, 0xed, 0x6b,
|
||||
0xf1, 0x61, 0x5b, 0x4c, 0xc8, 0x1e, 0xf4, 0xc2,
|
||||
0xae, 0x08, 0x5e, 0x2d, 0x5f, 0xf8, 0x12, 0x7f,
|
||||
0xa2, 0xfc, 0xbb, 0x21, 0x18, 0x30, 0xda, 0xfe,
|
||||
0x40, 0xfb, 0x01, 0xca, 0x2e, 0x37, 0x0e, 0xce,
|
||||
0xdd, 0x76, 0x87, 0x82, 0x46, 0x0b, 0x3a, 0x77,
|
||||
0x8f, 0xc0, 0x72, 0x07, 0x2c, 0x7f, 0x9d, 0x1e,
|
||||
0x86, 0x5b, 0xed, 0x27, 0x29, 0xdf, 0x03, 0x97,
|
||||
0x62, 0xef, 0x44, 0xd3, 0x5b, 0x3d, 0xdb, 0x9c,
|
||||
0x5e, 0x1b, 0x7b, 0x39, 0xb4, 0x0b, 0x6d, 0x04,
|
||||
0x6b, 0xbb, 0xbb, 0x2c, 0x5f, 0xcf, 0xb3, 0x7a,
|
||||
0x05, 0x02, 0x03, 0x01, 0x00, 0x01 };
|
||||
|
||||
static const unsigned char kTestRsaPrivateKey3_2048[] = {
|
||||
0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02,
|
||||
0x82, 0x01, 0x01, 0x00, 0xa5, 0xd0, 0xd7, 0x3e,
|
||||
0x0e, 0x2d, 0xfb, 0x43, 0x51, 0x99, 0xea, 0x40,
|
||||
0x1e, 0x2d, 0x89, 0xe4, 0xa2, 0x3e, 0xfc, 0x51,
|
||||
0x3d, 0x0e, 0x83, 0xa7, 0xe0, 0xa5, 0x41, 0x04,
|
||||
0x1e, 0x14, 0xc5, 0xa7, 0x5c, 0x61, 0x36, 0x44,
|
||||
0xb3, 0x08, 0x05, 0x5b, 0x14, 0xde, 0x01, 0x0c,
|
||||
0x32, 0x3c, 0x9a, 0x91, 0x00, 0x50, 0xa8, 0x1d,
|
||||
0xcc, 0x9f, 0x8f, 0x35, 0xb7, 0xc2, 0x75, 0x08,
|
||||
0x32, 0x8b, 0x10, 0x3a, 0x86, 0xf9, 0xd7, 0x78,
|
||||
0xa3, 0x9d, 0x74, 0x10, 0xc6, 0x24, 0xb1, 0x7f,
|
||||
0xa5, 0xbf, 0x5f, 0xc2, 0xd7, 0x15, 0xa3, 0x1d,
|
||||
0xe0, 0x15, 0x6b, 0x1b, 0x0e, 0x38, 0xba, 0x34,
|
||||
0xbc, 0x95, 0x47, 0x94, 0x40, 0x70, 0xac, 0x99,
|
||||
0x1f, 0x0b, 0x8e, 0x56, 0x93, 0x36, 0x2b, 0x6d,
|
||||
0x04, 0xe7, 0x95, 0x1a, 0x37, 0xda, 0x16, 0x57,
|
||||
0x99, 0xee, 0x03, 0x68, 0x16, 0x31, 0xaa, 0xc3,
|
||||
0xb7, 0x92, 0x75, 0x53, 0xfc, 0xf6, 0x20, 0x55,
|
||||
0x44, 0xf8, 0xd4, 0x8d, 0x78, 0x15, 0xc7, 0x1a,
|
||||
0xb6, 0xde, 0x6c, 0xe8, 0x49, 0x5d, 0xaf, 0xa8,
|
||||
0x4e, 0x6f, 0x7c, 0xe2, 0x6a, 0x4c, 0xd5, 0xe7,
|
||||
0x8c, 0x8f, 0x0b, 0x5d, 0x3a, 0x09, 0xd6, 0xb3,
|
||||
0x44, 0xab, 0xe0, 0x35, 0x52, 0x7c, 0x66, 0x85,
|
||||
0xa4, 0x40, 0xd7, 0x20, 0xec, 0x24, 0x05, 0x06,
|
||||
0xd9, 0x84, 0x51, 0x5a, 0xd2, 0x38, 0xd5, 0x1d,
|
||||
0xea, 0x70, 0x2a, 0x21, 0xe6, 0x82, 0xfd, 0xa4,
|
||||
0x46, 0x1c, 0x4f, 0x59, 0x6e, 0x29, 0x3d, 0xae,
|
||||
0xb8, 0x8e, 0xee, 0x77, 0x1f, 0x15, 0x33, 0xcf,
|
||||
0x94, 0x1d, 0x87, 0x3c, 0x37, 0xc5, 0x89, 0xe8,
|
||||
0x7d, 0x85, 0xb3, 0xbc, 0xe8, 0x62, 0x6a, 0x84,
|
||||
0x7f, 0xfe, 0x9a, 0x85, 0x3f, 0x39, 0xe8, 0xaa,
|
||||
0x16, 0xa6, 0x8f, 0x87, 0x7f, 0xcb, 0xc1, 0xd6,
|
||||
0xf2, 0xec, 0x2b, 0xa7, 0xdd, 0x49, 0x98, 0x7b,
|
||||
0x6f, 0xdd, 0x69, 0x6d, 0x02, 0x03, 0x01, 0x00,
|
||||
0x01, 0x02, 0x82, 0x01, 0x00, 0x43, 0x8f, 0x19,
|
||||
0x83, 0xb1, 0x27, 0x4e, 0xee, 0x98, 0xba, 0xcb,
|
||||
0x54, 0xa0, 0x77, 0x11, 0x6d, 0xd4, 0x25, 0x31,
|
||||
0x8c, 0xb0, 0x01, 0xcf, 0xe6, 0x80, 0x83, 0x14,
|
||||
0x40, 0x67, 0x39, 0x33, 0x67, 0x03, 0x1e, 0xa0,
|
||||
0x8b, 0xd1, 0x1d, 0xfd, 0x80, 0xa4, 0xb9, 0xe7,
|
||||
0x57, 0x5e, 0xc8, 0x8e, 0x79, 0x71, 0xd5, 0x6b,
|
||||
0x09, 0xe9, 0x2b, 0x41, 0xa0, 0x33, 0x64, 0xc9,
|
||||
0x66, 0x33, 0xa1, 0xb1, 0x55, 0x07, 0x55, 0x98,
|
||||
0x53, 0x10, 0xe6, 0xc0, 0x39, 0x6d, 0x61, 0xd9,
|
||||
0xe8, 0x16, 0x52, 0x28, 0xe4, 0x2b, 0xda, 0x27,
|
||||
0x01, 0xaf, 0x21, 0x4a, 0xe8, 0x55, 0x1d, 0x0b,
|
||||
0xd1, 0x1c, 0xdc, 0xfd, 0xb3, 0x0b, 0xa6, 0x5c,
|
||||
0xcc, 0x6e, 0x77, 0xb8, 0xe0, 0xd1, 0x4e, 0x0a,
|
||||
0xd7, 0x7a, 0x5e, 0x18, 0xc3, 0xfb, 0xe9, 0xa1,
|
||||
0x9c, 0xc3, 0x9c, 0xd4, 0x4a, 0x7e, 0x70, 0x72,
|
||||
0x11, 0x18, 0x24, 0x56, 0x24, 0xdf, 0xf8, 0xba,
|
||||
0xac, 0x5b, 0x54, 0xd3, 0xc4, 0x65, 0x69, 0xc8,
|
||||
0x79, 0x94, 0x16, 0x88, 0x9a, 0x68, 0x1c, 0xbc,
|
||||
0xd4, 0xca, 0xec, 0x5e, 0x07, 0x4a, 0xc9, 0x54,
|
||||
0x7a, 0x4b, 0xdb, 0x19, 0x88, 0xf6, 0xbe, 0x50,
|
||||
0x9d, 0x9e, 0x9d, 0x88, 0x5b, 0x4a, 0x23, 0x86,
|
||||
0x2b, 0xa9, 0xa6, 0x6c, 0x70, 0x7d, 0xe1, 0x11,
|
||||
0xba, 0xbf, 0x03, 0x2e, 0xf1, 0x46, 0x7e, 0x1b,
|
||||
0xed, 0x06, 0x11, 0x57, 0xad, 0x4a, 0xcb, 0xe5,
|
||||
0xb1, 0x11, 0x05, 0x0a, 0x30, 0xb1, 0x73, 0x79,
|
||||
0xcd, 0x7a, 0x04, 0xcc, 0x70, 0xe9, 0x95, 0xe4,
|
||||
0x27, 0xc2, 0xd5, 0x2d, 0x92, 0x44, 0xdf, 0xb4,
|
||||
0x94, 0xa8, 0x73, 0xa1, 0x4a, 0xc3, 0xcc, 0xc4,
|
||||
0x0e, 0x8d, 0xa1, 0x6a, 0xc2, 0xd8, 0x03, 0x7f,
|
||||
0xfa, 0xa7, 0x76, 0x0d, 0xad, 0x87, 0x88, 0xa0,
|
||||
0x77, 0xaf, 0x3b, 0x23, 0xd1, 0x66, 0x0b, 0x31,
|
||||
0x2b, 0xaf, 0xef, 0xd5, 0x41, 0x02, 0x81, 0x81,
|
||||
0x00, 0xdb, 0xc1, 0xe7, 0xdd, 0xba, 0x3c, 0x1f,
|
||||
0x9c, 0x64, 0xca, 0xa0, 0x63, 0xdb, 0xd2, 0x47,
|
||||
0x5c, 0x6e, 0x8a, 0xa3, 0x16, 0xd5, 0xda, 0xc2,
|
||||
0x25, 0x64, 0x0a, 0x02, 0xbc, 0x7d, 0x7f, 0x50,
|
||||
0xab, 0xe0, 0x66, 0x03, 0x53, 0x7d, 0x77, 0x6d,
|
||||
0x6c, 0x61, 0x58, 0x09, 0x73, 0xcd, 0x18, 0xe9,
|
||||
0x53, 0x0b, 0x5c, 0xa2, 0x71, 0x14, 0x02, 0xfd,
|
||||
0x55, 0xda, 0xe9, 0x77, 0x24, 0x7c, 0x2a, 0x4e,
|
||||
0xb9, 0xd9, 0x5d, 0x58, 0xf6, 0x26, 0xd0, 0xd8,
|
||||
0x3d, 0xcf, 0x8c, 0x89, 0x65, 0x6c, 0x35, 0x19,
|
||||
0xb6, 0x63, 0xff, 0xa0, 0x71, 0x49, 0xcd, 0x6d,
|
||||
0x5b, 0x3d, 0x8f, 0xea, 0x6f, 0xa9, 0xba, 0x43,
|
||||
0xe5, 0xdd, 0x39, 0x3a, 0x78, 0x8f, 0x07, 0xb8,
|
||||
0xab, 0x58, 0x07, 0xb7, 0xd2, 0xf8, 0x07, 0x02,
|
||||
0x9b, 0x79, 0x26, 0x32, 0x22, 0x38, 0x91, 0x01,
|
||||
0x90, 0x81, 0x29, 0x94, 0xad, 0x77, 0xeb, 0x86,
|
||||
0xb9, 0x02, 0x81, 0x81, 0x00, 0xc1, 0x29, 0x88,
|
||||
0xbd, 0x96, 0x31, 0x33, 0x7b, 0x77, 0x5d, 0x32,
|
||||
0x12, 0x5e, 0xdf, 0x28, 0x0c, 0x96, 0x0d, 0xa8,
|
||||
0x22, 0xdf, 0xd3, 0x35, 0xd7, 0xb0, 0x41, 0xcb,
|
||||
0xe7, 0x94, 0x8a, 0xa4, 0xed, 0xd2, 0xfb, 0xd2,
|
||||
0xf3, 0xf2, 0x95, 0xff, 0xd8, 0x33, 0x3f, 0x8c,
|
||||
0xd7, 0x65, 0xe4, 0x0c, 0xcc, 0xfe, 0x32, 0x66,
|
||||
0xfa, 0x50, 0xe2, 0xcf, 0xf0, 0xbe, 0x05, 0xb1,
|
||||
0xbc, 0xbe, 0x44, 0x09, 0xb4, 0xfe, 0x95, 0x06,
|
||||
0x18, 0xd7, 0x59, 0xc6, 0xef, 0x2d, 0x22, 0xa0,
|
||||
0x73, 0x5e, 0x77, 0xdf, 0x8d, 0x09, 0x2c, 0xb8,
|
||||
0xcc, 0xeb, 0x10, 0x4d, 0xa7, 0xd0, 0x4b, 0x46,
|
||||
0xba, 0x7d, 0x8b, 0x6a, 0x55, 0x47, 0x55, 0xd3,
|
||||
0xd7, 0xb1, 0x88, 0xfd, 0x27, 0x3e, 0xf9, 0x5b,
|
||||
0x7b, 0xae, 0x6d, 0x08, 0x9f, 0x0c, 0x2a, 0xe1,
|
||||
0xdd, 0xb9, 0xe3, 0x55, 0x13, 0x55, 0xa3, 0x6d,
|
||||
0x06, 0xbb, 0xe0, 0x1e, 0x55, 0x02, 0x81, 0x80,
|
||||
0x61, 0x73, 0x3d, 0x64, 0xff, 0xdf, 0x05, 0x8d,
|
||||
0x8e, 0xcc, 0xa4, 0x0f, 0x64, 0x3d, 0x7d, 0x53,
|
||||
0xa9, 0xd9, 0x64, 0xb5, 0x0d, 0xa4, 0x72, 0x8f,
|
||||
0xae, 0x2b, 0x1a, 0x47, 0x87, 0xc7, 0x5b, 0x78,
|
||||
0xbc, 0x8b, 0xc0, 0x51, 0xd7, 0xc3, 0x8c, 0x0c,
|
||||
0x91, 0xa6, 0x3e, 0x9a, 0xd1, 0x8a, 0x88, 0x7d,
|
||||
0x40, 0xfe, 0x95, 0x32, 0x5b, 0xd3, 0x6f, 0x90,
|
||||
0x11, 0x01, 0x92, 0xc9, 0xe5, 0x1d, 0xc5, 0xc7,
|
||||
0x78, 0x72, 0x82, 0xae, 0xb5, 0x4b, 0xcb, 0x78,
|
||||
0xad, 0x7e, 0xfe, 0xb6, 0xb1, 0x23, 0x63, 0x01,
|
||||
0x94, 0x9a, 0x99, 0x05, 0x63, 0xda, 0xea, 0xf1,
|
||||
0x98, 0xfd, 0x26, 0xd2, 0xd9, 0x8b, 0x35, 0xec,
|
||||
0xcb, 0x0b, 0x43, 0xb8, 0x8e, 0x84, 0xb8, 0x09,
|
||||
0x93, 0x81, 0xe8, 0xac, 0x6f, 0x3c, 0x7c, 0x95,
|
||||
0x81, 0x45, 0xc4, 0xd9, 0x94, 0x08, 0x09, 0x8f,
|
||||
0x91, 0x17, 0x65, 0x4c, 0xff, 0x6e, 0xbc, 0x51,
|
||||
0x02, 0x81, 0x81, 0x00, 0xc1, 0x0d, 0x9d, 0xd8,
|
||||
0xbd, 0xaf, 0x56, 0xe0, 0xe3, 0x1f, 0x85, 0xd7,
|
||||
0xce, 0x72, 0x02, 0x38, 0xf2, 0x0f, 0x9c, 0x27,
|
||||
0x9e, 0xc4, 0x1d, 0x60, 0x00, 0x8d, 0x02, 0x19,
|
||||
0xe5, 0xdf, 0xdb, 0x8e, 0xc5, 0xfb, 0x61, 0x8e,
|
||||
0xe6, 0xb8, 0xfc, 0x07, 0x3c, 0xd1, 0x1b, 0x16,
|
||||
0x7c, 0x83, 0x3c, 0x37, 0xf5, 0x26, 0xb2, 0xbd,
|
||||
0x22, 0xf2, 0x4d, 0x19, 0x33, 0x11, 0xc5, 0xdd,
|
||||
0xf9, 0xdb, 0x4e, 0x48, 0x52, 0xd8, 0xe6, 0x4b,
|
||||
0x15, 0x90, 0x68, 0xbe, 0xca, 0xc1, 0x7c, 0xd3,
|
||||
0x51, 0x6b, 0x45, 0x46, 0x54, 0x11, 0x1a, 0x71,
|
||||
0xd3, 0xcd, 0x6b, 0x8f, 0x79, 0x22, 0x83, 0x02,
|
||||
0x08, 0x4f, 0xba, 0x6a, 0x98, 0xed, 0x32, 0xd8,
|
||||
0xb4, 0x5b, 0x51, 0x88, 0x53, 0xec, 0x2c, 0x7e,
|
||||
0xa4, 0x89, 0xdc, 0xbf, 0xf9, 0x0d, 0x32, 0xc8,
|
||||
0xc3, 0xec, 0x6d, 0x2e, 0xf1, 0xbc, 0x70, 0x4e,
|
||||
0xf6, 0x9e, 0xbc, 0x31, 0x02, 0x81, 0x81, 0x00,
|
||||
0xd3, 0x35, 0x1b, 0x19, 0x75, 0x3f, 0x61, 0xf2,
|
||||
0x55, 0x03, 0xce, 0x25, 0xa9, 0xdf, 0x0c, 0x0a,
|
||||
0x3b, 0x47, 0x42, 0xdc, 0x38, 0x4b, 0x13, 0x4d,
|
||||
0x1f, 0x86, 0x58, 0x4f, 0xd8, 0xee, 0xfa, 0x76,
|
||||
0x15, 0xfb, 0x6e, 0x55, 0x31, 0xf2, 0xd2, 0x62,
|
||||
0x32, 0xa5, 0xc4, 0x23, 0x5e, 0x08, 0xa9, 0x83,
|
||||
0x07, 0xac, 0x8c, 0xa3, 0x7e, 0x18, 0xc0, 0x1c,
|
||||
0x57, 0x63, 0x8d, 0x05, 0x17, 0x47, 0x1b, 0xd3,
|
||||
0x74, 0x73, 0x20, 0x04, 0xfb, 0xc8, 0x1a, 0x43,
|
||||
0x04, 0x36, 0xc8, 0x19, 0xbe, 0xdc, 0xa6, 0xe5,
|
||||
0x0f, 0x25, 0x62, 0x24, 0x96, 0x92, 0xb6, 0xb3,
|
||||
0x97, 0xad, 0x57, 0x9a, 0x90, 0x37, 0x4e, 0x31,
|
||||
0x44, 0x74, 0xfa, 0x7c, 0xb4, 0xea, 0xfc, 0x15,
|
||||
0xa7, 0xb0, 0x51, 0xcc, 0xee, 0x1e, 0xed, 0x5b,
|
||||
0x98, 0x18, 0x0e, 0x65, 0xb6, 0x4b, 0x69, 0x0b,
|
||||
0x21, 0xdc, 0x86, 0x17, 0x6e, 0xc8, 0xee, 0x24 };
|
||||
|
||||
static const unsigned char kTestRsaPublicKey3_2048[] = {
|
||||
0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
|
||||
0x00, 0xa5, 0xd0, 0xd7, 0x3e, 0x0e, 0x2d, 0xfb,
|
||||
0x43, 0x51, 0x99, 0xea, 0x40, 0x1e, 0x2d, 0x89,
|
||||
0xe4, 0xa2, 0x3e, 0xfc, 0x51, 0x3d, 0x0e, 0x83,
|
||||
0xa7, 0xe0, 0xa5, 0x41, 0x04, 0x1e, 0x14, 0xc5,
|
||||
0xa7, 0x5c, 0x61, 0x36, 0x44, 0xb3, 0x08, 0x05,
|
||||
0x5b, 0x14, 0xde, 0x01, 0x0c, 0x32, 0x3c, 0x9a,
|
||||
0x91, 0x00, 0x50, 0xa8, 0x1d, 0xcc, 0x9f, 0x8f,
|
||||
0x35, 0xb7, 0xc2, 0x75, 0x08, 0x32, 0x8b, 0x10,
|
||||
0x3a, 0x86, 0xf9, 0xd7, 0x78, 0xa3, 0x9d, 0x74,
|
||||
0x10, 0xc6, 0x24, 0xb1, 0x7f, 0xa5, 0xbf, 0x5f,
|
||||
0xc2, 0xd7, 0x15, 0xa3, 0x1d, 0xe0, 0x15, 0x6b,
|
||||
0x1b, 0x0e, 0x38, 0xba, 0x34, 0xbc, 0x95, 0x47,
|
||||
0x94, 0x40, 0x70, 0xac, 0x99, 0x1f, 0x0b, 0x8e,
|
||||
0x56, 0x93, 0x36, 0x2b, 0x6d, 0x04, 0xe7, 0x95,
|
||||
0x1a, 0x37, 0xda, 0x16, 0x57, 0x99, 0xee, 0x03,
|
||||
0x68, 0x16, 0x31, 0xaa, 0xc3, 0xb7, 0x92, 0x75,
|
||||
0x53, 0xfc, 0xf6, 0x20, 0x55, 0x44, 0xf8, 0xd4,
|
||||
0x8d, 0x78, 0x15, 0xc7, 0x1a, 0xb6, 0xde, 0x6c,
|
||||
0xe8, 0x49, 0x5d, 0xaf, 0xa8, 0x4e, 0x6f, 0x7c,
|
||||
0xe2, 0x6a, 0x4c, 0xd5, 0xe7, 0x8c, 0x8f, 0x0b,
|
||||
0x5d, 0x3a, 0x09, 0xd6, 0xb3, 0x44, 0xab, 0xe0,
|
||||
0x35, 0x52, 0x7c, 0x66, 0x85, 0xa4, 0x40, 0xd7,
|
||||
0x20, 0xec, 0x24, 0x05, 0x06, 0xd9, 0x84, 0x51,
|
||||
0x5a, 0xd2, 0x38, 0xd5, 0x1d, 0xea, 0x70, 0x2a,
|
||||
0x21, 0xe6, 0x82, 0xfd, 0xa4, 0x46, 0x1c, 0x4f,
|
||||
0x59, 0x6e, 0x29, 0x3d, 0xae, 0xb8, 0x8e, 0xee,
|
||||
0x77, 0x1f, 0x15, 0x33, 0xcf, 0x94, 0x1d, 0x87,
|
||||
0x3c, 0x37, 0xc5, 0x89, 0xe8, 0x7d, 0x85, 0xb3,
|
||||
0xbc, 0xe8, 0x62, 0x6a, 0x84, 0x7f, 0xfe, 0x9a,
|
||||
0x85, 0x3f, 0x39, 0xe8, 0xaa, 0x16, 0xa6, 0x8f,
|
||||
0x87, 0x7f, 0xcb, 0xc1, 0xd6, 0xf2, 0xec, 0x2b,
|
||||
0xa7, 0xdd, 0x49, 0x98, 0x7b, 0x6f, 0xdd, 0x69,
|
||||
0x6d, 0x02, 0x03, 0x01, 0x00, 0x01 };
|
||||
|
||||
RsaTestKeys::RsaTestKeys() :
|
||||
private_key_1_3072_bits_(kTestRsaPrivateKey1_3072, kTestRsaPrivateKey1_3072
|
||||
+ sizeof(kTestRsaPrivateKey1_3072)),
|
||||
public_key_1_3072_bits_(kTestRsaPublicKey1_3072, kTestRsaPublicKey1_3072
|
||||
+ sizeof(kTestRsaPublicKey1_3072)),
|
||||
private_key_2_2048_bits_(kTestRsaPrivateKey2_2048, kTestRsaPrivateKey2_2048
|
||||
+ sizeof(kTestRsaPrivateKey2_2048)),
|
||||
public_key_2_2048_bits_(kTestRsaPublicKey2_2048, kTestRsaPublicKey2_2048
|
||||
+ sizeof(kTestRsaPublicKey2_2048)),
|
||||
private_key_3_2048_bits_(kTestRsaPrivateKey3_2048, kTestRsaPrivateKey3_2048
|
||||
+ sizeof(kTestRsaPrivateKey3_2048)),
|
||||
public_key_3_2048_bits_(kTestRsaPublicKey3_2048, kTestRsaPublicKey3_2048
|
||||
+ sizeof(kTestRsaPublicKey3_2048)) {
|
||||
}
|
||||
|
||||
} // namespace widevine
|
||||
64
common/rsa_test_keys.h
Normal file
64
common/rsa_test_keys.h
Normal file
@@ -0,0 +1,64 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2016 Google Inc.
|
||||
//
|
||||
// This software is licensed under the terms defined in the Widevine Master
|
||||
// License Agreement. For a copy of this agreement, please contact
|
||||
// widevine-licensing@google.com.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
// Description:
|
||||
// RSA keys generated using fake_prng for purposes of testing.
|
||||
|
||||
#ifndef COMMON_RSA_TEST_KEYS_H_
|
||||
#define COMMON_RSA_TEST_KEYS_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace widevine {
|
||||
|
||||
// Container for test RSA keys
|
||||
class RsaTestKeys {
|
||||
public:
|
||||
RsaTestKeys();
|
||||
|
||||
// Returns 3072-bit private RSA test key 1
|
||||
const std::string& private_test_key_1_3072_bits() const {
|
||||
return private_key_1_3072_bits_;
|
||||
}
|
||||
// Returns 3072-bit public RSA test key 1
|
||||
const std::string& public_test_key_1_3072_bits() const {
|
||||
return public_key_1_3072_bits_;
|
||||
}
|
||||
// Returns 2048-bit private RSA test key 2
|
||||
const std::string& private_test_key_2_2048_bits() const {
|
||||
return private_key_2_2048_bits_;
|
||||
}
|
||||
// Returns 2048-bit public RSA test key 2
|
||||
const std::string& public_test_key_2_2048_bits() const {
|
||||
return public_key_2_2048_bits_;
|
||||
}
|
||||
// Returns 2048-bit private RSA test key 3
|
||||
const std::string& private_test_key_3_2048_bits() const {
|
||||
return private_key_3_2048_bits_;
|
||||
}
|
||||
// Returns 2048-bit public RSA test key 3
|
||||
const std::string& public_test_key_3_2048_bits() const {
|
||||
return public_key_3_2048_bits_;
|
||||
}
|
||||
|
||||
private:
|
||||
RsaTestKeys(const RsaTestKeys&) = delete;
|
||||
RsaTestKeys& operator=(const RsaTestKeys&) = delete;
|
||||
|
||||
std::string private_key_1_3072_bits_;
|
||||
std::string public_key_1_3072_bits_;
|
||||
std::string private_key_2_2048_bits_;
|
||||
std::string public_key_2_2048_bits_;
|
||||
std::string private_key_3_2048_bits_;
|
||||
std::string public_key_3_2048_bits_;
|
||||
};
|
||||
|
||||
} // namespace widevine
|
||||
|
||||
#endif // COMMON_RSA_TEST_KEYS_H_
|
||||
386
common/rsa_util.cc
Normal file
386
common/rsa_util.cc
Normal file
@@ -0,0 +1,386 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2016 Google Inc.
|
||||
//
|
||||
// This software is licensed under the terms defined in the Widevine Master
|
||||
// License Agreement. For a copy of this agreement, please contact
|
||||
// widevine-licensing@google.com.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
// Description:
|
||||
// RSA utility functions for serializing and deserializing RSA keys,
|
||||
// encryption, and signing.
|
||||
|
||||
#include "common/rsa_util.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "glog/logging.h"
|
||||
#include "openssl/bio.h"
|
||||
#include "openssl/evp.h"
|
||||
#include "openssl/pem.h"
|
||||
#include "openssl/x509.h"
|
||||
|
||||
namespace widevine {
|
||||
namespace rsa_util {
|
||||
|
||||
static bool SerializeRsaKey(const RSA* key, std::string* serialized_key,
|
||||
bool serialize_private_key) {
|
||||
if (key == NULL) {
|
||||
LOG(ERROR) << (serialize_private_key ? "Private" : "Public")
|
||||
<< " RSA key is NULL.";
|
||||
return false;
|
||||
}
|
||||
if (serialized_key == NULL) {
|
||||
LOG(ERROR) << "Pointer to hold serialized RSA" << (serialize_private_key ?
|
||||
"Private" : "Public") << "Key is NULL.";
|
||||
return false;
|
||||
}
|
||||
BIO* bio = BIO_new(BIO_s_mem());
|
||||
if (bio == NULL) {
|
||||
LOG(ERROR) << "BIO_new returned NULL";
|
||||
return false;
|
||||
}
|
||||
bool success = false;
|
||||
if ((serialize_private_key ?
|
||||
i2d_RSAPrivateKey_bio(bio, const_cast<RSA*>(key)) :
|
||||
i2d_RSAPublicKey_bio(bio, const_cast<RSA*>(key))) != 0) {
|
||||
int serialized_size = BIO_pending(bio);
|
||||
serialized_key->assign(serialized_size, 0);
|
||||
if (BIO_read(bio, &(*serialized_key)[0], serialized_size) ==
|
||||
serialized_size) {
|
||||
success = true;
|
||||
} else {
|
||||
LOG(ERROR) << "BIO_read failure";
|
||||
}
|
||||
} else {
|
||||
LOG(ERROR) << (serialize_private_key ? "Private" : "Public") <<
|
||||
" key serialization failure";
|
||||
}
|
||||
BIO_free(bio);
|
||||
return success;
|
||||
}
|
||||
|
||||
static bool DeserializeRsaKey(const std::string& serialized_key, RSA** key,
|
||||
bool deserialize_private_key) {
|
||||
if (serialized_key.empty()) {
|
||||
LOG(ERROR) << "Serialized RSA" << (deserialize_private_key ?
|
||||
"Private" : "Public") << "Key is empty.";
|
||||
return false;
|
||||
}
|
||||
if (key == NULL) {
|
||||
LOG(ERROR) << "Pointer to hold new RSA " << (deserialize_private_key ?
|
||||
"private" : "public") << " key is NULL.";
|
||||
return false;
|
||||
}
|
||||
BIO* bio = BIO_new_mem_buf(const_cast<char*>(serialized_key.data()),
|
||||
serialized_key.size());
|
||||
if (bio == NULL) {
|
||||
LOG(ERROR) << "BIO_new_mem_buf returned NULL";
|
||||
return false;
|
||||
}
|
||||
*key = deserialize_private_key ? d2i_RSAPrivateKey_bio(bio, NULL) :
|
||||
d2i_RSAPublicKey_bio(bio, NULL);
|
||||
BIO_free(bio);
|
||||
if (*key == NULL) {
|
||||
LOG(ERROR) << (deserialize_private_key ? "Private" : "Public") <<
|
||||
" RSA key deserialization failure";
|
||||
}
|
||||
return *key != NULL;
|
||||
}
|
||||
|
||||
bool SerializeRsaPrivateKey(const RSA* private_key,
|
||||
std::string* serialized_private_key) {
|
||||
return SerializeRsaKey(private_key, serialized_private_key, true);
|
||||
}
|
||||
|
||||
bool DeserializeRsaPrivateKey(const std::string& serialized_private_key,
|
||||
RSA** private_key) {
|
||||
return DeserializeRsaKey(serialized_private_key, private_key, true);
|
||||
}
|
||||
|
||||
bool SerializeRsaPublicKey(const RSA* public_key,
|
||||
std::string* serialized_public_key) {
|
||||
return SerializeRsaKey(public_key, serialized_public_key, false);
|
||||
}
|
||||
|
||||
bool DeserializeRsaPublicKey(const std::string& serialized_public_key,
|
||||
RSA** public_key) {
|
||||
return DeserializeRsaKey(serialized_public_key, public_key, false);
|
||||
}
|
||||
|
||||
bool SerializePrivateKeyInfo(const RSA* private_key,
|
||||
std::string* serialized_private_key) {
|
||||
if (private_key == NULL) {
|
||||
LOG(ERROR) << "Private RSA key is NULL.";
|
||||
return false;
|
||||
}
|
||||
if (serialized_private_key == NULL) {
|
||||
LOG(ERROR) << "Pointer to hold serialized PrivateKeyInfo is NULL.";
|
||||
return false;
|
||||
}
|
||||
// The following method of serializing a PKCS#8 PrivateKeyInfo object
|
||||
// was obtained from analyzing the openssl utility code, as the official
|
||||
// mechanism via i2d_PKCS8PrivateKey_bio is broken in the current openssl
|
||||
// version (1.0.0c). Please refer to b/8560683.
|
||||
EVP_PKEY* evp = EVP_PKEY_new();
|
||||
if (evp == NULL) {
|
||||
LOG(ERROR) << "EVP_PKEY_new returned NULL.";
|
||||
return false;
|
||||
}
|
||||
bool success = false;
|
||||
PKCS8_PRIV_KEY_INFO *pkcs8_pki = NULL;
|
||||
BIO* bio = NULL;
|
||||
if (EVP_PKEY_set1_RSA(evp, const_cast<RSA*>(private_key)) == 0) {
|
||||
LOG(ERROR) << "EVP_PKEY_set1_RSA failed.";
|
||||
goto cleanup;
|
||||
}
|
||||
pkcs8_pki = EVP_PKEY2PKCS8(evp);
|
||||
if (pkcs8_pki == NULL) {
|
||||
LOG(ERROR) << "EVP_PKEY2PKCS8 returned NULL.";
|
||||
goto cleanup;
|
||||
}
|
||||
bio = BIO_new(BIO_s_mem());
|
||||
if (bio == NULL) {
|
||||
LOG(ERROR) << "BIO_new returned NULL.";
|
||||
goto cleanup;
|
||||
}
|
||||
if (i2d_PKCS8_PRIV_KEY_INFO_bio(bio, pkcs8_pki) == 0) {
|
||||
LOG(ERROR) << "i2d_PKCS8_PRIV_KEY_INFO_bio failed.";
|
||||
goto cleanup;
|
||||
}
|
||||
{
|
||||
int serialized_size = BIO_pending(bio);
|
||||
serialized_private_key->assign(serialized_size, 0);
|
||||
if (BIO_read(bio, &(*serialized_private_key)[0], serialized_size) !=
|
||||
serialized_size) {
|
||||
LOG(ERROR) << "BIO_read failed.";
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
success = true;
|
||||
|
||||
cleanup:
|
||||
if (bio != NULL) {
|
||||
BIO_free(bio);
|
||||
}
|
||||
if (pkcs8_pki != NULL) {
|
||||
PKCS8_PRIV_KEY_INFO_free(pkcs8_pki);
|
||||
}
|
||||
EVP_PKEY_free(evp);
|
||||
return success;
|
||||
}
|
||||
|
||||
bool DeserializePrivateKeyInfo(const std::string& serialized_private_key,
|
||||
RSA** private_key) {
|
||||
if (serialized_private_key.empty()) {
|
||||
LOG(ERROR) << "Serialized PrivateKeyInfo is empty.";
|
||||
return false;
|
||||
}
|
||||
if (private_key == NULL) {
|
||||
LOG(ERROR) << "Pointer to hold new RSA private key is NULL.";
|
||||
return false;
|
||||
}
|
||||
// The following method of deserializing a PKCS#8 PrivateKeyInfo object
|
||||
// was obtained from analyzing the openssl utility code, as the official
|
||||
// mechanism via d2i_PKCS8PrivateKey_bio is broken in the current openssl
|
||||
// version (1.0.0c). Please refer to b/8560683.
|
||||
BIO* bio = BIO_new_mem_buf(const_cast<char*>(serialized_private_key.data()),
|
||||
serialized_private_key.size());
|
||||
if (bio == NULL) {
|
||||
LOG(ERROR) << "BIO_new_mem_buf returned NULL";
|
||||
return false;
|
||||
}
|
||||
bool success = false;
|
||||
EVP_PKEY* evp = NULL;
|
||||
PKCS8_PRIV_KEY_INFO *pkcs8_pki = d2i_PKCS8_PRIV_KEY_INFO_bio(bio, NULL);
|
||||
if (pkcs8_pki == NULL) {
|
||||
LOG(ERROR) << "d2i_PKCS8_PRIV_KEY_INFO_bio returned NULL.";
|
||||
goto cleanup;
|
||||
}
|
||||
evp = EVP_PKCS82PKEY(pkcs8_pki);
|
||||
if (evp == NULL) {
|
||||
LOG(ERROR) << "EVP_PKCS82PKEY returned NULL.";
|
||||
goto cleanup;
|
||||
}
|
||||
*private_key = EVP_PKEY_get1_RSA(evp);
|
||||
if (*private_key == NULL) {
|
||||
LOG(ERROR) << "PrivateKeyInfo did not contain an RSA key.";
|
||||
goto cleanup;
|
||||
}
|
||||
success = true;
|
||||
|
||||
cleanup:
|
||||
if (evp != NULL) {
|
||||
EVP_PKEY_free(evp);
|
||||
}
|
||||
if (pkcs8_pki != NULL) {
|
||||
PKCS8_PRIV_KEY_INFO_free(pkcs8_pki);
|
||||
}
|
||||
BIO_free(bio);
|
||||
return success;
|
||||
}
|
||||
|
||||
bool RsaPrivateKeyToPrivateKeyInfo(const std::string& rsa_private_key,
|
||||
std::string* private_key_info) {
|
||||
RSA* key = NULL;
|
||||
if (DeserializeRsaPrivateKey(rsa_private_key, &key)) {
|
||||
bool success = SerializePrivateKeyInfo(key, private_key_info);
|
||||
RSA_free(key);
|
||||
return success;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PrivateKeyInfoToRsaPrivateKey(const std::string& private_key_info,
|
||||
std::string* rsa_private_key) {
|
||||
RSA* key = NULL;
|
||||
if (DeserializePrivateKeyInfo(private_key_info, &key)) {
|
||||
bool success = SerializeRsaPrivateKey(key, rsa_private_key);
|
||||
RSA_free(key);
|
||||
return success;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SerializeEncryptedPrivateKeyInfo(const RSA* private_key,
|
||||
const std::string& passphrase,
|
||||
std::string* serialized_private_key) {
|
||||
if (private_key == NULL) {
|
||||
LOG(ERROR) << "Private RSA key is NULL.";
|
||||
return false;
|
||||
}
|
||||
if (passphrase.empty()) {
|
||||
LOG(ERROR) << "Passphrase for RSA key encryption is empty.";
|
||||
return false;
|
||||
}
|
||||
if (serialized_private_key == NULL) {
|
||||
LOG(ERROR) << "Pointer to hold serialized EncryptedPrivateKeyInfo is NULL.";
|
||||
return false;
|
||||
}
|
||||
EVP_PKEY* evp = EVP_PKEY_new();
|
||||
if (evp == NULL) {
|
||||
LOG(ERROR) << "EVP_PKEY_new returned NULL.";
|
||||
return false;
|
||||
}
|
||||
bool success = false;
|
||||
BIO* bio = NULL;
|
||||
if (EVP_PKEY_set1_RSA(evp, const_cast<RSA*>(private_key)) == 0) {
|
||||
LOG(ERROR) << "EVP_PKEY_set1_RSA failed.";
|
||||
goto cleanup;
|
||||
}
|
||||
bio = BIO_new(BIO_s_mem());
|
||||
if (bio == NULL) {
|
||||
LOG(ERROR) << "BIO_new returned NULL.";
|
||||
goto cleanup;
|
||||
}
|
||||
if (i2d_PKCS8PrivateKey_bio(bio, evp, EVP_aes_256_cbc(),
|
||||
const_cast<char*>(passphrase.data()),
|
||||
passphrase.size(), NULL, NULL) == 0) {
|
||||
LOG(ERROR) << "i2d_PKCS8PrivateKey_bio failed.";
|
||||
goto cleanup;
|
||||
}
|
||||
{
|
||||
int serialized_size = BIO_pending(bio);
|
||||
serialized_private_key->assign(serialized_size, 0);
|
||||
if (BIO_read(bio, &(*serialized_private_key)[0], serialized_size) !=
|
||||
serialized_size) {
|
||||
LOG(ERROR) << "BIO_read failed.";
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
success = true;
|
||||
|
||||
cleanup:
|
||||
if (bio != NULL) {
|
||||
BIO_free(bio);
|
||||
}
|
||||
EVP_PKEY_free(evp);
|
||||
return success;
|
||||
}
|
||||
|
||||
namespace {
|
||||
// Password retrieval function used by DeserializeEncryptedPrivateKeyInfo below.
|
||||
int get_password(char *buf, int size, int rwflag, void *u) {
|
||||
CHECK(buf);
|
||||
CHECK(u);
|
||||
const std::string* pass(static_cast<const std::string*>(u));
|
||||
if (!pass->empty() && size >= static_cast<int>(pass->size())) {
|
||||
memcpy(buf, pass->data(), pass->size());
|
||||
return pass->size();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
bool DeserializeEncryptedPrivateKeyInfo(const std::string& serialized_private_key,
|
||||
const std::string& passphrase,
|
||||
RSA** private_key) {
|
||||
if (serialized_private_key.empty()) {
|
||||
LOG(ERROR) << "Serialized RSAEncryptedPrivateKeyInfo is empty.";
|
||||
return false;
|
||||
}
|
||||
if (passphrase.empty()) {
|
||||
LOG(ERROR) << "Passphrase for RSA key decryption is empty.";
|
||||
return false;
|
||||
}
|
||||
if (private_key == NULL) {
|
||||
LOG(ERROR) << "Pointer to hold new RSA private key is NULL.";
|
||||
return false;
|
||||
}
|
||||
BIO* bio = BIO_new_mem_buf(const_cast<char*>(serialized_private_key.data()),
|
||||
serialized_private_key.size());
|
||||
if (bio == NULL) {
|
||||
LOG(ERROR) << "BIO_new_mem_buf returned NULL";
|
||||
return false;
|
||||
}
|
||||
bool success = false;
|
||||
EVP_PKEY* evp = d2i_PKCS8PrivateKey_bio(bio, NULL, get_password,
|
||||
const_cast<std::string*>(&passphrase));
|
||||
if (evp == NULL) {
|
||||
LOG(ERROR) << "d2i_PKCS8PrivateKey_bio returned NULL.";
|
||||
goto cleanup;
|
||||
}
|
||||
*private_key = EVP_PKEY_get1_RSA(evp);
|
||||
if (*private_key == NULL) {
|
||||
LOG(ERROR) << "EncryptedPrivateKeyInfo did not contain an RSA key.";
|
||||
goto cleanup;
|
||||
}
|
||||
success = true;
|
||||
|
||||
cleanup:
|
||||
if (evp != NULL) {
|
||||
EVP_PKEY_free(evp);
|
||||
}
|
||||
BIO_free(bio);
|
||||
return success;
|
||||
}
|
||||
|
||||
bool RsaPrivateKeyToEncryptedPrivateKeyInfo(const std::string& rsa_private_key,
|
||||
const std::string& passphrase,
|
||||
std::string* private_key_info) {
|
||||
RSA* key = NULL;
|
||||
if (DeserializeRsaPrivateKey(rsa_private_key, &key)) {
|
||||
bool success = SerializeEncryptedPrivateKeyInfo(key,
|
||||
passphrase,
|
||||
private_key_info);
|
||||
RSA_free(key);
|
||||
return success;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EncryptedPrivateKeyInfoToRsaPrivateKey(const std::string& private_key_info,
|
||||
const std::string& passphrase,
|
||||
std::string* rsa_private_key) {
|
||||
RSA* key = NULL;
|
||||
if (DeserializeEncryptedPrivateKeyInfo(private_key_info, passphrase, &key)) {
|
||||
bool success = SerializeRsaPrivateKey(key, rsa_private_key);
|
||||
RSA_free(key);
|
||||
return success;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace rsa_util
|
||||
} // namespace widevine
|
||||
153
common/rsa_util.h
Normal file
153
common/rsa_util.h
Normal file
@@ -0,0 +1,153 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2016 Google Inc.
|
||||
//
|
||||
// This software is licensed under the terms defined in the Widevine Master
|
||||
// License Agreement. For a copy of this agreement, please contact
|
||||
// widevine-licensing@google.com.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
// Description:
|
||||
// RSA utility functions for serializing and deserializing RSA keys,
|
||||
// encryption, and signing.
|
||||
|
||||
#ifndef COMMON_RSA_UTIL_H_
|
||||
#define COMMON_RSA_UTIL_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "openssl/rsa.h"
|
||||
|
||||
namespace widevine {
|
||||
namespace rsa_util {
|
||||
|
||||
// Serialize RSA private key into DER encoded PKCS#1 RSAPrivateKey.
|
||||
// - private_key is the RSA key to be serialized, which must not be NULL.
|
||||
// - serialized_private_key is a pointer to the std::string to hold the serialized
|
||||
// PKCS#1 RSAPrivateKey object. Caller retains ownership of the string. This
|
||||
// parameter must not be NULL.
|
||||
// Returns true if successful, false otherwise.
|
||||
bool SerializeRsaPrivateKey(const RSA* private_key,
|
||||
std::string* serialized_private_key);
|
||||
|
||||
// Deserialize RSA private key from DER encoded PKCS#1 RSAPrivateKey.
|
||||
// - serialized_private_key is the DER-encoded PKCS#1 RSAPrivateKey to be
|
||||
// deserialized.
|
||||
// - private_key is a pointer to an RSA structure pointer to point to a newly
|
||||
// allocated RSA structure. Caller assumes ownership of the new RSA pointer,
|
||||
// which is not allocated if the method fails. This parameter must not be
|
||||
// NULL.
|
||||
// Returns true if successful, false otherwise.
|
||||
bool DeserializeRsaPrivateKey(const std::string& serialized_private_key,
|
||||
RSA** private_key);
|
||||
|
||||
// Serialize RSA key into DER encoded PKCS#1 RSAPublicKey.
|
||||
// - public_key is the RSA key to be serialized, which must not be NULL.
|
||||
// - serialized_public_key is a pointer to the std::string to hold the serialized
|
||||
// PKCS#1 RSAPublicKey object. Caller retains ownership of the string. This
|
||||
// parameter must not be NULL.
|
||||
// Returns true if successful, false otherwise.
|
||||
bool SerializeRsaPublicKey(const RSA* public_key,
|
||||
std::string* serialized_public_key);
|
||||
|
||||
// Deserialize RSA public key from DER encoded PKCS#1 RSAPublicKey.
|
||||
// - serialized_public_key is the DER-encoded PKCS#1 RSAPublicKey to be
|
||||
// deserialized.
|
||||
// - public_key is a pointer to an RSA structure pointer to point to a newly
|
||||
// allocated RSA structure. Caller assumes ownership of the new RSA pointer,
|
||||
// which is not allocated if the method fails. This parameter must not be
|
||||
// NULL.
|
||||
// Returns true if successful, false otherwise.
|
||||
bool DeserializeRsaPublicKey(const std::string& serialized_public_key,
|
||||
RSA** public_key);
|
||||
|
||||
// Serialize RSA private key into DER encoded PKCS#8 PrivateKeyInfo.
|
||||
// - private_key is the RSA key to be serialized, which must not be NULL.
|
||||
// - serialized_private_key is a pointer to the std::string to hold the serialized
|
||||
// PKCS#8 PrivateKeyInfo object. Caller retains ownership of the string. This
|
||||
// parameter must not be NULL.
|
||||
// Returns true if successful, false otherwise.
|
||||
bool SerializePrivateKeyInfo(const RSA* private_key,
|
||||
std::string* serialized_private_key);
|
||||
|
||||
// Deserialize RSA private key from DER encoded PKCS#8 PrivateKeyInfo.
|
||||
// - serialized_private_key is the DER-encoded PKCS#8 PrivateKeyInfo to be
|
||||
// deserialized.
|
||||
// - private_key is a pointer to an RSA structure pointer to point to a newly
|
||||
// allocated RSA structure. Caller assumes ownership of the new RSA pointer,
|
||||
// which is not allocated if the method fails. This parameter must not be
|
||||
// NULL.
|
||||
// Returns true if successful, false otherwise.
|
||||
bool DeserializePrivateKeyInfo(const std::string& serialized_private_key,
|
||||
RSA** private_key);
|
||||
|
||||
// Convert DER-encoded PKCS#1 RSAPrivateKey to DER-encoded PKCS#8
|
||||
// PrivateKeyInfo.
|
||||
// - rsa_private_key is the PKCS#1 RSAPrivateKey to be converted.
|
||||
// - private_key_info is a pointer to std::string to hold the PKCS#8 PrivateKeyInfo.
|
||||
// The caller retains ownership of this parameter, which must not be NULL.
|
||||
// Returns true if successful, false otherwise.
|
||||
bool RsaPrivateKeyToPrivateKeyInfo(const std::string& rsa_private_key,
|
||||
std::string* private_key_info);
|
||||
|
||||
// Convert DER-encoded PKCS#8 PrivateKeyInfo to DER-encoded PKCS#1
|
||||
// RSAPrivateKey.
|
||||
// - private_key_info is the PKCS#8 PrivateKeyInfo to be converted.
|
||||
// - rsa_private_key is a pointer to std::string to hold the PKCS#1 RSAPrivateKey.
|
||||
// The caller retains ownership of this parameter, which must not be NULL.
|
||||
// Returns true if successful, false otherwise.
|
||||
bool PrivateKeyInfoToRsaPrivateKey(const std::string& private_key_info,
|
||||
std::string* rsa_private_key);
|
||||
|
||||
|
||||
// Serialize RSA private key into DER encoded PKCS#8 EncryptedPrivateKeyInfo.
|
||||
// - private_key is the RSA key to be serialized, which must not be NULL.
|
||||
// - passphrase is the password to use for PKCS#5 v2.0 3DES encryption.
|
||||
// - serialized_private_key is a pointer to the std::string to hold the serialized
|
||||
// PKCS#8 EncryptedPrivateKeyInfo object. Caller retains ownership of the
|
||||
// string. This parameter must not be NULL.
|
||||
// Returns true if successful, false otherwise.
|
||||
bool SerializeEncryptedPrivateKeyInfo(const RSA* private_key,
|
||||
const std::string& passphrase,
|
||||
std::string* serialized_private_key);
|
||||
|
||||
// Deserialize RSA private key from DER encoded PKCS#8 EncryptedPrivateKeyInfo.
|
||||
// - serialized_private_key is the DER-encoded PKCS#8 EncryptedPrivateKeyInfo to
|
||||
// be deserialized.
|
||||
// - passphrase is the password to use for key decryption.
|
||||
// - private_key is a pointer to an RSA structure pointer to point to a newly
|
||||
// allocated RSA structure. Caller assumes ownership of the new RSA pointer,
|
||||
// which is not allocated if the method fails. This parameter must not be
|
||||
// NULL.
|
||||
// Returns true if successful, false otherwise.
|
||||
bool DeserializeEncryptedPrivateKeyInfo(const std::string& serialized_private_key,
|
||||
const std::string& passphrase,
|
||||
RSA** private_key);
|
||||
|
||||
// Convert DER-encoded PKCS#1 RSAPrivateKey to DER-encoded PKCS#8
|
||||
// EncryptedPrivateKeyInfo.
|
||||
// - rsa_private_key is the PKCS#1 RSAPrivateKey to be converted.
|
||||
// - passphrase is the password to use for PKCS#5 v2.1 AES-256-CBC encryption.
|
||||
// - private_key_info is a pointer to std::string to hold the PKCS#8
|
||||
// EncryptedPrivateKeyInfo.
|
||||
// The caller retains ownership of this parameter, which must not be NULL.
|
||||
// Returns true if successful, false otherwise.
|
||||
bool RsaPrivateKeyToEncryptedPrivateKeyInfo(const std::string& rsa_private_key,
|
||||
const std::string& passphrase,
|
||||
std::string* private_key_info);
|
||||
|
||||
// Convert DER-encoded PKCS#8 EncryptedPrivateKeyInfo to DER-encoded PKCS#1
|
||||
// RSAPrivateKey.
|
||||
// - private_key_info is the PKCS#8 EncryptedPrivateKeyInfo to be converted.
|
||||
// - passphrase is the password to use for key decryption.
|
||||
// - rsa_private_key is a pointer to std::string to hold the PKCS#1 RSAPrivateKey.
|
||||
// The caller retains ownership of this parameter, which must not be NULL.
|
||||
// Returns true if successful, false otherwise.
|
||||
bool EncryptedPrivateKeyInfoToRsaPrivateKey(const std::string& private_key_info,
|
||||
const std::string& passphrase,
|
||||
std::string* rsa_private_key);
|
||||
|
||||
} // namespace rsa_util
|
||||
} // namespace widevine
|
||||
|
||||
#endif // COMMON_RSA_UTIL_H_
|
||||
225
common/rsa_util_test.cc
Normal file
225
common/rsa_util_test.cc
Normal file
@@ -0,0 +1,225 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2016 Google Inc.
|
||||
//
|
||||
// This software is licensed under the terms defined in the Widevine Master
|
||||
// License Agreement. For a copy of this agreement, please contact
|
||||
// widevine-licensing@google.com.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
// Description:
|
||||
// Unit test for rsa_util RSA utilties library.
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "testing/base/public/test_utils.h"
|
||||
#include "common/rsa_test_keys.h"
|
||||
#include "common/rsa_util.h"
|
||||
|
||||
namespace widevine {
|
||||
namespace rsa_util {
|
||||
|
||||
class RsaUtilTest : public ::testing::Test {
|
||||
protected:
|
||||
RsaTestKeys test_keys_;
|
||||
};
|
||||
|
||||
TEST_F(RsaUtilTest, SerializeDeserializePrivateKey) {
|
||||
RSA* private_key;
|
||||
std::string serialized_private_key;
|
||||
// Key 1
|
||||
EXPECT_TRUE(DeserializeRsaPrivateKey(
|
||||
test_keys_.private_test_key_1_3072_bits(), &private_key));
|
||||
ASSERT_TRUE(private_key != NULL);
|
||||
EXPECT_TRUE(SerializeRsaPrivateKey(private_key, &serialized_private_key));
|
||||
EXPECT_EQ(serialized_private_key, test_keys_.private_test_key_1_3072_bits());
|
||||
EXPECT_EQ(RSA_check_key(private_key), 1);
|
||||
RSA_free(private_key);
|
||||
// Key 2
|
||||
EXPECT_TRUE(DeserializeRsaPrivateKey(
|
||||
test_keys_.private_test_key_2_2048_bits(), &private_key));
|
||||
ASSERT_TRUE(private_key != NULL);
|
||||
EXPECT_TRUE(SerializeRsaPrivateKey(private_key, &serialized_private_key));
|
||||
EXPECT_EQ(serialized_private_key, test_keys_.private_test_key_2_2048_bits());
|
||||
EXPECT_EQ(RSA_check_key(private_key), 1);
|
||||
RSA_free(private_key);
|
||||
// Key 3
|
||||
EXPECT_TRUE(DeserializeRsaPrivateKey(
|
||||
test_keys_.private_test_key_3_2048_bits(), &private_key));
|
||||
ASSERT_TRUE(private_key != NULL);
|
||||
EXPECT_TRUE(SerializeRsaPrivateKey(private_key, &serialized_private_key));
|
||||
EXPECT_EQ(serialized_private_key, test_keys_.private_test_key_3_2048_bits());
|
||||
EXPECT_EQ(RSA_check_key(private_key), 1);
|
||||
RSA_free(private_key);
|
||||
// Invalid key
|
||||
EXPECT_FALSE(DeserializeRsaPrivateKey("this is a bad key", &private_key));
|
||||
}
|
||||
|
||||
TEST_F(RsaUtilTest, SerializeDeserializePublicKey) {
|
||||
RSA* public_key;
|
||||
std::string serialized_public_key;
|
||||
// Key 1
|
||||
EXPECT_TRUE(DeserializeRsaPublicKey(
|
||||
test_keys_.public_test_key_1_3072_bits(), &public_key));
|
||||
ASSERT_TRUE(public_key != NULL);
|
||||
EXPECT_TRUE(SerializeRsaPublicKey(public_key, &serialized_public_key));
|
||||
EXPECT_EQ(serialized_public_key, test_keys_.public_test_key_1_3072_bits());
|
||||
RSA_free(public_key);
|
||||
// Key 2
|
||||
EXPECT_TRUE(DeserializeRsaPublicKey(
|
||||
test_keys_.public_test_key_2_2048_bits(), &public_key));
|
||||
ASSERT_TRUE(public_key != NULL);
|
||||
EXPECT_TRUE(SerializeRsaPublicKey(public_key, &serialized_public_key));
|
||||
EXPECT_EQ(serialized_public_key, test_keys_.public_test_key_2_2048_bits());
|
||||
RSA_free(public_key);
|
||||
// Key 3
|
||||
EXPECT_TRUE(DeserializeRsaPublicKey(
|
||||
test_keys_.public_test_key_3_2048_bits(), &public_key));
|
||||
ASSERT_TRUE(public_key != NULL);
|
||||
EXPECT_TRUE(SerializeRsaPublicKey(public_key, &serialized_public_key));
|
||||
EXPECT_EQ(serialized_public_key, test_keys_.public_test_key_3_2048_bits());
|
||||
RSA_free(public_key);
|
||||
// Invalid key
|
||||
EXPECT_FALSE(DeserializeRsaPublicKey("this is a bad key", &public_key));
|
||||
}
|
||||
|
||||
TEST_F(RsaUtilTest, PublicKeyExtraction) {
|
||||
RSA* private_key;
|
||||
std::string serialized_public_key;
|
||||
// Key 1
|
||||
EXPECT_TRUE(DeserializeRsaPrivateKey(
|
||||
test_keys_.private_test_key_1_3072_bits(), &private_key));
|
||||
ASSERT_TRUE(private_key != NULL);
|
||||
EXPECT_TRUE(SerializeRsaPublicKey(private_key, &serialized_public_key));
|
||||
EXPECT_EQ(serialized_public_key, test_keys_.public_test_key_1_3072_bits());
|
||||
RSA_free(private_key);
|
||||
// Key 2
|
||||
EXPECT_TRUE(DeserializeRsaPrivateKey(
|
||||
test_keys_.private_test_key_2_2048_bits(), &private_key));
|
||||
ASSERT_TRUE(private_key != NULL);
|
||||
EXPECT_TRUE(SerializeRsaPublicKey(private_key, &serialized_public_key));
|
||||
EXPECT_EQ(serialized_public_key, test_keys_.public_test_key_2_2048_bits());
|
||||
RSA_free(private_key);
|
||||
// Key 3
|
||||
EXPECT_TRUE(DeserializeRsaPrivateKey(
|
||||
test_keys_.private_test_key_3_2048_bits(), &private_key));
|
||||
ASSERT_TRUE(private_key != NULL);
|
||||
EXPECT_TRUE(SerializeRsaPublicKey(private_key, &serialized_public_key));
|
||||
EXPECT_EQ(serialized_public_key, test_keys_.public_test_key_3_2048_bits());
|
||||
RSA_free(private_key);
|
||||
}
|
||||
|
||||
TEST_F(RsaUtilTest, Pkcs8PrivateKeyInfo) {
|
||||
// The PKCS#1 <-> PKCS#8 conversion routines exercise all the PKCS#8
|
||||
// serialization/deserialization functionality , so we test those.
|
||||
std::string serialized_pkcs8;
|
||||
std::string serialized_pkcs1;
|
||||
// Key 1
|
||||
EXPECT_TRUE(RsaPrivateKeyToPrivateKeyInfo(
|
||||
test_keys_.private_test_key_1_3072_bits(), &serialized_pkcs8));
|
||||
EXPECT_TRUE(PrivateKeyInfoToRsaPrivateKey(serialized_pkcs8,
|
||||
&serialized_pkcs1));
|
||||
EXPECT_NE(serialized_pkcs1, serialized_pkcs8);
|
||||
EXPECT_EQ(test_keys_.private_test_key_1_3072_bits(), serialized_pkcs1);
|
||||
// Key 2
|
||||
EXPECT_TRUE(RsaPrivateKeyToPrivateKeyInfo(
|
||||
test_keys_.private_test_key_2_2048_bits(), &serialized_pkcs8));
|
||||
EXPECT_TRUE(PrivateKeyInfoToRsaPrivateKey(serialized_pkcs8,
|
||||
&serialized_pkcs1));
|
||||
EXPECT_NE(serialized_pkcs1, serialized_pkcs8);
|
||||
EXPECT_EQ(test_keys_.private_test_key_2_2048_bits(), serialized_pkcs1);
|
||||
// Key 3
|
||||
EXPECT_TRUE(RsaPrivateKeyToPrivateKeyInfo(
|
||||
test_keys_.private_test_key_3_2048_bits(), &serialized_pkcs8));
|
||||
EXPECT_TRUE(PrivateKeyInfoToRsaPrivateKey(serialized_pkcs8,
|
||||
&serialized_pkcs1));
|
||||
EXPECT_NE(serialized_pkcs1, serialized_pkcs8);
|
||||
EXPECT_EQ(test_keys_.private_test_key_3_2048_bits(), serialized_pkcs1);
|
||||
}
|
||||
|
||||
TEST_F(RsaUtilTest, Pkcs8EncryptedPrivateKeyInfo) {
|
||||
// The PKCS#1 <-> PKCS#8 conversion routines exercise all the PKCS#8
|
||||
// serialization/deserialization functionality , so we test those.
|
||||
std::string serialized_pkcs8;
|
||||
std::string serialized_pkcs1;
|
||||
std::string passphrase("passphrase");
|
||||
// Key 1
|
||||
EXPECT_TRUE(RsaPrivateKeyToEncryptedPrivateKeyInfo(
|
||||
test_keys_.private_test_key_1_3072_bits(), passphrase,
|
||||
&serialized_pkcs8));
|
||||
EXPECT_TRUE(EncryptedPrivateKeyInfoToRsaPrivateKey(serialized_pkcs8,
|
||||
passphrase,
|
||||
&serialized_pkcs1));
|
||||
EXPECT_NE(serialized_pkcs1, serialized_pkcs8);
|
||||
EXPECT_EQ(test_keys_.private_test_key_1_3072_bits(), serialized_pkcs1);
|
||||
// Key 2
|
||||
EXPECT_TRUE(RsaPrivateKeyToEncryptedPrivateKeyInfo(
|
||||
test_keys_.private_test_key_2_2048_bits(), passphrase,
|
||||
&serialized_pkcs8));
|
||||
EXPECT_TRUE(EncryptedPrivateKeyInfoToRsaPrivateKey(serialized_pkcs8,
|
||||
passphrase,
|
||||
&serialized_pkcs1));
|
||||
EXPECT_NE(serialized_pkcs1, serialized_pkcs8);
|
||||
EXPECT_EQ(test_keys_.private_test_key_2_2048_bits(), serialized_pkcs1);
|
||||
// Key 3
|
||||
EXPECT_TRUE(RsaPrivateKeyToEncryptedPrivateKeyInfo(
|
||||
test_keys_.private_test_key_3_2048_bits(), passphrase,
|
||||
&serialized_pkcs8));
|
||||
EXPECT_TRUE(EncryptedPrivateKeyInfoToRsaPrivateKey(serialized_pkcs8,
|
||||
passphrase,
|
||||
&serialized_pkcs1));
|
||||
EXPECT_NE(serialized_pkcs1, serialized_pkcs8);
|
||||
EXPECT_EQ(test_keys_.private_test_key_3_2048_bits(), serialized_pkcs1);
|
||||
}
|
||||
|
||||
TEST_F(RsaUtilTest, FailOnInvalidParams) {
|
||||
RSA* test_input_key = NULL;
|
||||
RSA* test_output_key = NULL;
|
||||
std::string test_string;
|
||||
std::string pass("password");
|
||||
ASSERT_TRUE(DeserializeRsaPrivateKey(
|
||||
test_keys_.private_test_key_2_2048_bits(), &test_input_key));
|
||||
ASSERT_TRUE(test_input_key != NULL);
|
||||
EXPECT_FALSE(SerializeRsaPrivateKey(NULL, &test_string));
|
||||
EXPECT_FALSE(SerializeRsaPrivateKey(test_input_key, NULL));
|
||||
EXPECT_FALSE(SerializeRsaPublicKey(NULL, &test_string));
|
||||
EXPECT_FALSE(SerializeRsaPublicKey(test_input_key, NULL));
|
||||
EXPECT_FALSE(SerializePrivateKeyInfo(NULL, &test_string));
|
||||
EXPECT_FALSE(SerializePrivateKeyInfo(test_input_key, NULL));
|
||||
EXPECT_FALSE(SerializeEncryptedPrivateKeyInfo(NULL, pass, &test_string));
|
||||
EXPECT_FALSE(SerializeEncryptedPrivateKeyInfo(test_input_key, pass, NULL));
|
||||
EXPECT_FALSE(DeserializeRsaPrivateKey("", &test_output_key));
|
||||
EXPECT_FALSE(DeserializeRsaPrivateKey(
|
||||
test_keys_.private_test_key_2_2048_bits(), NULL));
|
||||
EXPECT_FALSE(DeserializeRsaPublicKey("", &test_output_key));
|
||||
EXPECT_FALSE(DeserializeRsaPublicKey(
|
||||
test_keys_.public_test_key_2_2048_bits(), NULL));
|
||||
EXPECT_FALSE(DeserializePrivateKeyInfo("", &test_output_key));
|
||||
EXPECT_FALSE(DeserializePrivateKeyInfo(
|
||||
test_keys_.private_test_key_2_2048_bits(), NULL));
|
||||
EXPECT_FALSE(DeserializeEncryptedPrivateKeyInfo("", pass, &test_output_key));
|
||||
EXPECT_FALSE(DeserializeEncryptedPrivateKeyInfo(
|
||||
test_keys_.private_test_key_2_2048_bits(), pass, NULL));
|
||||
RSA_free(test_input_key);
|
||||
}
|
||||
|
||||
TEST_F(RsaUtilTest, Pkcs8FailOnInvalidPassword) {
|
||||
RSA* test_input_key = NULL;
|
||||
RSA* test_output_key = NULL;
|
||||
std::string serialized_pkcs8;
|
||||
std::string pass("password");
|
||||
ASSERT_TRUE(DeserializeRsaPrivateKey(
|
||||
test_keys_.private_test_key_2_2048_bits(), &test_input_key));
|
||||
EXPECT_FALSE(SerializeEncryptedPrivateKeyInfo(test_input_key, "",
|
||||
&serialized_pkcs8));
|
||||
ASSERT_TRUE(SerializeEncryptedPrivateKeyInfo(test_input_key, pass,
|
||||
&serialized_pkcs8));
|
||||
EXPECT_FALSE(DeserializeEncryptedPrivateKeyInfo(serialized_pkcs8, pass + "a",
|
||||
&test_output_key));
|
||||
EXPECT_TRUE(DeserializeEncryptedPrivateKeyInfo(serialized_pkcs8, pass,
|
||||
&test_output_key));
|
||||
RSA_free(test_input_key);
|
||||
RSA_free(test_output_key);
|
||||
}
|
||||
|
||||
} // namespace rsa_util
|
||||
} // namespace widevine
|
||||
29
common/sha_util.cc
Normal file
29
common/sha_util.cc
Normal file
@@ -0,0 +1,29 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2016 Google Inc.
|
||||
//
|
||||
// This software is licensed under the terms defined in the Widevine Master
|
||||
// License Agreement. For a copy of this agreement, please contact
|
||||
// widevine-licensing@google.com.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "common/sha_util.h"
|
||||
|
||||
#include "openssl/sha.h"
|
||||
|
||||
namespace widevine {
|
||||
|
||||
std::string Sha1_Hash(const std::string& message) {
|
||||
return std::string(reinterpret_cast<char*>(
|
||||
SHA1(reinterpret_cast<const uint8_t*>(message.data()),
|
||||
message.size(), nullptr)),
|
||||
SHA_DIGEST_LENGTH);
|
||||
}
|
||||
|
||||
std::string Sha256_Hash(const std::string& message) {
|
||||
return std::string(reinterpret_cast<char*>(
|
||||
SHA256(reinterpret_cast<const uint8_t*>(message.data()),
|
||||
message.size(), nullptr)),
|
||||
SHA256_DIGEST_LENGTH);
|
||||
}
|
||||
|
||||
} // namespace widevine
|
||||
24
common/sha_util.h
Normal file
24
common/sha_util.h
Normal file
@@ -0,0 +1,24 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2016 Google Inc.
|
||||
//
|
||||
// This software is licensed under the terms defined in the Widevine Master
|
||||
// License Agreement. For a copy of this agreement, please contact
|
||||
// widevine-licensing@google.com.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef COMMON_SHA_UTIL_H_
|
||||
#define COMMON_SHA_UTIL_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace widevine {
|
||||
|
||||
// Calculates SHA1 hash.
|
||||
std::string Sha1_Hash(const std::string& message);
|
||||
|
||||
// Calculates SHA256 hash.
|
||||
std::string Sha256_Hash(const std::string& message);
|
||||
|
||||
} // namespace widevine
|
||||
|
||||
#endif // COMMON_SHA_UTIL_H_
|
||||
51
common/sha_util_test.cc
Normal file
51
common/sha_util_test.cc
Normal file
@@ -0,0 +1,51 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2016 Google Inc.
|
||||
//
|
||||
// This software is licensed under the terms defined in the Widevine Master
|
||||
// License Agreement. For a copy of this agreement, please contact
|
||||
// widevine-licensing@google.com.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "common/sha_util.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace widevine {
|
||||
|
||||
TEST(ShaUtilTest, Sha1Empty) {
|
||||
const uint8_t kExpected[] = {
|
||||
0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55,
|
||||
0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09,
|
||||
};
|
||||
EXPECT_EQ(std::string(kExpected, kExpected + sizeof(kExpected)), Sha1_Hash(""));
|
||||
}
|
||||
|
||||
TEST(ShaUtilTest, Sha256Empty) {
|
||||
const uint8_t kExpected[] = {
|
||||
0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4,
|
||||
0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b,
|
||||
0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55,
|
||||
};
|
||||
EXPECT_EQ(std::string(kExpected, kExpected + sizeof(kExpected)), Sha256_Hash(""));
|
||||
}
|
||||
|
||||
TEST(ShaUtilTest, Sha1) {
|
||||
const uint8_t kExpected[] = {
|
||||
0x5f, 0xfd, 0x3b, 0x85, 0x2c, 0xcd, 0xd4, 0x48, 0x80, 0x9a,
|
||||
0xbb, 0x17, 0x2e, 0x19, 0xbb, 0xb9, 0xc0, 0x1a, 0x43, 0xa4,
|
||||
};
|
||||
EXPECT_EQ(std::string(kExpected, kExpected + sizeof(kExpected)),
|
||||
Sha1_Hash("random std::string"));
|
||||
}
|
||||
|
||||
TEST(ShaUtilTest, Sha256) {
|
||||
const uint8_t kExpected[] = {
|
||||
0xa8, 0x2a, 0xf4, 0xe9, 0x6b, 0x5b, 0x8d, 0x82, 0x5a, 0x69, 0x10,
|
||||
0xb9, 0x08, 0xec, 0xcd, 0xc4, 0x40, 0x1a, 0xf1, 0xe6, 0x63, 0xdb,
|
||||
0x5e, 0xdf, 0x2d, 0x7d, 0xfb, 0x71, 0x2d, 0xb9, 0x65, 0x29,
|
||||
};
|
||||
EXPECT_EQ(std::string(kExpected, kExpected + sizeof(kExpected)),
|
||||
Sha256_Hash("random std::string"));
|
||||
}
|
||||
|
||||
} // namespace widevine
|
||||
Reference in New Issue
Block a user