DASH Media Packaging SDK
 All Classes Namespaces Functions Variables Typedefs Enumerator
rsa_key.cc
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 //
7 // RSA signature details:
8 // Algorithm: RSASSA-PSS
9 // Hash algorithm: SHA1
10 // Mask generation function: mgf1SHA1
11 // Salt length: 20 bytes
12 // Trailer field: 0xbc
13 //
14 // RSA encryption details:
15 // Algorithm: RSA-OAEP
16 // Mask generation function: mgf1SHA1
17 // Label (encoding paramter): empty std::string
18 
19 #include "packager/media/base/rsa_key.h"
20 
21 #include <openssl/err.h>
22 #include <openssl/rsa.h>
23 #include <openssl/x509.h>
24 #include <vector>
25 
26 #include "packager/base/logging.h"
27 #include "packager/base/sha1.h"
28 #include "packager/base/stl_util.h"
29 
30 namespace {
31 
32 const size_t kPssSaltLength = 20u;
33 
34 // Serialize rsa key from DER encoded PKCS#1 RSAPrivateKey.
35 RSA* DeserializeRsaKey(const std::string& serialized_key,
36  bool deserialize_private_key) {
37  if (serialized_key.empty()) {
38  LOG(ERROR) << "Serialized RSA Key is empty.";
39  return NULL;
40  }
41 
42  BIO* bio = BIO_new_mem_buf(const_cast<char*>(serialized_key.data()),
43  serialized_key.size());
44  if (bio == NULL) {
45  LOG(ERROR) << "BIO_new_mem_buf returned NULL.";
46  return NULL;
47  }
48  RSA* rsa_key = deserialize_private_key ? d2i_RSAPrivateKey_bio(bio, NULL)
49  : d2i_RSAPublicKey_bio(bio, NULL);
50  BIO_free(bio);
51  return rsa_key;
52 }
53 
54 RSA* DeserializeRsaPrivateKey(const std::string& serialized_key) {
55  RSA* rsa_key = DeserializeRsaKey(serialized_key, true);
56  if (!rsa_key) {
57  LOG(ERROR) << "Private RSA key deserialization failure.";
58  return NULL;
59  }
60  if (RSA_check_key(rsa_key) != 1) {
61  LOG(ERROR) << "Invalid RSA Private key: " << ERR_error_string(
62  ERR_get_error(), NULL);
63  RSA_free(rsa_key);
64  return NULL;
65  }
66  return rsa_key;
67 }
68 
69 RSA* DeserializeRsaPublicKey(const std::string& serialized_key) {
70  RSA* rsa_key = DeserializeRsaKey(serialized_key, false);
71  if (!rsa_key) {
72  LOG(ERROR) << "Private RSA key deserialization failure.";
73  return NULL;
74  }
75  if (RSA_size(rsa_key) <= 0) {
76  LOG(ERROR) << "Invalid RSA Public key: " << ERR_error_string(
77  ERR_get_error(), NULL);
78  RSA_free(rsa_key);
79  return NULL;
80  }
81  return rsa_key;
82 }
83 
84 } // namespace
85 
86 namespace edash_packager {
87 namespace media {
88 
89 RsaPrivateKey::RsaPrivateKey(RSA* rsa_key) : rsa_key_(rsa_key) {
90  DCHECK(rsa_key);
91 }
92 RsaPrivateKey::~RsaPrivateKey() {
93  if (rsa_key_ != NULL)
94  RSA_free(rsa_key_);
95 }
96 
97 RsaPrivateKey* RsaPrivateKey::Create(const std::string& serialized_key) {
98  RSA* rsa_key = DeserializeRsaPrivateKey(serialized_key);
99  return rsa_key == NULL ? NULL : new RsaPrivateKey(rsa_key);
100 }
101 
102 bool RsaPrivateKey::Decrypt(const std::string& encrypted_message,
103  std::string* decrypted_message) {
104  DCHECK(decrypted_message);
105 
106  size_t rsa_size = RSA_size(rsa_key_);
107  if (encrypted_message.size() != rsa_size) {
108  LOG(ERROR) << "Encrypted RSA message has the wrong size (expected "
109  << rsa_size << ", actual " << encrypted_message.size() << ").";
110  return false;
111  }
112 
113  decrypted_message->resize(rsa_size);
114  int decrypted_size = RSA_private_decrypt(
115  rsa_size,
116  reinterpret_cast<const uint8_t*>(encrypted_message.data()),
117  reinterpret_cast<uint8_t*>(string_as_array(decrypted_message)),
118  rsa_key_,
119  RSA_PKCS1_OAEP_PADDING);
120 
121  if (decrypted_size == -1) {
122  LOG(ERROR) << "RSA private decrypt failure: " << ERR_error_string(
123  ERR_get_error(), NULL);
124  return false;
125  }
126  decrypted_message->resize(decrypted_size);
127  return true;
128 }
129 
130 bool RsaPrivateKey::GenerateSignature(const std::string& message,
131  std::string* signature) {
132  DCHECK(signature);
133  if (message.empty()) {
134  LOG(ERROR) << "Message to be signed is empty.";
135  return false;
136  }
137 
138  std::string message_digest = base::SHA1HashString(message);
139 
140  // Add PSS padding.
141  size_t rsa_size = RSA_size(rsa_key_);
142  std::vector<uint8_t> padded_digest(rsa_size);
143  if (!RSA_padding_add_PKCS1_PSS_mgf1(
144  rsa_key_,
145  &padded_digest[0],
146  reinterpret_cast<uint8_t*>(string_as_array(&message_digest)),
147  EVP_sha1(),
148  EVP_sha1(),
149  kPssSaltLength)) {
150  LOG(ERROR) << "RSA padding failure: " << ERR_error_string(ERR_get_error(),
151  NULL);
152  return false;
153  }
154 
155  // Encrypt PSS padded digest.
156  signature->resize(rsa_size);
157  int signature_size = RSA_private_encrypt(
158  padded_digest.size(),
159  &padded_digest[0],
160  reinterpret_cast<uint8_t*>(string_as_array(signature)),
161  rsa_key_,
162  RSA_NO_PADDING);
163 
164  if (signature_size != static_cast<int>(rsa_size)) {
165  LOG(ERROR) << "RSA private encrypt failure: " << ERR_error_string(
166  ERR_get_error(), NULL);
167  return false;
168  }
169  return true;
170 }
171 
172 RsaPublicKey::RsaPublicKey(RSA* rsa_key) : rsa_key_(rsa_key) {
173  DCHECK(rsa_key);
174 }
175 RsaPublicKey::~RsaPublicKey() {
176  if (rsa_key_ != NULL)
177  RSA_free(rsa_key_);
178 }
179 
180 RsaPublicKey* RsaPublicKey::Create(const std::string& serialized_key) {
181  RSA* rsa_key = DeserializeRsaPublicKey(serialized_key);
182  return rsa_key == NULL ? NULL : new RsaPublicKey(rsa_key);
183 }
184 
185 bool RsaPublicKey::Encrypt(const std::string& clear_message,
186  std::string* encrypted_message) {
187  DCHECK(encrypted_message);
188  if (clear_message.empty()) {
189  LOG(ERROR) << "Message to be encrypted is empty.";
190  return false;
191  }
192 
193  size_t rsa_size = RSA_size(rsa_key_);
194  encrypted_message->resize(rsa_size);
195  int encrypted_size = RSA_public_encrypt(
196  clear_message.size(),
197  reinterpret_cast<const uint8_t*>(clear_message.data()),
198  reinterpret_cast<uint8_t*>(string_as_array(encrypted_message)),
199  rsa_key_,
200  RSA_PKCS1_OAEP_PADDING);
201 
202  if (encrypted_size != static_cast<int>(rsa_size)) {
203  LOG(ERROR) << "RSA public encrypt failure: " << ERR_error_string(
204  ERR_get_error(), NULL);
205  return false;
206  }
207  return true;
208 }
209 
210 bool RsaPublicKey::VerifySignature(const std::string& message,
211  const std::string& signature) {
212  if (message.empty()) {
213  LOG(ERROR) << "Signed message is empty.";
214  return false;
215  }
216 
217  size_t rsa_size = RSA_size(rsa_key_);
218  if (signature.size() != rsa_size) {
219  LOG(ERROR) << "Message signature is of the wrong size (expected "
220  << rsa_size << ", actual " << signature.size() << ").";
221  return false;
222  }
223 
224  // Decrypt the signature.
225  std::vector<uint8_t> padded_digest(signature.size());
226  int decrypted_size =
227  RSA_public_decrypt(signature.size(),
228  reinterpret_cast<const uint8_t*>(signature.data()),
229  &padded_digest[0],
230  rsa_key_,
231  RSA_NO_PADDING);
232 
233  if (decrypted_size != static_cast<int>(rsa_size)) {
234  LOG(ERROR) << "RSA public decrypt failure: " << ERR_error_string(
235  ERR_get_error(), NULL);
236  return false;
237  }
238 
239  std::string message_digest = base::SHA1HashString(message);
240 
241  // Verify PSS padding.
242  return RSA_verify_PKCS1_PSS_mgf1(
243  rsa_key_,
244  reinterpret_cast<const uint8_t*>(message_digest.data()),
245  EVP_sha1(),
246  EVP_sha1(),
247  &padded_digest[0],
248  kPssSaltLength) != 0;
249 }
250 
251 } // namespace media
252 } // namespace edash_packager
bool Decrypt(const std::string &encrypted_message, std::string *decrypted_message)
Definition: rsa_key.cc:102
bool GenerateSignature(const std::string &message, std::string *signature)
Definition: rsa_key.cc:130
static RsaPrivateKey * Create(const std::string &serialized_key)
Definition: rsa_key.cc:97
static RsaPublicKey * Create(const std::string &serialized_key)
Definition: rsa_key.cc:180
bool VerifySignature(const std::string &message, const std::string &signature)
Definition: rsa_key.cc:210
bool Encrypt(const std::string &clear_message, std::string *encrypted_message)
Definition: rsa_key.cc:185
Rsa public key, used for signature verification and encryption.
Definition: rsa_key.h:53
Rsa private key, used for message signing and decryption.
Definition: rsa_key.h:24