Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/security/nss/cmd/certutil/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 142 kB image not shown  

Quelle  certutil.c   Sprache: C

 
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


/*
** certutil.c
**
** utility for managing certificates and the cert database
**
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#if defined(WIN32)
#include "fcntl.h"
#include "io.h"
#endif

#include "secutil.h"

#if defined(XP_UNIX)
#include <unistd.h>
#endif

#include "nspr.h"
#include "prtypes.h"
#include "prtime.h"
#include "prlong.h"

#include "pk11func.h"
#include "secasn1.h"
#include "cert.h"
#include "cryptohi.h"
#include "secoid.h"
#include "certdb.h"
#include "nss.h"
#include "certutil.h"
#include "basicutil.h"
#include "ssl.h"

#define MIN_KEY_BITS 512
/* MAX_KEY_BITS should agree with RSA_MAX_MODULUS_BITS in freebl */
#define MAX_KEY_BITS 8192
#define DEFAULT_KEY_BITS 2048

#define GEN_BREAK(e) \
    rv = e;          \
    break;

char *progName;

static SECStatus
ChangeCertTrust(CERTCertDBHandle *handle, CERTCertificate *cert,
                CERTCertTrust *trust, PK11SlotInfo *slot, void *pwdata)
{
    SECStatus rv;

    rv = CERT_ChangeCertTrust(handle, cert, trust);
    if (rv != SECSuccess) {
        if (PORT_GetError() == SEC_ERROR_TOKEN_NOT_LOGGED_IN) {
            rv = PK11_Authenticate(slot, PR_TRUE, pwdata);
            if (PORT_GetError() == SEC_ERROR_TOKEN_NOT_LOGGED_IN) {
                PK11SlotInfo *internalslot;
                internalslot = PK11_GetInternalKeySlot();
                rv = PK11_Authenticate(internalslot, PR_TRUE, pwdata);
                if (rv != SECSuccess) {
                    SECU_PrintError(progName,
                                    "could not authenticate to token %s.",
                                    PK11_GetTokenName(internalslot));
                    PK11_FreeSlot(internalslot);
                    return SECFailure;
                }
                PK11_FreeSlot(internalslot);
            }
            rv = CERT_ChangeCertTrust(handle, cert, trust);
        }
    }
    return rv;
}

static CERTCertificateRequest *
GetCertRequest(const SECItem *reqDER, void *pwarg)
{
    CERTCertificateRequest *certReq = NULL;
    CERTSignedData signedData;
    PLArenaPool *arena = NULL;
    SECStatus rv;

    do {
        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
        if (arena == NULL) {
            GEN_BREAK(SECFailure);
        }

        certReq = (CERTCertificateRequest *)PORT_ArenaZAlloc(arena, sizeof(CERTCertificateRequest));
        if (!certReq) {
            GEN_BREAK(SECFailure);
        }
        certReq->arena = arena;

        /* Since cert request is a signed data, must decode to get the inner
           data
         */

        PORT_Memset(&signedData, 0, sizeof(signedData));
        rv = SEC_ASN1DecodeItem(arena, &signedData,
                                SEC_ASN1_GET(CERT_SignedDataTemplate), reqDER);
        if (rv) {
            break;
        }
        rv = SEC_ASN1DecodeItem(arena, certReq,
                                SEC_ASN1_GET(CERT_CertificateRequestTemplate), &signedData.data);
        if (rv) {
            break;
        }
        rv = CERT_VerifySignedDataWithPublicKeyInfo(&signedData,
                                                    &certReq->subjectPublicKeyInfo, pwarg);
    } while (0);

    if (rv) {
        SECU_PrintError(progName, "bad certificate request\n");
        if (arena) {
            PORT_FreeArena(arena, PR_FALSE);
        }
        certReq = NULL;
    }

    return certReq;
}

static SECStatus
AddCert(PK11SlotInfo *slot, CERTCertDBHandle *handle, char *name, char *trusts,
        const SECItem *certDER, PRBool emailcert, void *pwdata)
{
    CERTCertTrust *trust = NULL;
    CERTCertificate *cert = NULL;
    SECStatus rv;

    do {
        /* Read in an ASCII cert and return a CERTCertificate */
        cert = CERT_DecodeCertFromPackage((char *)certDER->data, certDER->len);
        if (!cert) {
            SECU_PrintError(progName, "could not decode certificate");
            GEN_BREAK(SECFailure);
        }

        /* Create a cert trust */
        trust = (CERTCertTrust *)PORT_ZAlloc(sizeof(CERTCertTrust));
        if (!trust) {
            SECU_PrintError(progName, "unable to allocate cert trust");
            GEN_BREAK(SECFailure);
        }

        rv = CERT_DecodeTrustString(trust, trusts);
        if (rv) {
            SECU_PrintError(progName, "unable to decode trust string");
            GEN_BREAK(SECFailure);
        }

        rv = PK11_ImportCert(slot, cert, CK_INVALID_HANDLE, name, PR_FALSE);
        if (rv != SECSuccess) {
            /* sigh, PK11_Import Cert and CERT_ChangeCertTrust should have
             * been coded to take a password arg. */

            if (PORT_GetError() == SEC_ERROR_TOKEN_NOT_LOGGED_IN) {
                rv = PK11_Authenticate(slot, PR_TRUE, pwdata);
                if (rv != SECSuccess) {
                    SECU_PrintError(progName,
                                    "could not authenticate to token %s.",
                                    PK11_GetTokenName(slot));
                    GEN_BREAK(SECFailure);
                }
                rv = PK11_ImportCert(slot, cert, CK_INVALID_HANDLE,
                                     name, PR_FALSE);
            }
            if (rv != SECSuccess) {
                SECU_PrintError(progName,
                                "could not add certificate to token or database");
                GEN_BREAK(SECFailure);
            }
        }
        rv = ChangeCertTrust(handle, cert, trust, slot, pwdata);
        if (rv != SECSuccess) {
            SECU_PrintError(progName,
                            "could not change trust on certificate");
            GEN_BREAK(SECFailure);
        }

        if (emailcert) {
            CERT_SaveSMimeProfile(cert, NULL, pwdata);
        }

    } while (0);

    CERT_DestroyCertificate(cert);
    PORT_Free(trust);

    return rv;
}

