74 lines
2.3 KiB
C++
74 lines
2.3 KiB
C++
////////////////////////////////////////////////////////////////////////////////
|
|
// Copyright 2013 Google LLC.
|
|
//
|
|
// 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/test_utils.h"
|
|
|
|
#include <stddef.h>
|
|
#include <memory>
|
|
|
|
#include "glog/logging.h"
|
|
#include "openssl/pem.h"
|
|
#include "openssl/rsa.h"
|
|
#include "openssl/sha.h"
|
|
|
|
namespace widevine {
|
|
|
|
util::Status GenerateRsaSignatureSha256Pkcs1(const std::string& pem_private_key,
|
|
const std::string& message,
|
|
std::string* signature) {
|
|
CHECK(signature);
|
|
if (pem_private_key.empty()) {
|
|
return util::Status(util::error::INVALID_ARGUMENT, "Empty PEM private key");
|
|
}
|
|
if (message.empty()) {
|
|
return util::Status(util::error::INVALID_ARGUMENT, "Empty message");
|
|
}
|
|
BIO* bio(NULL);
|
|
bio = BIO_new_mem_buf(const_cast<char*>(pem_private_key.data()),
|
|
pem_private_key.size());
|
|
if (bio == NULL) {
|
|
return util::Status(util::error::INTERNAL, "BIO allocation failed");
|
|
}
|
|
util::Status status;
|
|
RSA* key(NULL);
|
|
std::unique_ptr<char[]> sig_buffer;
|
|
unsigned int sig_size;
|
|
unsigned char digest[SHA256_DIGEST_LENGTH];
|
|
key = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL);
|
|
if (key == NULL) {
|
|
status = util::Status(util::Status::canonical_space(),
|
|
util::error::INVALID_ARGUMENT,
|
|
"PEM RSA private key load failed");
|
|
goto cleanup;
|
|
}
|
|
SHA256(reinterpret_cast<const unsigned char*>(message.data()), message.size(),
|
|
digest);
|
|
sig_size = RSA_size(key);
|
|
sig_buffer.reset(new char[sig_size]);
|
|
if (RSA_sign(NID_sha256, digest, sizeof(digest),
|
|
reinterpret_cast<unsigned char*>(sig_buffer.get()), &sig_size,
|
|
key) != 1) {
|
|
status =
|
|
util::Status(util::Status::canonical_space(), util::error::INTERNAL,
|
|
"RSA private encrypt failed");
|
|
goto cleanup;
|
|
}
|
|
signature->assign(sig_buffer.get(), sig_size);
|
|
|
|
cleanup:
|
|
if (key != NULL) {
|
|
RSA_free(key);
|
|
}
|
|
if (bio != NULL) {
|
|
BIO_free(bio);
|
|
}
|
|
return status;
|
|
}
|
|
|
|
} // namespace widevine
|