summaryrefslogtreecommitdiffstats
path: root/security/manager/ssl/tests/unit/tlsserver/cmd/OCSPStaplingServer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'security/manager/ssl/tests/unit/tlsserver/cmd/OCSPStaplingServer.cpp')
-rw-r--r--security/manager/ssl/tests/unit/tlsserver/cmd/OCSPStaplingServer.cpp153
1 files changed, 153 insertions, 0 deletions
diff --git a/security/manager/ssl/tests/unit/tlsserver/cmd/OCSPStaplingServer.cpp b/security/manager/ssl/tests/unit/tlsserver/cmd/OCSPStaplingServer.cpp
new file mode 100644
index 0000000000..b35484572f
--- /dev/null
+++ b/security/manager/ssl/tests/unit/tlsserver/cmd/OCSPStaplingServer.cpp
@@ -0,0 +1,153 @@
+/* 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 that delivers various stapled OCSP responses.
+// The client is expected to connect, initiate an SSL handshake (with SNI
+// to indicate which "server" to connect to), and verify the OCSP response.
+// 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 "OCSPCommon.h"
+#include "TLSServer.h"
+
+using namespace mozilla;
+using namespace mozilla::test;
+
+const OCSPHost sOCSPHosts[] = {
+ {"ocsp-stapling-good.example.com", ORTGood, nullptr, nullptr},
+ {"ocsp-stapling-revoked.example.com", ORTRevoked, nullptr, nullptr},
+ {"ocsp-stapling-revoked-old.example.com", ORTRevokedOld, nullptr, nullptr},
+ {"ocsp-stapling-unknown.example.com", ORTUnknown, nullptr, nullptr},
+ {"ocsp-stapling-unknown-old.example.com", ORTUnknownOld, nullptr, nullptr},
+ {"ocsp-stapling-good-other.example.com", ORTGoodOtherCert,
+ "ocspOtherEndEntity", nullptr},
+ {"ocsp-stapling-good-other-ca.example.com", ORTGoodOtherCA, "other-test-ca",
+ nullptr},
+ {"ocsp-stapling-expired.example.com", ORTExpired, nullptr, nullptr},
+ {"ocsp-stapling-expired-fresh-ca.example.com", ORTExpiredFreshCA, nullptr,
+ nullptr},
+ {"ocsp-stapling-none.example.com", ORTNone, nullptr, nullptr},
+ {"ocsp-stapling-empty.example.com", ORTEmpty, nullptr, nullptr},
+ {"ocsp-stapling-malformed.example.com", ORTMalformed, nullptr, nullptr},
+ {"ocsp-stapling-srverr.example.com", ORTSrverr, nullptr, nullptr},
+ {"ocsp-stapling-trylater.example.com", ORTTryLater, nullptr, nullptr},
+ {"ocsp-stapling-needssig.example.com", ORTNeedsSig, nullptr, nullptr},
+ {"ocsp-stapling-unauthorized.example.com", ORTUnauthorized, nullptr,
+ nullptr},
+ {"ocsp-stapling-with-intermediate.example.com", ORTGood, nullptr,
+ "ocspEEWithIntermediate"},
+ {"ocsp-stapling-bad-signature.example.com", ORTBadSignature, nullptr,
+ nullptr},
+ {"ocsp-stapling-skip-responseBytes.example.com", ORTSkipResponseBytes,
+ nullptr, nullptr},
+ {"ocsp-stapling-critical-extension.example.com", ORTCriticalExtension,
+ nullptr, nullptr},
+ {"ocsp-stapling-noncritical-extension.example.com", ORTNoncriticalExtension,
+ nullptr, nullptr},
+ {"ocsp-stapling-empty-extensions.example.com", ORTEmptyExtensions, nullptr,
+ nullptr},
+ {"ocsp-stapling-delegated-included.example.com", ORTDelegatedIncluded,
+ "delegatedSigner", nullptr},
+ {"ocsp-stapling-delegated-included-last.example.com",
+ ORTDelegatedIncludedLast, "delegatedSigner", nullptr},
+ {"ocsp-stapling-delegated-missing.example.com", ORTDelegatedMissing,
+ "delegatedSigner", nullptr},
+ {"ocsp-stapling-delegated-missing-multiple.example.com",
+ ORTDelegatedMissingMultiple, "delegatedSigner", nullptr},
+ {"ocsp-stapling-delegated-no-extKeyUsage.example.com", ORTDelegatedIncluded,
+ "invalidDelegatedSignerNoExtKeyUsage", nullptr},
+ {"ocsp-stapling-delegated-from-intermediate.example.com",
+ ORTDelegatedIncluded, "invalidDelegatedSignerFromIntermediate", nullptr},
+ {"ocsp-stapling-delegated-keyUsage-crlSigning.example.com",
+ ORTDelegatedIncluded, "invalidDelegatedSignerKeyUsageCrlSigning", nullptr},
+ {"ocsp-stapling-delegated-wrong-extKeyUsage.example.com",
+ ORTDelegatedIncluded, "invalidDelegatedSignerWrongExtKeyUsage", nullptr},
+ {"ocsp-stapling-ancient-valid.example.com", ORTAncientAlmostExpired,
+ nullptr, nullptr},
+ {"keysize-ocsp-delegated.example.com", ORTDelegatedIncluded,
+ "rsa-1016-keysizeDelegatedSigner", nullptr},
+ {"revoked-ca-cert-used-as-end-entity.example.com", ORTRevoked,
+ "ca-used-as-end-entity", nullptr},
+ {"ocsp-stapling-must-staple.example.com", ORTGood, nullptr,
+ "must-staple-ee"},
+ {"ocsp-stapling-must-staple-revoked.example.com", ORTRevoked, nullptr,
+ "must-staple-ee"},
+ {"ocsp-stapling-must-staple-missing.example.com", ORTNone, nullptr,
+ "must-staple-ee"},
+ {"ocsp-stapling-must-staple-empty.example.com", ORTEmpty, nullptr,
+ "must-staple-ee"},
+ {"ocsp-stapling-must-staple-ee-with-must-staple-int.example.com", ORTGood,
+ nullptr, "must-staple-ee-with-must-staple-int"},
+ {"ocsp-stapling-plain-ee-with-must-staple-int.example.com", ORTGood,
+ nullptr, "must-staple-missing-ee"},
+ {"ocsp-stapling-must-staple-expired.example.com", ORTExpired, nullptr,
+ "must-staple-ee"},
+ {"ocsp-stapling-must-staple-try-later.example.com", ORTTryLater, nullptr,
+ "must-staple-ee"},
+ {"ocsp-stapling-must-staple-invalid-signer.example.com", ORTGoodOtherCA,
+ "other-test-ca", "must-staple-ee"},
+ {"multi-tls-feature-good.example.com", ORTNone, nullptr,
+ "multi-tls-feature-good-ee"},
+ {"multi-tls-feature-bad.example.com", ORTNone, nullptr,
+ "multi-tls-feature-bad-ee"},
+ {nullptr, ORTNull, nullptr, nullptr}};
+
+int32_t DoSNISocketConfig(PRFileDesc* aFd, const SECItem* aSrvNameArr,
+ uint32_t aSrvNameArrSize, void* aArg) {
+ const OCSPHost* host =
+ GetHostForSNI(aSrvNameArr, aSrvNameArrSize, sOCSPHosts);
+ if (!host) {
+ return SSL_SNI_SEND_ALERT;
+ }
+
+ if (gDebugLevel >= DEBUG_VERBOSE) {
+ fprintf(stderr, "found pre-defined host '%s'\n", host->mHostName);
+ }
+
+ const char* certNickname =
+ host->mServerCertName ? host->mServerCertName : DEFAULT_CERT_NICKNAME;
+
+ UniqueCERTCertificate cert;
+ SSLKEAType certKEA;
+ if (SECSuccess != ConfigSecureServerWithNamedCert(aFd, certNickname, &cert,
+ &certKEA, nullptr)) {
+ return SSL_SNI_SEND_ALERT;
+ }
+
+ // If the OCSP response type is "none", don't staple a response.
+ if (host->mORT == ORTNone) {
+ return 0;
+ }
+
+ UniquePLArenaPool arena(PORT_NewArena(1024));
+ if (!arena) {
+ PrintPRError("PORT_NewArena failed");
+ return SSL_SNI_SEND_ALERT;
+ }
+
+ // response is contained by the arena - freeing the arena will free it
+ SECItemArray* response = GetOCSPResponseForType(host->mORT, cert, arena,
+ host->mAdditionalCertName, 0);
+ if (!response) {
+ return SSL_SNI_SEND_ALERT;
+ }
+
+ // SSL_SetStapledOCSPResponses makes a deep copy of response
+ SECStatus st = SSL_SetStapledOCSPResponses(aFd, response, certKEA);
+ if (st != SECSuccess) {
+ PrintPRError("SSL_SetStapledOCSPResponses failed");
+ return SSL_SNI_SEND_ALERT;
+ }
+
+ return 0;
+}
+
+int main(int argc, char* argv[]) {
+ return StartServer(argc, argv, DoSNISocketConfig, nullptr);
+}