security/manager/ssl/tests/unit/tlsserver/cmd/OCSPStaplingServer.cpp

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:d342bde0f63b
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 delivers various stapled OCSP responses.
6 // The client is expected to connect, initiate an SSL handshake (with SNI
7 // to indicate which "server" to connect to), and verify the OCSP response.
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 "OCSPCommon.h"
17 #include "TLSServer.h"
18
19 using namespace mozilla;
20 using namespace mozilla::test;
21
22 const OCSPHost sOCSPHosts[] =
23 {
24 { "ocsp-stapling-good.example.com", ORTGood, nullptr },
25 { "ocsp-stapling-revoked.example.com", ORTRevoked, nullptr },
26 { "ocsp-stapling-revoked-old.example.com", ORTRevokedOld, nullptr },
27 { "ocsp-stapling-unknown.example.com", ORTUnknown, nullptr },
28 { "ocsp-stapling-unknown-old.example.com", ORTUnknownOld, nullptr },
29 { "ocsp-stapling-good-other.example.com", ORTGoodOtherCert, "ocspOtherEndEntity" },
30 { "ocsp-stapling-good-other-ca.example.com", ORTGoodOtherCA, "otherCA" },
31 { "ocsp-stapling-expired.example.com", ORTExpired, nullptr },
32 { "ocsp-stapling-expired-fresh-ca.example.com", ORTExpiredFreshCA, nullptr },
33 { "ocsp-stapling-none.example.com", ORTNone, nullptr },
34 { "ocsp-stapling-empty.example.com", ORTEmpty, nullptr },
35 { "ocsp-stapling-malformed.example.com", ORTMalformed, nullptr },
36 { "ocsp-stapling-srverr.example.com", ORTSrverr, nullptr },
37 { "ocsp-stapling-trylater.example.com", ORTTryLater, nullptr },
38 { "ocsp-stapling-needssig.example.com", ORTNeedsSig, nullptr },
39 { "ocsp-stapling-unauthorized.example.com", ORTUnauthorized, nullptr },
40 { "ocsp-stapling-with-intermediate.example.com", ORTGood, "ocspEEWithIntermediate" },
41 { "ocsp-stapling-bad-signature.example.com", ORTBadSignature, nullptr },
42 { "ocsp-stapling-skip-responseBytes.example.com", ORTSkipResponseBytes, nullptr },
43 { "ocsp-stapling-critical-extension.example.com", ORTCriticalExtension, nullptr },
44 { "ocsp-stapling-noncritical-extension.example.com", ORTNoncriticalExtension, nullptr },
45 { "ocsp-stapling-empty-extensions.example.com", ORTEmptyExtensions, nullptr },
46 { "ocsp-stapling-delegated-included.example.com", ORTDelegatedIncluded, "delegatedSigner" },
47 { "ocsp-stapling-delegated-included-last.example.com", ORTDelegatedIncludedLast, "delegatedSigner" },
48 { "ocsp-stapling-delegated-missing.example.com", ORTDelegatedMissing, "delegatedSigner" },
49 { "ocsp-stapling-delegated-missing-multiple.example.com", ORTDelegatedMissingMultiple, "delegatedSigner" },
50 { "ocsp-stapling-delegated-no-extKeyUsage.example.com", ORTDelegatedIncluded, "invalidDelegatedSignerNoExtKeyUsage" },
51 { "ocsp-stapling-delegated-from-intermediate.example.com", ORTDelegatedIncluded, "invalidDelegatedSignerFromIntermediate" },
52 { "ocsp-stapling-delegated-keyUsage-crlSigning.example.com", ORTDelegatedIncluded, "invalidDelegatedSignerKeyUsageCrlSigning" },
53 { "ocsp-stapling-delegated-wrong-extKeyUsage.example.com", ORTDelegatedIncluded, "invalidDelegatedSignerWrongExtKeyUsage" },
54 { "ocsp-stapling-ancient-valid.example.com", ORTAncientAlmostExpired, nullptr},
55 { nullptr, ORTNull, nullptr }
56 };
57
58 int32_t
59 DoSNISocketConfig(PRFileDesc *aFd, const SECItem *aSrvNameArr,
60 uint32_t aSrvNameArrSize, void *aArg)
61 {
62 const OCSPHost *host = GetHostForSNI(aSrvNameArr, aSrvNameArrSize,
63 sOCSPHosts);
64 if (!host) {
65 return SSL_SNI_SEND_ALERT;
66 }
67
68 if (gDebugLevel >= DEBUG_VERBOSE) {
69 fprintf(stderr, "found pre-defined host '%s'\n", host->mHostName);
70 }
71
72 const char *certNickname;
73 if (strcmp(host->mHostName,
74 "ocsp-stapling-with-intermediate.example.com") == 0) {
75 certNickname = host->mAdditionalCertName;
76 } else {
77 certNickname = DEFAULT_CERT_NICKNAME;
78 }
79
80 ScopedCERTCertificate cert;
81 SSLKEAType certKEA;
82 if (SECSuccess != ConfigSecureServerWithNamedCert(aFd, certNickname,
83 &cert, &certKEA)) {
84 return SSL_SNI_SEND_ALERT;
85 }
86
87 // If the OCSP response type is "none", don't staple a response.
88 if (host->mORT == ORTNone) {
89 return 0;
90 }
91
92 PLArenaPool *arena = PORT_NewArena(1024);
93 if (!arena) {
94 PrintPRError("PORT_NewArena failed");
95 return SSL_SNI_SEND_ALERT;
96 }
97
98 // response is contained by the arena - freeing the arena will free it
99 SECItemArray *response = GetOCSPResponseForType(host->mORT, cert, arena,
100 host->mAdditionalCertName);
101 if (!response) {
102 PORT_FreeArena(arena, PR_FALSE);
103 return SSL_SNI_SEND_ALERT;
104 }
105
106 // SSL_SetStapledOCSPResponses makes a deep copy of response
107 SECStatus st = SSL_SetStapledOCSPResponses(aFd, response, certKEA);
108 PORT_FreeArena(arena, PR_FALSE);
109 if (st != SECSuccess) {
110 PrintPRError("SSL_SetStapledOCSPResponses failed");
111 return SSL_SNI_SEND_ALERT;
112 }
113
114 return 0;
115 }
116
117 int
118 main(int argc, char *argv[])
119 {
120 if (argc != 2) {
121 fprintf(stderr, "usage: %s <NSS DB directory>\n", argv[0]);
122 return 1;
123 }
124
125 return StartServer(argv[1], DoSNISocketConfig, nullptr);
126 }

mercurial