mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
bug 1188100 - fold PSM's test_client_cert.js into necko's test_tls_server.js r=mcmanus
This commit is contained in:
parent
0897b64884
commit
9db6074701
@ -6,16 +6,6 @@
|
||||
const { utils: Cu, interfaces: Ci } = Components;
|
||||
const { XPCOMUtils } = Cu.import("resource://gre/modules/XPCOMUtils.jsm", {});
|
||||
|
||||
function CertDialogService() {}
|
||||
CertDialogService.prototype = {
|
||||
classID: Components.ID("{a70153f2-3590-4317-93e9-73b3e7ffca5d}"),
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsICertificateDialogs]),
|
||||
|
||||
getPKCS12FilePassword: function() {
|
||||
return true; // Simulates entering an empty password
|
||||
}
|
||||
};
|
||||
|
||||
let Prompter = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPrompt]),
|
||||
alert: function() {} // Do nothing when asked to show an alert
|
||||
@ -32,6 +22,5 @@ WindowWatcherService.prototype = {
|
||||
};
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([
|
||||
CertDialogService,
|
||||
WindowWatcherService
|
||||
]);
|
@ -1,4 +1,2 @@
|
||||
component {a70153f2-3590-4317-93e9-73b3e7ffca5d} cert_dialog.js
|
||||
contract @mozilla.org/nsCertificateDialogs;1 {a70153f2-3590-4317-93e9-73b3e7ffca5d}
|
||||
component {01ae923c-81bb-45db-b860-d423b0fc4fe1} cert_dialog.js
|
||||
contract @mozilla.org/embedcomp/window-watcher;1 {01ae923c-81bb-45db-b860-d423b0fc4fe1}
|
@ -38,7 +38,7 @@ function getCert() {
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function startServer(cert) {
|
||||
function startServer(cert, expectingPeerCert, clientCertificateConfig) {
|
||||
let tlsServer = Cc["@mozilla.org/network/tls-server-socket;1"]
|
||||
.createInstance(Ci.nsITLSServerSocket);
|
||||
tlsServer.init(-1, true, -1);
|
||||
@ -57,8 +57,12 @@ function startServer(cert) {
|
||||
},
|
||||
onHandshakeDone: function(socket, status) {
|
||||
do_print("TLS handshake done");
|
||||
ok(!!status.peerCert, "Has peer cert");
|
||||
ok(status.peerCert.equals(cert), "Peer cert matches expected cert");
|
||||
if (expectingPeerCert) {
|
||||
ok(!!status.peerCert, "Has peer cert");
|
||||
ok(status.peerCert.equals(cert), "Peer cert matches expected cert");
|
||||
} else {
|
||||
ok(!status.peerCert, "No peer cert (as expected)");
|
||||
}
|
||||
|
||||
equal(status.tlsVersionUsed, Ci.nsITLSClientStatus.TLS_VERSION_1_2,
|
||||
"Using TLS 1.2");
|
||||
@ -78,7 +82,7 @@ function startServer(cert) {
|
||||
|
||||
tlsServer.setSessionCache(false);
|
||||
tlsServer.setSessionTickets(false);
|
||||
tlsServer.setRequestClientCertificate(Ci.nsITLSServerSocket.REQUIRE_ALWAYS);
|
||||
tlsServer.setRequestClientCertificate(clientCertificateConfig);
|
||||
|
||||
tlsServer.asyncListen(listener);
|
||||
|
||||
@ -92,7 +96,9 @@ function storeCertOverride(port, cert) {
|
||||
overrideBits, true);
|
||||
}
|
||||
|
||||
function startClient(port, cert) {
|
||||
function startClient(port, cert, expectingBadCertAlert) {
|
||||
let SSL_ERROR_BASE = Ci.nsINSSErrorsService.NSS_SSL_ERROR_BASE;
|
||||
let SSL_ERROR_BAD_CERT_ALERT = SSL_ERROR_BASE + 17;
|
||||
let transport =
|
||||
socketTransportService.createTransport(["ssl"], 1, "127.0.0.1", port, null);
|
||||
let input;
|
||||
@ -117,22 +123,23 @@ function startClient(port, cert) {
|
||||
output.close();
|
||||
inputDeferred.resolve();
|
||||
} catch (e) {
|
||||
let SEC_ERROR_BASE = Ci.nsINSSErrorsService.NSS_SEC_ERROR_BASE;
|
||||
let SEC_ERROR_UNKNOWN_ISSUER = SEC_ERROR_BASE + 13;
|
||||
let errorCode = -1 * (e.result & 0xFFFF);
|
||||
if (errorCode == SEC_ERROR_UNKNOWN_ISSUER) {
|
||||
do_print("Client doesn't like server cert");
|
||||
if (expectingBadCertAlert && errorCode == SSL_ERROR_BAD_CERT_ALERT) {
|
||||
inputDeferred.resolve();
|
||||
} else {
|
||||
inputDeferred.reject(e);
|
||||
}
|
||||
inputDeferred.reject(e);
|
||||
}
|
||||
},
|
||||
|
||||
onOutputStreamReady: function(output) {
|
||||
try {
|
||||
// Set the cert we want to avoid any cert UI prompts
|
||||
let clientSecInfo = transport.securityInfo;
|
||||
let tlsControl = clientSecInfo.QueryInterface(Ci.nsISSLSocketControl);
|
||||
tlsControl.clientCert = cert;
|
||||
// Set the client certificate as appropriate.
|
||||
if (cert) {
|
||||
let clientSecInfo = transport.securityInfo;
|
||||
let tlsControl = clientSecInfo.QueryInterface(Ci.nsISSLSocketControl);
|
||||
tlsControl.clientCert = cert;
|
||||
}
|
||||
|
||||
output.write("HELLO", 5);
|
||||
do_print("Output to server written");
|
||||
@ -140,8 +147,6 @@ function startClient(port, cert) {
|
||||
input = transport.openInputStream(0, 0, 0);
|
||||
input.asyncWait(handler, 0, 0, Services.tm.currentThread);
|
||||
} catch (e) {
|
||||
let SSL_ERROR_BASE = Ci.nsINSSErrorsService.NSS_SSL_ERROR_BASE;
|
||||
let SSL_ERROR_BAD_CERT_ALERT = SSL_ERROR_BASE + 17;
|
||||
let errorCode = -1 * (e.result & 0xFFFF);
|
||||
if (errorCode == SSL_ERROR_BAD_CERT_ALERT) {
|
||||
do_print("Server doesn't like client cert");
|
||||
@ -158,10 +163,53 @@ function startClient(port, cert) {
|
||||
return promise.all([inputDeferred.promise, outputDeferred.promise]);
|
||||
}
|
||||
|
||||
// Replace the UI dialog that prompts the user to pick a client certificate.
|
||||
do_load_manifest("client_cert_chooser.manifest");
|
||||
|
||||
add_task(function*() {
|
||||
let cert = yield getCert();
|
||||
ok(!!cert, "Got self-signed cert");
|
||||
let port = startServer(cert);
|
||||
let port = startServer(cert, true, Ci.nsITLSServerSocket.REQUIRE_ALWAYS);
|
||||
storeCertOverride(port, cert);
|
||||
yield startClient(port, cert);
|
||||
yield startClient(port, cert, false);
|
||||
});
|
||||
|
||||
add_task(function*() {
|
||||
let cert = yield getCert();
|
||||
ok(!!cert, "Got self-signed cert");
|
||||
let port = startServer(cert, true, Ci.nsITLSServerSocket.REQUIRE_ALWAYS);
|
||||
storeCertOverride(port, cert);
|
||||
yield startClient(port, null, true);
|
||||
});
|
||||
|
||||
add_task(function*() {
|
||||
let cert = yield getCert();
|
||||
ok(!!cert, "Got self-signed cert");
|
||||
let port = startServer(cert, true, Ci.nsITLSServerSocket.REQUEST_ALWAYS);
|
||||
storeCertOverride(port, cert);
|
||||
yield startClient(port, cert, false);
|
||||
});
|
||||
|
||||
add_task(function*() {
|
||||
let cert = yield getCert();
|
||||
ok(!!cert, "Got self-signed cert");
|
||||
let port = startServer(cert, false, Ci.nsITLSServerSocket.REQUEST_ALWAYS);
|
||||
storeCertOverride(port, cert);
|
||||
yield startClient(port, null, false);
|
||||
});
|
||||
|
||||
add_task(function*() {
|
||||
let cert = yield getCert();
|
||||
ok(!!cert, "Got self-signed cert");
|
||||
let port = startServer(cert, false, Ci.nsITLSServerSocket.REQUEST_NEVER);
|
||||
storeCertOverride(port, cert);
|
||||
yield startClient(port, cert, false);
|
||||
});
|
||||
|
||||
add_task(function*() {
|
||||
let cert = yield getCert();
|
||||
ok(!!cert, "Got self-signed cert");
|
||||
let port = startServer(cert, false, Ci.nsITLSServerSocket.REQUEST_NEVER);
|
||||
storeCertOverride(port, cert);
|
||||
yield startClient(port, null, false);
|
||||
});
|
||||
|
@ -4,6 +4,8 @@ tail =
|
||||
skip-if = toolkit == 'gonk'
|
||||
support-files =
|
||||
CA.cert.der
|
||||
client_cert_chooser.js
|
||||
client_cert_chooser.manifest
|
||||
data/image.png
|
||||
data/system_root.lnk
|
||||
data/test_psl.txt
|
||||
|
@ -1,68 +0,0 @@
|
||||
// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
"use strict";
|
||||
|
||||
// Tests specifying a particular client cert to use via the nsISSLSocketControl
|
||||
// |clientCert| attribute prior to connecting to the server.
|
||||
|
||||
function run_test() {
|
||||
do_get_profile();
|
||||
|
||||
// Init key token (to prevent password prompt)
|
||||
const tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"]
|
||||
.getService(Ci.nsIPK11TokenDB);
|
||||
let keyToken = tokenDB.getInternalKeyToken();
|
||||
if (keyToken.needsUserInit) {
|
||||
keyToken.initPassword("");
|
||||
}
|
||||
|
||||
// Replace the UI dialog that would prompt for the following PKCS #12 file's
|
||||
// password, as well as an alert that appears after it succeeds.
|
||||
do_load_manifest("test_client_cert/cert_dialog.manifest");
|
||||
|
||||
// Load the user cert and look it up in XPCOM format
|
||||
const certDB = Cc["@mozilla.org/security/x509certdb;1"]
|
||||
.getService(Ci.nsIX509CertDB);
|
||||
let clientCertFile = do_get_file("test_client_cert/client-cert.p12", false);
|
||||
certDB.importPKCS12File(null, clientCertFile);
|
||||
|
||||
// Find the cert by its common name
|
||||
let clientCert;
|
||||
let certs = certDB.getCerts().getEnumerator();
|
||||
while (certs.hasMoreElements()) {
|
||||
let cert = certs.getNext().QueryInterface(Ci.nsIX509Cert);
|
||||
if (cert.certType === Ci.nsIX509Cert.USER_CERT &&
|
||||
cert.commonName === "client-cert") {
|
||||
clientCert = cert;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ok(clientCert, "Client cert found");
|
||||
|
||||
add_tls_server_setup("ClientAuthServer");
|
||||
|
||||
add_connection_test("noclientauth.example.com", PRErrorCodeSuccess);
|
||||
|
||||
add_connection_test("requestclientauth.example.com", PRErrorCodeSuccess);
|
||||
add_connection_test("requestclientauth.example.com", PRErrorCodeSuccess,
|
||||
null, null, transport => {
|
||||
do_print("Setting client cert on transport");
|
||||
let sslSocketControl = transport.securityInfo
|
||||
.QueryInterface(Ci.nsISSLSocketControl);
|
||||
sslSocketControl.clientCert = clientCert;
|
||||
});
|
||||
|
||||
add_connection_test("requireclientauth.example.com",
|
||||
SSL_ERROR_BAD_CERT_ALERT);
|
||||
add_connection_test("requireclientauth.example.com", PRErrorCodeSuccess,
|
||||
null, null, transport => {
|
||||
do_print("Setting client cert on transport");
|
||||
let sslSocketControl =
|
||||
transport.securityInfo.QueryInterface(Ci.nsISSLSocketControl);
|
||||
sslSocketControl.clientCert = clientCert;
|
||||
});
|
||||
|
||||
run_next_test();
|
||||
}
|
Binary file not shown.
@ -1,33 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import tempfile, os, sys, random
|
||||
|
||||
libpath = os.path.abspath("../psm_common_py")
|
||||
sys.path.append(libpath)
|
||||
|
||||
import CertUtils
|
||||
|
||||
dest_dir = os.getcwd()
|
||||
db = tempfile.mkdtemp()
|
||||
|
||||
serial = random.randint(100, 40000000)
|
||||
name = "client-cert"
|
||||
[key, cert] = CertUtils.generate_cert_generic(db, dest_dir, serial, "rsa",
|
||||
name, "")
|
||||
CertUtils.generate_pkcs12(db, dest_dir, cert, key, name)
|
||||
|
||||
# Print a blank line and the fingerprint of the cert that ClientAuthServer.cpp
|
||||
# should be modified with.
|
||||
print
|
||||
CertUtils.print_cert_info(cert)
|
||||
print ('You now MUST update the fingerprint in ClientAuthServer.cpp to match ' +
|
||||
'the fingerprint printed above.')
|
||||
|
||||
# Remove unnecessary .der file
|
||||
os.remove(dest_dir + "/" + name + ".der")
|
@ -1,116 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 sw=2 tw=80 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// This is a standalone server for testing client cert authentication.
|
||||
// The client is expected to connect, initiate an SSL handshake (with SNI
|
||||
// to indicate which "server" to connect to), and verify the certificate.
|
||||
// If all is good, the client then sends one encrypted byte and receives that
|
||||
// same byte back.
|
||||
// This server also has the ability to "call back" another process waiting on
|
||||
// it. That is, when the server is all set up and ready to receive connections,
|
||||
// it will connect to a specified port and issue a simple HTTP request.
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "hasht.h"
|
||||
#include "ScopedNSSTypes.h"
|
||||
#include "ssl.h"
|
||||
#include "TLSServer.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::test;
|
||||
|
||||
struct ClientAuthHost
|
||||
{
|
||||
const char *mHostName;
|
||||
bool mRequestClientAuth;
|
||||
bool mRequireClientAuth;
|
||||
};
|
||||
|
||||
// Hostname, cert nickname pairs.
|
||||
static const ClientAuthHost sClientAuthHosts[] =
|
||||
{
|
||||
{ "noclientauth.example.com", false, false },
|
||||
{ "requestclientauth.example.com", true, false },
|
||||
{ "requireclientauth.example.com", true, true },
|
||||
{ nullptr, false, false }
|
||||
};
|
||||
|
||||
static const unsigned char sClientCertFingerprint[] =
|
||||
{
|
||||
0xD2, 0x2F, 0x00, 0x9A, 0x9E, 0xED, 0x79, 0xDC,
|
||||
0x8D, 0x17, 0x98, 0x8E, 0xEC, 0x76, 0x05, 0x91,
|
||||
0xA5, 0xF6, 0xC9, 0xFA, 0x16, 0x8B, 0xD2, 0x5F,
|
||||
0xE1, 0x52, 0x04, 0x7C, 0xF4, 0x76, 0x42, 0x9D
|
||||
};
|
||||
|
||||
SECStatus
|
||||
AuthCertificateHook(void* arg, PRFileDesc* fd, PRBool checkSig,
|
||||
PRBool isServer)
|
||||
{
|
||||
ScopedCERTCertificate clientCert(SSL_PeerCertificate(fd));
|
||||
|
||||
unsigned char certFingerprint[SHA256_LENGTH];
|
||||
SECStatus rv = PK11_HashBuf(SEC_OID_SHA256, certFingerprint,
|
||||
clientCert->derCert.data,
|
||||
clientCert->derCert.len);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
static_assert(sizeof(sClientCertFingerprint) == SHA256_LENGTH,
|
||||
"Ensure fingerprint has corrent length");
|
||||
bool match = !memcmp(certFingerprint, sClientCertFingerprint,
|
||||
sizeof(certFingerprint));
|
||||
return match ? SECSuccess : SECFailure;
|
||||
}
|
||||
|
||||
int32_t
|
||||
DoSNISocketConfig(PRFileDesc* aFd, const SECItem* aSrvNameArr,
|
||||
uint32_t aSrvNameArrSize, void* aArg)
|
||||
{
|
||||
const ClientAuthHost *host = GetHostForSNI(aSrvNameArr, aSrvNameArrSize,
|
||||
sClientAuthHosts);
|
||||
if (!host) {
|
||||
return SSL_SNI_SEND_ALERT;
|
||||
}
|
||||
|
||||
if (gDebugLevel >= DEBUG_VERBOSE) {
|
||||
fprintf(stderr, "found pre-defined host '%s'\n", host->mHostName);
|
||||
}
|
||||
|
||||
SECStatus srv = ConfigSecureServerWithNamedCert(aFd, DEFAULT_CERT_NICKNAME,
|
||||
nullptr, nullptr);
|
||||
if (srv != SECSuccess) {
|
||||
return SSL_SNI_SEND_ALERT;
|
||||
}
|
||||
|
||||
SSL_OptionSet(aFd, SSL_REQUEST_CERTIFICATE, host->mRequestClientAuth);
|
||||
if (host->mRequireClientAuth) {
|
||||
SSL_OptionSet(aFd, SSL_REQUIRE_CERTIFICATE, SSL_REQUIRE_ALWAYS);
|
||||
} else {
|
||||
SSL_OptionSet(aFd, SSL_REQUIRE_CERTIFICATE, SSL_REQUIRE_NEVER);
|
||||
}
|
||||
|
||||
// Override default client auth hook to just check fingerprint
|
||||
srv = SSL_AuthCertificateHook(aFd, AuthCertificateHook, nullptr);
|
||||
if (srv != SECSuccess) {
|
||||
return SSL_SNI_SEND_ALERT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "usage: %s <NSS DB directory>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return StartServer(argv[1], DoSNISocketConfig, nullptr);
|
||||
}
|
@ -8,7 +8,6 @@ FAIL_ON_WARNINGS = True
|
||||
|
||||
GeckoSimplePrograms([
|
||||
'BadCertServer',
|
||||
'ClientAuthServer',
|
||||
'GenerateOCSPResponse',
|
||||
'OCSPStaplingServer',
|
||||
], linkage=None)
|
||||
|
@ -8,7 +8,6 @@ support-files =
|
||||
tlsserver/**
|
||||
test_cert_signatures/**
|
||||
test_certviewer_invalid_oids/**
|
||||
test_client_cert/**
|
||||
test_ev_certs/**
|
||||
test_getchain/**
|
||||
test_intermediate_basic_usage_constraints/**
|
||||
@ -134,8 +133,6 @@ skip-if = toolkit == 'gonk' && debug
|
||||
run-sequentially = hardcoded ports
|
||||
[test_cert_chains.js]
|
||||
run-sequentially = hardcoded ports
|
||||
[test_client_cert.js]
|
||||
run-sequentially = hardcoded ports
|
||||
[test_nsCertType.js]
|
||||
run-sequentially = hardcoded ports
|
||||
[test_nsIX509Cert_utf8.js]
|
||||
|
@ -23,7 +23,6 @@ TEST_HARNESS_BINS := \
|
||||
certutil$(BIN_SUFFIX) \
|
||||
pk12util$(BIN_SUFFIX) \
|
||||
BadCertServer$(BIN_SUFFIX) \
|
||||
ClientAuthServer$(BIN_SUFFIX) \
|
||||
OCSPStaplingServer$(BIN_SUFFIX) \
|
||||
GenerateOCSPResponse$(BIN_SUFFIX) \
|
||||
fix_stack_using_bpsyms.py \
|
||||
|
@ -387,7 +387,6 @@ class XPCShellRemote(xpcshell.XPCShellTests, object):
|
||||
"certutil",
|
||||
"pk12util",
|
||||
"BadCertServer",
|
||||
"ClientAuthServer",
|
||||
"OCSPStaplingServer",
|
||||
"GenerateOCSPResponse"]
|
||||
for fname in binaries:
|
||||
|
@ -614,7 +614,6 @@ NO_PKG_FILES += \
|
||||
certutil* \
|
||||
pk12util* \
|
||||
BadCertServer* \
|
||||
ClientAuthServer* \
|
||||
OCSPStaplingServer* \
|
||||
GenerateOCSPResponse* \
|
||||
chrome/chrome.rdf \
|
||||
|
Loading…
Reference in New Issue
Block a user