bug 932519 - (1/3) move common OCSP response generation test code for refactoring r=cviecco r=briansmith

--HG--
rename : security/manager/ssl/tests/unit/tlsserver/cmd/OCSPStaplingServer.cpp => security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp
rename : security/manager/ssl/tests/unit/tlsserver/cmd/OCSPStaplingServer.cpp => security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.h
This commit is contained in:
David Keeler 2013-11-11 13:43:04 -08:00
Родитель a159c977b2
Коммит 67c258e9bf
4 изменённых файлов: 249 добавлений и 216 удалений

Просмотреть файл

@ -12,39 +12,13 @@
// it will connect to a specified port and issue a simple HTTP request.
#include <stdio.h>
#include "OCSPCommon.h"
#include "TLSServer.h"
#include "ScopedNSSTypes.h"
#include "ssl.h"
#include "secerr.h"
using namespace mozilla;
using namespace mozilla::test;
enum OCSPStapleResponseType
{
OSRTNull = 0,
OSRTGood, // the certificate is good
OSRTRevoked, // the certificate has been revoked
OSRTUnknown, // the responder doesn't know if the cert is good
OSRTGoodOtherCert, // the response references a different certificate
OSRTGoodOtherCA, // the wrong CA has signed the response
OSRTExpired, // the signature on the response has expired
OSRTExpiredFreshCA, // fresh signature, but old validity period
OSRTNone, // no stapled response
OSRTEmpty, // an empty stapled response
OSRTMalformed, // the response from the responder was malformed
OSRTSrverr, // the response indicates there was a server error
OSRTTryLater, // the responder replied with "try again later"
OSRTNeedsSig, // the response needs a signature
OSRTUnauthorized // the responder is not authorized for this certificate
};
struct OCSPHost
{
const char *mHostName;
OCSPStapleResponseType mOSRT;
};
const OCSPHost sOCSPHosts[] =
{
{ "ocsp-stapling-good.example.com", OSRTGood },
@ -64,194 +38,6 @@ const OCSPHost sOCSPHosts[] =
{ nullptr, OSRTNull }
};
SECItemArray *
GetOCSPResponseForType(OCSPStapleResponseType aOSRT, CERTCertificate *aCert,
PLArenaPool *aArena)
{
if (aOSRT == OSRTNone) {
if (gDebugLevel >= DEBUG_WARNINGS) {
fprintf(stderr, "GetOCSPResponseForType called with type OSRTNone, "
"which makes no sense.\n");
}
return nullptr;
}
PRTime now = PR_Now();
ScopedCERTOCSPCertID id(CERT_CreateOCSPCertID(aCert, now));
if (!id) {
PrintPRError("CERT_CreateOCSPCertID failed");
return nullptr;
}
PRTime nextUpdate = now + 10 * PR_USEC_PER_SEC;
PRTime oneDay = 60*60*24 * (PRTime)PR_USEC_PER_SEC;
PRTime expiredTime = now - oneDay;
PRTime oldNow = now - (8 * oneDay);
PRTime oldNextUpdate = oldNow + 10 * PR_USEC_PER_SEC;
CERTOCSPSingleResponse *sr = nullptr;
switch (aOSRT) {
case OSRTGood:
case OSRTGoodOtherCA:
sr = CERT_CreateOCSPSingleResponseGood(aArena, id, now, &nextUpdate);
if (!sr) {
PrintPRError("CERT_CreateOCSPSingleResponseGood failed");
return nullptr;
}
id.forget(); // owned by sr now
break;
case OSRTRevoked:
sr = CERT_CreateOCSPSingleResponseRevoked(aArena, id, now, &nextUpdate,
expiredTime, nullptr);
if (!sr) {
PrintPRError("CERT_CreateOCSPSingleResponseRevoked failed");
return nullptr;
}
id.forget(); // owned by sr now
break;
case OSRTUnknown:
sr = CERT_CreateOCSPSingleResponseUnknown(aArena, id, now, &nextUpdate);
if (!sr) {
PrintPRError("CERT_CreateOCSPSingleResponseUnknown failed");
return nullptr;
}
id.forget(); // owned by sr now
break;
case OSRTExpired:
case OSRTExpiredFreshCA:
sr = CERT_CreateOCSPSingleResponseGood(aArena, id, oldNow, &oldNextUpdate);
if (!sr) {
PrintPRError("CERT_CreateOCSPSingleResponseGood failed");
return nullptr;
}
id.forget(); // owned by sr now
break;
case OSRTGoodOtherCert:
{
ScopedCERTCertificate otherCert(
PK11_FindCertFromNickname("ocspOtherEndEntity", nullptr));
if (!otherCert) {
PrintPRError("PK11_FindCertFromNickname failed");
return nullptr;
}
ScopedCERTOCSPCertID otherID(CERT_CreateOCSPCertID(otherCert, now));
if (!otherID) {
PrintPRError("CERT_CreateOCSPCertID failed");
return nullptr;
}
sr = CERT_CreateOCSPSingleResponseGood(aArena, otherID, now, &nextUpdate);
if (!sr) {
PrintPRError("CERT_CreateOCSPSingleResponseGood failed");
return nullptr;
}
otherID.forget(); // owned by sr now
break;
}
case OSRTEmpty:
case OSRTMalformed:
case OSRTSrverr:
case OSRTTryLater:
case OSRTNeedsSig:
case OSRTUnauthorized:
break;
default:
if (gDebugLevel >= DEBUG_ERRORS) {
fprintf(stderr, "bad ocsp response type: %d\n", aOSRT);
}
return nullptr;
}
ScopedCERTCertificate ca;
if (aOSRT == OSRTGoodOtherCA) {
ca = PK11_FindCertFromNickname("otherCA", nullptr);
if (!ca) {
PrintPRError("PK11_FindCertFromNickname failed");
return nullptr;
}
} else {
// XXX CERT_FindCertIssuer uses the old, deprecated path-building logic
ca = CERT_FindCertIssuer(aCert, now, certUsageSSLCA);
if (!ca) {
PrintPRError("CERT_FindCertIssuer failed");
return nullptr;
}
}
PRTime signTime = now;
if (aOSRT == OSRTExpired) {
signTime = oldNow;
}
CERTOCSPSingleResponse **responses;
SECItem *response = nullptr;
switch (aOSRT) {
case OSRTMalformed:
response = CERT_CreateEncodedOCSPErrorResponse(
aArena, SEC_ERROR_OCSP_MALFORMED_REQUEST);
if (!response) {
PrintPRError("CERT_CreateEncodedOCSPErrorResponse failed");
return nullptr;
}
break;
case OSRTSrverr:
response = CERT_CreateEncodedOCSPErrorResponse(
aArena, SEC_ERROR_OCSP_SERVER_ERROR);
if (!response) {
PrintPRError("CERT_CreateEncodedOCSPErrorResponse failed");
return nullptr;
}
break;
case OSRTTryLater:
response = CERT_CreateEncodedOCSPErrorResponse(
aArena, SEC_ERROR_OCSP_TRY_SERVER_LATER);
if (!response) {
PrintPRError("CERT_CreateEncodedOCSPErrorResponse failed");
return nullptr;
}
break;
case OSRTNeedsSig:
response = CERT_CreateEncodedOCSPErrorResponse(
aArena, SEC_ERROR_OCSP_REQUEST_NEEDS_SIG);
if (!response) {
PrintPRError("CERT_CreateEncodedOCSPErrorResponse failed");
return nullptr;
}
break;
case OSRTUnauthorized:
response = CERT_CreateEncodedOCSPErrorResponse(
aArena, SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST);
if (!response) {
PrintPRError("CERT_CreateEncodedOCSPErrorResponse failed");
return nullptr;
}
break;
case OSRTEmpty:
break;
default:
// responses is contained in aArena and will be freed when aArena is
responses = PORT_ArenaNewArray(aArena, CERTOCSPSingleResponse *, 2);
if (!responses) {
PrintPRError("PORT_ArenaNewArray failed");
return nullptr;
}
responses[0] = sr;
responses[1] = nullptr;
response = CERT_CreateEncodedOCSPSuccessResponse(
aArena, ca, ocspResponderID_byName, signTime, responses, nullptr);
if (!response) {
PrintPRError("CERT_CreateEncodedOCSPSuccessResponse failed");
return nullptr;
}
break;
}
SECItemArray *arr = SECITEM_AllocArray(aArena, nullptr, 1);
arr->items[0].data = response ? response->data : nullptr;
arr->items[0].len = response ? response->len : 0;
return arr;
}
int32_t
DoSNISocketConfig(PRFileDesc *aFd, const SECItem *aSrvNameArr,
uint32_t aSrvNameArrSize, void *aArg)

