security/nss/cmd/ocspresp/ocspresp.c

Wed, 31 Dec 2014 07:16:47 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:16:47 +0100
branch
TOR_BUG_9701
changeset 3
141e0f1194b1
permissions
-rw-r--r--

Revert simplistic fix pending revisit of Mozilla integration attempt.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 /*
michael@0 6 * ocspresp - self test for OCSP response creation
michael@0 7 */
michael@0 8
michael@0 9 #include "nspr.h"
michael@0 10 #include "secutil.h"
michael@0 11 #include "secpkcs7.h"
michael@0 12 #include "cert.h"
michael@0 13 #include "certdb.h"
michael@0 14 #include "nss.h"
michael@0 15 #include "pk11func.h"
michael@0 16 #include "cryptohi.h"
michael@0 17 #include "ocsp.h"
michael@0 18
michael@0 19 #if defined(XP_UNIX)
michael@0 20 #include <unistd.h>
michael@0 21 #endif
michael@0 22
michael@0 23 #include <stdio.h>
michael@0 24 #include <string.h>
michael@0 25
michael@0 26 secuPWData pwdata = { PW_NONE, 0 };
michael@0 27
michael@0 28 static PRBool
michael@0 29 getCaAndSubjectCert(CERTCertDBHandle *certHandle,
michael@0 30 const char *caNick, const char *eeNick,
michael@0 31 CERTCertificate **outCA, CERTCertificate **outCert)
michael@0 32 {
michael@0 33 *outCA = CERT_FindCertByNickname(certHandle, caNick);
michael@0 34 *outCert = CERT_FindCertByNickname(certHandle, eeNick);
michael@0 35 return *outCA && *outCert;
michael@0 36 }
michael@0 37
michael@0 38 static SECItem *
michael@0 39 encode(PLArenaPool *arena, CERTOCSPCertID *cid, CERTCertificate *ca)
michael@0 40 {
michael@0 41 SECItem *response;
michael@0 42 PRTime now = PR_Now();
michael@0 43 PRTime nextUpdate;
michael@0 44 CERTOCSPSingleResponse **responses;
michael@0 45 CERTOCSPSingleResponse *sr;
michael@0 46
michael@0 47 if (!arena)
michael@0 48 return NULL;
michael@0 49
michael@0 50 nextUpdate = now + 10 * PR_USEC_PER_SEC; /* in the future */
michael@0 51
michael@0 52 sr = CERT_CreateOCSPSingleResponseGood(arena, cid, now, &nextUpdate);
michael@0 53
michael@0 54 /* meaning of value 2: one entry + one end marker */
michael@0 55 responses = PORT_ArenaNewArray(arena, CERTOCSPSingleResponse*, 2);
michael@0 56 if (responses == NULL)
michael@0 57 return NULL;
michael@0 58
michael@0 59 responses[0] = sr;
michael@0 60 responses[1] = NULL;
michael@0 61
michael@0 62 response = CERT_CreateEncodedOCSPSuccessResponse(
michael@0 63 arena, ca, ocspResponderID_byName, now, responses, &pwdata);
michael@0 64
michael@0 65 return response;
michael@0 66 }
michael@0 67
michael@0 68 static SECItem *
michael@0 69 encodeRevoked(PLArenaPool *arena, CERTOCSPCertID *cid, CERTCertificate *ca)
michael@0 70 {
michael@0 71 SECItem *response;
michael@0 72 PRTime now = PR_Now();
michael@0 73 PRTime revocationTime;
michael@0 74 CERTOCSPSingleResponse **responses;
michael@0 75 CERTOCSPSingleResponse *sr;
michael@0 76
michael@0 77 if (!arena)
michael@0 78 return NULL;
michael@0 79
michael@0 80 revocationTime = now - 10 * PR_USEC_PER_SEC; /* in the past */
michael@0 81
michael@0 82 sr = CERT_CreateOCSPSingleResponseRevoked(arena, cid, now, NULL,
michael@0 83 revocationTime, NULL);
michael@0 84
michael@0 85 /* meaning of value 2: one entry + one end marker */
michael@0 86 responses = PORT_ArenaNewArray(arena, CERTOCSPSingleResponse*, 2);
michael@0 87 if (responses == NULL)
michael@0 88 return NULL;
michael@0 89
michael@0 90 responses[0] = sr;
michael@0 91 responses[1] = NULL;
michael@0 92
michael@0 93 response = CERT_CreateEncodedOCSPSuccessResponse(
michael@0 94 arena, ca, ocspResponderID_byName, now, responses, &pwdata);
michael@0 95
michael@0 96 return response;
michael@0 97 }
michael@0 98
michael@0 99 int Usage(void)
michael@0 100 {
michael@0 101 PRFileDesc *pr_stderr = PR_STDERR;
michael@0 102 PR_fprintf (pr_stderr, "ocspresp runs an internal selftest for OCSP response creation");
michael@0 103 PR_fprintf (pr_stderr, "Usage:");
michael@0 104 PR_fprintf (pr_stderr,
michael@0 105 "\tocspresp <dbdir> <CA-nick> <EE-nick> [-p <pass>] [-f <file>]\n");
michael@0 106 PR_fprintf (pr_stderr,
michael@0 107 "\tdbdir: Find security databases in \"dbdir\"\n");
michael@0 108 PR_fprintf (pr_stderr,
michael@0 109 "\tCA-nick: nickname of a trusted CA certificate with private key\n");
michael@0 110 PR_fprintf (pr_stderr,
michael@0 111 "\tEE-nick: nickname of a entity cert issued by CA\n");
michael@0 112 PR_fprintf (pr_stderr,
michael@0 113 "\t-p: a password for db\n");
michael@0 114 PR_fprintf (pr_stderr,
michael@0 115 "\t-f: a filename containing the password for db\n");
michael@0 116 return -1;
michael@0 117 }
michael@0 118
michael@0 119 int
michael@0 120 main(int argc, char **argv)
michael@0 121 {
michael@0 122 SECStatus rv;
michael@0 123 int retval = -1;
michael@0 124 CERTCertDBHandle *certHandle = NULL;
michael@0 125 CERTCertificate *caCert = NULL, *cert = NULL;
michael@0 126 CERTOCSPCertID *cid = NULL;
michael@0 127 PLArenaPool *arena = NULL;
michael@0 128 PRTime now = PR_Now();
michael@0 129
michael@0 130 SECItem *encoded = NULL;
michael@0 131 CERTOCSPResponse *decoded = NULL;
michael@0 132 SECStatus statusDecoded;
michael@0 133
michael@0 134 SECItem *encodedRev = NULL;
michael@0 135 CERTOCSPResponse *decodedRev = NULL;
michael@0 136 SECStatus statusDecodedRev;
michael@0 137
michael@0 138 SECItem *encodedFail = NULL;
michael@0 139 CERTOCSPResponse *decodedFail = NULL;
michael@0 140 SECStatus statusDecodedFail;
michael@0 141
michael@0 142 CERTCertificate *obtainedSignerCert = NULL;
michael@0 143
michael@0 144 if (argc != 4 && argc != 6) {
michael@0 145 return Usage();
michael@0 146 }
michael@0 147
michael@0 148 if (argc == 6) {
michael@0 149 if (!strcmp(argv[4], "-p")) {
michael@0 150 pwdata.source = PW_PLAINTEXT;
michael@0 151 pwdata.data = PORT_Strdup(argv[5]);
michael@0 152 }
michael@0 153 else if (!strcmp(argv[4], "-f")) {
michael@0 154 pwdata.source = PW_FROMFILE;
michael@0 155 pwdata.data = PORT_Strdup(argv[5]);
michael@0 156 }
michael@0 157 else
michael@0 158 return Usage();
michael@0 159 }
michael@0 160
michael@0 161 PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
michael@0 162 /*rv = NSS_Init(SECU_ConfigDirectory(NULL));*/
michael@0 163 rv = NSS_Init(argv[1]);
michael@0 164 if (rv != SECSuccess) {
michael@0 165 SECU_PrintPRandOSError(argv[0]);
michael@0 166 goto loser;
michael@0 167 }
michael@0 168
michael@0 169 PK11_SetPasswordFunc(SECU_GetModulePassword);
michael@0 170
michael@0 171 certHandle = CERT_GetDefaultCertDB();
michael@0 172 if (!certHandle)
michael@0 173 goto loser;
michael@0 174
michael@0 175 if (!getCaAndSubjectCert(certHandle, argv[2], argv[3], &caCert, &cert))
michael@0 176 goto loser;
michael@0 177
michael@0 178 cid = CERT_CreateOCSPCertID(cert, now);
michael@0 179
michael@0 180 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
michael@0 181 encoded = encode(arena, cid, caCert);
michael@0 182 PORT_Assert(encoded);
michael@0 183 decoded = CERT_DecodeOCSPResponse(encoded);
michael@0 184 statusDecoded = CERT_GetOCSPResponseStatus(decoded);
michael@0 185 PORT_Assert(statusDecoded == SECSuccess);
michael@0 186
michael@0 187 statusDecoded = CERT_VerifyOCSPResponseSignature(decoded, certHandle, &pwdata,
michael@0 188 &obtainedSignerCert, caCert);
michael@0 189 PORT_Assert(statusDecoded == SECSuccess);
michael@0 190 statusDecoded = CERT_GetOCSPStatusForCertID(certHandle, decoded, cid,
michael@0 191 obtainedSignerCert, now);
michael@0 192 PORT_Assert(statusDecoded == SECSuccess);
michael@0 193 CERT_DestroyCertificate(obtainedSignerCert);
michael@0 194
michael@0 195 encodedRev = encodeRevoked(arena, cid, caCert);
michael@0 196 PORT_Assert(encodedRev);
michael@0 197 decodedRev = CERT_DecodeOCSPResponse(encodedRev);
michael@0 198 statusDecodedRev = CERT_GetOCSPResponseStatus(decodedRev);
michael@0 199 PORT_Assert(statusDecodedRev == SECSuccess);
michael@0 200
michael@0 201 statusDecodedRev = CERT_VerifyOCSPResponseSignature(decodedRev, certHandle, &pwdata,
michael@0 202 &obtainedSignerCert, caCert);
michael@0 203 PORT_Assert(statusDecodedRev == SECSuccess);
michael@0 204 statusDecodedRev = CERT_GetOCSPStatusForCertID(certHandle, decodedRev, cid,
michael@0 205 obtainedSignerCert, now);
michael@0 206 PORT_Assert(statusDecodedRev == SECFailure);
michael@0 207 PORT_Assert(PORT_GetError() == SEC_ERROR_REVOKED_CERTIFICATE);
michael@0 208 CERT_DestroyCertificate(obtainedSignerCert);
michael@0 209
michael@0 210 encodedFail = CERT_CreateEncodedOCSPErrorResponse(
michael@0 211 arena, SEC_ERROR_OCSP_TRY_SERVER_LATER);
michael@0 212 PORT_Assert(encodedFail);
michael@0 213 decodedFail = CERT_DecodeOCSPResponse(encodedFail);
michael@0 214 statusDecodedFail = CERT_GetOCSPResponseStatus(decodedFail);
michael@0 215 PORT_Assert(statusDecodedFail == SECFailure);
michael@0 216 PORT_Assert(PORT_GetError() == SEC_ERROR_OCSP_TRY_SERVER_LATER);
michael@0 217
michael@0 218 retval = 0;
michael@0 219 loser:
michael@0 220 if (retval != 0)
michael@0 221 SECU_PrintError(argv[0], "tests failed");
michael@0 222
michael@0 223 if (cid)
michael@0 224 CERT_DestroyOCSPCertID(cid);
michael@0 225 if (cert)
michael@0 226 CERT_DestroyCertificate(cert);
michael@0 227 if (caCert)
michael@0 228 CERT_DestroyCertificate(caCert);
michael@0 229 if (arena)
michael@0 230 PORT_FreeArena(arena, PR_FALSE);
michael@0 231 if (decoded)
michael@0 232 CERT_DestroyOCSPResponse(decoded);
michael@0 233 if (decodedRev)
michael@0 234 CERT_DestroyOCSPResponse(decodedRev);
michael@0 235 if (decodedFail)
michael@0 236 CERT_DestroyOCSPResponse(decodedFail);
michael@0 237 if (pwdata.data) {
michael@0 238 PORT_Free(pwdata.data);
michael@0 239 }
michael@0 240
michael@0 241 if (NSS_Shutdown() != SECSuccess) {
michael@0 242 SECU_PrintError(argv[0], "NSS shutdown:");
michael@0 243 if (retval == 0)
michael@0 244 retval = -2;
michael@0 245 }
michael@0 246
michael@0 247 return retval;
michael@0 248 }

mercurial