summaryrefslogtreecommitdiffstats
path: root/security/nss/gtests/nss_bogo_shim/nss_bogo_shim.cc
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@wolfbeast.com>2019-01-06 15:14:54 +0100
committerwolfbeast <mcwerewolf@wolfbeast.com>2019-01-06 15:14:54 +0100
commitcc6a935ce54b573c1efd7533aff00e7bf0a9959c (patch)
treec8ad266edb7ea1e7b93aaaaa98847cf662373668 /security/nss/gtests/nss_bogo_shim/nss_bogo_shim.cc
parentd129c900c9f943adb69c1fb20ba1a029fdd95cff (diff)
parent9f4afc2552a67cc675b8b8af2ecb8ebc04a473a7 (diff)
downloadUXP-cc6a935ce54b573c1efd7533aff00e7bf0a9959c.tar
UXP-cc6a935ce54b573c1efd7533aff00e7bf0a9959c.tar.gz
UXP-cc6a935ce54b573c1efd7533aff00e7bf0a9959c.tar.lz
UXP-cc6a935ce54b573c1efd7533aff00e7bf0a9959c.tar.xz
UXP-cc6a935ce54b573c1efd7533aff00e7bf0a9959c.zip
Merge branch 'master' into Pale_Moon-release
# Conflicts: # application/palemoon/components/feeds/FeedWriter.js # application/palemoon/config/version.txt # security/manager/ssl/nsSTSPreloadList.errors # security/manager/ssl/nsSTSPreloadList.inc
Diffstat (limited to 'security/nss/gtests/nss_bogo_shim/nss_bogo_shim.cc')
-rw-r--r--security/nss/gtests/nss_bogo_shim/nss_bogo_shim.cc179
1 files changed, 106 insertions, 73 deletions
diff --git a/security/nss/gtests/nss_bogo_shim/nss_bogo_shim.cc b/security/nss/gtests/nss_bogo_shim/nss_bogo_shim.cc
index 72dbd5771..b2ce6898d 100644
--- a/security/nss/gtests/nss_bogo_shim/nss_bogo_shim.cc
+++ b/security/nss/gtests/nss_bogo_shim/nss_bogo_shim.cc
@@ -18,6 +18,7 @@
#include "ssl3prot.h"
#include "sslerr.h"
#include "sslproto.h"
+#include "nss_scoped_ptrs.h"
#include "nsskeys.h"
@@ -33,30 +34,9 @@ std::string FormatError(PRErrorCode code) {
class TestAgent {
public:
- TestAgent(const Config& cfg)
- : cfg_(cfg),
- pr_fd_(nullptr),
- ssl_fd_(nullptr),
- cert_(nullptr),
- key_(nullptr) {}
+ TestAgent(const Config& cfg) : cfg_(cfg) {}
- ~TestAgent() {
- if (pr_fd_) {
- PR_Close(pr_fd_);
- }
-
- if (ssl_fd_) {
- PR_Close(ssl_fd_);
- }
-
- if (key_) {
- SECKEY_DestroyPrivateKey(key_);
- }
-
- if (cert_) {
- CERT_DestroyCertificate(cert_);
- }
- }
+ ~TestAgent() {}
static std::unique_ptr<TestAgent> Create(const Config& cfg) {
std::unique_ptr<TestAgent> agent(new TestAgent(cfg));
@@ -81,39 +61,46 @@ class TestAgent {
return false;
}
- SECStatus rv = SSL_ResetHandshake(ssl_fd_, cfg_.get<bool>("server"));
+ SECStatus rv = SSL_ResetHandshake(ssl_fd_.get(), cfg_.get<bool>("server"));
if (rv != SECSuccess) return false;
return true;
}
bool ConnectTcp() {
+ // Try IPv6 first, then IPv4 in case of failure.
+ if (!OpenConnection("::1") && !OpenConnection("127.0.0.1")) {
+ return false;
+ }
+
+ ssl_fd_ = ScopedPRFileDesc(SSL_ImportFD(NULL, pr_fd_.get()));
+ if (!ssl_fd_) {
+ return false;
+ }
+ pr_fd_.release();
+
+ return true;
+ }
+
+ bool OpenConnection(const char* ip) {
PRStatus prv;
PRNetAddr addr;
- // Try IPv6 first.
- prv = PR_StringToNetAddr("::1", &addr);
+ prv = PR_StringToNetAddr(ip, &addr);
+
if (prv != PR_SUCCESS) {
- // If that fails, try IPv4.
- prv = PR_StringToNetAddr("127.0.0.1", &addr);
- if (prv != PR_SUCCESS) {
- return false;
- }
+ return false;
}
+
addr.inet.port = PR_htons(cfg_.get<int>("port"));
- pr_fd_ = PR_OpenTCPSocket(addr.raw.family);
+ pr_fd_ = ScopedPRFileDesc(PR_OpenTCPSocket(addr.raw.family));
if (!pr_fd_) return false;
- prv = PR_Connect(pr_fd_, &addr, PR_INTERVAL_NO_TIMEOUT);
+ prv = PR_Connect(pr_fd_.get(), &addr, PR_INTERVAL_NO_TIMEOUT);
if (prv != PR_SUCCESS) {
return false;
}
-
- ssl_fd_ = SSL_ImportFD(NULL, pr_fd_);
- if (!ssl_fd_) return false;
- pr_fd_ = nullptr;
-
return true;
}
@@ -121,21 +108,24 @@ class TestAgent {
SECStatus rv;
if (cfg_.get<std::string>("key-file") != "") {
- key_ = ReadPrivateKey(cfg_.get<std::string>("key-file"));
+ key_ = ScopedSECKEYPrivateKey(
+ ReadPrivateKey(cfg_.get<std::string>("key-file")));
if (!key_) return false;
}
if (cfg_.get<std::string>("cert-file") != "") {
- cert_ = ReadCertificate(cfg_.get<std::string>("cert-file"));
+ cert_ = ScopedCERTCertificate(
+ ReadCertificate(cfg_.get<std::string>("cert-file")));
if (!cert_) return false;
}
// Needed because certs are not entirely valid.
- rv = SSL_AuthCertificateHook(ssl_fd_, AuthCertificateHook, this);
+ rv = SSL_AuthCertificateHook(ssl_fd_.get(), AuthCertificateHook, this);
if (rv != SECSuccess) return false;
if (cfg_.get<bool>("server")) {
// Server
- rv = SSL_ConfigServerCert(ssl_fd_, cert_, key_, nullptr, 0);
+ rv = SSL_ConfigServerCert(ssl_fd_.get(), cert_.get(), key_.get(), nullptr,
+ 0);
if (rv != SECSuccess) {
std::cerr << "Couldn't configure server cert\n";
return false;
@@ -143,7 +133,8 @@ class TestAgent {
} else if (key_ && cert_) {
// Client.
- rv = SSL_GetClientAuthDataHook(ssl_fd_, GetClientAuthDataHook, this);
+ rv =
+ SSL_GetClientAuthDataHook(ssl_fd_.get(), GetClientAuthDataHook, this);
if (rv != SECSuccess) return false;
}
@@ -263,36 +254,36 @@ class TestAgent {
bool SetupOptions() {
SECStatus rv =
- SSL_OptionSet(ssl_fd_, SSL_ENABLE_TLS13_COMPAT_MODE, PR_TRUE);
+ SSL_OptionSet(ssl_fd_.get(), SSL_ENABLE_TLS13_COMPAT_MODE, PR_TRUE);
if (rv != SECSuccess) return false;
- rv = SSL_OptionSet(ssl_fd_, SSL_ENABLE_SESSION_TICKETS, PR_TRUE);
+ rv = SSL_OptionSet(ssl_fd_.get(), SSL_ENABLE_SESSION_TICKETS, PR_TRUE);
if (rv != SECSuccess) return false;
SSLVersionRange vrange;
if (!GetVersionRange(&vrange, ssl_variant_stream)) return false;
- rv = SSL_VersionRangeSet(ssl_fd_, &vrange);
+ rv = SSL_VersionRangeSet(ssl_fd_.get(), &vrange);
if (rv != SECSuccess) return false;
SSLVersionRange verify_vrange;
- rv = SSL_VersionRangeGet(ssl_fd_, &verify_vrange);
+ rv = SSL_VersionRangeGet(ssl_fd_.get(), &verify_vrange);
if (rv != SECSuccess) return false;
if (vrange.min != verify_vrange.min || vrange.max != verify_vrange.max)
return false;
- rv = SSL_OptionSet(ssl_fd_, SSL_NO_CACHE, false);
+ rv = SSL_OptionSet(ssl_fd_.get(), SSL_NO_CACHE, false);
if (rv != SECSuccess) return false;
auto alpn = cfg_.get<std::string>("advertise-alpn");
if (!alpn.empty()) {
assert(!cfg_.get<bool>("server"));
- rv = SSL_OptionSet(ssl_fd_, SSL_ENABLE_ALPN, PR_TRUE);
+ rv = SSL_OptionSet(ssl_fd_.get(), SSL_ENABLE_ALPN, PR_TRUE);
if (rv != SECSuccess) return false;
rv = SSL_SetNextProtoNego(
- ssl_fd_, reinterpret_cast<const unsigned char*>(alpn.c_str()),
+ ssl_fd_.get(), reinterpret_cast<const unsigned char*>(alpn.c_str()),
alpn.size());
if (rv != SECSuccess) return false;
}
@@ -312,23 +303,23 @@ class TestAgent {
[](int scheme) { return static_cast<SSLSignatureScheme>(scheme); });
rv = SSL_SignatureSchemePrefSet(
- ssl_fd_, sig_schemes.data(),
+ ssl_fd_.get(), sig_schemes.data(),
static_cast<unsigned int>(sig_schemes.size()));
if (rv != SECSuccess) return false;
}
if (cfg_.get<bool>("fallback-scsv")) {
- rv = SSL_OptionSet(ssl_fd_, SSL_ENABLE_FALLBACK_SCSV, PR_TRUE);
+ rv = SSL_OptionSet(ssl_fd_.get(), SSL_ENABLE_FALLBACK_SCSV, PR_TRUE);
if (rv != SECSuccess) return false;
}
if (cfg_.get<bool>("false-start")) {
- rv = SSL_OptionSet(ssl_fd_, SSL_ENABLE_FALSE_START, PR_TRUE);
+ rv = SSL_OptionSet(ssl_fd_.get(), SSL_ENABLE_FALSE_START, PR_TRUE);
if (rv != SECSuccess) return false;
}
if (cfg_.get<bool>("enable-ocsp-stapling")) {
- rv = SSL_OptionSet(ssl_fd_, SSL_ENABLE_OCSP_STAPLING, PR_TRUE);
+ rv = SSL_OptionSet(ssl_fd_.get(), SSL_ENABLE_OCSP_STAPLING, PR_TRUE);
if (rv != SECSuccess) return false;
}
@@ -336,29 +327,63 @@ class TestAgent {
if (requireClientCert || cfg_.get<bool>("verify-peer")) {
assert(cfg_.get<bool>("server"));
- rv = SSL_OptionSet(ssl_fd_, SSL_REQUEST_CERTIFICATE, PR_TRUE);
+ rv = SSL_OptionSet(ssl_fd_.get(), SSL_REQUEST_CERTIFICATE, PR_TRUE);
if (rv != SECSuccess) return false;
rv = SSL_OptionSet(
- ssl_fd_, SSL_REQUIRE_CERTIFICATE,
+ ssl_fd_.get(), SSL_REQUIRE_CERTIFICATE,
requireClientCert ? SSL_REQUIRE_ALWAYS : SSL_REQUIRE_NO_ERROR);
if (rv != SECSuccess) return false;
}
if (!cfg_.get<bool>("server")) {
// Needed to make resumption work.
- rv = SSL_SetURL(ssl_fd_, "server");
+ rv = SSL_SetURL(ssl_fd_.get(), "server");
if (rv != SECSuccess) return false;
}
- rv = SSL_OptionSet(ssl_fd_, SSL_ENABLE_EXTENDED_MASTER_SECRET, PR_TRUE);
+ rv = SSL_OptionSet(ssl_fd_.get(), SSL_ENABLE_EXTENDED_MASTER_SECRET,
+ PR_TRUE);
if (rv != SECSuccess) return false;
- if (!EnableNonExportCiphers()) return false;
+ if (!ConfigureCiphers()) return false;
return true;
}
+ bool ConfigureCiphers() {
+ auto cipherList = cfg_.get<std::string>("nss-cipher");
+
+ if (cipherList.empty()) {
+ return EnableNonExportCiphers();
+ }
+
+ for (size_t i = 0; i < SSL_NumImplementedCiphers; ++i) {
+ SSLCipherSuiteInfo csinfo;
+ std::string::size_type n;
+ SECStatus rv = SSL_GetCipherSuiteInfo(SSL_ImplementedCiphers[i], &csinfo,
+ sizeof(csinfo));
+ if (rv != SECSuccess) {
+ return false;
+ }
+
+ // Check if cipherList contains the name of the Cipher Suite and
+ // enable/disable accordingly.
+ n = cipherList.find(csinfo.cipherSuiteName, 0);
+ if (std::string::npos == n) {
+ rv = SSL_CipherPrefSet(ssl_fd_.get(), SSL_ImplementedCiphers[i],
+ PR_FALSE);
+ } else {
+ rv = SSL_CipherPrefSet(ssl_fd_.get(), SSL_ImplementedCiphers[i],
+ PR_TRUE);
+ }
+ if (rv != SECSuccess) {
+ return false;
+ }
+ }
+ return true;
+ }
+
bool EnableNonExportCiphers() {
for (size_t i = 0; i < SSL_NumImplementedCiphers; ++i) {
SSLCipherSuiteInfo csinfo;
@@ -369,7 +394,7 @@ class TestAgent {
return false;
}
- rv = SSL_CipherPrefSet(ssl_fd_, SSL_ImplementedCiphers[i], PR_TRUE);
+ rv = SSL_CipherPrefSet(ssl_fd_.get(), SSL_ImplementedCiphers[i], PR_TRUE);
if (rv != SECSuccess) {
return false;
}
@@ -388,19 +413,19 @@ class TestAgent {
CERTCertificate** cert,
SECKEYPrivateKey** privKey) {
TestAgent* a = static_cast<TestAgent*>(self);
- *cert = CERT_DupCertificate(a->cert_);
- *privKey = SECKEY_CopyPrivateKey(a->key_);
+ *cert = CERT_DupCertificate(a->cert_.get());
+ *privKey = SECKEY_CopyPrivateKey(a->key_.get());
return SECSuccess;
}
- SECStatus Handshake() { return SSL_ForceHandshake(ssl_fd_); }
+ SECStatus Handshake() { return SSL_ForceHandshake(ssl_fd_.get()); }
// Implement a trivial echo client/server. Read bytes from the other side,
// flip all the bits, and send them back.
SECStatus ReadWrite() {
for (;;) {
uint8_t block[512];
- int32_t rv = PR_Read(ssl_fd_, block, sizeof(block));
+ int32_t rv = PR_Read(ssl_fd_.get(), block, sizeof(block));
if (rv < 0) {
std::cerr << "Failure reading\n";
return SECFailure;
@@ -412,7 +437,7 @@ class TestAgent {
block[i] ^= 0xff;
}
- rv = PR_Write(ssl_fd_, block, len);
+ rv = PR_Write(ssl_fd_.get(), block, len);
if (rv != len) {
std::cerr << "Write failure\n";
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
@@ -431,7 +456,7 @@ class TestAgent {
// reader and writer.
uint8_t block[600];
memset(block, ch, sizeof(block));
- int32_t rv = PR_Write(ssl_fd_, block, sizeof(block));
+ int32_t rv = PR_Write(ssl_fd_.get(), block, sizeof(block));
if (rv != sizeof(block)) {
std::cerr << "Write failure\n";
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
@@ -440,7 +465,7 @@ class TestAgent {
size_t left = sizeof(block);
while (left) {
- rv = PR_Read(ssl_fd_, block, left);
+ rv = PR_Read(ssl_fd_.get(), block, left);
if (rv < 0) {
std::cerr << "Failure reading\n";
return SECFailure;
@@ -494,7 +519,7 @@ class TestAgent {
SSLNextProtoState state;
char chosen[256];
unsigned int chosen_len;
- rv = SSL_GetNextProto(ssl_fd_, &state,
+ rv = SSL_GetNextProto(ssl_fd_.get(), &state,
reinterpret_cast<unsigned char*>(chosen),
&chosen_len, sizeof(chosen));
if (rv != SECSuccess) {
@@ -514,7 +539,7 @@ class TestAgent {
auto sig_alg = cfg_.get<int>("expect-peer-signature-algorithm");
if (sig_alg) {
SSLChannelInfo info;
- rv = SSL_GetChannelInfo(ssl_fd_, &info, sizeof(info));
+ rv = SSL_GetChannelInfo(ssl_fd_.get(), &info, sizeof(info));
if (rv != SECSuccess) {
PRErrorCode err = PR_GetError();
std::cerr << "SSL_GetChannelInfo failed with error=" << FormatError(err)
@@ -534,10 +559,10 @@ class TestAgent {
private:
const Config& cfg_;
- PRFileDesc* pr_fd_;
- PRFileDesc* ssl_fd_;
- CERTCertificate* cert_;
- SECKEYPrivateKey* key_;
+ ScopedPRFileDesc pr_fd_;
+ ScopedPRFileDesc ssl_fd_;
+ ScopedCERTCertificate cert_;
+ ScopedSECKEYPrivateKey key_;
};
std::unique_ptr<const Config> ReadConfig(int argc, char** argv) {
@@ -559,11 +584,14 @@ std::unique_ptr<const Config> ReadConfig(int argc, char** argv) {
cfg->AddEntry<bool>("write-then-read", false);
cfg->AddEntry<bool>("require-any-client-certificate", false);
cfg->AddEntry<bool>("verify-peer", false);
+ cfg->AddEntry<bool>("is-handshaker-supported", false);
+ cfg->AddEntry<std::string>("handshaker-path", ""); // Ignore this
cfg->AddEntry<std::string>("advertise-alpn", "");
cfg->AddEntry<std::string>("expect-alpn", "");
cfg->AddEntry<std::vector<int>>("signing-prefs", std::vector<int>());
cfg->AddEntry<std::vector<int>>("verify-prefs", std::vector<int>());
cfg->AddEntry<int>("expect-peer-signature-algorithm", 0);
+ cfg->AddEntry<std::string>("nss-cipher", "");
auto rv = cfg->ParseArgs(argc, argv);
switch (rv) {
@@ -602,6 +630,11 @@ int main(int argc, char** argv) {
return GetExitCode(false);
}
+ if (cfg->get<bool>("is-handshaker-supported")) {
+ std::cout << "No\n";
+ return 0;
+ }
+
if (cfg->get<bool>("server")) {
if (SSL_ConfigServerSessionIDCache(1024, 0, 0, ".") != SECSuccess) {
std::cerr << "Couldn't configure session cache\n";