static SECStatus
CertReq(SECKEYPrivateKey *privk, SECKEYPublicKey *pubk, KeyType keyType,
        SECOidTag hashAlgTag, CERTName *subject, const char *phone, int ascii,
        const char *emailAddrs, const char *dnsNames,
        certutilExtnList extnList, const char *extGeneric,
        PRBool pssCertificate, /*out*/ SECItem *result)
{
    CERTSubjectPublicKeyInfo *spki;
    CERTCertificateRequest *cr;
    SECItem *encoding;
    SECOidTag signAlgTag;
    SECStatus rv;
    PLArenaPool *arena;
    void *extHandle;
    SECItem signedReq = { siBuffer, NULL, 0 };
    SECAlgorithmID signAlg;
    SECItem *params = NULL;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (!arena) {
        SECU_PrintError(progName, "out of memory");
        return SECFailure;
    }

    /* Create info about public key */
    spki = SECKEY_CreateSubjectPublicKeyInfo(pubk);
    if (!spki) {
        PORT_FreeArena(arena, PR_FALSE);
        SECU_PrintError(progName, "unable to create subject public key");
        return SECFailure;
    }

    /* Change cert type to RSA-PSS, if desired. */
    if (pssCertificate) {
        params = SEC_CreateSignatureAlgorithmParameters(arena,
                                                        NULL,
                                                        SEC_OID_PKCS1_RSA_PSS_SIGNATURE,
                                                        hashAlgTag,
                                                        NULL,
                                                        privk);
        if (!params) {
            PORT_FreeArena(arena, PR_FALSE);
            SECKEY_DestroySubjectPublicKeyInfo(spki);
            SECU_PrintError(progName, "unable to create RSA-PSS parameters");
            return SECFailure;
        }

        spki->algorithm.parameters.data = NULL;
        rv = SECOID_SetAlgorithmID(arena, &spki->algorithm,
                                   SEC_OID_PKCS1_RSA_PSS_SIGNATURE,
                                   hashAlgTag == SEC_OID_UNKNOWN ? NULL : params);
        if (rv != SECSuccess) {
            PORT_FreeArena(arena, PR_FALSE);
            SECKEY_DestroySubjectPublicKeyInfo(spki);
            SECU_PrintError(progName, "unable to set algorithm ID");
            return SECFailure;
        }
    }

    /* Generate certificate request */
    cr = CERT_CreateCertificateRequest(subject, spki, NULL);
    SECKEY_DestroySubjectPublicKeyInfo(spki);
    if (!cr) {
        PORT_FreeArena(arena, PR_FALSE);
        SECU_PrintError(progName, "unable to make certificate request");
        return SECFailure;
    }

    extHandle = CERT_StartCertificateRequestAttributes(cr);
    if (extHandle == NULL) {
        PORT_FreeArena(arena, PR_FALSE);
        CERT_DestroyCertificateRequest(cr);
        return SECFailure;
    }
    if (AddExtensions(extHandle, emailAddrs, dnsNames, extnList, extGeneric) !=
        SECSuccess) {
        PORT_FreeArena(arena, PR_FALSE);
        CERT_FinishExtensions(extHandle);
        CERT_DestroyCertificateRequest(cr);
        return SECFailure;
    }
    CERT_FinishExtensions(extHandle);
    CERT_FinishCertificateRequestAttributes(cr);

    /* Der encode the request */
    encoding = SEC_ASN1EncodeItem(arena, NULL, cr,
                                  SEC_ASN1_GET(CERT_CertificateRequestTemplate));
    CERT_DestroyCertificateRequest(cr);
    if (encoding == NULL) {
        PORT_FreeArena(arena, PR_FALSE);
        SECU_PrintError(progName, "der encoding of request failed");
        return SECFailure;
    }

    PORT_Memset(&signAlg, 0, sizeof(signAlg));
    if (pssCertificate) {
        rv = SECOID_SetAlgorithmID(arena, &signAlg,
                                   SEC_OID_PKCS1_RSA_PSS_SIGNATURE, params);
        if (rv != SECSuccess) {
            PORT_FreeArena(arena, PR_FALSE);
            SECU_PrintError(progName, "unable to set algorithm ID");
            return SECFailure;
        }
    } else {
        signAlgTag = SEC_GetSignatureAlgorithmOidTag(keyType, hashAlgTag);
        if (signAlgTag == SEC_OID_UNKNOWN) {
            PORT_FreeArena(arena, PR_FALSE);
            SECU_PrintError(progName, "unknown Key or Hash type");
            return SECFailure;
        }
        rv = SECOID_SetAlgorithmID(arena, &signAlg, signAlgTag, 0);
        if (rv != SECSuccess) {
            PORT_FreeArena(arena, PR_FALSE);
            SECU_PrintError(progName, "unable to set algorithm ID");
            return SECFailure;
        }
    }

    /* Sign the request */
    rv = SEC_DerSignDataWithAlgorithmID(arena, &signedReq,
                                        encoding->data, encoding->len,
                                        privk, &signAlg);
    if (rv) {
        PORT_FreeArena(arena, PR_FALSE);
        SECU_PrintError(progName, "signing of data failed");
        return SECFailure;
    }

    /* Encode request in specified format */
    if (ascii) {
        char *obuf;
        char *header, *name, *email, *org, *state, *country;

        obuf = BTOA_ConvertItemToAscii(&signedReq);
        if (!obuf) {
            goto oom;
        }

        name = CERT_GetCommonName(subject);
        if (!name) {
            name = PORT_Strdup("(not specified)");
        }

        if (!phone)
            phone = "(not specified)";

        email = CERT_GetCertEmailAddress(subject);
        if (!email)
            email = PORT_Strdup("(not specified)");

        org = CERT_GetOrgName(subject);
        if (!org)
            org = PORT_Strdup("(not specified)");

        state = CERT_GetStateName(subject);
        if (!state)
            state = PORT_Strdup("(not specified)");

        country = CERT_GetCountryName(subject);
        if (!country)
            country = PORT_Strdup("(not specified)");

        header = PR_smprintf(
            "\nCertificate request generated by Netscape certutil\n"
            "Phone: %s\n\n"
            "Common Name: %s\n"
            "Email: %s\n"
            "Organization: %s\n"
            "State: %s\n"
            "Country: %s\n\n"
            "%s\n",
            phone, name, email, org, state, country, NS_CERTREQ_HEADER);

        PORT_Free(name);
        PORT_Free(email);
        PORT_Free(org);
        PORT_Free(state);
        PORT_Free(country);

        if (header) {
            char *trailer = PR_smprintf("\n%s\n", NS_CERTREQ_TRAILER);
            if (trailer) {
                PRUint32 headerLen = PL_strlen(header);
                PRUint32 obufLen = PL_strlen(obuf);
                PRUint32 trailerLen = PL_strlen(trailer);
                SECITEM_AllocItem(NULL, result,
                                  headerLen + obufLen + trailerLen);
                if (result->data) {
                    PORT_Memcpy(result->data, header, headerLen);
                    PORT_Memcpy(result->data + headerLen, obuf, obufLen);
                    PORT_Memcpy(result->data + headerLen + obufLen,
                                trailer, trailerLen);
                }
                PR_smprintf_free(trailer);
            }
            PR_smprintf_free(header);
        }
        PORT_Free(obuf);
    } else {
        (void)SECITEM_CopyItem(NULL, result, &signedReq);
    }

    if (!result->data) {
    oom:
        SECU_PrintError(progName, "out of memory");
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        rv = SECFailure;
    }

    PORT_FreeArena(arena, PR_FALSE);
    return rv;
}

static SECStatus
ChangeTrustAttributes(CERTCertDBHandle *handle, PK11SlotInfo *slot,
                      char *name, char *trusts, void *pwdata)
{
    SECStatus rv;
    CERTCertificate *cert;
    CERTCertTrust *trust;

    cert = CERT_FindCertByNicknameOrEmailAddrCX(handle, name, pwdata);
    if (!cert) {
        SECU_PrintError(progName, "could not find certificate named \"%s\"",
                        name);
        return SECFailure;
    }

    trust = (CERTCertTrust *)PORT_ZAlloc(sizeof(CERTCertTrust));
    if (!trust) {
        SECU_PrintError(progName, "unable to allocate cert trust");
        return SECFailure;
    }

    /* This function only decodes these characters: pPwcTCu, */
    rv = CERT_DecodeTrustString(trust, trusts);
    if (rv) {
        SECU_PrintError(progName, "unable to decode trust string");
        return SECFailure;
    }

    /* CERT_ChangeCertTrust API does not have a way to pass in
     * a context, so NSS can't prompt for the password if it needs to.
     * check to see if the failure was token not logged in and
     * log in if need be. */

    rv = ChangeCertTrust(handle, cert, trust, slot, pwdata);
    if (rv != SECSuccess) {
        SECU_PrintError(progName, "unable to modify trust attributes");
        return SECFailure;
    }
    CERT_DestroyCertificate(cert);
    PORT_Free(trust);

    return SECSuccess;
}

static SECStatus
DumpChain(CERTCertDBHandle *handle, char *name, PRBool ascii,
          PRBool simpleSelfSigned)
{
    CERTCertificate *the_cert;
    CERTCertificateList *chain;
    int i, j;
    the_cert = SECU_FindCertByNicknameOrFilename(handle, name,
                                                 ascii, NULL);
    if (!the_cert) {
        SECU_PrintError(progName, "Could not find: %s\n", name);
        return SECFailure;
    }
    if (simpleSelfSigned &&
        SECEqual == SECITEM_CompareItem(&the_cert->derIssuer,
                                        &the_cert->derSubject)) {
        printf("\"%s\" [%s]\n\n", the_cert->nickname, the_cert->subjectName);
        CERT_DestroyCertificate(the_cert);
        return SECSuccess;
    }

    chain = CERT_CertChainFromCert(the_cert, 0, PR_TRUE);
    CERT_DestroyCertificate(the_cert);
    if (!chain) {
        SECU_PrintError(progName, "Could not obtain chain for: %s\n", name);
        return SECFailure;
    }
    for (i = chain->len - 1; i >= 0; i--) {
        CERTCertificate *c;
        c = CERT_FindCertByDERCert(handle, &chain->certs[i]);
        for (j = i; j < chain->len - 1; j++) {
            printf(" ");
        }
        if (c) {
            printf("\"%s\" [%s]\n\n", c->nickname, c->subjectName);
            CERT_DestroyCertificate(c);
        } else {
            printf("(null)\n\n");
        }
    }
    CERT_DestroyCertificateList(chain);
    return SECSuccess;
}

