Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/security/nss/lib/ssl/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 7 kB image not shown  

Quelle  tls13signature.c   Sprache: C

 

/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * TLS 1.3 Protocol
 *
 * 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/. */

#include "sslimpl.h"
#include "cryptohi.h"
#include "keyhi.h"

/* we put this here because it only affects TLS 1.3, and not TLS 1.2 and earlier
 * which use the old sign hashes interface. The TLS 1.3 protocol is friendly to
 * algorthims that don't have a signed hashes interface */

/* we generate an algorithm ID rather than just use an OID to support RSAPSS.
 * It's generated completely from the scheme */

static SECAlgorithmID *
tls_GetSignatureAlgorithmId(PLArenaPool *arena, SSLSignatureScheme scheme,
                            SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey)
{
    SECAlgorithmID *newAlgID = PORT_ArenaZNew(arena, SECAlgorithmID);
    SECOidTag algTag = SEC_OID_UNKNOWN;
    SECOidTag hashAlgTag = SEC_OID_UNKNOWN;
    SECStatus rv;

    switch (scheme) {
        /* For the algTag the difference between rsa_pss_rsae and
         * rsa_pss_pss is in the selection of the cert.
         * At this stage, the signatures are the same, so for our
         * purposed they are equivalent */

        case ssl_sig_rsa_pss_rsae_sha256:
        case ssl_sig_rsa_pss_pss_sha256:
            algTag = SEC_OID_PKCS1_RSA_PSS_SIGNATURE;
            hashAlgTag = SEC_OID_SHA256;
            break;
        case ssl_sig_rsa_pss_rsae_sha384:
        case ssl_sig_rsa_pss_pss_sha384:
            algTag = SEC_OID_PKCS1_RSA_PSS_SIGNATURE;
            hashAlgTag = SEC_OID_SHA384;
            break;
        case ssl_sig_rsa_pss_rsae_sha512:
        case ssl_sig_rsa_pss_pss_sha512:
            algTag = SEC_OID_PKCS1_RSA_PSS_SIGNATURE;
            hashAlgTag = SEC_OID_SHA512;
            break;
        /* the curve comes from the key and should have already been
         * enforced at a different level */

        case ssl_sig_ecdsa_secp256r1_sha256:
            algTag = SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE;
            hashAlgTag = SEC_OID_SHA256;
            break;
        case ssl_sig_ecdsa_secp384r1_sha384:
            algTag = SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE;
            hashAlgTag = SEC_OID_SHA384;
            break;
        case ssl_sig_ecdsa_secp521r1_sha512:
            algTag = SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE;
            hashAlgTag = SEC_OID_SHA512;
            break;

        /* the following is unsupported in tls 1.3 and greater, just break.
         * We include them here explicitly so we get the compiler warning about
         * missing enums in the switch statement. default would be a break anyway.
         * That way we'll know to update this table when new algorithms are
         * added */


        /* as of now edward curve signatures are not supported in NSS. That
         * could change, and this is part the code that would pick up the
         * change (need OIDS for the hash variants of these signature, and
         * then add them here) */

        case ssl_sig_ed25519:
        case ssl_sig_ed448:

        /* sha1 hashes in sigs are explicitly disallowed in TLS 1.3 or greater */
        case ssl_sig_ecdsa_sha1:

        /* rsa pkcs1 sigs are explicitly disallowed in TLS 1.3 and greater */
        case ssl_sig_rsa_pkcs1_sha1:
        case ssl_sig_rsa_pkcs1_sha256:
        case ssl_sig_rsa_pkcs1_sha384:
        case ssl_sig_rsa_pkcs1_sha512:

        /* dsa sigs are explicitly disallowed in TLS 1.3 and greater */
        case ssl_sig_dsa_sha1:
        case ssl_sig_dsa_sha256:
        case ssl_sig_dsa_sha384:
        case ssl_sig_dsa_sha512:

        /* special sig variants that aren't supported in TLS 1.3 or greater */
        case ssl_sig_rsa_pkcs1_sha1md5:
        case ssl_sig_none:
            break;
    }

    /* the earlier code should have made sure none of the unsupported
     * algorithms were accepted */

    PORT_Assert(algTag != SEC_OID_UNKNOWN);
    if (algTag == SEC_OID_UNKNOWN) {
        PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
        return NULL;
    }

    /* now get the algorithm ID algTag will override whatever is normally
     * selected from the key */

    rv = SEC_CreateSignatureAlgorithmID(arena, newAlgID, algTag, hashAlgTag,
                                        NULL, privKey, pubKey);
    if (rv != SECSuccess) {
        return NULL;
    }
    return newAlgID;
}

