Use unique_ptr in SSLCertChain.

In particular, this allows us to have a
SSLCertChain(std::vector<std::unique_ptr<SSLCertificate>>) constructor
that avoids making a copy.

Bug: webrtc:8289
Change-Id: If353ad886a73aecff98b2939db15c40ada6b4474
Reviewed-on: https://webrtc-review.googlesource.com/4361
Commit-Queue: David Benjamin <davidben@webrtc.org>
Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#20093}
This commit is contained in:
David Benjamin 2017-09-29 12:27:18 -04:00 committed by Commit Bot
parent 9c37537a72
commit 3df76b1df1
3 changed files with 38 additions and 24 deletions

View File

@ -17,6 +17,7 @@
#include "rtc_base/checks.h"
#include "rtc_base/messagedigest.h"
#include "rtc_base/ptr_util.h"
#include "rtc_base/sslidentity.h"
namespace rtc {
@ -72,16 +73,14 @@ class FakeSSLCertificate : public rtc::SSLCertificate {
std::unique_ptr<SSLCertChain> GetChain() const override {
if (certs_.empty())
return nullptr;
std::vector<SSLCertificate*> new_certs(certs_.size());
std::vector<std::unique_ptr<SSLCertificate>> new_certs(certs_.size());
std::transform(certs_.begin(), certs_.end(), new_certs.begin(), DupCert);
std::unique_ptr<SSLCertChain> chain(new SSLCertChain(new_certs));
std::for_each(new_certs.begin(), new_certs.end(), DeleteCert);
return chain;
return MakeUnique<SSLCertChain>(std::move(new_certs));
}
private:
static FakeSSLCertificate* DupCert(FakeSSLCertificate cert) {
return cert.GetReference();
static std::unique_ptr<SSLCertificate> DupCert(FakeSSLCertificate cert) {
return cert.GetUniqueReference();
}
static void DeleteCert(SSLCertificate* cert) { delete cert; }
std::string data_;

View File

@ -13,11 +13,13 @@
#include <ctime>
#include <string>
#include <utility>
#include "rtc_base/base64.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/opensslidentity.h"
#include "rtc_base/ptr_util.h"
#include "rtc_base/sslfingerprint.h"
namespace rtc {
@ -59,6 +61,10 @@ std::unique_ptr<SSLCertificateStats> SSLCertificate::GetStats() const {
return GetStats(std::move(issuer));
}
std::unique_ptr<SSLCertificate> SSLCertificate::GetUniqueReference() const {
return WrapUnique(GetReference());
}
std::unique_ptr<SSLCertificateStats> SSLCertificate::GetStats(
std::unique_ptr<SSLCertificateStats> issuer) const {
// TODO(bemasc): Move this computation to a helper class that caches these
@ -193,18 +199,33 @@ std::string SSLIdentity::DerToPem(const std::string& pem_type,
return result.str();
}
SSLCertChain::SSLCertChain(std::vector<std::unique_ptr<SSLCertificate>> certs)
: certs_(std::move(certs)) {}
SSLCertChain::SSLCertChain(const std::vector<SSLCertificate*>& certs) {
RTC_DCHECK(!certs.empty());
certs_.resize(certs.size());
std::transform(certs.begin(), certs.end(), certs_.begin(), DupCert);
std::transform(
certs.begin(), certs.end(), certs_.begin(),
[](const SSLCertificate* cert) -> std::unique_ptr<SSLCertificate> {
return cert->GetUniqueReference();
});
}
SSLCertChain::SSLCertChain(const SSLCertificate* cert) {
certs_.push_back(cert->GetReference());
certs_.push_back(cert->GetUniqueReference());
}
SSLCertChain::~SSLCertChain() {
std::for_each(certs_.begin(), certs_.end(), DeleteCert);
SSLCertChain::~SSLCertChain() {}
SSLCertChain* SSLCertChain::Copy() const {
std::vector<std::unique_ptr<SSLCertificate>> new_certs(certs_.size());
std::transform(certs_.begin(), certs_.end(), new_certs.begin(),
[](const std::unique_ptr<SSLCertificate>& cert)
-> std::unique_ptr<SSLCertificate> {
return cert->GetUniqueReference();
});
return new SSLCertChain(std::move(new_certs));
}
// static

View File

@ -60,10 +60,13 @@ class SSLCertificate {
virtual ~SSLCertificate() {}
// Returns a new SSLCertificate object instance wrapping the same
// underlying certificate, including its chain if present.
// Caller is responsible for freeing the returned object.
// underlying certificate, including its chain if present. Caller is
// responsible for freeing the returned object. Use GetUniqueReference
// instead.
virtual SSLCertificate* GetReference() const = 0;
std::unique_ptr<SSLCertificate> GetUniqueReference() const;
// Provides the cert chain, or null. The chain includes a copy of each
// certificate, excluding the leaf.
virtual std::unique_ptr<SSLCertChain> GetChain() const = 0;
@ -103,6 +106,7 @@ class SSLCertificate {
// SSLCertificate pointers.
class SSLCertChain {
public:
explicit SSLCertChain(std::vector<std::unique_ptr<SSLCertificate>> certs);
// These constructors copy the provided SSLCertificate(s), so the caller
// retains ownership.
explicit SSLCertChain(const std::vector<SSLCertificate*>& certs);
@ -117,20 +121,10 @@ class SSLCertChain {
// Returns a new SSLCertChain object instance wrapping the same underlying
// certificate chain. Caller is responsible for freeing the returned object.
SSLCertChain* Copy() const {
return new SSLCertChain(certs_);
}
SSLCertChain* Copy() const;
private:
// Helper function for duplicating a vector of certificates.
static SSLCertificate* DupCert(const SSLCertificate* cert) {
return cert->GetReference();
}
// Helper function for deleting a vector of certificates.
static void DeleteCert(SSLCertificate* cert) { delete cert; }
std::vector<SSLCertificate*> certs_;
std::vector<std::unique_ptr<SSLCertificate>> certs_;
RTC_DISALLOW_COPY_AND_ASSIGN(SSLCertChain);
};