Просмотреть файл

@ -0,0 +1,203 @@
/* 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/. */
#include "OCSPCommon.h"
#include <stdio.h>
#include "TLSServer.h"
#include "ScopedNSSTypes.h"
#include "secerr.h"
using namespace mozilla;
using namespace mozilla::test;
SECItemArray *
GetOCSPResponseForType(OCSPStapleResponseType aOSRT, CERTCertificate *aCert,
PLArenaPool *aArena)
{
if (aOSRT == OSRTNone) {
if (gDebugLevel >= DEBUG_WARNINGS) {
fprintf(stderr, "GetOCSPResponseForType called with type OSRTNone, "
"which makes no sense.\n");
}
return nullptr;
}
PRTime now = PR_Now();
ScopedCERTOCSPCertID id(CERT_CreateOCSPCertID(aCert, now));
if (!id) {
PrintPRError("CERT_CreateOCSPCertID failed");
return nullptr;
}
PRTime nextUpdate = now + 10 * PR_USEC_PER_SEC;
PRTime oneDay = 60*60*24 * (PRTime)PR_USEC_PER_SEC;
PRTime expiredTime = now - oneDay;
PRTime oldNow = now - (8 * oneDay);
PRTime oldNextUpdate = oldNow + 10 * PR_USEC_PER_SEC;
CERTOCSPSingleResponse *sr = nullptr;
switch (aOSRT) {
case OSRTGood:
case OSRTGoodOtherCA:
sr = CERT_CreateOCSPSingleResponseGood(aArena, id, now, &nextUpdate);
if (!sr) {
PrintPRError("CERT_CreateOCSPSingleResponseGood failed");
return nullptr;
}
id.forget(); // owned by sr now
break;
case OSRTRevoked:
sr = CERT_CreateOCSPSingleResponseRevoked(aArena, id, now, &nextUpdate,
expiredTime, nullptr);
if (!sr) {
PrintPRError("CERT_CreateOCSPSingleResponseRevoked failed");
return nullptr;
}
id.forget(); // owned by sr now
break;
case OSRTUnknown:
sr = CERT_CreateOCSPSingleResponseUnknown(aArena, id, now, &nextUpdate);
if (!sr) {
PrintPRError("CERT_CreateOCSPSingleResponseUnknown failed");
return nullptr;
}
id.forget(); // owned by sr now
break;
case OSRTExpired:
case OSRTExpiredFreshCA:
sr = CERT_CreateOCSPSingleResponseGood(aArena, id, oldNow, &oldNextUpdate);
if (!sr) {
PrintPRError("CERT_CreateOCSPSingleResponseGood failed");
return nullptr;
}
id.forget(); // owned by sr now
break;
case OSRTGoodOtherCert:
{
ScopedCERTCertificate otherCert(
PK11_FindCertFromNickname("ocspOtherEndEntity", nullptr));
if (!otherCert) {
PrintPRError("PK11_FindCertFromNickname failed");
return nullptr;
}
ScopedCERTOCSPCertID otherID(CERT_CreateOCSPCertID(otherCert, now));
if (!otherID) {
PrintPRError("CERT_CreateOCSPCertID failed");
return nullptr;
}
sr = CERT_CreateOCSPSingleResponseGood(aArena, otherID, now, &nextUpdate);
if (!sr) {
PrintPRError("CERT_CreateOCSPSingleResponseGood failed");
return nullptr;
}
otherID.forget(); // owned by sr now
break;
}
case OSRTEmpty:
case OSRTMalformed:
case OSRTSrverr:
case OSRTTryLater:
case OSRTNeedsSig:
case OSRTUnauthorized:
break;
default:
if (gDebugLevel >= DEBUG_ERRORS) {
fprintf(stderr, "bad ocsp response type: %d\n", aOSRT);
}
return nullptr;
}
ScopedCERTCertificate ca;
if (aOSRT == OSRTGoodOtherCA) {
ca = PK11_FindCertFromNickname("otherCA", nullptr);
if (!ca) {
PrintPRError("PK11_FindCertFromNickname failed");
return nullptr;
}
} else {
// XXX CERT_FindCertIssuer uses the old, deprecated path-building logic
ca = CERT_FindCertIssuer(aCert, now, certUsageSSLCA);
if (!ca) {
PrintPRError("CERT_FindCertIssuer failed");
return nullptr;
}
}
PRTime signTime = now;
if (aOSRT == OSRTExpired) {
signTime = oldNow;
}
CERTOCSPSingleResponse **responses;
SECItem *response = nullptr;
switch (aOSRT) {
case OSRTMalformed:
response = CERT_CreateEncodedOCSPErrorResponse(
aArena, SEC_ERROR_OCSP_MALFORMED_REQUEST);
if (!response) {
PrintPRError("CERT_CreateEncodedOCSPErrorResponse failed");
return nullptr;
}
break;
case OSRTSrverr:
response = CERT_CreateEncodedOCSPErrorResponse(
aArena, SEC_ERROR_OCSP_SERVER_ERROR);
if (!response) {
PrintPRError("CERT_CreateEncodedOCSPErrorResponse failed");
return nullptr;
}
break;
case OSRTTryLater:
response = CERT_CreateEncodedOCSPErrorResponse(
aArena, SEC_ERROR_OCSP_TRY_SERVER_LATER);
if (!response) {
PrintPRError("CERT_CreateEncodedOCSPErrorResponse failed");
return nullptr;
}
break;
case OSRTNeedsSig:
response = CERT_CreateEncodedOCSPErrorResponse(
aArena, SEC_ERROR_OCSP_REQUEST_NEEDS_SIG);
if (!response) {
PrintPRError("CERT_CreateEncodedOCSPErrorResponse failed");
return nullptr;
}
break;
case OSRTUnauthorized:
response = CERT_CreateEncodedOCSPErrorResponse(
aArena, SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST);
if (!response) {
PrintPRError("CERT_CreateEncodedOCSPErrorResponse failed");
return nullptr;
}
break;
case OSRTEmpty:
break;
default:
// responses is contained in aArena and will be freed when aArena is
responses = PORT_ArenaNewArray(aArena, CERTOCSPSingleResponse *, 2);
if (!responses) {
PrintPRError("PORT_ArenaNewArray failed");
return nullptr;
}
responses[0] = sr;
responses[1] = nullptr;
response = CERT_CreateEncodedOCSPSuccessResponse(
aArena, ca, ocspResponderID_byName, signTime, responses, nullptr);
if (!response) {
PrintPRError("CERT_CreateEncodedOCSPSuccessResponse failed");
return nullptr;
}
break;
}
SECItemArray *arr = SECITEM_AllocArray(aArena, nullptr, 1);
arr->items[0].data = response ? response->data : nullptr;
arr->items[0].len = response ? response->len : 0;
return arr;
}

