Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions | Variables
ocspclnt.c File Reference
#include "secutil.h"
#include "nspr.h"
#include "plgetopt.h"
#include "nss.h"
#include "cert.h"
#include "ocsp.h"
#include "xconst.h"
#include "ocspti.h"

Go to the source code of this file.

Defines

#define DEFAULT_DB_DIR   "~/.netscape"
#define NOTYET(opt)

Functions

static void synopsis (char *program_name)
static void short_usage (char *program_name)
static void long_usage (char *program_name)
static SECItem * read_file_into_item (PRFileDesc *in_file, SECItemType si_type)
static SECStatus create_request (FILE *out_file, CERTCertDBHandle *handle, const char *cert_name, PRBool add_service_locator, PRBool add_acceptable_responses)
static SECStatus dump_response (FILE *out_file, CERTCertDBHandle *handle, const char *cert_name, const char *responder_url)
static SECStatus get_cert_status (FILE *out_file, CERTCertDBHandle *handle, const char *cert_name, int64 verify_time)
static SECStatus verify_cert (FILE *out_file, CERTCertDBHandle *handle, const char *cert_name, SECCertUsage cert_usage, int64 verify_time)
static void print_ocsp_version (FILE *out_file, SECItem *version, int level)
static void print_ocsp_cert_id (FILE *out_file, CERTOCSPCertID *cert_id, int level)
static void print_raw_certificates (FILE *out_file, SECItem **raw_certs, int level)
static void print_ocsp_extensions (FILE *out_file, CERTCertExtension **extensions, char *msg, int level)
static void print_single_request (FILE *out_file, ocspSingleRequest *single, int level)
static SECStatus print_request (FILE *out_file, SECItem *data)
static void print_revoked_info (FILE *out_file, ocspRevokedInfo *revoked_info, int level)
static void print_cert_status (FILE *out_file, ocspCertStatus *status, int level)
static void print_single_response (FILE *out_file, CERTOCSPSingleResponse *single, int level)
static void print_responder_id (FILE *out_file, ocspResponderID *responderID, int level)
static void print_response_data (FILE *out_file, ocspResponseData *responseData, int level)
static void print_basic_response (FILE *out_file, ocspBasicOCSPResponse *basic, int level)
static SECStatus print_response (FILE *out_file, SECItem *data, CERTCertDBHandle *handle)
static SECStatus cert_usage_from_char (const char *cert_usage_str, SECCertUsage *cert_usage)
int main (int argc, char **argv)
 The Xalan testcases app.

Variables

static char * responseStatusNames []

Define Documentation

#define DEFAULT_DB_DIR   "~/.netscape"

Definition at line 64 of file ocspclnt.c.

#define NOTYET (   opt)
Value:
{                                                       \
           PR_fprintf (PR_STDERR, "%s not yet working\n", opt);       \
           exit (-1);                                                 \
       }

Function Documentation

static SECStatus cert_usage_from_char ( const char *  cert_usage_str,
SECCertUsage cert_usage 
) [static]

Definition at line 894 of file ocspclnt.c.

{
    PORT_Assert (cert_usage_str != NULL);
    PORT_Assert (cert_usage != NULL);

    if (PORT_Strlen (cert_usage_str) != 1)
       return SECFailure;

    switch (*cert_usage_str) {
      case 'c':
       *cert_usage = certUsageSSLClient;
       break;
      case 's':
       *cert_usage = certUsageSSLServer;
       break;
      case 'e':
       *cert_usage = certUsageEmailRecipient;
       break;
      case 'E':
       *cert_usage = certUsageEmailSigner;
       break;
      case 'S':
       *cert_usage = certUsageObjectSigner;
       break;
      case 'C':
       *cert_usage = certUsageVerifyCA;
       break;
      default:
       return SECFailure;
    }

    return SECSuccess;
}

Here is the caller graph for this function:

static SECStatus create_request ( FILE out_file,
CERTCertDBHandle *  handle,
const char *  cert_name,
PRBool  add_service_locator,
PRBool  add_acceptable_responses 
) [static]

