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