Просмотреть файл

@ -0,0 +1,43 @@
/* 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/. */
// Implements generating OCSP responses of various types. Used by the
// programs in tlsserver/cmd.
#ifndef OCSPCommon_h
#define OCSPCommon_h
#include "certt.h"
#include "seccomon.h"
enum OCSPStapleResponseType
{
OSRTNull = 0,
OSRTGood, // the certificate is good
OSRTRevoked, // the certificate has been revoked
OSRTUnknown, // the responder doesn't know if the cert is good
OSRTGoodOtherCert, // the response references a different certificate
OSRTGoodOtherCA, // the wrong CA has signed the response
OSRTExpired, // the signature on the response has expired
OSRTExpiredFreshCA, // fresh signature, but old validity period
OSRTNone, // no stapled response
OSRTEmpty, // an empty stapled response
OSRTMalformed, // the response from the responder was malformed
OSRTSrverr, // the response indicates there was a server error
OSRTTryLater, // the responder replied with "try again later"
OSRTNeedsSig, // the response needs a signature
OSRTUnauthorized // the responder is not authorized for this certificate
};
struct OCSPHost
{
const char *mHostName;
OCSPStapleResponseType mOSRT;
};
SECItemArray *
GetOCSPResponseForType(OCSPStapleResponseType aOSRT, CERTCertificate *aCert,
PLArenaPool *aArena);
#endif // OCSPCommon_h

Просмотреть файл

@ -7,6 +7,7 @@
MODULE = 'tlsserver'
SOURCES += [
'OCSPCommon.cpp',
'TLSServer.cpp',
]