static SECStatus
outputCertOrExtension(CERTCertificate *the_cert, PRBool raw, PRBool ascii,
                      SECItem *extensionOID, PRFileDesc *outfile)
{
    SECItem data;
    PRInt32 numBytes;
    SECStatus rv = SECFailure;
    if (extensionOID) {
        int i;
        PRBool found = PR_FALSE;
        for (i = 0; the_cert->extensions[i] != NULL; i++) {
            CERTCertExtension *extension = the_cert->extensions[i];
            if (SECITEM_CompareItem(&extension->id, extensionOID) == SECEqual) {
                found = PR_TRUE;
                numBytes = PR_Write(outfile, extension->value.data,
                                    extension->value.len);
                rv = SECSuccess;
                if (numBytes != (PRInt32)extension->value.len) {
                    SECU_PrintSystemError(progName, "error writing extension");
                    rv = SECFailure;
                }
                break;
            }
        }
        if (!found) {
            SECU_PrintSystemError(progName, "extension not found");
            rv = SECFailure;
        }
    } else {
        data.data = the_cert->derCert.data;
        data.len = the_cert->derCert.len;
        if (ascii) {
            PR_fprintf(outfile, "%s\n%s\n%s\n", NS_CERT_HEADER,
                       BTOA_DataToAscii(data.data, data.len), NS_CERT_TRAILER);
            rv = SECSuccess;
        } else if (raw) {
            numBytes = PR_Write(outfile, data.data, data.len);
            rv = SECSuccess;
            if (numBytes != (PRInt32)data.len) {
                SECU_PrintSystemError(progName, "error writing raw cert");
                rv = SECFailure;
            }
        } else {
            rv = SEC_PrintCertificateAndTrust(the_cert, "Certificate", NULL);
            if (rv != SECSuccess) {
                SECU_PrintError(progName, "problem printing certificate");
            }
        }
    }
    return rv;
}

static SECStatus
listCerts(CERTCertDBHandle *handle, char *name, char *email,
          PK11SlotInfo *slot, PRBool raw, PRBool ascii,
          SECItem *extensionOID,
          PRFileDesc *outfile, void *pwarg)
{
    SECStatus rv = SECFailure;
    CERTCertList *certs;
    CERTCertListNode *node;

    /* List certs on a non-internal slot. */
    if (!PK11_IsFriendly(slot) && PK11_NeedLogin(slot)) {
        SECStatus newrv = PK11_Authenticate(slot, PR_TRUE, pwarg);
        if (newrv != SECSuccess) {
            SECU_PrintError(progName, "could not authenticate to token %s.",
                            PK11_GetTokenName(slot));
            return SECFailure;
        }
    }
    if (name) {
        CERTCertificate *the_cert =
            SECU_FindCertByNicknameOrFilename(handle, name, ascii, NULL);
        if (!the_cert) {
            SECU_PrintError(progName, "Could not find cert: %s\n", name);
            return SECFailure;
        }
        /* Here, we have one cert with the desired nickname or email
         * address.  Now, we will attempt to get a list of ALL certs
         * with the same subject name as the cert we have.  That list
         * should contain, at a minimum, the one cert we have already found.
         * If the list of certs is empty (NULL), the libraries have failed.
         */

        certs = CERT_CreateSubjectCertList(NULL, handle, &the_cert->derSubject,
                                           PR_Now(), PR_FALSE);
        CERT_DestroyCertificate(the_cert);
        if (!certs) {
            PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
            SECU_PrintError(progName, "problem printing certificates");
            return SECFailure;
        }
        for (node = CERT_LIST_HEAD(certs); !CERT_LIST_END(node, certs);
             node = CERT_LIST_NEXT(node)) {
            rv = outputCertOrExtension(node->cert, raw, ascii, extensionOID,
                                       outfile);
            if (rv != SECSuccess) {
                break;
            }
        }
    } else if (email) {
        certs = PK11_FindCertsFromEmailAddress(email, NULL);
        if (!certs) {
            SECU_PrintError(progName,
                            "Could not find certificates for email address: %s\n",
                            email);
            return SECFailure;
        }
        for (node = CERT_LIST_HEAD(certs); !CERT_LIST_END(node, certs);
             node = CERT_LIST_NEXT(node)) {
            rv = outputCertOrExtension(node->cert, raw, ascii, extensionOID,
                                       outfile);
            if (rv != SECSuccess) {
                break;
            }
        }
    } else {
        certs = PK11_ListCertsInSlot(slot);
        if (certs) {
            for (node = CERT_LIST_HEAD(certs); !CERT_LIST_END(node, certs);
                 node = CERT_LIST_NEXT(node)) {
                SECU_PrintCertNickname(node, stdout);
            }
            rv = SECSuccess;
        }
    }
    if (certs) {
        CERT_DestroyCertList(certs);
    }
    if (rv) {
        SECU_PrintError(progName, "problem printing certificate nicknames");
        return SECFailure;
    }

    return SECSuccess; /* not rv ?? */
}

static SECStatus
ListCerts(CERTCertDBHandle *handle, char *nickname, char *email,
          PK11SlotInfo *slot, PRBool raw, PRBool ascii,
          SECItem *extensionOID,
          PRFileDesc *outfile, secuPWData *pwdata)
{
    SECStatus rv;

    if (slot && PK11_NeedUserInit(slot)) {
        printf("\nDatabase needs user init\n");
    }

    if (!ascii && !raw && !nickname && !email) {
        PR_fprintf(outfile, "\n%-60s %-5s\n%-60s %-5s\n\n",
                   "Certificate Nickname""Trust Attributes""",
                   "SSL,S/MIME,JAR/XPI");
    }
    if (slot == NULL) {
        CERTCertList *list;
        CERTCertListNode *node;

        list = PK11_ListCerts(PK11CertListAll, pwdata);
        for (node = CERT_LIST_HEAD(list); !CERT_LIST_END(node, list);
             node = CERT_LIST_NEXT(node)) {
            SECU_PrintCertNickname(node, stdout);
        }
        CERT_DestroyCertList(list);
        return SECSuccess;
    }
    rv = listCerts(handle, nickname, email, slot, raw, ascii,
                   extensionOID, outfile, pwdata);
    return rv;
}

static SECStatus
DeleteCert(CERTCertDBHandle *handle, char *name, void *pwdata)
{
    SECStatus rv;
    CERTCertificate *cert;

    cert = CERT_FindCertByNicknameOrEmailAddrCX(handle, name, pwdata);
    if (!cert) {
        SECU_PrintError(progName, "could not find certificate named \"%s\"",
                        name);
        return SECFailure;
    }

    rv = SEC_DeletePermCertificate(cert);
    CERT_DestroyCertificate(cert);
    if (rv) {
        SECU_PrintError(progName, "unable to delete certificate");
    }
    return rv;
}

static SECStatus
RenameCert(CERTCertDBHandle *handle, char *name, char *newName, void *pwdata)
{
    SECStatus rv;
    CERTCertificate *cert;

    cert = CERT_FindCertByNicknameOrEmailAddrCX(handle, name, pwdata);
    if (!cert) {
        SECU_PrintError(progName, "could not find certificate named \"%s\"",
                        name);
        return SECFailure;
    }

    rv = __PK11_SetCertificateNickname(cert, newName);
    CERT_DestroyCertificate(cert);
    if (rv) {
        SECU_PrintError(progName, "unable to rename certificate");
    }
    return rv;
}

static SECStatus
ValidateCert(CERTCertDBHandle *handle, char *name, char *date,
             char *certUsage, PRBool checkSig, PRBool logit,
             PRBool ascii, secuPWData *pwdata)
{
    SECStatus rv;
    CERTCertificate *cert = NULL;
    PRTime timeBoundary;
    SECCertificateUsage usage;
    CERTVerifyLog reallog;
    CERTVerifyLog *log = NULL;

    if (!certUsage) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return (SECFailure);
    }

    switch (*certUsage) {
        case 'O':
            usage = certificateUsageStatusResponder;
            break;
        case 'L':
            usage = certificateUsageSSLCA;
            break;
        case 'A':
            usage = certificateUsageAnyCA;
            break;
        case 'Y':
            usage = certificateUsageVerifyCA;
            break;
        case 'C':
            usage = certificateUsageSSLClient;
            break;
        case 'V':
            usage = certificateUsageSSLServer;
            break;
        case 'I':
            usage = certificateUsageIPsec;
            break;
        case 'S':
            usage = certificateUsageEmailSigner;
            break;
        case 'R':
            usage = certificateUsageEmailRecipient;
            break;
        case 'J':
            usage = certificateUsageObjectSigner;
            break;
        default:
            PORT_SetError(SEC_ERROR_INVALID_ARGS);
            return (SECFailure);
    }
    do {
        cert = SECU_FindCertByNicknameOrFilename(handle, name, ascii,
                                                 NULL);
        if (!cert) {
            SECU_PrintError(progName, "could not find certificate named \"%s\"",
                            name);
            GEN_BREAK(SECFailure)
        }

        if (date != NULL) {
            rv = DER_AsciiToTime(&timeBoundary, date);
            if (rv) {
                SECU_PrintError(progName, "invalid input date");
                GEN_BREAK(SECFailure)
            }
        } else {
            timeBoundary = PR_Now();
        }

        if (logit) {
            log = &reallog;

            log->count = 0;
            log->head = NULL;
            log->tail = NULL;
            log->arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
            if (log->arena == NULL) {
                SECU_PrintError(progName, "out of memory");
                GEN_BREAK(SECFailure)
            }
        }

        rv = CERT_VerifyCertificate(handle, cert, checkSig, usage,
                                    timeBoundary, pwdata, log, &usage);
        if (log) {
            if (log->head == NULL) {
                fprintf(stdout, "%s: certificate is valid\n", progName);
                GEN_BREAK(SECSuccess)
            } else {
                char *nick;
                CERTVerifyLogNode *node;

                node = log->head;
                while (node) {
                    if (node->cert->nickname != NULL) {
                        nick = node->cert->nickname;
                    } else {
                        nick = node->cert->subjectName;
                    }
                    fprintf(stderr, "%s : %s\n", nick,
                            SECU_Strerror(node->error));
                    CERT_DestroyCertificate(node->cert);
                    node = node->next;
                }
            }
        } else {
            if (rv != SECSuccess) {
                PRErrorCode perr = PORT_GetError();
                fprintf(stdout, "%s: certificate is invalid: %s\n",
                        progName, SECU_Strerror(perr));
                GEN_BREAK(SECFailure)
            }
            fprintf(stdout, "%s: certificate is valid\n", progName);
            GEN_BREAK(SECSuccess)
        }
    } while (0);

    if (cert) {
        CERT_DestroyCertificate(cert);
    }

    return (rv);
}

