Coverage Report

Created: 2024-05-20 06:23

/src/nss/lib/ssl/tls13psk.c
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "nss.h"
8
#include "pk11func.h"
9
#include "ssl.h"
10
#include "sslproto.h"
11
#include "sslimpl.h"
12
#include "ssl3exthandle.h"
13
#include "tls13exthandle.h"
14
#include "tls13hkdf.h"
15
#include "tls13psk.h"
16
17
SECStatus
18
SSLExp_AddExternalPsk0Rtt(PRFileDesc *fd, PK11SymKey *key, const PRUint8 *identity,
19
                          unsigned int identityLen, SSLHashType hash,
20
                          PRUint16 zeroRttSuite, PRUint32 maxEarlyData)
21
0
{
22
23
0
    sslSocket *ss = ssl_FindSocket(fd);
24
0
    if (!ss) {
25
0
        SSL_DBG(("%d: SSL[%d]: bad socket in SSLExp_SetExternalPsk",
26
0
                 SSL_GETPID(), fd));
27
0
        return SECFailure;
28
0
    }
29
30
0
    if (!key || !identity || !identityLen || identityLen > 0xFFFF ||
31
0
        (hash != ssl_hash_sha256 && hash != ssl_hash_sha384)) {
32
0
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
33
0
        return SECFailure;
34
0
    }
35
36
0
    SECItem label = { siBuffer, CONST_CAST(unsigned char, identity), identityLen };
37
0
    sslPsk *psk = tls13_MakePsk(PK11_ReferenceSymKey(key), ssl_psk_external,
38
0
                                hash, &label);
39
0
    if (!psk) {
40
0
        PORT_SetError(SEC_ERROR_NO_MEMORY);
41
0
        return SECFailure;
42
0
    }
43
0
    psk->zeroRttSuite = zeroRttSuite;
44
0
    psk->maxEarlyData = maxEarlyData;
45
0
    SECStatus rv = SECFailure;
46
47
0
    ssl_Get1stHandshakeLock(ss);
48
0
    ssl_GetSSL3HandshakeLock(ss);
49
50
0
    if (ss->psk) {
51
0
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
52
0
        tls13_DestroyPsk(psk);
53
0
    } else {
54
0
        ss->psk = psk;
55
0
        rv = SECSuccess;
56
0
        tls13_ResetHandshakePsks(ss, &ss->ssl3.hs.psks);
57
0
    }
58
59
0
    ssl_ReleaseSSL3HandshakeLock(ss);
60
0
    ssl_Release1stHandshakeLock(ss);
61
62
0
    return rv;
63
0
}
64
65
SECStatus
66
SSLExp_AddExternalPsk(PRFileDesc *fd, PK11SymKey *key, const PRUint8 *identity,
67
                      unsigned int identityLen, SSLHashType hash)
68
0
{
69
0
    return SSLExp_AddExternalPsk0Rtt(fd, key, identity, identityLen,
70
0
                                     hash, TLS_NULL_WITH_NULL_NULL, 0);
71
0
}
72
73
SECStatus
74
SSLExp_RemoveExternalPsk(PRFileDesc *fd, const PRUint8 *identity, unsigned int identityLen)
75
0
{
76
0
    if (!identity || !identityLen) {
77
0
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
78
0
        return SECFailure;
79
0
    }
80
81
0
    sslSocket *ss = ssl_FindSocket(fd);
82
0
    if (!ss) {
83
0
        SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetPSK",
84
0
                 SSL_GETPID(), fd));
85
0
        return SECFailure;
86
0
    }
87
88
0
    SECItem removeIdentity = { siBuffer,
89
0
                               (unsigned char *)identity,
90
0
                               identityLen };
91
92
0
    SECStatus rv;
93
0
    ssl_Get1stHandshakeLock(ss);
94
0
    ssl_GetSSL3HandshakeLock(ss);
95
96
0
    if (!ss->psk || SECITEM_CompareItem(&ss->psk->label, &removeIdentity) != SECEqual) {
97
0
        PORT_SetError(SEC_ERROR_NO_KEY);
98
0
        rv = SECFailure;
99
0
    } else {
100
0
        tls13_DestroyPsk(ss->psk);
101
0
        ss->psk = NULL;
102
0
        tls13_ResetHandshakePsks(ss, &ss->ssl3.hs.psks);
103
0
        rv = SECSuccess;
104
0
    }
105
106
0
    ssl_ReleaseSSL3HandshakeLock(ss);
107
0
    ssl_Release1stHandshakeLock(ss);
108
109
0
    return rv;
