-
Notifications
You must be signed in to change notification settings - Fork 57
/
Copy pathssl_certificate.cc
123 lines (101 loc) · 4.63 KB
/
ssl_certificate.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "rtc_base/ssl_certificate.h"
#include <string>
#include <utility>
#include "absl/algorithm/container.h"
#include "absl/memory/memory.h"
#include "rtc_base/checks.h"
#include "rtc_base/openssl_certificate.h"
#include "rtc_base/ssl_fingerprint.h"
#include "rtc_base/third_party/base64/base64.h"
namespace rtc {
//////////////////////////////////////////////////////////////////////
// SSLCertificateStats
//////////////////////////////////////////////////////////////////////
SSLCertificateStats::SSLCertificateStats(
std::string&& fingerprint,
std::string&& fingerprint_algorithm,
std::string&& base64_certificate,
std::unique_ptr<SSLCertificateStats> issuer)
: fingerprint(std::move(fingerprint)),
fingerprint_algorithm(std::move(fingerprint_algorithm)),
base64_certificate(std::move(base64_certificate)),
issuer(std::move(issuer)) {}
SSLCertificateStats::~SSLCertificateStats() {}
//////////////////////////////////////////////////////////////////////
// SSLCertificate
//////////////////////////////////////////////////////////////////////
std::unique_ptr<SSLCertificateStats> SSLCertificate::GetStats() const {
// TODO(bemasc): Move this computation to a helper class that caches these
// values to reduce CPU use in |StatsCollector::GetStats|. This will require
// adding a fast |SSLCertificate::Equals| to detect certificate changes.
std::string digest_algorithm;
if (!GetSignatureDigestAlgorithm(&digest_algorithm))
return nullptr;
// |SSLFingerprint::Create| can fail if the algorithm returned by
// |SSLCertificate::GetSignatureDigestAlgorithm| is not supported by the
// implementation of |SSLCertificate::ComputeDigest|. This currently happens
// with MD5- and SHA-224-signed certificates when linked to libNSS.
std::unique_ptr<SSLFingerprint> ssl_fingerprint =
SSLFingerprint::Create(digest_algorithm, *this);
if (!ssl_fingerprint)
return nullptr;
std::string fingerprint = ssl_fingerprint->GetRfc4572Fingerprint();
Buffer der_buffer;
ToDER(&der_buffer);
std::string der_base64;
Base64::EncodeFromArray(der_buffer.data(), der_buffer.size(), &der_base64);
return absl::make_unique<SSLCertificateStats>(std::move(fingerprint),
std::move(digest_algorithm),
std::move(der_base64), nullptr);
}
//////////////////////////////////////////////////////////////////////
// SSLCertChain
//////////////////////////////////////////////////////////////////////
SSLCertChain::SSLCertChain(std::unique_ptr<SSLCertificate> single_cert) {
certs_.push_back(std::move(single_cert));
}
SSLCertChain::SSLCertChain(std::vector<std::unique_ptr<SSLCertificate>> certs)
: certs_(std::move(certs)) {}
SSLCertChain::SSLCertChain(SSLCertChain&& rhs) = default;
SSLCertChain& SSLCertChain::operator=(SSLCertChain&&) = default;
SSLCertChain::~SSLCertChain() = default;
std::unique_ptr<SSLCertChain> SSLCertChain::Clone() const {
std::vector<std::unique_ptr<SSLCertificate>> new_certs(certs_.size());
absl::c_transform(
certs_, new_certs.begin(),
[](const std::unique_ptr<SSLCertificate>& cert)
-> std::unique_ptr<SSLCertificate> { return cert->Clone(); });
return absl::make_unique<SSLCertChain>(std::move(new_certs));
}
std::unique_ptr<SSLCertificateStats> SSLCertChain::GetStats() const {
// We have a linked list of certificates, starting with the first element of
// |certs_| and ending with the last element of |certs_|. The "issuer" of a
// certificate is the next certificate in the chain. Stats are produced for
// each certificate in the list. Here, the "issuer" is the issuer's stats.
std::unique_ptr<SSLCertificateStats> issuer;
// The loop runs in reverse so that the |issuer| is known before the
// certificate issued by |issuer|.
for (ptrdiff_t i = certs_.size() - 1; i >= 0; --i) {
std::unique_ptr<SSLCertificateStats> new_stats = certs_[i]->GetStats();
if (new_stats) {
new_stats->issuer = std::move(issuer);
}
issuer = std::move(new_stats);
}
return issuer;
}
// static
std::unique_ptr<SSLCertificate> SSLCertificate::FromPEMString(
const std::string& pem_string) {
return OpenSSLCertificate::FromPEMString(pem_string);
}
} // namespace rtc