Coverage Report

Created: 2026-02-18 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/nss/lib/ssl/tls13signature.c
Line
Count
Source
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * TLS 1.3 Protocol
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8
#include "sslimpl.h"
9
#include "cryptohi.h"
10
#include "keyhi.h"
11
12
/* we put this here because it only affects TLS 1.3, and not TLS 1.2 and earlier
13
 * which use the old sign hashes interface. The TLS 1.3 protocol is friendly to
14
 * algorthims that don't have a signed hashes interface */
15
/* we generate an algorithm ID rather than just use an OID to support RSAPSS.
16
 * It's generated completely from the scheme */
17
static SECAlgorithmID *
18
tls_GetSignatureAlgorithmId(PLArenaPool *arena, SSLSignatureScheme scheme,
19
                            SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey)
20
2.72k
{
21
2.72k
    SECAlgorithmID *newAlgID = PORT_ArenaZNew(arena, SECAlgorithmID);
22
2.72k
    SECOidTag algTag = SEC_OID_UNKNOWN;
23
2.72k
    SECOidTag hashAlgTag = SEC_OID_UNKNOWN;
24
2.72k
    SECStatus rv;
25
26
2.72k
    switch (scheme) {
27
        /* For the algTag the difference between rsa_pss_rsae and
28
         * rsa_pss_pss is in the selection of the cert.
29
         * At this stage, the signatures are the same, so for our
30
         * purposed they are equivalent */
31
924
        case ssl_sig_rsa_pss_rsae_sha256:
32
924
        case ssl_sig_rsa_pss_pss_sha256:
33
924
            algTag = SEC_OID_PKCS1_RSA_PSS_SIGNATURE;
34
924
            hashAlgTag = SEC_OID_SHA256;
35
924
            break;
36
411
        case ssl_sig_rsa_pss_rsae_sha384:
37
411
        case ssl_sig_rsa_pss_pss_sha384:
38
411
            algTag = SEC_OID_PKCS1_RSA_PSS_SIGNATURE;
39
411
            hashAlgTag = SEC_OID_SHA384;
40
411
            break;
41
551
        case ssl_sig_rsa_pss_rsae_sha512:
42
551
        case ssl_sig_rsa_pss_pss_sha512:
43
551
            algTag = SEC_OID_PKCS1_RSA_PSS_SIGNATURE;
44
551
            hashAlgTag = SEC_OID_SHA512;
45
551
            break;
46
        /* the curve comes from the key and should have already been
47
         * enforced at a different level */
48
841
        case ssl_sig_ecdsa_secp256r1_sha256:
49
841
            algTag = SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE;
50
841
            hashAlgTag = SEC_OID_SHA256;
51
841
            break;
52
0
        case ssl_sig_ecdsa_secp384r1_sha384:
53
0
            algTag = SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE;
54
0
            hashAlgTag = SEC_OID_SHA384;
55
0
            break;
56
0
        case ssl_sig_ecdsa_secp521r1_sha512:
57
0
            algTag = SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE;
58
0
            hashAlgTag = SEC_OID_SHA512;
59
0
            break;
60
61
        /* the following is unsupported in tls 1.3 and greater, just break.
62
         * We include them here explicitly so we get the compiler warning about
63
         * missing enums in the switch statement. default would be a break anyway.
64
         * That way we'll know to update this table when new algorithms are
65
         * added */
66
67
        /* as of now edward curve signatures are not supported in NSS. That
68
         * could change, and this is part the code that would pick up the
69
         * change (need OIDS for the hash variants of these signature, and
70
         * then add them here) */
71
0
        case ssl_sig_ed25519:
72
0
        case ssl_sig_ed448:
73
74
        /* sha1 hashes in sigs are explicitly disallowed in TLS 1.3 or greater */
75
0
        case ssl_sig_ecdsa_sha1:
76
77
        /* rsa pkcs1 sigs are explicitly disallowed in TLS 1.3 and greater */
78
0
        case ssl_sig_rsa_pkcs1_sha1:
79
0
        case ssl_sig_rsa_pkcs1_sha256:
80
0
        case ssl_sig_rsa_pkcs1_sha384:
81
0
        case ssl_sig_rsa_pkcs1_sha512:
82
83
        /* dsa sigs are explicitly disallowed in TLS 1.3 and greater */
84
0
        case ssl_sig_dsa_sha1:
85
0
        case ssl_sig_dsa_sha256:
86
0
        case ssl_sig_dsa_sha384:
87
0
        case ssl_sig_dsa_sha512:
88
89
        /* special sig variants that aren't supported in TLS 1.3 or greater */
90
0
        case ssl_sig_rsa_pkcs1_sha1md5:
91
0
        case ssl_sig_none:
92
0
            break;
93
2.72k
    }
94
95
    /* the earlier code should have made sure none of the unsupported
96
     * algorithms were accepted */
97
2.72k
    PORT_Assert(algTag != SEC_OID_UNKNOWN);
98
2.72k
    if (algTag == SEC_OID_UNKNOWN) {
99
0
        PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
100
0
        return NULL;
101
0
    }
102
103
    /* now get the algorithm ID algTag will override whatever is normally
104
     * selected from the key */
105
2.72k
    rv = SEC_CreateSignatureAlgorithmID(arena, newAlgID, algTag, hashAlgTag,
106
2.72k
                                        NULL, privKey, pubKey);
107
2.72k
    if (rv != SECSuccess) {
108
0
        return NULL;
109
0
    }
110
2.72k
    return newAlgID;
111
2.72k
}
112
113
tlsSignOrVerifyContext
114
tls_CreateSignOrVerifyContext(SECKEYPrivateKey *privKey,
115
                              SECKEYPublicKey *pubKey,
116
                              SSLSignatureScheme scheme, sslSignOrVerify type,
117
                              SECItem *signature, void *pwArg)