110
0
}
111
112
sslPsk *
113
tls13_CopyPsk(sslPsk *opsk)
114
0
{
115
0
    if (!opsk || !opsk->key) {
116
0
        return NULL;
117
0
    }
118
119
0
    sslPsk *psk = PORT_ZNew(sslPsk);
120
0
    if (!psk) {
121
0
        return NULL;
122
0
    }
123
124
0
    SECStatus rv = SECITEM_CopyItem(NULL, &psk->label, &opsk->label);
125
0
    if (rv != SECSuccess) {
126
0
        PORT_Free(psk);
127
0
        return NULL;
128
0
    }
129
    /* We should only have the initial key. Binder keys
130
     * are derived during the handshake.  */
131
0
    PORT_Assert(opsk->type == ssl_psk_external);
132
0
    PORT_Assert(opsk->key);
133
0
    PORT_Assert(!opsk->binderKey);
134
0
    psk->hash = opsk->hash;
135
0
    psk->type = opsk->type;
136
0
    psk->key = opsk->key ? PK11_ReferenceSymKey(opsk->key) : NULL;
137
0
    psk->binderKey = opsk->binderKey ? PK11_ReferenceSymKey(opsk->binderKey) : NULL;
138
0
    return psk;
139
0
}
140
141
void
142
tls13_DestroyPsk(sslPsk *psk)
143
7.93k
{
144
7.93k
    if (!psk) {
145
7.93k
        return;
146
7.93k
    }
147
0
    if (psk->key) {
148
0
        PK11_FreeSymKey(psk->key);
149
0
        psk->key = NULL;
150
0
    }
151
0
    if (psk->binderKey) {
152
0
        PK11_FreeSymKey(psk->binderKey);
153
0
        psk->binderKey = NULL;
154
0
    }
155
0
    SECITEM_ZfreeItem(&psk->label, PR_FALSE);
156
0
    PORT_ZFree(psk, sizeof(*psk));
157
0
}
158
159
void
160
tls13_DestroyPskList(PRCList *list)
161
24.2k
{
162
24.2k
    PRCList *cur_p;
163
24.2k
    while (!PR_CLIST_IS_EMPTY(list)) {
164
0
        cur_p = PR_LIST_TAIL(list);
165
0
        PR_REMOVE_LINK(cur_p);
166
0
        tls13_DestroyPsk((sslPsk *)cur_p);
167
0
    }
168
24.2k
}
169
170
sslPsk *
171
tls13_MakePsk(PK11SymKey *key, SSLPskType pskType, SSLHashType hashType, const SECItem *label)
172
0
{
173
0
    sslPsk *psk = PORT_ZNew(sslPsk);
174
0
    if (!psk) {
175
0
        PORT_SetError(SEC_ERROR_NO_MEMORY);
176
0
        return NULL;
177
0
    }
178
0
    psk->type = pskType;
179
0
    psk->hash = hashType;
180
0
    psk->key = key;
181
182
    /* Label is NULL in the resumption case. */
183
0
    if (label) {
184
0
        PORT_Assert(psk->type != ssl_psk_resume);
185
0
        SECStatus rv = SECITEM_CopyItem(NULL, &psk->label, label);
186
0
        if (rv != SECSuccess) {
187
0
            PORT_SetError(SEC_ERROR_NO_MEMORY);
188
0
            tls13_DestroyPsk(psk);
189
0
            return NULL;
190
0
        }
191
0
    }
192
193
0
    return psk;
194
0
}
195
196
/* Destroy any existing PSKs in |list| then copy
197
 * in the configured |ss->psk|, if any.*/
198
SECStatus
199
tls13_ResetHandshakePsks(sslSocket *ss, PRCList *list)
200
7.93k
{
201
7.93k
    tls13_DestroyPskList(list);
202
7.93k
    PORT_Assert(!ss->xtnData.selectedPsk);
203
7.93k
    ss->xtnData.selectedPsk = NULL;
204
7.93k
    if (ss->psk) {
205
0
        PORT_Assert(ss->psk->type == ssl_psk_external);
206
0
        PORT_Assert(ss->psk->key);
207
0
        PORT_Assert(!ss->psk->binderKey);
208
209
0
        sslPsk *epsk = tls13_MakePsk(PK11_ReferenceSymKey(ss->psk->key),
210
0
                                     ss->psk->type, ss->psk->hash, &ss->psk->label);
211
0
        if (!epsk) {
212
0
            return SECFailure;
213
0
        }
214
0
        epsk->zeroRttSuite = ss->psk->zeroRttSuite;
215
0
        epsk->maxEarlyData = ss->psk->maxEarlyData;
216
0
        PR_APPEND_LINK(&epsk->link, list);
217
0
    }
218
7.93k
    return SECSuccess;
219
7.93k
}