static PRBool
ItemIsPrintableASCII(const SECItem *item)
{
    unsigned char *src = item->data;
    unsigned int len = item->len;
    while (len-- > 0) {
        unsigned char uc = *src++;
        if (uc < 0x20 || uc > 0x7e)
            return PR_FALSE;
    }
    return PR_TRUE;
}

/* Caller ensures that dst is at least item->len*2+1 bytes long */
static void
SECItemToHex(const SECItem *item, char *dst)
{
    if (dst && item && item->data) {
        unsigned char *src = item->data;
        unsigned int len = item->len;
        for (; len > 0; --len, dst += 2) {
            snprintf(dst, 3, "%02x", *src++);
        }
        *dst = '\0';
    }
}

static const char *const keyTypeName[] = {
    "null""rsa""dsa""fortezza""dh""kea""ec""rsaPss""rsaOaep"
};

#define MAX_CKA_ID_BIN_LEN 20
#define MAX_CKA_ID_STR_LEN 40

/* output human readable key ID in buffer, which should have at least
 * MAX_CKA_ID_STR_LEN + 3 octets (quotations and a null terminator) */

static void
formatPrivateKeyID(SECKEYPrivateKey *privkey, char *buffer)
{
    SECItem *ckaID;

    ckaID = PK11_GetLowLevelKeyIDForPrivateKey(privkey);
    if (!ckaID) {
        strcpy(buffer, "(no CKA_ID)");
    } else if (ItemIsPrintableASCII(ckaID)) {
        int len = PR_MIN(MAX_CKA_ID_STR_LEN, ckaID->len);
        buffer[0] = '"';
        memcpy(buffer + 1, ckaID->data, len);
        buffer[1 + len] = '"';
        buffer[2 + len] = '\0';
    } else {
        /* print ckaid in hex */
        SECItem idItem = *ckaID;
        if (idItem.len > MAX_CKA_ID_BIN_LEN)
            idItem.len = MAX_CKA_ID_BIN_LEN;
        SECItemToHex(&idItem, buffer);
    }
    SECITEM_ZfreeItem(ckaID, PR_TRUE);
}

/* print key number, key ID (in hex or ASCII), key label (nickname) */
static SECStatus
PrintKey(PRFileDesc *out, const char *nickName, int count,
         SECKEYPrivateKey *key, void *pwarg)
{
    char ckaIDbuf[MAX_CKA_ID_STR_LEN + 4];
    CERTCertificate *cert;
    KeyType keyType;

    formatPrivateKeyID(key, ckaIDbuf);
    cert = PK11_GetCertFromPrivateKey(key);
    if (cert) {
        keyType = CERT_GetCertKeyType(&cert->subjectPublicKeyInfo);
        CERT_DestroyCertificate(cert);
    } else {
        keyType = key->keyType;
    }
    PR_fprintf(out, "<%2d> %-8.8s %-42.42s %s\n", count,
               keyTypeName[keyType], ckaIDbuf, nickName);

    return SECSuccess;
}

/* returns SECSuccess if ANY keys are found, SECFailure otherwise. */
static SECStatus
ListKeysInSlot(PK11SlotInfo *slot, const char *nickName, KeyType keyType,
               void *pwarg)
{
    SECKEYPrivateKeyList *list;
    SECKEYPrivateKeyListNode *node;
    int count = 0;

    if (PK11_NeedLogin(slot)) {
        SECStatus rv = PK11_Authenticate(slot, PR_TRUE, pwarg);
        if (rv != SECSuccess) {
            SECU_PrintError(progName, "could not authenticate to token %s.",
                            PK11_GetTokenName(slot));
            return SECFailure;
        }
    }

    if (nickName && nickName[0])
        list = PK11_ListPrivKeysInSlot(slot, (char *)nickName, pwarg);
    else
        list = PK11_ListPrivateKeysInSlot(slot);
    if (list == NULL) {
        SECU_PrintError(progName, "problem listing keys");
        return SECFailure;
    }
    for (node = PRIVKEY_LIST_HEAD(list);
         !PRIVKEY_LIST_END(node, list);
         node = PRIVKEY_LIST_NEXT(node)) {
        char *keyName;
        static const char orphan[] = { "(orphan)" };

        if (keyType != nullKey && keyType != node->key->keyType)
            continue;
        keyName = PK11_GetPrivateKeyNickname(node->key);
        if (!keyName || !keyName[0]) {
            /* Try extra hard to find nicknames for keys that lack them. */
            CERTCertificate *cert;
            PORT_Free((void *)keyName);
            keyName = NULL;
            cert = PK11_GetCertFromPrivateKey(node->key);
            if (cert) {
                if (cert->nickname && cert->nickname[0]) {
                    keyName = PORT_Strdup(cert->nickname);
                } else if (cert->emailAddr && cert->emailAddr[0]) {
                    keyName = PORT_Strdup(cert->emailAddr);
                }
                CERT_DestroyCertificate(cert);
            }
        }
        if (nickName) {
            if (!keyName || PL_strcmp(keyName, nickName)) {
                /* PKCS#11 module returned unwanted keys */
                PORT_Free((void *)keyName);
                continue;
            }
        }
        if (!keyName)
            keyName = (char *)orphan;

        PrintKey(PR_STDOUT, keyName, count, node->key, pwarg);

        if (keyName != (char *)orphan)
            PORT_Free((void *)keyName);
        count++;
    }
    SECKEY_DestroyPrivateKeyList(list);

    if (count == 0) {
        PR_fprintf(PR_STDOUT, "%s: no keys found\n", progName);
        return SECFailure;
    }
    return SECSuccess;
}

/* returns SECSuccess if ANY keys are found, SECFailure otherwise. */
static SECStatus
ListKeys(PK11SlotInfo *slot, const char *nickName, int index,
         KeyType keyType, PRBool dopriv, secuPWData *pwdata)
{
    SECStatus rv = SECFailure;
    static const char fmt[] =
        "%s: Checking token \"%.33s\" in slot \"%.65s\"\n";

    if (slot == NULL) {
        PK11SlotList *list;
        PK11SlotListElement *le;

        list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_FALSE, pwdata);
        if (list) {
            for (le = list->head; le; le = le->next) {
                PR_fprintf(PR_STDOUT, fmt, progName,
                           PK11_GetTokenName(le->slot),
                           PK11_GetSlotName(le->slot));
                rv &= ListKeysInSlot(le->slot, nickName, keyType, pwdata);
            }
            PK11_FreeSlotList(list);
        }
    } else {
        PR_fprintf(PR_STDOUT, fmt, progName, PK11_GetTokenName(slot),
                   PK11_GetSlotName(slot));
        rv = ListKeysInSlot(slot, nickName, keyType, pwdata);
    }
    return rv;
}

static SECStatus
DeleteCertAndKey(char *nickname, secuPWData *pwdata)
{
    SECStatus rv;
    CERTCertificate *cert;
    PK11SlotInfo *slot;

    slot = PK11_GetInternalKeySlot();
    if (PK11_NeedLogin(slot)) {
        rv = PK11_Authenticate(slot, PR_TRUE, pwdata);
        if (rv != SECSuccess) {
            SECU_PrintError(progName, "could not authenticate to token %s.",
                            PK11_GetTokenName(slot));
            PK11_FreeSlot(slot);
            return SECFailure;
        }
    }
    cert = PK11_FindCertFromNickname(nickname, pwdata);
    if (!cert) {
        PK11_FreeSlot(slot);
        return SECFailure;
    }
    rv = PK11_DeleteTokenCertAndKey(cert, pwdata);
    if (rv != SECSuccess) {
        SECU_PrintError("problem deleting private key \"%s\"\n", nickname);
    }
    CERT_DestroyCertificate(cert);
    PK11_FreeSlot(slot);
    return rv;
}

