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

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/security/manager/ssl/tests/unit/tlsserver/cmd/OCSPStaplingServer.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,126 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +// This is a standalone server that delivers various stapled OCSP responses.
     1.9 +// The client is expected to connect, initiate an SSL handshake (with SNI
    1.10 +// to indicate which "server" to connect to), and verify the OCSP response.
    1.11 +// If all is good, the client then sends one encrypted byte and receives that
    1.12 +// same byte back.
    1.13 +// This server also has the ability to "call back" another process waiting on
    1.14 +// it. That is, when the server is all set up and ready to receive connections,
    1.15 +// it will connect to a specified port and issue a simple HTTP request.
    1.16 +
    1.17 +#include <stdio.h>
    1.18 +
    1.19 +#include "OCSPCommon.h"
    1.20 +#include "TLSServer.h"
    1.21 +
    1.22 +using namespace mozilla;
    1.23 +using namespace mozilla::test;
    1.24 +
    1.25 +const OCSPHost sOCSPHosts[] =
    1.26 +{
    1.27 +  { "ocsp-stapling-good.example.com", ORTGood, nullptr },
    1.28 +  { "ocsp-stapling-revoked.example.com", ORTRevoked, nullptr },
    1.29 +  { "ocsp-stapling-revoked-old.example.com", ORTRevokedOld, nullptr },
    1.30 +  { "ocsp-stapling-unknown.example.com", ORTUnknown, nullptr },
    1.31 +  { "ocsp-stapling-unknown-old.example.com", ORTUnknownOld, nullptr },
    1.32 +  { "ocsp-stapling-good-other.example.com", ORTGoodOtherCert, "ocspOtherEndEntity" },
    1.33 +  { "ocsp-stapling-good-other-ca.example.com", ORTGoodOtherCA, "otherCA" },
    1.34 +  { "ocsp-stapling-expired.example.com", ORTExpired, nullptr },
    1.35 +  { "ocsp-stapling-expired-fresh-ca.example.com", ORTExpiredFreshCA, nullptr },
    1.36 +  { "ocsp-stapling-none.example.com", ORTNone, nullptr },
    1.37 +  { "ocsp-stapling-empty.example.com", ORTEmpty, nullptr },
    1.38 +  { "ocsp-stapling-malformed.example.com", ORTMalformed, nullptr },
    1.39 +  { "ocsp-stapling-srverr.example.com", ORTSrverr, nullptr },
    1.40 +  { "ocsp-stapling-trylater.example.com", ORTTryLater, nullptr },
    1.41 +  { "ocsp-stapling-needssig.example.com", ORTNeedsSig, nullptr },
    1.42 +  { "ocsp-stapling-unauthorized.example.com", ORTUnauthorized, nullptr },
    1.43 +  { "ocsp-stapling-with-intermediate.example.com", ORTGood, "ocspEEWithIntermediate" },
    1.44 +  { "ocsp-stapling-bad-signature.example.com", ORTBadSignature, nullptr },
    1.45 +  { "ocsp-stapling-skip-responseBytes.example.com", ORTSkipResponseBytes, nullptr },
    1.46 +  { "ocsp-stapling-critical-extension.example.com", ORTCriticalExtension, nullptr },
    1.47 +  { "ocsp-stapling-noncritical-extension.example.com", ORTNoncriticalExtension, nullptr },
    1.48 +  { "ocsp-stapling-empty-extensions.example.com", ORTEmptyExtensions, nullptr },
    1.49 +  { "ocsp-stapling-delegated-included.example.com", ORTDelegatedIncluded, "delegatedSigner" },
    1.50 +  { "ocsp-stapling-delegated-included-last.example.com", ORTDelegatedIncludedLast, "delegatedSigner" },
    1.51 +  { "ocsp-stapling-delegated-missing.example.com", ORTDelegatedMissing, "delegatedSigner" },
    1.52 +  { "ocsp-stapling-delegated-missing-multiple.example.com", ORTDelegatedMissingMultiple, "delegatedSigner" },
    1.53 +  { "ocsp-stapling-delegated-no-extKeyUsage.example.com", ORTDelegatedIncluded, "invalidDelegatedSignerNoExtKeyUsage" },
    1.54 +  { "ocsp-stapling-delegated-from-intermediate.example.com", ORTDelegatedIncluded, "invalidDelegatedSignerFromIntermediate" },
    1.55 +  { "ocsp-stapling-delegated-keyUsage-crlSigning.example.com", ORTDelegatedIncluded, "invalidDelegatedSignerKeyUsageCrlSigning" },
    1.56 +  { "ocsp-stapling-delegated-wrong-extKeyUsage.example.com", ORTDelegatedIncluded, "invalidDelegatedSignerWrongExtKeyUsage" },
    1.57 +  { "ocsp-stapling-ancient-valid.example.com", ORTAncientAlmostExpired, nullptr},
    1.58 +  { nullptr, ORTNull, nullptr }
    1.59 +};
    1.60 +
    1.61 +int32_t
    1.62 +DoSNISocketConfig(PRFileDesc *aFd, const SECItem *aSrvNameArr,
    1.63 +                  uint32_t aSrvNameArrSize, void *aArg)
    1.64 +{
    1.65 +  const OCSPHost *host = GetHostForSNI(aSrvNameArr, aSrvNameArrSize,
    1.66 +                                       sOCSPHosts);
    1.67 +  if (!host) {
    1.68 +    return SSL_SNI_SEND_ALERT;
    1.69 +  }
    1.70 +
    1.71 +  if (gDebugLevel >= DEBUG_VERBOSE) {
    1.72 +    fprintf(stderr, "found pre-defined host '%s'\n", host->mHostName);
    1.73 +  }
    1.74 +
    1.75 +  const char *certNickname;
    1.76 +  if (strcmp(host->mHostName,
    1.77 +             "ocsp-stapling-with-intermediate.example.com") == 0) {
    1.78 +    certNickname = host->mAdditionalCertName;
    1.79 +  } else {
    1.80 +    certNickname = DEFAULT_CERT_NICKNAME;
    1.81 +  }
    1.82 +
    1.83 +  ScopedCERTCertificate cert;
    1.84 +  SSLKEAType certKEA;
    1.85 +  if (SECSuccess != ConfigSecureServerWithNamedCert(aFd, certNickname,
    1.86 +                                                    &cert, &certKEA)) {
    1.87 +    return SSL_SNI_SEND_ALERT;
    1.88 +  }
    1.89 +
    1.90 +  // If the OCSP response type is "none", don't staple a response.
    1.91 +  if (host->mORT == ORTNone) {
    1.92 +    return 0;
    1.93 +  }
    1.94 +
    1.95 +  PLArenaPool *arena = PORT_NewArena(1024);
    1.96 +  if (!arena) {
    1.97 +    PrintPRError("PORT_NewArena failed");
    1.98 +    return SSL_SNI_SEND_ALERT;
    1.99 +  }
   1.100 +
   1.101 +  // response is contained by the arena - freeing the arena will free it
   1.102 +  SECItemArray *response = GetOCSPResponseForType(host->mORT, cert, arena,
   1.103 +                                                  host->mAdditionalCertName);
   1.104 +  if (!response) {
   1.105 +    PORT_FreeArena(arena, PR_FALSE);
   1.106 +    return SSL_SNI_SEND_ALERT;
   1.107 +  }
   1.108 +
   1.109 +  // SSL_SetStapledOCSPResponses makes a deep copy of response
   1.110 +  SECStatus st = SSL_SetStapledOCSPResponses(aFd, response, certKEA);
   1.111 +  PORT_FreeArena(arena, PR_FALSE);
   1.112 +  if (st != SECSuccess) {
   1.113 +    PrintPRError("SSL_SetStapledOCSPResponses failed");
   1.114 +    return SSL_SNI_SEND_ALERT;
   1.115 +  }
   1.116 +
   1.117 +  return 0;
   1.118 +}
   1.119 +
   1.120 +int
   1.121 +main(int argc, char *argv[])
   1.122 +{
   1.123 +  if (argc != 2) {
   1.124 +    fprintf(stderr, "usage: %s <NSS DB directory>\n", argv[0]);
   1.125 +    return 1;
   1.126 +  }
   1.127 +
   1.128 +  return StartServer(argv[1], DoSNISocketConfig, nullptr);
   1.129 +}

mercurial