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

Quelle  pk1sign.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/. */


/*
 * pk1sign
 */


#include "nspr.h"
#include "plgetopt.h"
#include "secutil.h"
#include "secpkcs7.h"
#include "cert.h"
#include "certdb.h"
#include "sechash.h" /* for HASH_GetHashObject() */
#include "nss.h"
#include "pk11func.h"
#include "cryptohi.h"
#include "plbase64.h"

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

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

#if (defined(XP_WIN) && !defined(WIN32)) || (defined(__sun) && !defined(SVR4))
extern int fread(char *, size_t, size_t, FILE *);
extern int fwrite(char *, size_t, size_t, FILE *);
extern int fprintf(FILE *, char *, ...);
#endif

static secuPWData pwdata = { PW_NONE, 0 };

SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)

SEC_ASN1Template CERTSignatureDataTemplate[] = {
    { SEC_ASN1_SEQUENCE,
      0, NULL, sizeof(CERTSignedData) },
    { SEC_ASN1_INLINE,
      offsetof(CERTSignedData, signatureAlgorithm),
      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
    { SEC_ASN1_BIT_STRING,
      offsetof(CERTSignedData, signature) },
    { 0 }
};

static void
Usage(char *progName)
{
    fprintf(stderr,
            "Usage: %s -k keyname [-d keydir] [-i input] [-o output]\n",
            progName);
    fprintf(stderr, "%-20s Nickname of key to use for signature\n",
            "-k keyname");
    fprintf(stderr, "%-20s Key database directory (default is ~/.netscape)\n",
            "-d keydir");
    fprintf(stderr, "%-20s Define an input file to use (default is stdin)\n",
            "-i input");
    fprintf(stderr, "%-20s Define an output file to use (default is stdout)\n",
            "-o output");
    fprintf(stderr, "%-20s Password to the key databse\n""-p");
    fprintf(stderr, "%-20s password file\n""-f");
    exit(-1);
}

static int
ExportPublicKey(FILE *outFile, CERTCertificate *cert)
{
    char *data;
    SECKEYPublicKey *publicKey;
    SECItem *item;

    if (!cert)
        return -1;

    publicKey = CERT_ExtractPublicKey(cert);
    if (!publicKey)
        return -1;

    item = SECKEY_EncodeDERSubjectPublicKeyInfo(publicKey);
    SECKEY_DestroyPublicKey(publicKey);
    if (!item)
        return -1;

    data = PL_Base64Encode((const char *)item->data, item->len, NULL);
    SECITEM_FreeItem(item, PR_TRUE);
    if (!data)
        return -1;

    fputs("pubkey:\n", outFile);
    fputs(data, outFile);
    fputs("\n", outFile);
    PR_Free(data);

    return 0;
}

static int
SignFile(FILE *outFile, PRFileDesc *inFile, CERTCertificate *cert)
{
    SECItem data2sign;
    SECStatus rv;
    SECOidTag algID;
    CERTSignedData sd;
    SECKEYPrivateKey *privKey = NULL;
    char *data = NULL;
    PLArenaPool *arena = NULL;
    SECItem *result = NULL;
    int returnValue = 0;

    if (outFile == NULL || inFile == NULL || cert == NULL) {
        return -1;
    }

    /* suck the file in */
    if (SECU_ReadDERFromFile(&data2sign, inFile, PR_FALSE,
                             PR_FALSE) != SECSuccess) {
        return -1;
    }

    privKey = NULL;
    privKey = PK11_FindKeyByAnyCert(cert, NULL);
    if (!privKey) {
        returnValue = -1;
        goto loser;
    }

    algID = SEC_GetSignatureAlgorithmOidTag(privKey->keyType, SEC_OID_SHA1);
    if (algID == SEC_OID_UNKNOWN) {
        returnValue = -1;
        goto loser;
    }

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);

    PORT_Memset(&sd, 0, sizeof(CERTSignedData));

    rv = SEC_SignData(&(sd.signature), data2sign.data, data2sign.len, privKey, algID);
    if (rv != SECSuccess) {
        fprintf(stderr, "Could not sign.\n");
        returnValue = -1;
        goto loser;
    }
    sd.signature.len = sd.signature.len << 3;

    rv = SECOID_SetAlgorithmID(arena, &sd.signatureAlgorithm, algID, 0);
    if (rv != SECSuccess) {
        fprintf(stderr, "Could not set alg id.\n");
        returnValue = -1;
        goto loser;
    }

    result = SEC_ASN1EncodeItem(arena, NULL, &sd, CERTSignatureDataTemplate);
    SECITEM_FreeItem(&(sd.signature), PR_FALSE);

    if (!result) {
        fprintf(stderr, "Could not encode.\n");
        returnValue = -1;
        goto loser;
    }

    data = PL_Base64Encode((const char *)result->data, result->len, NULL);
    if (!data) {
        returnValue = -1;
        goto loser;
    }

    fputs("signature:\n", outFile);
    fputs(data, outFile);
    fputs("\n", outFile);
    ExportPublicKey(outFile, cert);

loser:
    if (privKey) {
        SECKEY_DestroyPrivateKey(privKey);
    }
    if (data) {
        PR_Free(data);
    }
    PORT_FreeArena(arena, PR_FALSE);

    return returnValue;
}