static SECKEYPrivateKey *
findPrivateKeyByID(PK11SlotInfo *slot, const char *ckaID, secuPWData *pwarg)
{
    PORTCheapArenaPool arena;
    SECItem ckaIDItem = { 0 };
    SECKEYPrivateKey *privkey = NULL;
    SECStatus rv;

    if (PK11_NeedLogin(slot)) {
        rv = PK11_Authenticate(slot, PR_TRUE, pwarg);
        if (rv != SECSuccess) {
            SECU_PrintError(progName, "could not authenticate to token %s.",
                            PK11_GetTokenName(slot));
            return NULL;
        }
    }

    if (0 == PL_strncasecmp("0x", ckaID, 2)) {
        ckaID += 2; /* skip leading "0x" */
    }
    PORT_InitCheapArena(&arena, DER_DEFAULT_CHUNKSIZE);
    if (SECU_HexString2SECItem(&arena.arena, &ckaIDItem, ckaID)) {
        privkey = PK11_FindKeyByKeyID(slot, &ckaIDItem, pwarg);
    }
    PORT_DestroyCheapArena(&arena);
    return privkey;
}

static SECStatus
DeleteKey(SECKEYPrivateKey *privkey, secuPWData *pwarg)
{
    SECStatus rv;
    PK11SlotInfo *slot;

    slot = PK11_GetSlotFromPrivateKey(privkey);
    if (PK11_NeedLogin(slot)) {
        rv = PK11_Authenticate(slot, PR_TRUE, pwarg);
        if (rv != SECSuccess) {
            SECU_PrintError(progName, "could not authenticate to token %s.",
                            PK11_GetTokenName(slot));
            return SECFailure;
        }
    }

    rv = PK11_DeleteTokenPrivateKey(privkey, PR_TRUE);
    if (rv != SECSuccess) {
        char ckaIDbuf[MAX_CKA_ID_STR_LEN + 4];
        formatPrivateKeyID(privkey, ckaIDbuf);
        SECU_PrintError("problem deleting private key \"%s\"\n", ckaIDbuf);
    }

    PK11_FreeSlot(slot);
    return rv;
}

/*
 *  L i s t M o d u l e s
 *
 *  Print a list of the PKCS11 modules that are
 *  available. This is useful for smartcard people to
 *  make sure they have the drivers loaded.
 *
 */

static SECStatus
ListModules(void)
{
    PK11SlotList *list;
    PK11SlotListElement *le;

    /* get them all! */
    list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_FALSE, NULL);
    if (list == NULL)
        return SECFailure;

    /* look at each slot*/
    for (le = list->head; le; le = le->next) {
        char *token_uri = PK11_GetTokenURI(le->slot);
        printf("\n");
        printf(" slot: %s\n", PK11_GetSlotName(le->slot));
        printf(" token: %s\n", PK11_GetTokenName(le->slot));
        printf(" uri: %s\n", token_uri);
        PORT_Free(token_uri);
    }
    PK11_FreeSlotList(list);

    return SECSuccess;
}

static void
PrintBuildFlags()
{
#ifdef NSS_FIPS_DISABLED
    PR_fprintf(PR_STDOUT, "NSS_FIPS_DISABLED\n");
#endif
#ifdef NSS_NO_INIT_SUPPORT
    PR_fprintf(PR_STDOUT, "NSS_NO_INIT_SUPPORT\n");
#endif
    exit(0);
}

static void
PrintSyntax()
{
#define FPS fprintf(stderr,
    FPS "Type %s -H for more detailed descriptions\n", progName);
    FPS "Usage: %s -N [-d certdir] [-P dbprefix] [-f pwfile] [--empty-password]\n", progName);
    FPS "Usage: %s -T [-d certdir] [-P dbprefix] [-h token-name]\n"
        "\t\t [-f pwfile] [-0 SSO-password]\n", progName);
    FPS "\t%s -A -n cert-name -t trustargs [-d certdir] [-P dbprefix] [-a] [-i input]\n",
        progName);
    FPS "\t%s -B -i batch-file\n", progName);
    FPS "\t%s -C [-c issuer-name | -x] -i cert-request-file -o cert-file\n"
        "\t\t [-m serial-number] [-w warp-months] [-v months-valid]\n"
        "\t\t [-f pwfile] [-d certdir] [-P dbprefix] [-Z hashAlg]\n"
        "\t\t [-1 | --keyUsage [keyUsageKeyword,..]] [-2] [-3] [-4]\n"
        "\t\t [-5 | --nsCertType [nsCertTypeKeyword,...]]\n"
        "\t\t [-6 | --extKeyUsage [extKeyUsageKeyword,...]] [-7 emailAddrs]\n"
        "\t\t [-8 dns-names] [-a]\n",
        progName);
    FPS "\t%s -D -n cert-name [-d certdir] [-P dbprefix]\n", progName);
    FPS "\t%s --rename -n cert-name --new-n new-cert-name\n"
        "\t\t [-d certdir] [-P dbprefix]\n", progName);
    FPS "\t%s -E -n cert-name -t trustargs [-d certdir] [-P dbprefix] [-a] [-i input]\n",
        progName);
    FPS "\t%s -F -n cert-name [-d certdir] [-P dbprefix]\n",
        progName);
    FPS "\t%s -F -k key-id [-d certdir] [-P dbprefix]\n",
        progName);
    FPS "\t%s -G -n key-name [-h token-name] [-k rsa] [-g key-size] [-y exp]\n"
        "\t\t [-f pwfile] [-z noisefile] [-d certdir] [-P dbprefix]\n", progName);
    FPS "\t%s -G [-h token-name] -k dsa [-q pqgfile -g key-size] [-f pwfile]\n"
        "\t\t [-z noisefile] [-d certdir] [-P dbprefix]\n", progName);
    FPS "\t%s -G [-h token-name] -k ec -q curve [-f pwfile]\n"
        "\t\t [-z noisefile] [-d certdir] [-P dbprefix]\n", progName);
    FPS "\t%s -K [-n key-name] [-h token-name] [-k dsa|ec|rsa|all]\n",
        progName);
    FPS "\t\t [-f pwfile] [-X] [-d certdir] [-P dbprefix]\n");
    FPS "\t%s --upgrade-merge --source-dir upgradeDir --upgrade-id uniqueID\n",
        progName);
    FPS "\t\t [--upgrade-token-name tokenName] [-d targetDBDir]\n");
    FPS "\t\t [-P targetDBPrefix] [--source-prefix upgradeDBPrefix]\n");
    FPS "\t\t [-f targetPWfile] [-@ upgradePWFile]\n");
    FPS "\t%s --merge --source-dir sourceDBDir [-d targetDBdir]\n",
        progName);
    FPS "\t\t [-P targetDBPrefix] [--source-prefix sourceDBPrefix]\n");
    FPS "\t\t [-f targetPWfile] [-@ sourcePWFile]\n");
    FPS "\t%s -L [-n cert-name] [-h token-name] [--email email-address]\n",
        progName);
    FPS "\t\t [-X] [-r] [-a] [--dump-ext-val OID] [-d certdir] [-P dbprefix]\n");
    FPS "\t%s --build-flags\n", progName);
    FPS "\t%s -M -n cert-name -t trustargs [-d certdir] [-P dbprefix]\n",
        progName);
    FPS "\t%s -O -n cert-name [-X] [-d certdir] [-a] [-P dbprefix]\n"
        "\t\t [--simple-self-signed]\n",
        progName);
    FPS "\t%s -R -s subj -o cert-request-file [-d certdir] [-P dbprefix] [-p phone] [-a]\n"
        "\t\t [-7 emailAddrs] [-k key-type-or-id] [-h token-name] [-f pwfile]\n"
        "\t\t [-g key-size] [-Z hashAlg]\n",
        progName);
    FPS "\t%s -V -n cert-name -u usage [-b time] [-e] [-a]\n"
        "\t\t[-X] [-d certdir] [-P dbprefix]\n",
        progName);
    FPS "Usage: %s -W [-d certdir] [-f pwfile] [-@newpwfile]\n",
        progName);
    FPS "\t%s -S -n cert-name -s subj [-c issuer-name | -x] -t trustargs\n"
        "\t\t [-k key-type-or-id] [-q key-params] [-h token-name] [-g key-size]\n"
        "\t\t [-m serial-number] [-w warp-months] [-v months-valid]\n"
        "\t\t [-f pwfile] [-d certdir] [-P dbprefix] [-Z hashAlg]\n"
        "\t\t [-p phone] [-1] [-2] [-3] [-4] [-5] [-6] [-7 emailAddrs]\n"
        "\t\t [-8 DNS-names]\n"
        "\t\t [--extAIA] [--extSIA] [--extCP] [--extPM] [--extPC] [--extIA]\n"
        "\t\t [--extSKID] [--extNC] [--extSAN type:name[,type:name]...]\n"
        "\t\t [--extGeneric OID:critical-flag:filename[,OID:critical-flag:filename]...]\n", progName);
    FPS "\t%s -U [-X] [-d certdir] [-P dbprefix]\n", progName);
    exit(1);
}

