Export provisioning sdk

Change-Id: I4d47d80444c9507f84896767dc676112ca11e901
This commit is contained in:
Kongqun Yang
2017-01-24 20:06:25 -08:00
parent d2903a4951
commit 8d17e4549a
110 changed files with 10187 additions and 0 deletions

164
common/BUILD Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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_

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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