118
2.72k
{
119
2.72k
    PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
120
2.72k
    tlsSignOrVerifyContext newCtx = { type, { NULL } };
121
2.72k
    SECStatus rv;
122
123
2.72k
    if (!arena) {
124
0
        goto loser;
125
0
    }
126
127
2.72k
    if (type == sig_sign) {
128
2.72k
        PORT_Assert(privKey);
129
2.72k
    } else {
130
0
        PORT_Assert(pubKey);
131
0
    }
132
133
    /* we use sigAlgID here because it automatically formats parameters
134
     * for PSS. */
135
2.72k
    SECAlgorithmID *sigAlgID = tls_GetSignatureAlgorithmId(arena, scheme,
136
2.72k
                                                           privKey, pubKey);
137
2.72k
    if (sigAlgID == NULL) {
138
0
        goto loser;
139
0
    }
140
2.72k
    if (type == sig_sign) {
141
2.72k
        newCtx.u.sig = SGN_NewContextWithAlgorithmID(sigAlgID, privKey);
142
2.72k
        if (!newCtx.u.sig) {
143
0
            goto loser;
144
0
        }
145
2.72k
        rv = SGN_Begin(newCtx.u.sig);
146
2.72k
    } else {
147
0
        newCtx.u.vfy = VFY_CreateContextWithAlgorithmID(pubKey, signature,
148
0
                                                        sigAlgID, NULL, pwArg);
149
0
        if (!newCtx.u.vfy) {
150
0
            goto loser;
151
0
        }
152
0
        rv = VFY_Begin(newCtx.u.vfy);
153
0
    }
154
2.72k
    if (rv != SECSuccess) {
155
0
        goto loser;
156
0
    }
157
2.72k
    PORT_FreeArena(arena, PR_FALSE);
158
2.72k
    return newCtx;
159
160
0
loser:
161
0
    tls_DestroySignOrVerifyContext(newCtx);
162
0
    if (arena) {
163
0
        PORT_FreeArena(arena, PR_FALSE);
164
0
    }
165
0
    return newCtx; /* pointer already set to NULL by destroy */
166
2.72k
}
167
168
SECStatus
169
tls_SignOrVerifyUpdate(tlsSignOrVerifyContext ctx, const unsigned char *buf,
170
                       int len)
171
8.18k
{
172
8.18k
    SECStatus rv;
173
8.18k
    if (ctx.type == sig_sign) {
174
8.18k
        rv = SGN_Update(ctx.u.sig, buf, len);
175
8.18k
    } else {
176
0
        rv = VFY_Update(ctx.u.vfy, buf, len);
177
0
    }
178
8.18k
    return rv;
179
8.18k
}
180
181
SECStatus
182
tls_SignOrVerifyEnd(tlsSignOrVerifyContext ctx, SECItem *sig)
183
2.72k
{
184
2.72k
    SECStatus rv;
185
2.72k
    if (ctx.type == sig_sign) {
186
2.72k
        rv = SGN_End(ctx.u.sig, sig);
187
2.72k
    } else {
188
        /* sig was already set in the context VFY_CreateContext */
189
0
        rv = VFY_End(ctx.u.vfy);
190
0
    }
191
    /* destroy the context on success */
192
2.72k
    if (rv == SECSuccess) {
193
2.72k
        tls_DestroySignOrVerifyContext(ctx);
194
2.72k
    }
195
2.72k
    return rv;
196
2.72k
}
197
198
void
199
tls_DestroySignOrVerifyContext(tlsSignOrVerifyContext ctx)
200
2.72k
{
201
2.72k
    if (ctx.type == sig_sign) {
202
2.72k
        if (ctx.u.sig) {
203
2.72k
            SGN_DestroyContext(ctx.u.sig, PR_TRUE);
204
2.72k
        }
205
2.72k
    } else {
206
0
        if (ctx.u.vfy) {
207
0
            VFY_DestroyContext(ctx.u.vfy, PR_TRUE);
208
0
        }
209
0
    }
210
2.72k
}