tlsSignOrVerifyContext
tls_CreateSignOrVerifyContext(SECKEYPrivateKey *privKey,
                              SECKEYPublicKey *pubKey,
                              SSLSignatureScheme scheme, sslSignOrVerify type,
                              SECItem *signature, void *pwArg)
{
    PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    tlsSignOrVerifyContext newCtx = { type, { NULL } };
    SECStatus rv;

    if (!arena) {
        goto loser;
    }

    if (type == sig_sign) {
        PORT_Assert(privKey);
    } else {
        PORT_Assert(pubKey);
    }

    /* we use sigAlgID here because it automatically formats parameters
     * for PSS. */

    SECAlgorithmID *sigAlgID = tls_GetSignatureAlgorithmId(arena, scheme,
                                                           privKey, pubKey);
    if (sigAlgID == NULL) {
        goto loser;
    }
    if (type == sig_sign) {
        newCtx.u.sig = SGN_NewContextWithAlgorithmID(sigAlgID, privKey);
        if (!newCtx.u.sig) {
            goto loser;
        }
        rv = SGN_Begin(newCtx.u.sig);
    } else {
        newCtx.u.vfy = VFY_CreateContextWithAlgorithmID(pubKey, signature,
                                                        sigAlgID, NULL, pwArg);
        if (!newCtx.u.vfy) {
            goto loser;
        }
        rv = VFY_Begin(newCtx.u.vfy);
    }
    if (rv != SECSuccess) {
        goto loser;
    }
    PORT_FreeArena(arena, PR_FALSE);
    return newCtx;

loser:
    tls_DestroySignOrVerifyContext(&newCtx);
    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }
    return newCtx; /* pointer already set to NULL by destroy */
}

SECStatus
tls_SignOrVerifyUpdate(tlsSignOrVerifyContext ctx, const unsigned char *buf,
                       int len)
{
    SECStatus rv;
    if (ctx.type == sig_sign) {
        rv = SGN_Update(ctx.u.sig, buf, len);
    } else {
        rv = VFY_Update(ctx.u.vfy, buf, len);
    }
    return rv;
}

SECStatus
tls_SignOrVerifyEnd(tlsSignOrVerifyContext ctx, SECItem *sig)
{
    SECStatus rv;
    if (ctx.type == sig_sign) {
        rv = SGN_End(ctx.u.sig, sig);
    } else {
        /* sig was already set in the context VFY_CreateContext */
        rv = VFY_End(ctx.u.vfy);
    }
    /* destroy the context on success */
    if (rv == SECSuccess) {
        tls_DestroySignOrVerifyContext(&ctx);
    }
    return rv;
}

/* Take ctx by pointer so we can NULL the freed pointer in the caller's
 * struct; tls_CreateSignOrVerifyContext relies on this to return a
 * NULL-ptr context on failure rather than a dangling one. */

void
tls_DestroySignOrVerifyContext(tlsSignOrVerifyContext *ctx)
{
    if (!ctx) {
        return;
    }
    if (ctx->type == sig_sign) {
        if (ctx->u.sig) {
            SGN_DestroyContext(ctx->u.sig, PR_TRUE);
        }
    } else {
        if (ctx->u.vfy) {
            VFY_DestroyContext(ctx->u.vfy, PR_TRUE);
        }
    }
    ctx->u.ptr = NULL;
}

Messung V0.5 in Prozent
C=83 H=91 G=86

¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

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.