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 }