tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

tls13psk.c (6096B)


      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 {
     22 
     23    sslSocket *ss = ssl_FindSocket(fd);
     24    if (!ss) {
     25        SSL_DBG(("%d: SSL[%d]: bad socket in SSLExp_SetExternalPsk",
     26                 SSL_GETPID(), fd));
     27        return SECFailure;
     28    }
     29 
     30    if (!key || !identity || !identityLen || identityLen > 0xFFFF ||
     31        (hash != ssl_hash_sha256 && hash != ssl_hash_sha384)) {
     32        PORT_SetError(SEC_ERROR_INVALID_ARGS);
     33        return SECFailure;
     34    }
     35 
     36    SECItem label = { siBuffer, CONST_CAST(unsigned char, identity), identityLen };
     37    sslPsk *psk = tls13_MakePsk(PK11_ReferenceSymKey(key), ssl_psk_external,
     38                                hash, &label);
     39    if (!psk) {
     40        PORT_SetError(SEC_ERROR_NO_MEMORY);
     41        return SECFailure;
     42    }
     43    psk->zeroRttSuite = zeroRttSuite;
     44    psk->maxEarlyData = maxEarlyData;
     45    SECStatus rv = SECFailure;
     46 
     47    ssl_Get1stHandshakeLock(ss);
     48    ssl_GetSSL3HandshakeLock(ss);
     49 
     50    if (ss->psk) {
     51        PORT_SetError(SEC_ERROR_INVALID_ARGS);
     52        tls13_DestroyPsk(psk);
     53    } else {
     54        ss->psk = psk;
     55        rv = SECSuccess;
     56        tls13_ResetHandshakePsks(ss, &ss->ssl3.hs.psks);
     57    }
     58 
     59    ssl_ReleaseSSL3HandshakeLock(ss);
     60    ssl_Release1stHandshakeLock(ss);
     61 
     62    return rv;
     63 }
     64 
     65 SECStatus
     66 SSLExp_AddExternalPsk(PRFileDesc *fd, PK11SymKey *key, const PRUint8 *identity,
     67                      unsigned int identityLen, SSLHashType hash)
     68 {
     69    return SSLExp_AddExternalPsk0Rtt(fd, key, identity, identityLen,
     70                                     hash, TLS_NULL_WITH_NULL_NULL, 0);
     71 }
     72 
     73 SECStatus
     74 SSLExp_RemoveExternalPsk(PRFileDesc *fd, const PRUint8 *identity, unsigned int identityLen)
     75 {
     76    if (!identity || !identityLen) {
     77        PORT_SetError(SEC_ERROR_INVALID_ARGS);
     78        return SECFailure;
     79    }
     80 
     81    sslSocket *ss = ssl_FindSocket(fd);
     82    if (!ss) {
     83        SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetPSK",
     84                 SSL_GETPID(), fd));
     85        return SECFailure;
     86    }
     87 
     88    SECItem removeIdentity = { siBuffer,
     89                               (unsigned char *)identity,
     90                               identityLen };
     91 
     92    SECStatus rv;
     93    ssl_Get1stHandshakeLock(ss);
     94    ssl_GetSSL3HandshakeLock(ss);
     95 
     96    if (!ss->psk || SECITEM_CompareItem(&ss->psk->label, &removeIdentity) != SECEqual) {
     97        PORT_SetError(SEC_ERROR_NO_KEY);
     98        rv = SECFailure;
     99    } else {
    100        tls13_DestroyPsk(ss->psk);
    101        ss->psk = NULL;
    102        tls13_ResetHandshakePsks(ss, &ss->ssl3.hs.psks);
    103        rv = SECSuccess;
    104    }
    105 
    106    ssl_ReleaseSSL3HandshakeLock(ss);
    107    ssl_Release1stHandshakeLock(ss);
    108 
    109    return rv;
    110 }
    111 
    112 sslPsk *
    113 tls13_CopyPsk(sslPsk *opsk)
    114 {
    115    if (!opsk || !opsk->key) {
    116        return NULL;
    117    }
    118 
    119    sslPsk *psk = PORT_ZNew(sslPsk);
    120    if (!psk) {
    121        return NULL;
    122    }
    123 
    124    SECStatus rv = SECITEM_CopyItem(NULL, &psk->label, &opsk->label);
    125    if (rv != SECSuccess) {
    126        PORT_Free(psk);
    127        return NULL;
    128    }
    129    /* We should only have the initial key. Binder keys
    130     * are derived during the handshake.  */
    131    PORT_Assert(opsk->type == ssl_psk_external);
    132    PORT_Assert(opsk->key);
    133    PORT_Assert(!opsk->binderKey);
    134    psk->hash = opsk->hash;
    135    psk->type = opsk->type;
    136    psk->key = opsk->key ? PK11_ReferenceSymKey(opsk->key) : NULL;
    137    psk->binderKey = opsk->binderKey ? PK11_ReferenceSymKey(opsk->binderKey) : NULL;
    138    return psk;
    139 }
    140 
    141 void
    142 tls13_DestroyPsk(sslPsk *psk)
    143 {
    144    if (!psk) {
    145        return;
    146    }
    147    if (psk->key) {
    148        PK11_FreeSymKey(psk->key);
    149        psk->key = NULL;
    150    }
    151    if (psk->binderKey) {
    152        PK11_FreeSymKey(psk->binderKey);
    153        psk->binderKey = NULL;
    154    }
    155    SECITEM_ZfreeItem(&psk->label, PR_FALSE);
    156    PORT_ZFree(psk, sizeof(*psk));
    157 }
    158 
    159 void
    160 tls13_DestroyPskList(PRCList *list)
    161 {
    162    PRCList *cur_p;
    163    while (!PR_CLIST_IS_EMPTY(list)) {
    164        cur_p = PR_LIST_TAIL(list);
    165        PR_REMOVE_LINK(cur_p);
    166        tls13_DestroyPsk((sslPsk *)cur_p);
    167    }
    168 }
    169 
    170 sslPsk *
    171 tls13_MakePsk(PK11SymKey *key, SSLPskType pskType, SSLHashType hashType, const SECItem *label)
    172 {
    173    sslPsk *psk = PORT_ZNew(sslPsk);
    174    if (!psk) {
    175        PORT_SetError(SEC_ERROR_NO_MEMORY);
    176        return NULL;
    177    }
    178    psk->type = pskType;
    179    psk->hash = hashType;
    180    psk->key = key;
    181 
    182    /* Label is NULL in the resumption case. */
    183    if (label) {
    184        PORT_Assert(psk->type != ssl_psk_resume);
    185        SECStatus rv = SECITEM_CopyItem(NULL, &psk->label, label);
    186        if (rv != SECSuccess) {
    187            PORT_SetError(SEC_ERROR_NO_MEMORY);
    188            tls13_DestroyPsk(psk);
    189            return NULL;
    190        }
    191    }
    192 
    193    return psk;
    194 }
    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 {
    201    tls13_DestroyPskList(list);
    202    PORT_Assert(!ss->xtnData.selectedPsk);
    203    ss->xtnData.selectedPsk = NULL;
    204    if (ss->psk) {
    205        PORT_Assert(ss->psk->type == ssl_psk_external);
    206        PORT_Assert(ss->psk->key);
    207        PORT_Assert(!ss->psk->binderKey);
    208 
    209        sslPsk *epsk = tls13_MakePsk(PK11_ReferenceSymKey(ss->psk->key),
    210                                     ss->psk->type, ss->psk->hash, &ss->psk->label);
    211        if (!epsk) {
    212            return SECFailure;
    213        }
    214        epsk->zeroRttSuite = ss->psk->zeroRttSuite;
    215        epsk->maxEarlyData = ss->psk->maxEarlyData;
    216        PR_APPEND_LINK(&epsk->link, list);
    217    }
    218    return SECSuccess;
    219 }