shill: OpenVPNDriver: Use an array for CA cert PEM
Switch to an array property for the "OpenVPN.CACertPEM" property.
This allows multiple CA certificates to be specified.
BUG=chromium:249363
TEST=Unit test
Change-Id: If9e94a81dc29fb3b689e9535d87fda771c0d58e5
Reviewed-on: https://gerrit.chromium.org/gerrit/58724
Commit-Queue: Paul Stewart <pstew@chromium.org>
Reviewed-by: Paul Stewart <pstew@chromium.org>
Tested-by: Paul Stewart <pstew@chromium.org>
diff --git a/certificate_file.cc b/certificate_file.cc
index 1a91795..4083a6a 100644
--- a/certificate_file.cc
+++ b/certificate_file.cc
@@ -43,15 +43,6 @@
}
}
-FilePath CertificateFile::CreatePEMFromString(const string &pem_contents) {
- string hex_data = ExtractHexData(pem_contents);
- if (hex_data.empty()) {
- return FilePath();
- }
- return WriteFile(StringPrintf(
- "%s\n%s%s\n", kPEMHeader, hex_data.c_str(), kPEMFooter));
-}
-
FilePath CertificateFile::CreatePEMFromStrings(
const vector<string> &pem_contents) {
vector<string> pem_output;
diff --git a/certificate_file.h b/certificate_file.h
index ad4ed1d..c3b87a1 100644
--- a/certificate_file.h
+++ b/certificate_file.h
@@ -23,9 +23,8 @@
explicit CertificateFile(GLib *glib);
virtual ~CertificateFile();
- // Write out a PEM file from an input string (or vector of strings)
- // in PEM format. Returns an empty path on failure.
- virtual base::FilePath CreatePEMFromString(const std::string &pem_contents);
+ // Write out a PEM file from an input vector of strings in PEM format.
+ // Returns an empty path on failure.
virtual base::FilePath CreatePEMFromStrings(
const std::vector<std::string> &pem_contents);
diff --git a/certificate_file_unittest.cc b/certificate_file_unittest.cc
index 125dc91..5c957a0 100644
--- a/certificate_file_unittest.cc
+++ b/certificate_file_unittest.cc
@@ -70,53 +70,38 @@
EXPECT_TRUE(GetOutputFile().empty());
}
-TEST_F(CertificateFileTest, CreatePEMFromString) {
+TEST_F(CertificateFileTest, CreatePEMFromStrings) {
// Create a formatted PEM file from the inner HEX data.
- FilePath outfile0 = certificate_file_.CreatePEMFromString(kPEMData);
+ const vector<string> kPEMVector0{ kPEMData };
+ FilePath outfile0 = certificate_file_.CreatePEMFromStrings(kPEMVector0);
EXPECT_FALSE(outfile0.empty());
EXPECT_TRUE(file_util::PathExists(outfile0));
EXPECT_TRUE(file_util::ContainsPath(certificate_directory_, outfile0));
string file_string0;
- string expected_output = StringPrintf(
- "%s\n%s%s\n", GetPEMHeader(), kPEMData, GetPEMFooter());
EXPECT_TRUE(file_util::ReadFileToString(outfile0, &file_string0));
- EXPECT_EQ(expected_output, file_string0);
+ string expected_output0 = StringPrintf(
+ "%s\n%s%s\n", GetPEMHeader(), kPEMData, GetPEMFooter());
+ EXPECT_EQ(expected_output0, file_string0);
+
// Create a formatted PEM file from formatted PEM.
- FilePath outfile1 = certificate_file_.CreatePEMFromString(expected_output);
+ const vector<string> kPEMVector1{ expected_output0, kPEMData };
+ FilePath outfile1 = certificate_file_.CreatePEMFromStrings(kPEMVector1);
EXPECT_FALSE(outfile1.empty());
EXPECT_TRUE(file_util::PathExists(outfile1));
EXPECT_FALSE(file_util::PathExists(outfile0)); // Old file is deleted.
string file_string1;
EXPECT_TRUE(file_util::ReadFileToString(outfile1, &file_string1));
- EXPECT_EQ(expected_output, file_string1);
+ string expected_output1 = StringPrintf(
+ "%s%s", expected_output0.c_str(), expected_output0.c_str());
+ EXPECT_EQ(expected_output1, file_string1);
// Fail to create a PEM file. Old file should not have been deleted.
- FilePath outfile2 = certificate_file_.CreatePEMFromString("");
+ const vector<string> kPEMVector2{ kPEMData, "" };
+ FilePath outfile2 = certificate_file_.CreatePEMFromStrings(kPEMVector2);
EXPECT_TRUE(outfile2.empty());
EXPECT_TRUE(file_util::PathExists(outfile1));
}
-TEST_F(CertificateFileTest, CreatePEMFromStrings) {
- // Create a formatted PEM file from the inner HEX data.
- const vector<string> kPEMVector0{ kPEMData, kPEMData };
- FilePath outfile0 = certificate_file_.CreatePEMFromStrings(kPEMVector0);
- EXPECT_FALSE(outfile0.empty());
- EXPECT_TRUE(file_util::PathExists(outfile0));
- EXPECT_TRUE(file_util::ContainsPath(certificate_directory_, outfile0));
- string expected_output = StringPrintf(
- "%s\n%s%s\n%s\n%s%s\n", GetPEMHeader(), kPEMData, GetPEMFooter(),
- GetPEMHeader(), kPEMData, GetPEMFooter());
- string file_string0;
- EXPECT_TRUE(file_util::ReadFileToString(outfile0, &file_string0));
- EXPECT_EQ(expected_output, file_string0);
-
- // Fail to create a PEM file. Old file should not have been deleted.
- const vector<string> kPEMVector1{ kPEMData, "" };
- FilePath outfile1 = certificate_file_.CreatePEMFromStrings(kPEMVector1);
- EXPECT_TRUE(outfile1.empty());
- EXPECT_TRUE(file_util::PathExists(outfile0));
-}
-
TEST_F(CertificateFileTest, CreateDERFromString) {
// Create a DER file from the inner HEX data.
const string kPEMString = kPEMData;
@@ -159,7 +144,7 @@
{
CertificateFile certificate_file(&glib_);
certificate_file.set_root_directory(temp_dir_.path());
- outfile = certificate_file.CreatePEMFromString(kPEMData);
+ outfile = certificate_file.CreatePEMFromStrings(vector<string>{ kPEMData });
EXPECT_TRUE(file_util::PathExists(outfile));
}
// The output file should be deleted when certificate_file goes out-of-scope.
diff --git a/mock_certificate_file.h b/mock_certificate_file.h
index cabbb74..e1f1a39 100644
--- a/mock_certificate_file.h
+++ b/mock_certificate_file.h
@@ -18,6 +18,8 @@
MOCK_METHOD1(CreatePEMFromString,
base::FilePath(const std::string &pem_contents));
+ MOCK_METHOD1(CreatePEMFromStrings,
+ base::FilePath(const std::vector<std::string> &pem_contents));
MOCK_METHOD1(CreateDERFromString,
base::FilePath(const std::string &pem_contents));
diff --git a/openvpn_driver.cc b/openvpn_driver.cc
index a2a7479..a5c0174 100644
--- a/openvpn_driver.cc
+++ b/openvpn_driver.cc
@@ -113,7 +113,7 @@
{ flimflam::kOpenVPNUserProperty, 0 },
{ flimflam::kProviderHostProperty, 0 },
{ flimflam::kProviderTypeProperty, 0 },
- { kOpenVPNCaCertPemProperty, 0 },
+ { kOpenVPNCaCertPemProperty, Property::kArray },
{ kOpenVPNCertProperty, 0 },
{ kOpenVPNKeyProperty, 0 },
{ kOpenVPNPingExitProperty, 0 },
@@ -663,7 +663,10 @@
args()->LookupString(flimflam::kOpenVPNCaCertProperty, "");
string ca_cert_nss =
args()->LookupString(flimflam::kOpenVPNCaCertNSSProperty, "");
- string ca_cert_pem = args()->LookupString(kOpenVPNCaCertPemProperty, "");
+ vector<string> ca_cert_pem;
+ if (args()->ContainsStrings(kOpenVPNCaCertPemProperty)) {
+ ca_cert_pem = args()->GetStrings(kOpenVPNCaCertPemProperty);
+ }
int num_ca_cert_types = 0;
if (!ca_cert.empty())
@@ -699,12 +702,12 @@
return true;
} else if (!ca_cert_pem.empty()) {
DCHECK(ca_cert.empty() && ca_cert_nss.empty());
- FilePath certfile = certificate_file_->CreatePEMFromString(ca_cert_pem);
+ FilePath certfile = certificate_file_->CreatePEMFromStrings(ca_cert_pem);
if (certfile.empty()) {
Error::PopulateAndLog(
error,
Error::kInvalidArguments,
- "Unable to extract PEM CA certificate.");
+ "Unable to extract PEM CA certificates.");
return false;
}
options->push_back(certfile.value());
diff --git a/openvpn_driver_unittest.cc b/openvpn_driver_unittest.cc
index 9f103a3..99c3d5d 100644
--- a/openvpn_driver_unittest.cc
+++ b/openvpn_driver_unittest.cc
@@ -110,6 +110,10 @@
driver_->args()->SetString(arg, value);
}
+ void SetArgArray(const string &arg, const vector<string> &value) {
+ driver_->args()->SetStrings(arg, value);
+ }
+
KeyValueStore *GetArgs() {
return driver_->args();
}
@@ -666,8 +670,8 @@
ExpectInFlags(options, "--ca", kNSSCertfile);
EXPECT_TRUE(error.IsSuccess());
- static const char kCaCertPEM[] = "---PEM CONTENTS---";
- SetArg(kOpenVPNCaCertPemProperty, kCaCertPEM);
+ const vector<string> kCaCertPEM{ "---PEM CONTENTS---" };
+ SetArgArray(kOpenVPNCaCertPemProperty, kCaCertPEM);
EXPECT_FALSE(driver_->InitCAOptions(&options, &error));
EXPECT_EQ(Error::kInvalidArguments, error.type());
EXPECT_EQ("Can't specify more than one of CACert, CACertNSS and CACertPEM.",
@@ -678,14 +682,14 @@
SetArg(flimflam::kProviderHostProperty, "");
static const char kPEMCertfile[] = "/tmp/pem-cert";
FilePath pem_cert(kPEMCertfile);
- EXPECT_CALL(*certificate_file_, CreatePEMFromString(kCaCertPEM))
+ EXPECT_CALL(*certificate_file_, CreatePEMFromStrings(kCaCertPEM))
.WillOnce(Return(empty_cert))
.WillOnce(Return(pem_cert));
error.Reset();
EXPECT_FALSE(driver_->InitCAOptions(&options, &error));
EXPECT_EQ(Error::kInvalidArguments, error.type());
- EXPECT_EQ("Unable to extract PEM CA certificate.", error.message());
+ EXPECT_EQ("Unable to extract PEM CA certificates.", error.message());
error.Reset();
options.clear();