enum usage_level {
    usage_all = 0,
    usage_selected = 1
};

static void luCommonDetailsAE();

static void
luA(enum usage_level ul, const char *command)
{
    int is_my_command = (command && 0 == strcmp(command, "A"));
    if (ul == usage_all || !command || is_my_command)
    FPS "%-15s Add a certificate to the database (create if needed)\n",
        "-A");
    if (ul == usage_selected && !is_my_command)
        return;
    if (ul == usage_all) {
    FPS "%-20s\n"" All options under -E apply");
    } else {
        luCommonDetailsAE();
    }
}

static void
luB(enum usage_level ul, const char *command)
{
    int is_my_command = (command && 0 == strcmp(command, "B"));
    if (ul == usage_all || !command || is_my_command)
    FPS "%-15s Run a series of certutil commands from a batch file\n""-B");
    if (ul == usage_selected && !is_my_command)
        return;
    FPS "%-20s Specify the batch file\n"" -i batch-file");
}

static void
luE(enum usage_level ul, const char *command)
{
    int is_my_command = (command && 0 == strcmp(command, "E"));
    if (ul == usage_all || !command || is_my_command)
    FPS "%-15s Add an Email certificate to the database (create if needed)\n",
        "-E");
    if (ul == usage_selected && !is_my_command)
        return;
    luCommonDetailsAE();
}

static void
luCommonDetailsAE()
{
    FPS "%-20s Specify the nickname of the certificate to add\n",
        " -n cert-name");
    FPS "%-20s Set the certificate trust attributes:\n",
        " -t trustargs");
    FPS "%-25s trustargs is of the form x,y,z where x is for SSL, y is for S/MIME,\n""");
    FPS "%-25s and z is for code signing. Use ,, for no explicit trust.\n""");
    FPS "%-25s p \t prohibited (explicitly distrusted)\n""");
    FPS "%-25s P \t trusted peer\n""");
    FPS "%-25s c \t valid CA\n""");
    FPS "%-25s T \t trusted CA to issue client certs (implies c)\n""");
    FPS "%-25s C \t trusted CA to issue server certs (implies c)\n""");
    FPS "%-25s u \t user cert\n""");
    FPS "%-25s w \t send warning\n""");
    FPS "%-25s g \t make step-up cert\n""");
    FPS "%-20s Specify the password file\n",
        " -f pwfile");
    FPS "%-20s Cert database directory (default is ~/.netscape)\n",
        " -d certdir");
    FPS "%-20s Cert & Key database prefix\n",
        " -P dbprefix");
    FPS "%-20s The input certificate is encoded in ASCII (RFC1113)\n",
        " -a");
    FPS "%-20s Specify the certificate file (default is stdin)\n",
        " -i input");
    FPS "\n");
}

static void
luC(enum usage_level ul, const char *command)
{
    int is_my_command = (command && 0 == strcmp(command, "C"));
    if (ul == usage_all || !command || is_my_command)
    FPS "%-15s Create a new binary certificate from a BINARY cert request\n",
        "-C");
    if (ul == usage_selected && !is_my_command)
        return;
    FPS "%-20s The nickname of the issuer cert\n",
        " -c issuer-name");
    FPS "%-20s The BINARY certificate request file\n",
        " -i cert-request ");
    FPS "%-20s Output binary cert to this file (default is stdout)\n",
        " -o output-cert");
    FPS "%-20s Self sign\n",
        " -x");
    FPS "%-20s Sign the certificate with RSA-PSS (the issuer key must be rsa)\n",
        " --pss-sign");
    FPS "%-20s Cert serial number\n",
        " -m serial-number");
    FPS "%-20s Time Warp\n",
        " -w warp-months");
    FPS "%-20s Months valid (default is 3)\n",
        " -v months-valid");
    FPS "%-20s Specify the password file\n",
        " -f pwfile");
    FPS "%-20s Cert database directory (default is ~/.netscape)\n",
        " -d certdir");
    FPS "%-20s Cert & Key database prefix\n",
        " -P dbprefix");
    FPS "%-20s \n"
              "%-20s Specify the hash algorithm to use. Possible keywords:\n"
              "%-20s \"MD2\", \"MD4\", \"MD5\", \"SHA1\", \"SHA224\",\n"
              "%-20s \"SHA256\", \"SHA384\", \"SHA512\"\n",
        " -Z hashAlg""""""");
    FPS "%-20s \n"
              "%-20s Create key usage extension. Possible keywords:\n"
              "%-20s \"digitalSignature\", \"nonRepudiation\", \"keyEncipherment\",\n"
              "%-20s \"dataEncipherment\", \"keyAgreement\", \"certSigning\",\n"
              "%-20s \"crlSigning\", \"critical\"\n",
        " -1 | --keyUsage keyword,keyword,...""""""""");
    FPS "%-20s Create basic constraint extension\n",
        " -2 ");
    FPS "%-20s Create authority key ID extension\n",
        " -3 ");
    FPS "%-20s Create crl distribution point extension\n",
        " -4 ");
    FPS "%-20s \n"
              "%-20s Create netscape cert type extension. Possible keywords:\n"
              "%-20s \"sslClient\", \"sslServer\", \"smime\", \"objectSigning\",\n"
              "%-20s \"sslCA\", \"smimeCA\", \"objectSigningCA\", \"critical\".\n",
        " -5 | --nsCertType keyword,keyword,... """"""");
    FPS "%-20s \n"
              "%-20s Create extended key usage extension. Possible keywords:\n"
              "%-20s \"serverAuth\", \"clientAuth\",\"codeSigning\",\n"
              "%-20s \"emailProtection\", \"timeStamp\",\"ocspResponder\",\n"
              "%-20s \"stepUp\", \"msTrustListSign\", \"x509Any\",\n"
              "%-20s \"ipsecIKE\", \"ipsecIKEEnd\", \"ipsecIKEIntermediate\",\n"
              "%-20s \"ipsecEnd\", \"ipsecTunnel\", \"ipsecUser\",\n"
              "%-20s \"critical\"\n",
        " -6 | --extKeyUsage keyword,keyword,...""""""""""""""");
    FPS "%-20s Create an email subject alt name extension\n",
        " -7 emailAddrs");
    FPS "%-20s Create an dns subject alt name extension\n",
        " -8 dnsNames");
    FPS "%-20s The input certificate request is encoded in ASCII (RFC1113)\n",
        " -a");
    FPS "\n");
}

static void
luG(enum usage_level ul, const char *command)
{
    int is_my_command = (command && 0 == strcmp(command, "G"));
    if (ul == usage_all || !command || is_my_command)
    FPS "%-15s Generate a new key pair\n",
        "-G");
    if (ul == usage_selected && !is_my_command)
        return;
    FPS "%-20s Name of token in which to generate key (default is internal)\n",
        " -h token-name");
    FPS "%-20s Type of key pair to generate (\"dsa\", \"ec\", \"rsa\" (default))\n",
        " -k key-type");
    FPS "%-20s Key size in bits, (min %d, max %d, default %d) (not for ec)\n",
        " -g key-size", MIN_KEY_BITS, MAX_KEY_BITS, DEFAULT_KEY_BITS);
    FPS "%-20s Set the public exponent value (3, 17, 65537) (rsa only)\n",
        " -y exp");
    FPS "%-20s Specify the password file\n",
        " -f password-file");
    FPS "%-20s Specify the noise file to be used\n",
        " -z noisefile");
    FPS "%-20s read PQG value from pqgfile (dsa only)\n",
        " -q pqgfile");
    FPS "%-20s Elliptic curve name (ec only)\n",
        " -q curve-name");
    FPS "%-20s One of nistp256, nistp384, nistp521, curve25519.\n""");
    FPS "%-20s If a custom token is present, the following curves are also supported:\n""");
    FPS "%-20s sect163k1, nistk163, sect163r1, sect163r2,\n""");
    FPS "%-20s nistb163, sect193r1, sect193r2, sect233k1, nistk233,\n""");
    FPS "%-20s sect233r1, nistb233, sect239k1, sect283k1, nistk283,\n""");
    FPS "%-20s sect283r1, nistb283, sect409k1, nistk409, sect409r1,\n""");
    FPS "%-20s nistb409, sect571k1, nistk571, sect571r1, nistb571,\n""");
    FPS "%-20s secp160k1, secp160r1, secp160r2, secp192k1, secp192r1,\n""");
    FPS "%-20s nistp192, secp224k1, secp224r1, nistp224, secp256k1,\n""");
    FPS "%-20s secp256r1, secp384r1, secp521r1,\n""");
    FPS "%-20s prime192v1, prime192v2, prime192v3, \n""");
    FPS "%-20s prime239v1, prime239v2, prime239v3, c2pnb163v1, \n""");
    FPS "%-20s c2pnb163v2, c2pnb163v3, c2pnb176v1, c2tnb191v1, \n""");
    FPS "%-20s c2tnb191v2, c2tnb191v3, \n""");
    FPS "%-20s c2pnb208w1, c2tnb239v1, c2tnb239v2, c2tnb239v3, \n""");
    FPS "%-20s c2pnb272w1, c2pnb304w1, \n""");
    FPS "%-20s c2tnb359w1, c2pnb368w1, c2tnb431r1, secp112r1, \n""");
    FPS "%-20s secp112r2, secp128r1, secp128r2, sect113r1, sect113r2\n""");
    FPS "%-20s sect131r1, sect131r2\n""");
    FPS "%-20s Key database directory (default is ~/.netscape)\n",
        " -d keydir");
    FPS "%-20s Cert & Key database prefix\n",
        " -P dbprefix");
    FPS "%-20s\n"
        "%-20s PKCS #11 key Attributes.\n",
        " --keyAttrFlags attrflags""");
    FPS "%-20s Comma separated list of key attribute attribute flags,\n""");
    FPS "%-20s selected from the following list of choices:\n""");
    FPS "%-20s {token | session} {public | private} {sensitive | insensitive}\n""");
    FPS "%-20s {modifiable | unmodifiable} {extractable | unextractable}\n""");
    FPS "%-20s\n",
        " --keyOpFlagsOn opflags");
    FPS "%-20s\n"
        "%-20s PKCS #11 key Operation Flags.\n",
        " --keyOpFlagsOff opflags""");
    FPS "%-20s Comma separated list of one or more of the following:\n""");
    FPS "%-20s encrypt, decrypt, sign, sign_recover, verify,\n""");
    FPS "%-20s verify_recover, wrap, unwrap, derive\n""");
    FPS "\n");
}

