michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: // This is a standalone server that uses various bad certificates. michael@0: // The client is expected to connect, initiate an SSL handshake (with SNI michael@0: // to indicate which "server" to connect to), and verify the certificate. michael@0: // If all is good, the client then sends one encrypted byte and receives that michael@0: // same byte back. michael@0: // This server also has the ability to "call back" another process waiting on michael@0: // it. That is, when the server is all set up and ready to receive connections, michael@0: // it will connect to a specified port and issue a simple HTTP request. michael@0: michael@0: #include michael@0: michael@0: #include "TLSServer.h" michael@0: michael@0: using namespace mozilla; michael@0: using namespace mozilla::test; michael@0: michael@0: struct BadCertHost michael@0: { michael@0: const char *mHostName; michael@0: const char *mCertName; michael@0: }; michael@0: michael@0: // Hostname, cert nickname pairs. michael@0: const BadCertHost sBadCertHosts[] = michael@0: { michael@0: { "expired.example.com", "expired" }, michael@0: { "selfsigned.example.com", "selfsigned" }, michael@0: { "unknownissuer.example.com", "unknownissuer" }, michael@0: { "mismatch.example.com", "mismatch" }, michael@0: { "expiredissuer.example.com", "expiredissuer" }, michael@0: { "md5signature.example.com", "md5signature" }, michael@0: { "untrusted.example.com", "localhostAndExampleCom" }, michael@0: { "untrustedissuer.example.com", "untrustedissuer" }, michael@0: { "mismatch-expired.example.com", "mismatch-expired" }, michael@0: { "mismatch-untrusted.example.com", "mismatch-untrusted" }, michael@0: { "untrusted-expired.example.com", "untrusted-expired" }, michael@0: { "md5signature-expired.example.com", "md5signature-expired" }, michael@0: { "mismatch-untrusted-expired.example.com", "mismatch-untrusted-expired" }, michael@0: { "inadequatekeyusage.example.com", "inadequatekeyusage" }, michael@0: { "selfsigned-inadequateEKU.example.com", "selfsigned-inadequateEKU" }, michael@0: { "self-signed-end-entity-with-cA-true.example.com", "self-signed-EE-with-cA-true" }, michael@0: // All of include-subdomains.pinning.example.com is pinned to End Entity michael@0: // Test Cert with nick localhostAndExampleCom. Any other nick will only michael@0: // pass pinning when security.cert_pinning.enforcement.level != strict and michael@0: // otherCA is added as a user-specified trust anchor. See StaticHPKPins.h. michael@0: { "include-subdomains.pinning.example.com", "localhostAndExampleCom" }, michael@0: { "good.include-subdomains.pinning.example.com", "localhostAndExampleCom" }, michael@0: { "bad.include-subdomains.pinning.example.com", "otherIssuerEE" }, michael@0: { "exclude-subdomains.pinning.example.com", "localhostAndExampleCom" }, michael@0: { "sub.exclude-subdomains.pinning.example.com", "otherIssuerEE" }, michael@0: { "test-mode.pinning.example.com", "otherIssuerEE" }, michael@0: { nullptr, nullptr } michael@0: }; michael@0: michael@0: int32_t michael@0: DoSNISocketConfig(PRFileDesc *aFd, const SECItem *aSrvNameArr, michael@0: uint32_t aSrvNameArrSize, void *aArg) michael@0: { michael@0: const BadCertHost *host = GetHostForSNI(aSrvNameArr, aSrvNameArrSize, michael@0: sBadCertHosts); michael@0: if (!host) { michael@0: return SSL_SNI_SEND_ALERT; michael@0: } michael@0: michael@0: if (gDebugLevel >= DEBUG_VERBOSE) { michael@0: fprintf(stderr, "found pre-defined host '%s'\n", host->mHostName); michael@0: } michael@0: michael@0: ScopedCERTCertificate cert; michael@0: SSLKEAType certKEA; michael@0: if (SECSuccess != ConfigSecureServerWithNamedCert(aFd, host->mCertName, michael@0: &cert, &certKEA)) { michael@0: return SSL_SNI_SEND_ALERT; michael@0: } michael@0: michael@0: return 0; michael@0: } michael@0: michael@0: int michael@0: main(int argc, char *argv[]) michael@0: { michael@0: if (argc != 2) { michael@0: fprintf(stderr, "usage: %s \n", argv[0]); michael@0: return 1; michael@0: } michael@0: michael@0: return StartServer(argv[1], DoSNISocketConfig, nullptr); michael@0: }