1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/cmd/ocspresp/ocspresp.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,248 @@ 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 +/* 1.9 + * ocspresp - self test for OCSP response creation 1.10 + */ 1.11 + 1.12 +#include "nspr.h" 1.13 +#include "secutil.h" 1.14 +#include "secpkcs7.h" 1.15 +#include "cert.h" 1.16 +#include "certdb.h" 1.17 +#include "nss.h" 1.18 +#include "pk11func.h" 1.19 +#include "cryptohi.h" 1.20 +#include "ocsp.h" 1.21 + 1.22 +#if defined(XP_UNIX) 1.23 +#include <unistd.h> 1.24 +#endif 1.25 + 1.26 +#include <stdio.h> 1.27 +#include <string.h> 1.28 + 1.29 +secuPWData pwdata = { PW_NONE, 0 }; 1.30 + 1.31 +static PRBool 1.32 +getCaAndSubjectCert(CERTCertDBHandle *certHandle, 1.33 + const char *caNick, const char *eeNick, 1.34 + CERTCertificate **outCA, CERTCertificate **outCert) 1.35 +{ 1.36 + *outCA = CERT_FindCertByNickname(certHandle, caNick); 1.37 + *outCert = CERT_FindCertByNickname(certHandle, eeNick); 1.38 + return *outCA && *outCert; 1.39 +} 1.40 + 1.41 +static SECItem * 1.42 +encode(PLArenaPool *arena, CERTOCSPCertID *cid, CERTCertificate *ca) 1.43 +{ 1.44 + SECItem *response; 1.45 + PRTime now = PR_Now(); 1.46 + PRTime nextUpdate; 1.47 + CERTOCSPSingleResponse **responses; 1.48 + CERTOCSPSingleResponse *sr; 1.49 + 1.50 + if (!arena) 1.51 + return NULL; 1.52 + 1.53 + nextUpdate = now + 10 * PR_USEC_PER_SEC; /* in the future */ 1.54 + 1.55 + sr = CERT_CreateOCSPSingleResponseGood(arena, cid, now, &nextUpdate); 1.56 + 1.57 + /* meaning of value 2: one entry + one end marker */ 1.58 + responses = PORT_ArenaNewArray(arena, CERTOCSPSingleResponse*, 2); 1.59 + if (responses == NULL) 1.60 + return NULL; 1.61 + 1.62 + responses[0] = sr; 1.63 + responses[1] = NULL; 1.64 + 1.65 + response = CERT_CreateEncodedOCSPSuccessResponse( 1.66 + arena, ca, ocspResponderID_byName, now, responses, &pwdata); 1.67 + 1.68 + return response; 1.69 +} 1.70 + 1.71 +static SECItem * 1.72 +encodeRevoked(PLArenaPool *arena, CERTOCSPCertID *cid, CERTCertificate *ca) 1.73 +{ 1.74 + SECItem *response; 1.75 + PRTime now = PR_Now(); 1.76 + PRTime revocationTime; 1.77 + CERTOCSPSingleResponse **responses; 1.78 + CERTOCSPSingleResponse *sr; 1.79 + 1.80 + if (!arena) 1.81 + return NULL; 1.82 + 1.83 + revocationTime = now - 10 * PR_USEC_PER_SEC; /* in the past */ 1.84 + 1.85 + sr = CERT_CreateOCSPSingleResponseRevoked(arena, cid, now, NULL, 1.86 + revocationTime, NULL); 1.87 + 1.88 + /* meaning of value 2: one entry + one end marker */ 1.89 + responses = PORT_ArenaNewArray(arena, CERTOCSPSingleResponse*, 2); 1.90 + if (responses == NULL) 1.91 + return NULL; 1.92 + 1.93 + responses[0] = sr; 1.94 + responses[1] = NULL; 1.95 + 1.96 + response = CERT_CreateEncodedOCSPSuccessResponse( 1.97 + arena, ca, ocspResponderID_byName, now, responses, &pwdata); 1.98 + 1.99 + return response; 1.100 +} 1.101 + 1.102 +int Usage(void) 1.103 +{ 1.104 + PRFileDesc *pr_stderr = PR_STDERR; 1.105 + PR_fprintf (pr_stderr, "ocspresp runs an internal selftest for OCSP response creation"); 1.106 + PR_fprintf (pr_stderr, "Usage:"); 1.107 + PR_fprintf (pr_stderr, 1.108 + "\tocspresp <dbdir> <CA-nick> <EE-nick> [-p <pass>] [-f <file>]\n"); 1.109 + PR_fprintf (pr_stderr, 1.110 + "\tdbdir: Find security databases in \"dbdir\"\n"); 1.111 + PR_fprintf (pr_stderr, 1.112 + "\tCA-nick: nickname of a trusted CA certificate with private key\n"); 1.113 + PR_fprintf (pr_stderr, 1.114 + "\tEE-nick: nickname of a entity cert issued by CA\n"); 1.115 + PR_fprintf (pr_stderr, 1.116 + "\t-p: a password for db\n"); 1.117 + PR_fprintf (pr_stderr, 1.118 + "\t-f: a filename containing the password for db\n"); 1.119 + return -1; 1.120 +} 1.121 + 1.122 +int 1.123 +main(int argc, char **argv) 1.124 +{ 1.125 + SECStatus rv; 1.126 + int retval = -1; 1.127 + CERTCertDBHandle *certHandle = NULL; 1.128 + CERTCertificate *caCert = NULL, *cert = NULL; 1.129 + CERTOCSPCertID *cid = NULL; 1.130 + PLArenaPool *arena = NULL; 1.131 + PRTime now = PR_Now(); 1.132 + 1.133 + SECItem *encoded = NULL; 1.134 + CERTOCSPResponse *decoded = NULL; 1.135 + SECStatus statusDecoded; 1.136 + 1.137 + SECItem *encodedRev = NULL; 1.138 + CERTOCSPResponse *decodedRev = NULL; 1.139 + SECStatus statusDecodedRev; 1.140 + 1.141 + SECItem *encodedFail = NULL; 1.142 + CERTOCSPResponse *decodedFail = NULL; 1.143 + SECStatus statusDecodedFail; 1.144 + 1.145 + CERTCertificate *obtainedSignerCert = NULL; 1.146 + 1.147 + if (argc != 4 && argc != 6) { 1.148 + return Usage(); 1.149 + } 1.150 + 1.151 + if (argc == 6) { 1.152 + if (!strcmp(argv[4], "-p")) { 1.153 + pwdata.source = PW_PLAINTEXT; 1.154 + pwdata.data = PORT_Strdup(argv[5]); 1.155 + } 1.156 + else if (!strcmp(argv[4], "-f")) { 1.157 + pwdata.source = PW_FROMFILE; 1.158 + pwdata.data = PORT_Strdup(argv[5]); 1.159 + } 1.160 + else 1.161 + return Usage(); 1.162 + } 1.163 + 1.164 + PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); 1.165 + /*rv = NSS_Init(SECU_ConfigDirectory(NULL));*/ 1.166 + rv = NSS_Init(argv[1]); 1.167 + if (rv != SECSuccess) { 1.168 + SECU_PrintPRandOSError(argv[0]); 1.169 + goto loser; 1.170 + } 1.171 + 1.172 + PK11_SetPasswordFunc(SECU_GetModulePassword); 1.173 + 1.174 + certHandle = CERT_GetDefaultCertDB(); 1.175 + if (!certHandle) 1.176 + goto loser; 1.177 + 1.178 + if (!getCaAndSubjectCert(certHandle, argv[2], argv[3], &caCert, &cert)) 1.179 + goto loser; 1.180 + 1.181 + cid = CERT_CreateOCSPCertID(cert, now); 1.182 + 1.183 + arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 1.184 + encoded = encode(arena, cid, caCert); 1.185 + PORT_Assert(encoded); 1.186 + decoded = CERT_DecodeOCSPResponse(encoded); 1.187 + statusDecoded = CERT_GetOCSPResponseStatus(decoded); 1.188 + PORT_Assert(statusDecoded == SECSuccess); 1.189 + 1.190 + statusDecoded = CERT_VerifyOCSPResponseSignature(decoded, certHandle, &pwdata, 1.191 + &obtainedSignerCert, caCert); 1.192 + PORT_Assert(statusDecoded == SECSuccess); 1.193 + statusDecoded = CERT_GetOCSPStatusForCertID(certHandle, decoded, cid, 1.194 + obtainedSignerCert, now); 1.195 + PORT_Assert(statusDecoded == SECSuccess); 1.196 + CERT_DestroyCertificate(obtainedSignerCert); 1.197 + 1.198 + encodedRev = encodeRevoked(arena, cid, caCert); 1.199 + PORT_Assert(encodedRev); 1.200 + decodedRev = CERT_DecodeOCSPResponse(encodedRev); 1.201 + statusDecodedRev = CERT_GetOCSPResponseStatus(decodedRev); 1.202 + PORT_Assert(statusDecodedRev == SECSuccess); 1.203 + 1.204 + statusDecodedRev = CERT_VerifyOCSPResponseSignature(decodedRev, certHandle, &pwdata, 1.205 + &obtainedSignerCert, caCert); 1.206 + PORT_Assert(statusDecodedRev == SECSuccess); 1.207 + statusDecodedRev = CERT_GetOCSPStatusForCertID(certHandle, decodedRev, cid, 1.208 + obtainedSignerCert, now); 1.209 + PORT_Assert(statusDecodedRev == SECFailure); 1.210 + PORT_Assert(PORT_GetError() == SEC_ERROR_REVOKED_CERTIFICATE); 1.211 + CERT_DestroyCertificate(obtainedSignerCert); 1.212 + 1.213 + encodedFail = CERT_CreateEncodedOCSPErrorResponse( 1.214 + arena, SEC_ERROR_OCSP_TRY_SERVER_LATER); 1.215 + PORT_Assert(encodedFail); 1.216 + decodedFail = CERT_DecodeOCSPResponse(encodedFail); 1.217 + statusDecodedFail = CERT_GetOCSPResponseStatus(decodedFail); 1.218 + PORT_Assert(statusDecodedFail == SECFailure); 1.219 + PORT_Assert(PORT_GetError() == SEC_ERROR_OCSP_TRY_SERVER_LATER); 1.220 + 1.221 + retval = 0; 1.222 +loser: 1.223 + if (retval != 0) 1.224 + SECU_PrintError(argv[0], "tests failed"); 1.225 + 1.226 + if (cid) 1.227 + CERT_DestroyOCSPCertID(cid); 1.228 + if (cert) 1.229 + CERT_DestroyCertificate(cert); 1.230 + if (caCert) 1.231 + CERT_DestroyCertificate(caCert); 1.232 + if (arena) 1.233 + PORT_FreeArena(arena, PR_FALSE); 1.234 + if (decoded) 1.235 + CERT_DestroyOCSPResponse(decoded); 1.236 + if (decodedRev) 1.237 + CERT_DestroyOCSPResponse(decodedRev); 1.238 + if (decodedFail) 1.239 + CERT_DestroyOCSPResponse(decodedFail); 1.240 + if (pwdata.data) { 1.241 + PORT_Free(pwdata.data); 1.242 + } 1.243 + 1.244 + if (NSS_Shutdown() != SECSuccess) { 1.245 + SECU_PrintError(argv[0], "NSS shutdown:"); 1.246 + if (retval == 0) 1.247 + retval = -2; 1.248 + } 1.249 + 1.250 + return retval; 1.251 +}