static void
luD(enum usage_level ul, const char *command)
{
    int is_my_command = (command && 0 == strcmp(command, "D"));
    if (ul == usage_all || !command || is_my_command)
    FPS "%-15s Delete a certificate from the database\n",
        "-D");
    if (ul == usage_selected && !is_my_command)
        return;
    FPS "%-20s The nickname of the cert to delete\n",
        " -n cert-name");
    FPS "%-20s Cert database directory (default is ~/.netscape)\n",
        " -d certdir");
    FPS "%-20s Cert & Key database prefix\n",
        " -P dbprefix");
    FPS "\n");
}

static void
luF(enum usage_level ul, const char *command)
{
    int is_my_command = (command && 0 == strcmp(command, "F"));
    if (ul == usage_all || !command || is_my_command)
    FPS "%-15s Delete a key and associated certificate from the database\n",
        "-F");
    if (ul == usage_selected && !is_my_command)
        return;
    FPS "%-20s The nickname of the key to delete\n",
        " -n cert-name");
    FPS "%-20s The key id of the key to delete, obtained using -K\n",
        " -k key-id");
    FPS "%-20s Cert database directory (default is ~/.netscape)\n",
        " -d certdir");
    FPS "%-20s Cert & Key database prefix\n",
        " -P dbprefix");
    FPS "\n");
}

static void
luU(enum usage_level ul, const char *command)
{
    int is_my_command = (command && 0 == strcmp(command, "U"));
    if (ul == usage_all || !command || is_my_command)
    FPS "%-15s List all modules\n"/*, or print out a single named module\n",*/
        "-U");
    if (ul == usage_selected && !is_my_command)
        return;
    FPS "%-20s Module database directory (default is '~/.netscape')\n",
        " -d moddir");
    FPS "%-20s Cert & Key database prefix\n",
        " -P dbprefix");
    FPS "%-20s force the database to open R/W\n",
        " -X");
    FPS "\n");
}

static void
luK(enum usage_level ul, const char *command)
{
    int is_my_command = (command && 0 == strcmp(command, "K"));
    if (ul == usage_all || !command || is_my_command)
    FPS "%-15s List all private keys\n",
        "-K");
    if (ul == usage_selected && !is_my_command)
        return;
    FPS "%-20s Name of token to search (\"all\" for all tokens)\n",
        " -h token-name ");

    FPS "%-20s Key type (\"all\" (default), \"dsa\","
                                                    " \"ec\","
                                                    " \"rsa\")\n",
        " -k key-type");
    FPS "%-20s The nickname of the key or associated certificate\n",
        " -n name");
    FPS "%-20s Specify the password file\n",
        " -f password-file");
    FPS "%-20s Key database directory (default is ~/.netscape)\n",
        " -d keydir");
    FPS "%-20s Cert & Key database prefix\n",
        " -P dbprefix");
    FPS "%-20s force the database to open R/W\n",
        " -X");
    FPS "\n");
}

static void
luL(enum usage_level ul, const char *command)
{
    int is_my_command = (command && 0 == strcmp(command, "L"));
    if (ul == usage_all || !command || is_my_command)
    FPS "%-15s List all certs, or print out a single named cert (or a subset)\n",
        "-L");
    if (ul == usage_selected && !is_my_command)
        return;
    FPS "%-20s Name of token to search (\"all\" for all tokens)\n",
        " -h token-name ");
    FPS "%-20s Pretty print named cert (list all if unspecified)\n",
        " -n cert-name");
    FPS "%-20s \n"
              "%-20s Pretty print cert with email address (list all if unspecified)\n",
        " --email email-address""");
    FPS "%-20s Cert database directory (default is ~/.netscape)\n",
        " -d certdir");
    FPS "%-20s Cert & Key database prefix\n",
        " -P dbprefix");
    FPS "%-20s force the database to open R/W\n",
        " -X");
    FPS "%-20s For single cert, print binary DER encoding\n",
        " -r");
    FPS "%-20s For single cert, print ASCII encoding (RFC1113)\n",
        " -a");
    FPS "%-20s \n"
              "%-20s For single cert, print binary DER encoding of extension OID\n",
        " --dump-ext-val OID""");
    FPS "\n");
}

static void
luM(enum usage_level ul, const char *command)
{
    int is_my_command = (command && 0 == strcmp(command, "M"));
    if (ul == usage_all || !command || is_my_command)
    FPS "%-15s Modify trust attributes of certificate\n",
        "-M");
    if (ul == usage_selected && !is_my_command)
        return;
    FPS "%-20s The nickname of the cert to modify\n",
        " -n cert-name");
    FPS "%-20s Set the certificate trust attributes (see -A above)\n",
        " -t trustargs");
    FPS "%-20s Cert database directory (default is ~/.netscape)\n",
        " -d certdir");
    FPS "%-20s Cert & Key database prefix\n",
        " -P dbprefix");
    FPS "\n");
}

static void
luN(enum usage_level ul, const char *command)
{
    int is_my_command = (command && 0 == strcmp(command, "N"));
    if (ul == usage_all || !command || is_my_command)
    FPS "%-15s Create a new certificate database\n",
        "-N");
    if (ul == usage_selected && !is_my_command)
        return;
    FPS "%-20s Cert database directory (default is ~/.netscape)\n",
        " -d certdir");
    FPS "%-20s Cert & Key database prefix\n",
        " -P dbprefix");
    FPS "%-20s Specify the password file\n",
        " -f password-file");
    FPS "%-20s use empty password when creating a new database\n",
        " --empty-password");
    FPS "\n");
}

static void
luT(enum usage_level ul, const char *command)
{
    int is_my_command = (command && 0 == strcmp(command, "T"));
    if (ul == usage_all || !command || is_my_command)
    FPS "%-15s Reset the Key database or token\n",
        "-T");
    if (ul == usage_selected && !is_my_command)
        return;
    FPS "%-20s Cert database directory (default is ~/.netscape)\n",
        " -d certdir");
    FPS "%-20s Cert & Key database prefix\n",
        " -P dbprefix");
    FPS "%-20s Token to reset (default is internal)\n",
        " -h token-name");
    FPS "%-20s Set token's Site Security Officer password\n",
        " -0 SSO-password");
    FPS "\n");
}

static void
luO(enum usage_level ul, const char *command)
{
    int is_my_command = (command && 0 == strcmp(command, "O"));
    if (ul == usage_all || !command || is_my_command)
    FPS "%-15s Print the chain of a certificate\n",
        "-O");
    if (ul == usage_selected && !is_my_command)
        return;
    FPS "%-20s The nickname of the cert to modify\n",
        " -n cert-name");
    FPS "%-20s Cert database directory (default is ~/.netscape)\n",
        " -d certdir");
    FPS "%-20s Input the certificate in ASCII (RFC1113); default is binary\n",
        " -a");
    FPS "%-20s Cert & Key database prefix\n",
        " -P dbprefix");
    FPS "%-20s force the database to open R/W\n",
        " -X");
    FPS "%-20s don't search for a chain if issuer name equals subject name\n",
        " --simple-self-signed");
    FPS "\n");
}