int
main(int argc, char **argv)
{
    char *progName;
    FILE *outFile;
    PRFileDesc *inFile;
    char *keyName = NULL;
    CERTCertDBHandle *certHandle;
    CERTCertificate *cert = NULL;
    PLOptState *optstate;
    PLOptStatus status;
    SECStatus rv;

    progName = strrchr(argv[0], '/');
    progName = progName ? progName + 1 : argv[0];

    inFile = NULL;
    outFile = NULL;
    keyName = NULL;

    /*
     * Parse command line arguments
     */

    optstate = PL_CreateOptState(argc, argv, "ed:k:i:o:p:f:");
    while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
        switch (optstate->option) {
            case '?':
                Usage(progName);
                break;

            case 'd':
                SECU_ConfigDirectory(optstate->value);
                break;

            case 'i':
                inFile = PR_Open(optstate->value, PR_RDONLY, 0);
                if (!inFile) {
                    fprintf(stderr, "%s: unable to open \"%s\" for reading\n",
                            progName, optstate->value);
                    return -1;
                }
                break;

            case 'k':
                keyName = strdup(optstate->value);
                break;

            case 'o':
                outFile = fopen(optstate->value, "wb");
                if (!outFile) {
                    fprintf(stderr, "%s: unable to open \"%s\" for writing\n",
                            progName, optstate->value);
                    return -1;
                }
                break;
            case 'p':
                pwdata.source = PW_PLAINTEXT;
                pwdata.data = strdup(optstate->value);
                break;

            case 'f':
                pwdata.source = PW_FROMFILE;
                pwdata.data = PORT_Strdup(optstate->value);
                break;
        }
    }

    if (!keyName)
        Usage(progName);

    if (!inFile)
        inFile = PR_STDIN;
    if (!outFile)
        outFile = stdout;

    /* Call the initialization routines */
    PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
    rv = NSS_Init(SECU_ConfigDirectory(NULL));
    if (rv != SECSuccess) {
        SECU_PrintPRandOSError(progName);
        goto loser;
    }

    PK11_SetPasswordFunc(SECU_GetModulePassword);

    /* open cert database */
    certHandle = CERT_GetDefaultCertDB();
    if (certHandle == NULL) {
        rv = SECFailure;
        goto loser;
    }

    /* find cert */
    cert = CERT_FindCertByNickname(certHandle, keyName);
    if (cert == NULL) {
        SECU_PrintError(progName,
                        "the corresponding cert for key \"%s\" does not exist",
                        keyName);
        rv = SECFailure;
        goto loser;
    }

    if (SignFile(outFile, inFile, cert)) {
        SECU_PrintError(progName, "problem signing data");
        rv = SECFailure;
        goto loser;
    }

loser:
    if (pwdata.data) {
        PORT_Free(pwdata.data);
    }
    if (keyName) {
        PORT_Free(keyName);
    }
    if (cert) {
        CERT_DestroyCertificate(cert);
    }
    if (inFile && inFile != PR_STDIN) {
        PR_Close(inFile);
    }
    if (outFile && outFile != stdout) {
        fclose(outFile);
    }
    if (NSS_Shutdown() != SECSuccess) {
        SECU_PrintError(progName, "NSS shutdown:");
        exit(1);
    }

    return (rv != SECSuccess);
}

Messung V0.5
C=98 H=79 G=88

¤ Dauer der Verarbeitung: 0.2 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.