diff options
Diffstat (limited to 'security/nss/cmd/ocspresp')
-rw-r--r-- | security/nss/cmd/ocspresp/Makefile | 47 | ||||
-rw-r--r-- | security/nss/cmd/ocspresp/manifest.mn | 15 | ||||
-rw-r--r-- | security/nss/cmd/ocspresp/ocspresp.c | 251 | ||||
-rw-r--r-- | security/nss/cmd/ocspresp/ocspresp.gyp | 24 |
4 files changed, 337 insertions, 0 deletions
diff --git a/security/nss/cmd/ocspresp/Makefile b/security/nss/cmd/ocspresp/Makefile new file mode 100644 index 000000000..6e1d4ecdf --- /dev/null +++ b/security/nss/cmd/ocspresp/Makefile @@ -0,0 +1,47 @@ +#! gmake +# +# 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/. + +####################################################################### +# (1) Include initial platform-independent assignments (MANDATORY). # +####################################################################### + +include manifest.mn + +####################################################################### +# (2) Include "global" configuration information. (OPTIONAL) # +####################################################################### + +include $(CORE_DEPTH)/coreconf/config.mk + +####################################################################### +# (3) Include "component" configuration information. (OPTIONAL) # +####################################################################### + +####################################################################### +# (4) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + +include ../platlibs.mk + +####################################################################### +# (5) Execute "global" rules. (OPTIONAL) # +####################################################################### + +include $(CORE_DEPTH)/coreconf/rules.mk + +####################################################################### +# (6) Execute "component" rules. (OPTIONAL) # +####################################################################### + + + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + +include ../platrules.mk + diff --git a/security/nss/cmd/ocspresp/manifest.mn b/security/nss/cmd/ocspresp/manifest.mn new file mode 100644 index 000000000..3608623b8 --- /dev/null +++ b/security/nss/cmd/ocspresp/manifest.mn @@ -0,0 +1,15 @@ +# +# 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/. + +CORE_DEPTH = ../.. + +MODULE = nss + +CSRCS = ocspresp.c + +REQUIRES = seccmd + +PROGRAM = ocspresp + diff --git a/security/nss/cmd/ocspresp/ocspresp.c b/security/nss/cmd/ocspresp/ocspresp.c new file mode 100644 index 000000000..632623c97 --- /dev/null +++ b/security/nss/cmd/ocspresp/ocspresp.c @@ -0,0 +1,251 @@ +/* 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/. */ + +/* + * ocspresp - self test for OCSP response creation + */ + +#include "nspr.h" +#include "secutil.h" +#include "secpkcs7.h" +#include "cert.h" +#include "certdb.h" +#include "nss.h" +#include "pk11func.h" +#include "cryptohi.h" +#include "ocsp.h" + +#if defined(XP_UNIX) +#include <unistd.h> +#endif + +#include <stdio.h> +#include <string.h> + +secuPWData pwdata = { PW_NONE, 0 }; + +static PRBool +getCaAndSubjectCert(CERTCertDBHandle *certHandle, + const char *caNick, const char *eeNick, + CERTCertificate **outCA, CERTCertificate **outCert) +{ + *outCA = CERT_FindCertByNickname(certHandle, caNick); + *outCert = CERT_FindCertByNickname(certHandle, eeNick); + return *outCA && *outCert; +} + +static SECItem * +encode(PLArenaPool *arena, CERTOCSPCertID *cid, CERTCertificate *ca) +{ + SECItem *response; + PRTime now = PR_Now(); + PRTime nextUpdate; + CERTOCSPSingleResponse **responses; + CERTOCSPSingleResponse *sr; + + if (!arena) + return NULL; + + nextUpdate = now + 10 * PR_USEC_PER_SEC; /* in the future */ + + sr = CERT_CreateOCSPSingleResponseGood(arena, cid, now, &nextUpdate); + + /* meaning of value 2: one entry + one end marker */ + responses = PORT_ArenaNewArray(arena, CERTOCSPSingleResponse *, 2); + if (responses == NULL) + return NULL; + + responses[0] = sr; + responses[1] = NULL; + + response = CERT_CreateEncodedOCSPSuccessResponse( + arena, ca, ocspResponderID_byName, now, responses, &pwdata); + + return response; +} + +static SECItem * +encodeRevoked(PLArenaPool *arena, CERTOCSPCertID *cid, CERTCertificate *ca) +{ + SECItem *response; + PRTime now = PR_Now(); + PRTime revocationTime; + CERTOCSPSingleResponse **responses; + CERTOCSPSingleResponse *sr; + + if (!arena) + return NULL; + + revocationTime = now - 10 * PR_USEC_PER_SEC; /* in the past */ + + sr = CERT_CreateOCSPSingleResponseRevoked(arena, cid, now, NULL, + revocationTime, NULL); + + /* meaning of value 2: one entry + one end marker */ + responses = PORT_ArenaNewArray(arena, CERTOCSPSingleResponse *, 2); + if (responses == NULL) + return NULL; + + responses[0] = sr; + responses[1] = NULL; + + response = CERT_CreateEncodedOCSPSuccessResponse( + arena, ca, ocspResponderID_byName, now, responses, &pwdata); + + return response; +} + +int +Usage(void) +{ + PRFileDesc *pr_stderr = PR_STDERR; + PR_fprintf(pr_stderr, "ocspresp runs an internal selftest for OCSP response creation"); + PR_fprintf(pr_stderr, "Usage:"); + PR_fprintf(pr_stderr, + "\tocspresp <dbdir> <CA-nick> <EE-nick> [-p <pass>] [-f <file>]\n"); + PR_fprintf(pr_stderr, + "\tdbdir: Find security databases in \"dbdir\"\n"); + PR_fprintf(pr_stderr, + "\tCA-nick: nickname of a trusted CA certificate with private key\n"); + PR_fprintf(pr_stderr, + "\tEE-nick: nickname of a entity cert issued by CA\n"); + PR_fprintf(pr_stderr, + "\t-p: a password for db\n"); + PR_fprintf(pr_stderr, + "\t-f: a filename containing the password for db\n"); + return -1; +} + +int +main(int argc, char **argv) +{ + SECStatus rv; + int retval = -1; + CERTCertDBHandle *certHandle = NULL; + CERTCertificate *caCert = NULL, *cert = NULL; + CERTOCSPCertID *cid = NULL; + PLArenaPool *arena = NULL; + PRTime now = PR_Now(); + + SECItem *encoded = NULL; + CERTOCSPResponse *decoded = NULL; + + SECItem *encodedRev = NULL; + CERTOCSPResponse *decodedRev = NULL; + + SECItem *encodedFail = NULL; + CERTOCSPResponse *decodedFail = NULL; + + CERTCertificate *obtainedSignerCert = NULL; + + if (argc != 4 && argc != 6) { + return Usage(); + } + + if (argc == 6) { + if (!strcmp(argv[4], "-p")) { + pwdata.source = PW_PLAINTEXT; + pwdata.data = PORT_Strdup(argv[5]); + } else if (!strcmp(argv[4], "-f")) { + pwdata.source = PW_FROMFILE; + pwdata.data = PORT_Strdup(argv[5]); + } else + return Usage(); + } + + PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); + /*rv = NSS_Init(SECU_ConfigDirectory(NULL));*/ + rv = NSS_Init(argv[1]); + if (rv != SECSuccess) { + SECU_PrintPRandOSError(argv[0]); + goto loser; + } + + PK11_SetPasswordFunc(SECU_GetModulePassword); + + certHandle = CERT_GetDefaultCertDB(); + if (!certHandle) + goto loser; + + if (!getCaAndSubjectCert(certHandle, argv[2], argv[3], &caCert, &cert)) + goto loser; + + cid = CERT_CreateOCSPCertID(cert, now); + + arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + encoded = encode(arena, cid, caCert); + PORT_Assert(encoded); + decoded = CERT_DecodeOCSPResponse(encoded); + PORT_CheckSuccess(CERT_GetOCSPResponseStatus(decoded)); + + PORT_CheckSuccess(CERT_VerifyOCSPResponseSignature(decoded, certHandle, &pwdata, + &obtainedSignerCert, caCert)); + PORT_CheckSuccess(CERT_GetOCSPStatusForCertID(certHandle, decoded, cid, + obtainedSignerCert, now)); + CERT_DestroyCertificate(obtainedSignerCert); + + encodedRev = encodeRevoked(arena, cid, caCert); + PORT_Assert(encodedRev); + decodedRev = CERT_DecodeOCSPResponse(encodedRev); + PORT_CheckSuccess(CERT_GetOCSPResponseStatus(decodedRev)); + + PORT_CheckSuccess(CERT_VerifyOCSPResponseSignature(decodedRev, certHandle, &pwdata, + &obtainedSignerCert, caCert)); +#ifdef DEBUG + { + SECStatus rv = CERT_GetOCSPStatusForCertID(certHandle, decodedRev, cid, + obtainedSignerCert, now); + PORT_Assert(rv == SECFailure); + PORT_Assert(PORT_GetError() == SEC_ERROR_REVOKED_CERTIFICATE); + } +#else + (void)CERT_GetOCSPStatusForCertID(certHandle, decodedRev, cid, + obtainedSignerCert, now); +#endif + CERT_DestroyCertificate(obtainedSignerCert); + + encodedFail = CERT_CreateEncodedOCSPErrorResponse( + arena, SEC_ERROR_OCSP_TRY_SERVER_LATER); + PORT_Assert(encodedFail); + decodedFail = CERT_DecodeOCSPResponse(encodedFail); +#ifdef DEBUG + { + SECStatus rv = CERT_GetOCSPResponseStatus(decodedFail); + PORT_Assert(rv == SECFailure); + PORT_Assert(PORT_GetError() == SEC_ERROR_OCSP_TRY_SERVER_LATER); + } +#else + (void)CERT_GetOCSPResponseStatus(decodedFail); +#endif + retval = 0; +loser: + if (retval != 0) + SECU_PrintError(argv[0], "tests failed"); + + if (cid) + CERT_DestroyOCSPCertID(cid); + if (cert) + CERT_DestroyCertificate(cert); + if (caCert) + CERT_DestroyCertificate(caCert); + if (arena) + PORT_FreeArena(arena, PR_FALSE); + if (decoded) + CERT_DestroyOCSPResponse(decoded); + if (decodedRev) + CERT_DestroyOCSPResponse(decodedRev); + if (decodedFail) + CERT_DestroyOCSPResponse(decodedFail); + if (pwdata.data) { + PORT_Free(pwdata.data); + } + + if (NSS_Shutdown() != SECSuccess) { + SECU_PrintError(argv[0], "NSS shutdown:"); + if (retval == 0) + retval = -2; + } + + return retval; +} diff --git a/security/nss/cmd/ocspresp/ocspresp.gyp b/security/nss/cmd/ocspresp/ocspresp.gyp new file mode 100644 index 000000000..81f02dfe8 --- /dev/null +++ b/security/nss/cmd/ocspresp/ocspresp.gyp @@ -0,0 +1,24 @@ +# 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/. +{ + 'includes': [ + '../../coreconf/config.gypi', + '../../cmd/platlibs.gypi' + ], + 'targets': [ + { + 'target_name': 'ocspresp', + 'type': 'executable', + 'sources': [ + 'ocspresp.c' + ], + 'dependencies': [ + '<(DEPTH)/exports.gyp:nss_exports' + ] + } + ], + 'variables': { + 'module': 'nss' + } +}
\ No newline at end of file |