tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

SanctionsTestServer.cpp (3376B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 // This is a standalone server that uses various bad certificates.
      6 // The client is expected to connect, initiate an SSL handshake (with SNI
      7 // to indicate which "server" to connect to), and verify the certificate.
      8 // If all is good, the client then sends one encrypted byte and receives that
      9 // same byte back.
     10 // This server also has the ability to "call back" another process waiting on
     11 // it. That is, when the server is all set up and ready to receive connections,
     12 // it will connect to a specified port and issue a simple HTTP request.
     13 
     14 #include <stdio.h>
     15 
     16 #include "TLSServer.h"
     17 
     18 using namespace mozilla;
     19 using namespace mozilla::test;
     20 
     21 struct SanctionsCertHost {
     22  const char* mHostName;
     23  const char* mCertName;
     24 };
     25 
     26 // Hostname, cert nickname pairs.
     27 const SanctionsCertHost sSanctionsCertHosts[] = {
     28    {"symantec-allowlist-after-cutoff.example.com",
     29     "symantec-ee-from-allowlist-after-cutoff"},
     30    {"symantec-allowlist-before-cutoff.example.com",
     31     "symantec-ee-from-allowlist-before-cutoff"},
     32    {"symantec-not-allowlisted-after-cutoff.example.com",
     33     "symantec-ee-not-allowlisted-after-cutoff"},
     34    {"symantec-not-allowlisted-before-cutoff.example.com",
     35     "symantec-ee-not-allowlisted-before-cutoff"},
     36    {"symantec-unaffected.example.com", "symantec-ee-unaffected"},
     37    {nullptr, nullptr}};
     38 
     39 int32_t DoSNISocketConfigBySubjectCN(PRFileDesc* aFd,
     40                                     const SECItem* aSrvNameArr,
     41                                     uint32_t aSrvNameArrSize) {
     42  for (uint32_t i = 0; i < aSrvNameArrSize; i++) {
     43    UniquePORTString name(
     44        static_cast<char*>(PORT_ZAlloc(aSrvNameArr[i].len + 1)));
     45    if (name) {
     46      PORT_Memcpy(name.get(), aSrvNameArr[i].data, aSrvNameArr[i].len);
     47      if (ConfigSecureServerWithNamedCert(aFd, name.get(), nullptr, nullptr,
     48                                          nullptr) == SECSuccess) {
     49        return 0;
     50      }
     51    }
     52  }
     53 
     54  return SSL_SNI_SEND_ALERT;
     55 }
     56 
     57 int32_t DoSNISocketConfig(PRFileDesc* aFd, const SECItem* aSrvNameArr,
     58                          uint32_t aSrvNameArrSize, void* aArg) {
     59  const SanctionsCertHost* host =
     60      GetHostForSNI(aSrvNameArr, aSrvNameArrSize, sSanctionsCertHosts);
     61  if (!host) {
     62    // No static cert <-> hostname mapping found. This happens when we use a
     63    // collection of certificates in a given directory and build a cert DB at
     64    // runtime, rather than using an NSS cert DB populated at build time.
     65    // (This will be the default in the future.)
     66    // For all given server names, check if the runtime-built cert DB contains
     67    // a certificate with a matching subject CN.
     68    return DoSNISocketConfigBySubjectCN(aFd, aSrvNameArr, aSrvNameArrSize);
     69  }
     70 
     71  if (gDebugLevel >= DEBUG_VERBOSE) {
     72    fprintf(stderr, "found pre-defined host '%s'\n", host->mHostName);
     73  }
     74 
     75  UniqueCERTCertificate cert;
     76  SSLKEAType certKEA;
     77  if (SECSuccess != ConfigSecureServerWithNamedCert(aFd, host->mCertName, &cert,
     78                                                    &certKEA, nullptr)) {
     79    return SSL_SNI_SEND_ALERT;
     80  }
     81 
     82  return 0;
     83 }
     84 
     85 int main(int argc, char* argv[]) {
     86  return StartServer(argc, argv, DoSNISocketConfig, nullptr);
     87 }