static void
luR(enum usage_level ul, const char *command)
{
    int is_my_command = (command && 0 == strcmp(command, "R"));
    if (ul == usage_all || !command || is_my_command)
    FPS "%-15s Generate a certificate request (stdout)\n",
        "-R");
    if (ul == usage_selected && !is_my_command)
        return;
    FPS "%-20s Specify the subject name (using RFC1485)\n",
        " -s subject");
    FPS "%-20s Output the cert request to this file\n",
        " -o output-req");
    FPS "%-20s Type of key pair to generate (\"dsa\", \"ec\", \"rsa\" (default))\n",
        " -k key-type-or-id");
    FPS "%-20s or nickname of the cert key to use, or key id obtained using -K\n",
        "");
    FPS "%-20s Name of token in which to generate key (default is internal)\n",
        " -h token-name");
    FPS "%-20s Key size in bits, RSA keys only (min %d, max %d, default %d)\n",
        " -g key-size", MIN_KEY_BITS, MAX_KEY_BITS, DEFAULT_KEY_BITS);
    FPS "%-20s Create a certificate request restricted to RSA-PSS (rsa only)\n",
        " --pss");
    FPS "%-20s Name of file containing PQG parameters (dsa only)\n",
        " -q pqgfile");
    FPS "%-20s Elliptic curve name (ec only)\n",
        " -q curve-name");
    FPS "%-20s See the \"-G\" option for a full list of supported names.\n",
        "");
    FPS "%-20s Specify the password file\n",
        " -f pwfile");
    FPS "%-20s Key database directory (default is ~/.netscape)\n",
        " -d keydir");
    FPS "%-20s Cert & Key database prefix\n",
        " -P dbprefix");
    FPS "%-20s Specify the contact phone number (\"123-456-7890\")\n",
        " -p phone");
    FPS "%-20s \n"
              "%-20s Specify the hash algorithm to use. Possible keywords:\n"
              "%-20s \"MD2\", \"MD4\", \"MD5\", \"SHA1\", \"SHA224\",\n"
              "%-20s \"SHA256\", \"SHA384\", \"SHA512\"\n",
        " -Z hashAlg""""""");
    FPS "%-20s Output the cert request in ASCII (RFC1113); default is binary\n",
        " -a");
    FPS "%-20s \n",
        " See -S for available extension options");
    FPS "%-20s \n",
        " See -G for available key flag options");
    FPS "\n");
}

static void
luV(enum usage_level ul, const char *command)
{
    int is_my_command = (command && 0 == strcmp(command, "V"));
    if (ul == usage_all || !command || is_my_command)
    FPS "%-15s Validate a certificate\n",
        "-V");
    if (ul == usage_selected && !is_my_command)
        return;
    FPS "%-20s The nickname of the cert to Validate\n",
        " -n cert-name");
    FPS "%-20s validity time (\"YYMMDDHHMMSS[+HHMM|-HHMM|Z]\")\n",
        " -b time");
    FPS "%-20s Check certificate signature \n",
        " -e ");
    FPS "%-20s Specify certificate usage:\n"" -u certusage");
    FPS "%-25s C \t SSL Client\n""");
    FPS "%-25s V \t SSL Server\n""");
    FPS "%-25s I \t IPsec\n""");
    FPS "%-25s L \t SSL CA\n""");
    FPS "%-25s A \t Any CA\n""");
    FPS "%-25s Y \t Verify CA\n""");
    FPS "%-25s S \t Email signer\n""");
    FPS "%-25s R \t Email Recipient\n""");
    FPS "%-25s O \t OCSP status responder\n""");
    FPS "%-25s J \t Object signer\n""");
    FPS "%-20s Cert database directory (default is ~/.netscape)\n",
        " -d certdir");
    FPS "%-20s Input the certificate in ASCII (RFC1113); default is binary\n",
        " -a");
    FPS "%-20s Cert & Key database prefix\n",
        " -P dbprefix");
    FPS "%-20s force the database to open R/W\n",
        " -X");
    FPS "\n");
}

static void
luW(enum usage_level ul, const char *command)
{
    int is_my_command = (command && 0 == strcmp(command, "W"));
    if (ul == usage_all || !command || is_my_command)
    FPS "%-15s Change the key database password\n",
        "-W");
    if (ul == usage_selected && !is_my_command)
        return;
    FPS "%-20s cert and key database directory\n",
        " -d certdir");
    FPS "%-20s Specify a file with the current password\n",
        " -f pwfile");
    FPS "%-20s Specify a file with the new password in two lines\n",
        " -@ newpwfile");
    FPS "\n");
}

static void
luRename(enum usage_level ul, const char *command)
{
    int is_my_command = (command && 0 == strcmp(command, "rename"));
    if (ul == usage_all || !command || is_my_command)
    FPS "%-15s Change the database nickname of a certificate\n",
        "--rename");
    if (ul == usage_selected && !is_my_command)
        return;
    FPS "%-20s The old nickname of the cert to rename\n",
        " -n cert-name");
    FPS "%-20s The new nickname of the cert to rename\n",
        " --new-n new-name");
    FPS "%-20s Cert database directory (default is ~/.netscape)\n",
        " -d certdir");
    FPS "%-20s Cert & Key database prefix\n",
        " -P dbprefix");
    FPS "\n");
}

static void
luUpgradeMerge(enum usage_level ul, const char *command)
{
    int is_my_command = (command && 0 == strcmp(command, "upgrade-merge"));
    if (ul == usage_all || !command || is_my_command)
    FPS "%-15s Upgrade an old database and merge it into a new one\n",
        "--upgrade-merge");
    if (ul == usage_selected && !is_my_command)
        return;
    FPS "%-20s Cert database directory to merge into (default is ~/.netscape)\n",
        " -d certdir");
    FPS "%-20s Cert & Key database prefix of the target database\n",
        " -P dbprefix");
    FPS "%-20s Specify the password file for the target database\n",
        " -f pwfile");
    FPS "%-20s \n%-20s Cert database directory to upgrade from\n",
        " --source-dir certdir""");
    FPS "%-20s \n%-20s Cert & Key database prefix of the upgrade database\n",
        " --source-prefix dbprefix""");
    FPS "%-20s \n%-20s Unique identifier for the upgrade database\n",
        " --upgrade-id uniqueID""");
    FPS "%-20s \n%-20s Name of the token while it is in upgrade state\n",
        " --upgrade-token-name name""");
    FPS "%-20s Specify the password file for the upgrade database\n",
        " -@ pwfile");
    FPS "\n");
}

static void
luMerge(enum usage_level ul, const char *command)
{
    int is_my_command = (command && 0 == strcmp(command, "merge"));
    if (ul == usage_all || !command || is_my_command)
    FPS "%-15s Merge source database into the target database\n",
        "--merge");
    if (ul == usage_selected && !is_my_command)
        return;
    FPS "%-20s Cert database directory of target (default is ~/.netscape)\n",
        " -d certdir");
    FPS "%-20s Cert & Key database prefix of the target database\n",
        " -P dbprefix");
    FPS "%-20s Specify the password file for the target database\n",
        " -f pwfile");
    FPS "%-20s \n%-20s Cert database directory of the source database\n",
        " --source-dir certdir""");
    FPS "%-20s \n%-20s Cert & Key database prefix of the source database\n",
        " --source-prefix dbprefix""");
    FPS "%-20s Specify the password file for the source database\n",
        " -@ pwfile");
    FPS "\n");
}

static void
luS(enum usage_level ul, const char *command)
{
    int is_my_command = (command && 0 == strcmp(command, "S"));
    if (ul == usage_all || !command || is_my_command)
    FPS "%-15s Make a certificate and add to database\n",
        "-S");
    if (ul == usage_selected && !is_my_command)
        return;
    FPS "%-20s Specify the nickname of the cert\n",
        " -n key-name");
    FPS "%-20s Specify the subject name (using RFC1485)\n",
        " -s subject");
    FPS "%-20s The nickname of the issuer cert\n",
        " -c issuer-name");
    FPS "%-20s Set the certificate trust attributes (see -A above)\n",
        " -t trustargs");
    FPS "%-20s Type of key pair to generate (\"dsa\", \"ec\", \"rsa\" (default))\n",
        " -k key-type-or-id");
    FPS "%-20s Name of token in which to generate key (default is internal)\n",
        " -h token-name");
    FPS "%-20s Key size in bits, RSA keys only (min %d, max %d, default %d)\n",
        " -g key-size", MIN_KEY_BITS, MAX_KEY_BITS, DEFAULT_KEY_BITS);
    FPS "%-20s Create a certificate restricted to RSA-PSS (rsa only)\n",
        " --pss");
    FPS "%-20s Name of file containing PQG parameters (dsa only)\n",
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=99 H=94 G=96

¤ Dauer der Verarbeitung: 0.40 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.