Definition at line 252 of file ocspclnt.c.

{
    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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static SECStatus dump_response ( FILE out_file,
CERTCertDBHandle *  handle,
const char *  cert_name,
const char *  responder_url 
) [static]

Definition at line 326 of file ocspclnt.c.

{
    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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static SECStatus get_cert_status ( FILE out_file,
CERTCertDBHandle *  handle,
const char *  cert_name,
int64  verify_time 
) [static]

Definition at line 400 of file ocspclnt.c.

{
    CERTCertificate *cert = NULL;
    SECStatus rv = SECFailure;

    if (handle == NULL || cert_name == NULL)
       goto loser;

    cert = CERT_FindCertByNicknameOrEmailAddr (handle, (char *) cert_name);
    if (cert == NULL)
       goto loser;

    rv = CERT_CheckOCSPStatus (handle, cert, verify_time, NULL);

    fprintf (out_file, "Check of certificate \"%s\" ", cert_name); 
    if (rv == SECSuccess) {
       fprintf (out_file, "succeeded.\n"); 
    } else {
       const char *error_string = SECU_Strerror(PORT_GetError());
       fprintf (out_file, "failed.  Reason:\n");
       if (error_string != NULL && PORT_Strlen(error_string) > 0)
           fprintf (out_file, "%s\n", error_string);
       else
           fprintf (out_file, "Unknown\n");
    }

    rv = SECSuccess;

loser:
    if (cert != NULL)
       CERT_DestroyCertificate (cert);

    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void long_usage ( char *  program_name) [static]

Definition at line 110 of file ocspclnt.c.

{
    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");
}

Here is the call graph for this function:

Here is the caller graph for this function:

int main ( int  argc,
char **  argv 
)

The Xalan testcases app.

Definition at line 930 of file ocspclnt.c.

{
    int               retval;
    char      *program_name;
    PRFileDesc       *in_file;
    FILE      *out_file;    /* not PRFileDesc until SECU accepts it */
    int               crequest, dresponse;
    int               prequest, presponse;
    int               ccert, vcert;
    const char       *db_dir, *date_str, *cert_usage_str, *name;
    const char       *responder_name, *responder_url, *signer_name;
    PRBool     add_acceptable_responses, add_service_locator;
    SECItem   *data = NULL;
    PLOptState       *optstate;
    SECStatus  rv;
    CERTCertDBHandle *handle = NULL;
    SECCertUsage cert_usage;
    int64      verify_time;

    retval = -1;            /* what we return/exit with on error */

    program_name = PL_strrchr(argv[0], '/');
    program_name = program_name ? (program_name + 1) : argv[0];

    in_file = PR_STDIN;
    out_file = stdout;

    crequest = 0;
    dresponse = 0;
    prequest = 0;
    presponse = 0;
    ccert = 0;
    vcert = 0;

    db_dir = NULL;
    date_str = NULL;
    cert_usage_str = NULL;
    name = NULL;
    responder_name = NULL;
    responder_url = NULL;
    signer_name = NULL;

    add_acceptable_responses = PR_FALSE;
    add_service_locator = PR_FALSE;

    optstate = PL_CreateOptState (argc, argv, "AHLPR:S:V:d:l:pr:s:t:u:w:");
    if (optstate == NULL) {
       SECU_PrintError (program_name, "PL_CreateOptState failed");
       return retval;
    }

    while (PL_GetNextOpt (optstate) == PL_OPT_OK) {
       switch (optstate->option) {
         case '?':
           short_usage (program_name);
           return retval;

         case 'A':
           add_acceptable_responses = PR_TRUE;
           break;

         case 'H':
           long_usage (program_name);
           return retval;

         case 'L':
           add_service_locator = PR_TRUE;
           break;

         case 'P':
           presponse = 1;
           break;

         case 'R':
           dresponse = 1;
           name = optstate->value;
           break;

         case 'S':
           ccert = 1;
           name = optstate->value;
           break;

         case 'V':
           vcert = 1;
           name = optstate->value;
           break;

         case 'd':
           db_dir = optstate->value;
           break;

         case 'l':
           responder_url = optstate->value;
           break;

         case 'p':
           prequest = 1;
           break;

         case 'r':
           crequest = 1;
           name = optstate->value;
           break;

         case 's':
           signer_name = optstate->value;
           break;

         case 't':
           responder_name = optstate->value;
           break;

         case 'u':
           cert_usage_str = optstate->value;
           break;

         case 'w':
           date_str = optstate->value;
           break;
       }
    }

    PL_DestroyOptState(optstate);

    if ((crequest + dresponse + prequest + presponse + ccert + vcert) != 1) {
       PR_fprintf (PR_STDERR, "%s: must specify exactly one command\n\n",
                  program_name);
       short_usage (program_name);
       return retval;
    }

    if (vcert) {
       if (cert_usage_str == NULL) {
           PR_fprintf (PR_STDERR, "%s: verification requires cert usage\n\n",
                     program_name);
           short_usage (program_name);
           return retval;
       }

       rv = cert_usage_from_char (cert_usage_str, &cert_usage);
       if (rv != SECSuccess) {
           PR_fprintf (PR_STDERR, "%s: invalid cert usage (\"%s\")\n\n",
                     program_name, cert_usage_str);
           long_usage (program_name);
           return retval;
       }
    }

    if (ccert + vcert) {
       if (responder_url != NULL || responder_name != NULL) {
           /*
            * To do a full status check, both the URL and the cert name
            * of the responder must be specified if either one is.
            */
           if (responder_url == NULL || responder_name == NULL) {
              if (responder_url == NULL)
                  PR_fprintf (PR_STDERR,
                            "%s: must also specify responder location\n\n",
                            program_name);
              else
                  PR_fprintf (PR_STDERR,
                            "%s: must also specify responder name\n\n",
                            program_name);
              short_usage (program_name);
              return retval;
           }
       }

       if (date_str != NULL) {
           rv = DER_AsciiToTime (&verify_time, (char *) date_str);
           if (rv != SECSuccess) {
              SECU_PrintError (program_name, "error converting time string");
              PR_fprintf (PR_STDERR, "\n");
              long_usage (program_name);
              return retval;
           }
       } else {
           verify_time = PR_Now();
       }
    }

    retval = -2;            /* errors change from usage to runtime */

    /*
     * Initialize the NSPR and Security libraries.
     */
    PR_Init (PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
    db_dir = SECU_ConfigDirectory (db_dir);
    rv = NSS_Init (db_dir);
    if (rv != SECSuccess) {
       SECU_PrintError (program_name, "NSS_Init failed");
       goto prdone;
    }
    SECU_RegisterDynamicOids();

    if (prequest + presponse) {
       data = read_file_into_item (in_file, siBuffer);
       if (data == NULL) {
           SECU_PrintError (program_name, "problem reading input");
           goto nssdone;
       }
    }

    if (crequest + dresponse + presponse + ccert + vcert) {
       handle = CERT_GetDefaultCertDB();
       if (handle == NULL) {
           SECU_PrintError (program_name, "problem getting certdb handle");
           goto nssdone;
       }

       /*
        * It would be fine to do the enable for all of these commands,
        * but this way we check that everything but an overall verify
        * can be done without it.  That is, that the individual pieces
        * work on their own.
        */
       if (vcert) {
           rv = CERT_EnableOCSPChecking (handle);
           if (rv != SECSuccess) {
              SECU_PrintError (program_name, "error enabling OCSP checking");
              goto nssdone;
           }
       }

       if ((ccert + vcert) && (responder_name != NULL)) {
           rv = CERT_SetOCSPDefaultResponder (handle, responder_url,
                                          responder_name);
           if (rv != SECSuccess) {
              SECU_PrintError (program_name,
                             "error setting default responder");
              goto nssdone;
           }

           rv = CERT_EnableOCSPDefaultResponder (handle);
           if (rv != SECSuccess) {
              SECU_PrintError (program_name,
                             "error enabling default responder");
              goto nssdone;
           }
       }
    }

#define NOTYET(opt)                                            \
       {                                                       \
           PR_fprintf (PR_STDERR, "%s not yet working\n", opt);       \
           exit (-1);                                                 \
       }

    if (crequest) {
       if (signer_name != NULL) {
           NOTYET("-s");
       }
       rv = create_request (out_file, handle, name, add_service_locator,
                          add_acceptable_responses);
    } else if (dresponse) {
       if (signer_name != NULL) {
           NOTYET("-s");
       }
       rv = dump_response (out_file, handle, name, responder_url);
    } else if (prequest) {
       rv = print_request (out_file, data);
    } else if (presponse) {
       rv = print_response (out_file, data, handle);
    } else if (ccert) {
       if (signer_name != NULL) {
           NOTYET("-s");
       }
       rv = get_cert_status (out_file, handle, name, verify_time);
    } else if (vcert) {
       if (signer_name != NULL) {
           NOTYET("-s");
       }
       rv = verify_cert (out_file, handle, name, cert_usage, verify_time);
    }

    if (rv != SECSuccess)
       SECU_PrintError (program_name, "error performing requested operation");
    else
       retval = 0;

nssdone:
    if (data != NULL) {
       SECITEM_FreeItem (data, PR_TRUE);
    }

    if (handle != NULL) {
       CERT_DisableOCSPDefaultResponder(handle);        
       CERT_DisableOCSPChecking (handle);
    }

    if (NSS_Shutdown () != SECSuccess) {
       retval = 1;
    }

prdone:
    PR_Cleanup ();
    return retval;
}

Here is the call graph for this function:

static void print_basic_response ( FILE out_file,
ocspBasicOCSPResponse *  basic,
int  level 
) [static]

Definition at line 780 of file ocspclnt.c.

{
    SECItem rawsig;

    SECU_Indent (out_file, level);
    fprintf (out_file, "Basic OCSP Response:\n");
    level++;

    print_response_data (out_file, basic->tbsResponseData, level);

    SECU_PrintAlgorithmID (out_file,
                        &(basic->responseSignature.signatureAlgorithm),
                        "Signature Algorithm", level);

    rawsig = basic->responseSignature.signature;
    DER_ConvertBitString (&rawsig);
    SECU_PrintAsHex (out_file, &rawsig, "Signature", level);

    print_raw_certificates (out_file, basic->responseSignature.derCerts, level);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void print_cert_status ( FILE out_file,
ocspCertStatus *  status,
int  level 
) [static]

Definition at line 675 of file ocspclnt.c.

{
    SECU_Indent (out_file, level);
    fprintf (out_file, "Status: ");

    switch (status->certStatusType) {
      case ocspCertStatus_good:
       fprintf (out_file, "Cert is good.\n");
       break;
      case ocspCertStatus_revoked:
       fprintf (out_file, "Cert has been revoked.\n");
       print_revoked_info (out_file, status->certStatusInfo.revokedInfo,
                         level + 1);
       break;
      case ocspCertStatus_unknown:
       fprintf (out_file, "Cert is unknown to responder.\n");
       break;
      default:
       fprintf (out_file, "Unrecognized status.\n");
       break;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void print_ocsp_cert_id ( FILE out_file,
CERTOCSPCertID *  cert_id,
int  level 
) [static]

Definition at line 512 of file ocspclnt.c.

{
    SECU_Indent (out_file, level);
    fprintf (out_file, "Cert ID:\n");
    level++;

    SECU_PrintAlgorithmID (out_file, &(cert_id->hashAlgorithm),
                        "Hash Algorithm", level);
    SECU_PrintAsHex (out_file, &(cert_id->issuerNameHash),
                   "Issuer Name Hash", level);
    SECU_PrintAsHex (out_file, &(cert_id->issuerKeyHash),
                   "Issuer Key Hash", level);
    SECU_PrintInteger (out_file, &(cert_id->serialNumber),
                     "Serial Number", level);
    /* XXX lookup the cert; if found, print something nice (nickname?) */
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void print_ocsp_extensions ( FILE out_file,
CERTCertExtension **  extensions,
char *  msg,
int  level 
) [static]

Definition at line 554 of file ocspclnt.c.

{
    if (extensions) {
       SECU_PrintExtensions (out_file, extensions, msg, level);
    } else {
       SECU_Indent (out_file, level);
       fprintf (out_file, "No %s\n", msg);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void print_ocsp_version ( FILE out_file,
SECItem *  version,
int  level 
) [static]

Definition at line 500 of file ocspclnt.c.

{
    if (version->len > 0) {
       SECU_PrintInteger (out_file, version, "Version", level);
    } else {
       SECU_Indent (out_file, level);
       fprintf (out_file, "Version: DEFAULT\n");
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void print_raw_certificates ( FILE out_file,
SECItem **  raw_certs,
int  level 
) [static]

Definition at line 531 of file ocspclnt.c.

{
    SECItem *raw_cert;
    int i = 0;
    char cert_label[50];

    SECU_Indent (out_file, level);

    if (raw_certs == NULL) {
       fprintf (out_file, "No Certificates.\n");
       return;
    }

    fprintf (out_file, "Certificate List:\n");
    while ((raw_cert = raw_certs[i++]) != NULL) {
       sprintf (cert_label, "Certificate (%d)", i);
       (void) SECU_PrintSignedData (out_file, raw_cert, cert_label, level + 1,
                                 SECU_PrintCertificate);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static SECStatus print_request ( FILE out_file,
SECItem *  data 
) [static]

Definition at line 580 of file ocspclnt.c.

{
    CERTOCSPRequest *request;
    ocspTBSRequest *tbsRequest;
    int level = 0;

    PORT_Assert (out_file != NULL);
    PORT_Assert (data != NULL);
    if (out_file == NULL || data == NULL) {
       PORT_SetError (SEC_ERROR_INVALID_ARGS);
       return SECFailure;
    }

    request = CERT_DecodeOCSPRequest (data);
    if (request == NULL || request->tbsRequest == NULL)
       return SECFailure;

    tbsRequest = request->tbsRequest;

    fprintf (out_file, "TBS Request:\n");
    level++;

    print_ocsp_version (out_file, &(tbsRequest->version), level);

    /*
     * XXX Probably should be an interface to get the signer name
     * without looking inside the tbsRequest at all.
     */
    if (tbsRequest->requestorName != NULL) {
       SECU_Indent (out_file, level);
       fprintf (out_file, "XXX print the requestorName\n");
    } else {
       SECU_Indent (out_file, level);
       fprintf (out_file, "No Requestor Name.\n");
    }

    if (tbsRequest->requestList != NULL) {
       int i;

       for (i = 0; tbsRequest->requestList[i] != NULL; i++) {
           SECU_Indent (out_file, level);
           fprintf (out_file, "Request %d:\n", i);
           print_single_request (out_file, tbsRequest->requestList[i],
                              level + 1);
       }
    } else {
       fprintf (out_file, "Request list is empty.\n");
    }

    print_ocsp_extensions (out_file, tbsRequest->requestExtensions,
                        "Request Extensions", level);

    if (request->optionalSignature != NULL) {
       ocspSignature *whole_sig;
       SECItem rawsig;

       fprintf (out_file, "Signature:\n");

       whole_sig = request->optionalSignature;
       SECU_PrintAlgorithmID (out_file, &(whole_sig->signatureAlgorithm),
                            "Signature Algorithm", level);

       rawsig = whole_sig->signature;
       DER_ConvertBitString (&rawsig);
       SECU_PrintAsHex (out_file, &rawsig, "Signature", level);

       print_raw_certificates (out_file, whole_sig->derCerts, level);

       fprintf (out_file, "XXX verify the sig and print result\n");
    } else {
       fprintf (out_file, "No Signature\n");
    }

    CERT_DestroyOCSPRequest (request);
    return SECSuccess;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void print_responder_id ( FILE out_file,
ocspResponderID *  responderID,
int  level 
) [static]

Definition at line 724 of file ocspclnt.c.

{
    SECU_Indent (out_file, level);
    fprintf (out_file, "Responder ID ");

    switch (responderID->responderIDType) {
      case ocspResponderID_byName:
       fprintf (out_file, "(byName):\n");
       SECU_PrintName (out_file, &(responderID->responderIDValue.name),
                     "Name", level + 1);
       break;
      case ocspResponderID_byKey:
       fprintf (out_file, "(byKey):\n");
       SECU_PrintAsHex (out_file, &(responderID->responderIDValue.keyHash),
                      "Key Hash", level + 1);
       break;
      default:
       fprintf (out_file, "Unrecognized Responder ID Type\n");
       break;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static SECStatus print_response ( FILE out_file,
SECItem *  data,
CERTCertDBHandle *  handle 
) [static]

Definition at line 821 of file ocspclnt.c.

{
    CERTOCSPResponse *response;
    int level = 0;

    PORT_Assert (out_file != NULL);
    PORT_Assert (data != NULL);
    if (out_file == NULL || data == NULL) {
       PORT_SetError (SEC_ERROR_INVALID_ARGS);
       return SECFailure;
    }

    response = CERT_DecodeOCSPResponse (data);
    if (response == NULL)
       return SECFailure;

    PORT_Assert (response->statusValue <= ocspResponse_other);
    fprintf (out_file, "Response Status: %s\n",
            responseStatusNames[response->statusValue]);

    if (response->statusValue == ocspResponse_successful) {
       ocspResponseBytes *responseBytes = response->responseBytes;
       SECStatus sigStatus;
       CERTCertificate *signerCert = NULL;

       PORT_Assert (responseBytes != NULL);

       level++;
       fprintf (out_file, "Response Bytes:\n");
       SECU_PrintObjectID (out_file, &(responseBytes->responseType),
                         "Response Type", level);
       switch (response->responseBytes->responseTypeTag) {
         case SEC_OID_PKIX_OCSP_BASIC_RESPONSE:
           print_basic_response (out_file,
                              responseBytes->decodedResponse.basic,
                              level);
           break;
         default:
           SECU_Indent (out_file, level);
           fprintf (out_file, "Unknown response syntax\n");
           break;
       }

       sigStatus = CERT_VerifyOCSPResponseSignature (response, handle,
                                                NULL, &signerCert, NULL);
       SECU_Indent (out_file, level);
       fprintf (out_file, "Signature verification ");
       if (sigStatus != SECSuccess) {
           fprintf (out_file, "failed: %s\n", SECU_Strerror (PORT_GetError()));
       } else {
           fprintf (out_file, "succeeded.\n");
           if (signerCert != NULL) {
              SECU_PrintName (out_file, &signerCert->subject, "Signer",
                            level);
              CERT_DestroyCertificate (signerCert);
           } else {
              SECU_Indent (out_file, level);
              fprintf (out_file, "No signer cert returned?\n");
           }
       }
    } else {
       SECU_Indent (out_file, level);
       fprintf (out_file, "Unsuccessful response, no more information.\n");
    }

    CERT_DestroyOCSPResponse (response);
    return SECSuccess;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void print_response_data ( FILE out_file,
ocspResponseData *  responseData,
int  level 
) [static]

Definition at line 748 of file ocspclnt.c.

{
    SECU_Indent (out_file, level);
    fprintf (out_file, "Response Data:\n");
    level++;

    print_ocsp_version (out_file, &(responseData->version), level);

    print_responder_id (out_file, responseData->responderID, level);

    SECU_PrintGeneralizedTime (out_file, &(responseData->producedAt),
                            "Produced At", level);

    if (responseData->responses != NULL) {
       int i;

       for (i = 0; responseData->responses[i] != NULL; i++) {
           SECU_Indent (out_file, level);
           fprintf (out_file, "Response %d:\n", i);
           print_single_response (out_file, responseData->responses[i],
                               level + 1);
       }
    } else {
       fprintf (out_file, "Response list is empty.\n");
    }

    print_ocsp_extensions (out_file, responseData->responseExtensions,
                        "Response Extensions", level);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void print_revoked_info ( FILE out_file,
ocspRevokedInfo *  revoked_info,
int  level 
) [static]

Definition at line 659 of file ocspclnt.c.

{
    SECU_PrintGeneralizedTime (out_file, &(revoked_info->revocationTime),
                            "Revocation Time", level);

    if (revoked_info->revocationReason != NULL) {
       SECU_PrintAsHex (out_file, revoked_info->revocationReason,
                      "Revocation Reason", level);
    } else {
       SECU_Indent (out_file, level);
       fprintf (out_file, "No Revocation Reason.\n");
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void print_single_request ( FILE out_file,
ocspSingleRequest *  single,
int  level 
) [static]

Definition at line 567 of file ocspclnt.c.

{
    print_ocsp_cert_id (out_file, single->reqCert, level);
    print_ocsp_extensions (out_file, single->singleRequestExtensions,
                        "Single Request Extensions", level);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void print_single_response ( FILE out_file,
CERTOCSPSingleResponse *  single,
int  level 
) [static]

Definition at line 700 of file ocspclnt.c.

{
    print_ocsp_cert_id (out_file, single->certID, level);

    print_cert_status (out_file, single->certStatus, level);

    SECU_PrintGeneralizedTime (out_file, &(single->thisUpdate),
                            "This Update", level);

    if (single->nextUpdate != NULL) {
       SECU_PrintGeneralizedTime (out_file, single->nextUpdate,
                               "Next Update", level);
    } else {
       SECU_Indent (out_file, level);
       fprintf (out_file, "No Next Update\n");
    }

    print_ocsp_extensions (out_file, single->singleExtensions,
                        "Single Response Extensions", level);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static SECItem* read_file_into_item ( PRFileDesc in_file,
SECItemType  si_type 
) [static]

Definition at line 193 of file ocspclnt.c.

{
    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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void short_usage ( char *  program_name) [static]

Definition at line 100 of file ocspclnt.c.

{
    PR_fprintf (PR_STDERR,
              "Type %s -H for more detailed descriptions\n",
              program_name);
    synopsis (program_name);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void synopsis ( char *  program_name) [static]

Definition at line 68 of file ocspclnt.c.

{
    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");
}

Here is the caller graph for this function:

static SECStatus verify_cert ( FILE out_file,
CERTCertDBHandle *  handle,
const char *  cert_name,
SECCertUsage  cert_usage,
int64  verify_time 
) [static]

Definition at line 443 of file ocspclnt.c.

{
    CERTCertificate *cert = NULL;
    SECStatus rv = SECFailure;

    if (handle == NULL || cert_name == NULL)
       goto loser;

    cert = CERT_FindCertByNicknameOrEmailAddr (handle, (char *) cert_name);
    if (cert == NULL)
       goto loser;

    rv = CERT_VerifyCert (handle, cert, PR_TRUE, cert_usage, verify_time,
                       NULL, NULL);

    fprintf (out_file, "Verification of certificate \"%s\" ", cert_name); 
    if (rv == SECSuccess) {
       fprintf (out_file, "succeeded.\n"); 
    } else {
       const char *error_string = SECU_Strerror(PORT_GetError());
       fprintf (out_file, "failed.  Reason:\n");
       if (error_string != NULL && PORT_Strlen(error_string) > 0)
           fprintf (out_file, "%s\n", error_string);
       else
           fprintf (out_file, "Unknown\n");
    }

    rv = SECSuccess;

loser:
    if (cert != NULL)
       CERT_DestroyCertificate (cert);

    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

char* responseStatusNames[] [static]
Initial value:
 {
    "successful (Response has valid confirmations)",
    "malformedRequest (Illegal confirmation request)",
    "internalError (Internal error in issuer)",
    "tryLater (Try again later)",
    "unused ((4) is not used)",
    "sigRequired (Must sign the request)",
    "unauthorized (Request unauthorized)",
    "other (Status value out of defined range)"
}

Definition at line 805 of file ocspclnt.c.