ocspclnt.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,221 行 · 第 1/3 页
C
1,221 行
/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Netscape security libraries. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1994-2000 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. *//* * Test program for client-side OCSP. * * $Id: ocspclnt.c,v 1.1 2000/03/31 20:09:29 relyea%netscape.com Exp $ */#include "secutil.h"#include "nspr.h"#include "plgetopt.h"#include "nss.h"#include "cert.h"#include "ocsp.h"#include "xconst.h" /* * XXX internal header file; needed to get at * cert_DecodeAuthInfoAccessExtension -- would be * nice to not need this, but that would require * better/different APIs. */#ifndef NO_PP /* * Compile with this every once in a while to be * sure that no dependencies on it get added * outside of the pretty-printing routines. */#include "ocspti.h" /* internals for pretty-printing routines *only* */#endif /* NO_PP */#define DEFAULT_DB_DIR "~/.netscape"static voidsynopsis (char *program_name){ PRFileDesc *pr_stderr; pr_stderr = PR_STDERR; PR_fprintf (pr_stderr, "Usage:"); PR_fprintf (pr_stderr, "\t%s -p [-d <dir>]\n", program_name); PR_fprintf (pr_stderr, "\t%s -P [-d <dir>]\n", program_name); PR_fprintf (pr_stderr, "\t%s -r <name> [-L] [-s <name>] [-d <dir>]\n", program_name); PR_fprintf (pr_stderr, "\t%s -R <name> [-l <location>] [-s <name>] [-d <dir>]\n", program_name); PR_fprintf (pr_stderr, "\t%s -S <name> [-l <location> -t <name>]\n", program_name); PR_fprintf (pr_stderr, "\t\t [-s <name>] [-w <time>] [-d <dir>]\n"); PR_fprintf (pr_stderr, "\t%s -V <name> -u <usage> [-l <location> -t <name>]\n", program_name); PR_fprintf (pr_stderr, "\t\t [-s <name>] [-w <time>] [-d <dir>]\n");}static voidshort_usage (char *program_name){ PR_fprintf (PR_STDERR, "Type %s -H for more detailed descriptions\n", program_name); synopsis (program_name);}static voidlong_usage (char *program_name){ PRFileDesc *pr_stderr; pr_stderr = PR_STDERR; synopsis (program_name); PR_fprintf (pr_stderr, "\nCommands (must specify exactly one):\n"); PR_fprintf (pr_stderr, " %-13s Pretty-print a binary request read from stdin\n", "-p"); PR_fprintf (pr_stderr, " %-13s Pretty-print a binary response read from stdin\n", "-P"); PR_fprintf (pr_stderr, " %-13s Create a request for cert \"nickname\" on stdout\n", "-r nickname"); PR_fprintf (pr_stderr, " %-13s Get response for cert \"nickname\", dump to stdout\n", "-R nickname"); PR_fprintf (pr_stderr, " %-13s Get status for cert \"nickname\"\n", "-S nickname"); PR_fprintf (pr_stderr, " %-13s Fully verify cert \"nickname\", w/ status check\n", "-V nickname"); PR_fprintf (pr_stderr, "Options:\n"); PR_fprintf (pr_stderr, " %-13s Add the service locator extension to the request\n", "-L"); PR_fprintf (pr_stderr, " %-13s Find security databases in \"dbdir\" (default %s)\n", "-d dbdir", DEFAULT_DB_DIR); PR_fprintf (pr_stderr, " %-13s Use \"location\" as URL of responder\n", "-l location"); PR_fprintf (pr_stderr, " %-13s Trust cert \"nickname\" as response signer\n", "-t nickname"); PR_fprintf (pr_stderr, " %-13s Sign requests with cert \"nickname\"\n", "-s nickname"); PR_fprintf (pr_stderr, " %-13s Type of certificate usage for verification:\n", "-u usage"); PR_fprintf (pr_stderr, "%-17s c SSL Client\n", ""); PR_fprintf (pr_stderr, "%-17s s SSL Server\n", ""); PR_fprintf (pr_stderr, "%-17s e Email Recipient\n", ""); PR_fprintf (pr_stderr, "%-17s E Email Signer\n", ""); PR_fprintf (pr_stderr, "%-17s S Object Signer\n", ""); PR_fprintf (pr_stderr, "%-17s C CA\n", ""); PR_fprintf (pr_stderr, " %-13s Validity time (default current time), one of:\n", "-w time"); PR_fprintf (pr_stderr, "%-17s %-25s (GMT)\n", "", "YYMMDDhhmm[ss]Z"); PR_fprintf (pr_stderr, "%-17s %-25s (later than GMT)\n", "", "YYMMDDhhmm[ss]+hhmm"); PR_fprintf (pr_stderr, "%-17s %-25s (earlier than GMT)\n", "", "YYMMDDhhmm[ss]-hhmm");}/* * XXX This is a generic function that would probably make a good * replacement for SECU_DER_Read (which is not at all specific to DER, * despite its name), but that requires fixing all of the tools... * Still, it should be done, whenenver I/somebody has the time. * (Also, consider whether this actually belongs in the security * library itself, not just in the command library.) * * This function takes an open file (a PRFileDesc *) and reads the * entire file into a SECItem. (Obviously, the file is intended to * be small enough that such a thing is advisable.) Both the SECItem * and the buffer it points to are allocated from the heap; the caller * is expected to free them. ("SECITEM_FreeItem(item, PR_TRUE)") */static SECItem *read_file_into_item (PRFileDesc *in_file, SECItemType si_type){ PRStatus prv; SECItem *item; PRFileInfo file_info; PRInt32 bytes_read; prv = PR_GetOpenFileInfo (in_file, &file_info); if (prv != PR_SUCCESS) return NULL; if (file_info.size == 0) { /* XXX Need a better error; just grabbed this one for expediency. */ PORT_SetError (SEC_ERROR_INPUT_LEN); return NULL; } if (file_info.size > 0xffff) { /* I think this is too big. */ PORT_SetError (SEC_ERROR_NO_MEMORY); return NULL; } item = PORT_Alloc (sizeof (SECItem)); if (item == NULL) return NULL; item->type = si_type; item->len = (unsigned int) file_info.size; item->data = PORT_Alloc ((size_t)item->len); if (item->data == NULL) goto loser; bytes_read = PR_Read (in_file, item->data, (PRInt32) item->len); if (bytes_read < 0) { /* Something went wrong; error is already set for us. */ goto loser; } else if (bytes_read == 0) { /* Something went wrong; we read nothing. But no system/nspr error. */ /* XXX Need to set an error here. */ goto loser; } else if (item->len != (unsigned int)bytes_read) { /* Something went wrong; we read less (or more!?) than we expected. */ /* XXX Need to set an error here. */ goto loser; } return item;loser: SECITEM_FreeItem (item, PR_TRUE); return NULL;}/* * Create a DER-encoded OCSP request (for the certificate whose nickname * is "name") and dump it out. */static SECStatuscreate_request (FILE *out_file, CERTCertDBHandle *handle, const char *cert_name, PRBool add_service_locator, PRBool add_acceptable_responses){ CERTCertificate *cert = NULL; CERTCertList *certs = NULL; CERTOCSPRequest *request = NULL; int64 now = PR_Now(); SECItem *encoding = NULL; SECStatus rv = SECFailure; if (handle == NULL || cert_name == NULL) goto loser; cert = CERT_FindCertByNicknameOrEmailAddr (handle, (char *) cert_name); if (cert == NULL) goto loser; /* * We need to create a list of one. */ certs = CERT_NewCertList(); if (certs == NULL) goto loser; if (CERT_AddCertToListTail (certs, cert) != SECSuccess) goto loser; /* * Now that cert is included in the list, we need to be careful * that we do not try to destroy it twice. This will prevent that. */ cert = NULL; request = CERT_CreateOCSPRequest (certs, now, add_service_locator, NULL); if (request == NULL) goto loser; if (add_acceptable_responses) { rv = CERT_AddOCSPAcceptableResponses(request, SEC_OID_PKIX_OCSP_BASIC_RESPONSE); if (rv != SECSuccess) goto loser; } encoding = CERT_EncodeOCSPRequest (NULL, request, NULL); if (encoding == NULL) goto loser; if (fwrite (encoding->data, encoding->len, 1, out_file) != 1) goto loser; rv = SECSuccess;loser: if (encoding != NULL) SECITEM_FreeItem(encoding, PR_TRUE); if (request != NULL) CERT_DestroyOCSPRequest(request); if (certs != NULL) CERT_DestroyCertList (certs); if (cert != NULL) CERT_DestroyCertificate (cert); return rv;}/* * Create a DER-encoded OCSP request (for the certificate whose nickname is * "cert_name"), then get and dump a corresponding response. The responder * location is either specified explicitly (as "responder_url") or found * via the AuthorityInfoAccess URL in the cert. */static SECStatusdump_response (FILE *out_file, CERTCertDBHandle *handle, const char *cert_name, const char *responder_url){ CERTCertificate *cert = NULL; CERTCertList *certs = NULL; char *loc = NULL; int64 now = PR_Now(); SECItem *response = NULL; SECStatus rv = SECFailure; PRBool includeServiceLocator; if (handle == NULL || cert_name == NULL) goto loser; cert = CERT_FindCertByNicknameOrEmailAddr (handle, (char *) cert_name); if (cert == NULL) goto loser; if (responder_url != NULL) { loc = (char *) responder_url; includeServiceLocator = PR_TRUE; } else { loc = CERT_GetOCSPAuthorityInfoAccessLocation (cert); if (loc == NULL) goto loser; includeServiceLocator = PR_FALSE; } /* * We need to create a list of one. */ certs = CERT_NewCertList(); if (certs == NULL) goto loser; if (CERT_AddCertToListTail (certs, cert) != SECSuccess) goto loser; /* * Now that cert is included in the list, we need to be careful * that we do not try to destroy it twice. This will prevent that. */ cert = NULL; response = CERT_GetEncodedOCSPResponse (NULL, certs, loc, now, includeServiceLocator, NULL, NULL, NULL); if (response == NULL) goto loser; if (fwrite (response->data, response->len, 1, out_file) != 1) goto loser; rv = SECSuccess;loser: if (response != NULL) SECITEM_FreeItem (response, PR_TRUE); if (certs != NULL) CERT_DestroyCertList (certs); if (loc != NULL && loc != responder_url) PORT_Free (loc); if (cert != NULL) CERT_DestroyCertificate (cert); return rv;}/* * Get the status for the specified certificate (whose nickname is "cert_name"). * Directly use the OCSP function rather than doing a full verification. */static SECStatusget_cert_status (FILE *out_file, CERTCertDBHandle *handle, const char *cert_name, int64 verify_time){ CERTCertificate *cert = NULL; SECStatus rv = SECFailure; if (handle == NULL || cert_name == NULL) goto loser; cert = CERT_FindCertByNicknameOrEmailAddr (handle, (char *) cert_name); if (cert == NULL)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?