[email protected] | 77b10182 | 2012-03-29 01:11:24 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | cdf8c57 | 2010-08-04 23:04:05 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
[email protected] | 8f1504b | 2013-03-07 13:43:10 | [diff] [blame] | 5 | #include "remoting/base/rsa_key_pair.h" |
[email protected] | cdf8c57 | 2010-08-04 23:04:05 | [diff] [blame] | 6 | |
[email protected] | 0950792 | 2011-02-04 02:16:49 | [diff] [blame] | 7 | #include <limits> |
[email protected] | cdf8c57 | 2010-08-04 23:04:05 | [diff] [blame] | 8 | #include <string> |
| 9 | #include <vector> |
| 10 | |
| 11 | #include "base/base64.h" |
[email protected] | cdf8c57 | 2010-08-04 23:04:05 | [diff] [blame] | 12 | #include "base/logging.h" |
[email protected] | 0950792 | 2011-02-04 02:16:49 | [diff] [blame] | 13 | #include "base/rand_util.h" |
[email protected] | 5d7eb86 | 2013-06-28 15:21:24 | [diff] [blame] | 14 | #include "base/time/time.h" |
[email protected] | 4b559b4d | 2011-04-14 17:37:14 | [diff] [blame] | 15 | #include "crypto/rsa_private_key.h" |
| 16 | #include "crypto/signature_creator.h" |
[email protected] | 5123d9c | 2013-06-27 09:18:43 | [diff] [blame] | 17 | #include "net/cert/x509_util.h" |
[email protected] | cdf8c57 | 2010-08-04 23:04:05 | [diff] [blame] | 18 | |
| 19 | namespace remoting { |
| 20 | |
[email protected] | 8f1504b | 2013-03-07 13:43:10 | [diff] [blame] | 21 | RsaKeyPair::RsaKeyPair(scoped_ptr<crypto::RSAPrivateKey> key) |
| 22 | : key_(key.Pass()){ |
| 23 | DCHECK(key_); |
[email protected] | cdf8c57 | 2010-08-04 23:04:05 | [diff] [blame] | 24 | } |
| 25 | |
[email protected] | 8f1504b | 2013-03-07 13:43:10 | [diff] [blame] | 26 | RsaKeyPair::~RsaKeyPair() {} |
| 27 | |
ajose | 1e515a6 | 2015-07-28 23:42:27 | [diff] [blame] | 28 | // static |
[email protected] | 8f1504b | 2013-03-07 13:43:10 | [diff] [blame] | 29 | scoped_refptr<RsaKeyPair> RsaKeyPair::Generate() { |
| 30 | scoped_ptr<crypto::RSAPrivateKey> key(crypto::RSAPrivateKey::Create(2048)); |
| 31 | if (!key) { |
| 32 | LOG(ERROR) << "Cannot generate private key."; |
| 33 | return NULL; |
| 34 | } |
| 35 | return new RsaKeyPair(key.Pass()); |
| 36 | } |
| 37 | |
ajose | 1e515a6 | 2015-07-28 23:42:27 | [diff] [blame] | 38 | // static |
[email protected] | 8f1504b | 2013-03-07 13:43:10 | [diff] [blame] | 39 | scoped_refptr<RsaKeyPair> RsaKeyPair::FromString( |
| 40 | const std::string& key_base64) { |
[email protected] | cdf8c57 | 2010-08-04 23:04:05 | [diff] [blame] | 41 | std::string key_str; |
| 42 | if (!base::Base64Decode(key_base64, &key_str)) { |
| 43 | LOG(ERROR) << "Failed to decode private key."; |
[email protected] | 8f1504b | 2013-03-07 13:43:10 | [diff] [blame] | 44 | return NULL; |
[email protected] | cdf8c57 | 2010-08-04 23:04:05 | [diff] [blame] | 45 | } |
| 46 | |
| 47 | std::vector<uint8> key_buf(key_str.begin(), key_str.end()); |
[email protected] | 8f1504b | 2013-03-07 13:43:10 | [diff] [blame] | 48 | scoped_ptr<crypto::RSAPrivateKey> key( |
| 49 | crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_buf)); |
| 50 | if (!key) { |
[email protected] | cdf8c57 | 2010-08-04 23:04:05 | [diff] [blame] | 51 | LOG(ERROR) << "Invalid private key."; |
[email protected] | 8f1504b | 2013-03-07 13:43:10 | [diff] [blame] | 52 | return NULL; |
[email protected] | cdf8c57 | 2010-08-04 23:04:05 | [diff] [blame] | 53 | } |
| 54 | |
[email protected] | 8f1504b | 2013-03-07 13:43:10 | [diff] [blame] | 55 | return new RsaKeyPair(key.Pass()); |
[email protected] | cdf8c57 | 2010-08-04 23:04:05 | [diff] [blame] | 56 | } |
| 57 | |
[email protected] | 8f1504b | 2013-03-07 13:43:10 | [diff] [blame] | 58 | std::string RsaKeyPair::ToString() const { |
[email protected] | cdf8c57 | 2010-08-04 23:04:05 | [diff] [blame] | 59 | // Check that the key initialized. |
| 60 | DCHECK(key_.get() != NULL); |
| 61 | |
[email protected] | cdf8c57 | 2010-08-04 23:04:05 | [diff] [blame] | 62 | std::vector<uint8> key_buf; |
[email protected] | 8f1504b | 2013-03-07 13:43:10 | [diff] [blame] | 63 | CHECK(key_->ExportPrivateKey(&key_buf)); |
[email protected] | cdf8c57 | 2010-08-04 23:04:05 | [diff] [blame] | 64 | std::string key_str(key_buf.begin(), key_buf.end()); |
| 65 | std::string key_base64; |
[email protected] | 33fca12 | 2013-12-11 01:48:50 | [diff] [blame] | 66 | base::Base64Encode(key_str, &key_base64); |
[email protected] | 77b10182 | 2012-03-29 01:11:24 | [diff] [blame] | 67 | return key_base64; |
[email protected] | cdf8c57 | 2010-08-04 23:04:05 | [diff] [blame] | 68 | } |
| 69 | |
[email protected] | 8f1504b | 2013-03-07 13:43:10 | [diff] [blame] | 70 | std::string RsaKeyPair::GetPublicKey() const { |
[email protected] | cdf8c57 | 2010-08-04 23:04:05 | [diff] [blame] | 71 | std::vector<uint8> public_key; |
[email protected] | 8f1504b | 2013-03-07 13:43:10 | [diff] [blame] | 72 | CHECK(key_->ExportPublicKey(&public_key)); |
[email protected] | cdf8c57 | 2010-08-04 23:04:05 | [diff] [blame] | 73 | std::string public_key_str(public_key.begin(), public_key.end()); |
| 74 | std::string public_key_base64; |
| 75 | base::Base64Encode(public_key_str, &public_key_base64); |
| 76 | return public_key_base64; |
| 77 | } |
| 78 | |
[email protected] | 8f1504b | 2013-03-07 13:43:10 | [diff] [blame] | 79 | std::string RsaKeyPair::SignMessage(const std::string& message) const { |
[email protected] | 4b559b4d | 2011-04-14 17:37:14 | [diff] [blame] | 80 | scoped_ptr<crypto::SignatureCreator> signature_creator( |
dougsteed | 0cf460ec | 2014-09-19 18:46:09 | [diff] [blame] | 81 | crypto::SignatureCreator::Create(key_.get(), |
| 82 | crypto::SignatureCreator::SHA1)); |
[email protected] | cdf8c57 | 2010-08-04 23:04:05 | [diff] [blame] | 83 | signature_creator->Update(reinterpret_cast<const uint8*>(message.c_str()), |
| 84 | message.length()); |
| 85 | std::vector<uint8> signature_buf; |
| 86 | signature_creator->Final(&signature_buf); |
| 87 | std::string signature_str(signature_buf.begin(), signature_buf.end()); |
| 88 | std::string signature_base64; |
| 89 | base::Base64Encode(signature_str, &signature_base64); |
| 90 | return signature_base64; |
| 91 | } |
| 92 | |
[email protected] | 8f1504b | 2013-03-07 13:43:10 | [diff] [blame] | 93 | std::string RsaKeyPair::GenerateCertificate() const { |
[email protected] | 5123d9c | 2013-06-27 09:18:43 | [diff] [blame] | 94 | std::string der_cert; |
[email protected] | d99b2fb4 | 2013-11-01 05:14:29 | [diff] [blame] | 95 | // Certificates are SHA1-signed because |key_| has likely been used to sign |
| 96 | // with SHA1 previously, and you should not re-use a key for signing data with |
| 97 | // multiple signature algorithms. |
[email protected] | 5123d9c | 2013-06-27 09:18:43 | [diff] [blame] | 98 | net::x509_util::CreateSelfSignedCert( |
| 99 | key_.get(), |
[email protected] | d99b2fb4 | 2013-11-01 05:14:29 | [diff] [blame] | 100 | net::x509_util::DIGEST_SHA1, |
[email protected] | 5123d9c | 2013-06-27 09:18:43 | [diff] [blame] | 101 | "CN=chromoting", |
| 102 | base::RandInt(1, std::numeric_limits<int>::max()), |
| 103 | base::Time::Now(), |
| 104 | base::Time::Now() + base::TimeDelta::FromDays(1), |
| 105 | &der_cert); |
| 106 | return der_cert; |
[email protected] | 0950792 | 2011-02-04 02:16:49 | [diff] [blame] | 107 | } |
| 108 | |
[email protected] | cdf8c57 | 2010-08-04 23:04:05 | [diff] [blame] | 109 | } // namespace remoting |