blob: 366d93dea3d3da46039758ae0aed7970c475e6d2 [file] [log] [blame]
[email protected]77b101822012-03-29 01:11:241// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]cdf8c572010-08-04 23:04:052// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]8f1504b2013-03-07 13:43:105#include "remoting/base/rsa_key_pair.h"
[email protected]cdf8c572010-08-04 23:04:056
[email protected]09507922011-02-04 02:16:497#include <limits>
[email protected]cdf8c572010-08-04 23:04:058#include <string>
9#include <vector>
10
11#include "base/base64.h"
[email protected]cdf8c572010-08-04 23:04:0512#include "base/logging.h"
[email protected]09507922011-02-04 02:16:4913#include "base/rand_util.h"
[email protected]5d7eb862013-06-28 15:21:2414#include "base/time/time.h"
[email protected]4b559b4d2011-04-14 17:37:1415#include "crypto/rsa_private_key.h"
16#include "crypto/signature_creator.h"
[email protected]5123d9c2013-06-27 09:18:4317#include "net/cert/x509_util.h"
[email protected]cdf8c572010-08-04 23:04:0518
19namespace remoting {
20
[email protected]8f1504b2013-03-07 13:43:1021RsaKeyPair::RsaKeyPair(scoped_ptr<crypto::RSAPrivateKey> key)
22 : key_(key.Pass()){
23 DCHECK(key_);
[email protected]cdf8c572010-08-04 23:04:0524}
25
[email protected]8f1504b2013-03-07 13:43:1026RsaKeyPair::~RsaKeyPair() {}
27
ajose1e515a62015-07-28 23:42:2728// static
[email protected]8f1504b2013-03-07 13:43:1029scoped_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
ajose1e515a62015-07-28 23:42:2738// static
[email protected]8f1504b2013-03-07 13:43:1039scoped_refptr<RsaKeyPair> RsaKeyPair::FromString(
40 const std::string& key_base64) {
[email protected]cdf8c572010-08-04 23:04:0541 std::string key_str;
42 if (!base::Base64Decode(key_base64, &key_str)) {
43 LOG(ERROR) << "Failed to decode private key.";
[email protected]8f1504b2013-03-07 13:43:1044 return NULL;
[email protected]cdf8c572010-08-04 23:04:0545 }
46
47 std::vector<uint8> key_buf(key_str.begin(), key_str.end());
[email protected]8f1504b2013-03-07 13:43:1048 scoped_ptr<crypto::RSAPrivateKey> key(
49 crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_buf));
50 if (!key) {
[email protected]cdf8c572010-08-04 23:04:0551 LOG(ERROR) << "Invalid private key.";
[email protected]8f1504b2013-03-07 13:43:1052 return NULL;
[email protected]cdf8c572010-08-04 23:04:0553 }
54
[email protected]8f1504b2013-03-07 13:43:1055 return new RsaKeyPair(key.Pass());
[email protected]cdf8c572010-08-04 23:04:0556}
57
[email protected]8f1504b2013-03-07 13:43:1058std::string RsaKeyPair::ToString() const {
[email protected]cdf8c572010-08-04 23:04:0559 // Check that the key initialized.
60 DCHECK(key_.get() != NULL);
61
[email protected]cdf8c572010-08-04 23:04:0562 std::vector<uint8> key_buf;
[email protected]8f1504b2013-03-07 13:43:1063 CHECK(key_->ExportPrivateKey(&key_buf));
[email protected]cdf8c572010-08-04 23:04:0564 std::string key_str(key_buf.begin(), key_buf.end());
65 std::string key_base64;
[email protected]33fca122013-12-11 01:48:5066 base::Base64Encode(key_str, &key_base64);
[email protected]77b101822012-03-29 01:11:2467 return key_base64;
[email protected]cdf8c572010-08-04 23:04:0568}
69
[email protected]8f1504b2013-03-07 13:43:1070std::string RsaKeyPair::GetPublicKey() const {
[email protected]cdf8c572010-08-04 23:04:0571 std::vector<uint8> public_key;
[email protected]8f1504b2013-03-07 13:43:1072 CHECK(key_->ExportPublicKey(&public_key));
[email protected]cdf8c572010-08-04 23:04:0573 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]8f1504b2013-03-07 13:43:1079std::string RsaKeyPair::SignMessage(const std::string& message) const {
[email protected]4b559b4d2011-04-14 17:37:1480 scoped_ptr<crypto::SignatureCreator> signature_creator(
dougsteed0cf460ec2014-09-19 18:46:0981 crypto::SignatureCreator::Create(key_.get(),
82 crypto::SignatureCreator::SHA1));
[email protected]cdf8c572010-08-04 23:04:0583 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]8f1504b2013-03-07 13:43:1093std::string RsaKeyPair::GenerateCertificate() const {
[email protected]5123d9c2013-06-27 09:18:4394 std::string der_cert;
[email protected]d99b2fb42013-11-01 05:14:2995 // 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]5123d9c2013-06-27 09:18:4398 net::x509_util::CreateSelfSignedCert(
99 key_.get(),
[email protected]d99b2fb42013-11-01 05:14:29100 net::x509_util::DIGEST_SHA1,
[email protected]5123d9c2013-06-27 09:18:43101 "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]09507922011-02-04 02:16:49107}
108
[email protected]cdf8c572010-08-04 23:04:05109} // namespace remoting