Files
mars-matrixssl/matrixssl/tls13Adapter.c
Janne Johansson 69b5f2c6c3 MatrixSSL 4.5.1
2022-07-29 12:30:12 +03:00

304 lines
7.4 KiB
C

/**
* @file tls13Adapter.c
* @version $Format:%h%d$
*
* Adapter layer for internal TLS 1.3 APIs.
*/
/*
* Copyright (c) 2013-2019 Rambus Inc.
* Copyright (c) PeerSec Networks, 2002-2011
* All Rights Reserved
*
* The latest version of this code is available at http://www.matrixssl.org
*
* This software is open source; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This General Public License does NOT permit incorporating this software
* into proprietary programs. If you are unable to comply with the GPL, a
* commercial license for this software may be purchased from Rambus at
* http://www.rambus.com/
*
* This program is distributed in WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* http://www.gnu.org/copyleft/gpl.html
*/
# include "matrixsslImpl.h"
# ifndef DEBUG_TLS_1_3_ADAPTER
# define DEBUG_TLS_1_3_ADAPTER
# endif
# ifdef USE_TLS_1_3_ONLY
/* TLS 1.3 code doesn't use pkaAfter. */
void freePkaAfter(ssl_t *ssl)
{
(void)ssl;
}
void clearFlightList(ssl_t *ssl)
{
flightEncode_t *msg, *next;
msg = ssl->flightEncode;
while (msg)
{
next = msg->next;
psFree(msg, ssl->flightPool);
msg = next;
}
ssl->flightEncode = NULL;
}
/* In TLS 1.3, tls13WriteClientHello is used instead. */
int32_t matrixSslEncodeClientHello(ssl_t *ssl,
sslBuf_t *out,
const psCipher16_t cipherSpec[],
uint8_t cipherSpecLen,
uint32 *requiredLen,
tlsExtension_t *userExt,
sslSessOpts_t *options)
{
(void)ssl;
(void)out;
(void)cipherSpec;
(void)cipherSpecLen;
(void)requiredLen;
(void)userExt;
(void)options;
return MATRIXSSL_SUCCESS;
}
int32 matrixSslGetEncodedSize(ssl_t *ssl, uint32 len)
{
# ifdef USE_TLS_1_3
uint32 ptLen = len;
# endif
len += ssl->recordHeadLen;
if (ssl->flags & SSL_FLAGS_WRITE_SECURE)
{
len += ssl->enMacSize;
/* Add AEAD overhead. */
len += AEAD_TAG_LEN(ssl);
/* TLS 1.3 does not send any part of the nonce over the
wire, but requires one additional byte and possibly
room for the padding. */
if (ssl->tls13BlockSize > 0)
{
ssl->tls13PadLen = tls13GetPadLen(ssl, ptLen);
}
len += 1; /* InnerPlaintext.type */
len += ssl->tls13PadLen; /* InnerPlaintext.zeros */
}
return len;
}
int32 matrixSslEncode(ssl_t *ssl,
unsigned char *buf,
uint32 size,
unsigned char *ptBuf,
uint32 *len)
{
return tls13EncodeAppData(ssl, buf, size, ptBuf, len);
}
/**
Return PS_TRUE if sigAlg is in peerSigAlgs, PS_FALSE otherwise.
peerSigAlgs should be the a set of masks we created after
parsing the peer's supported_signature_algorithms list
in ClientHello or CertificateRequest.
*/
psBool_t peerSupportsSigAlg(int32_t sigAlg,
uint16_t peerSigAlgs)
{
uint16_t yes;
if (sigAlg == OID_MD5_RSA_SIG)
{
yes = ((peerSigAlgs & HASH_SIG_MD5_RSA_MASK) != 0);
}
else if (sigAlg == OID_SHA1_RSA_SIG)
{
yes = ((peerSigAlgs & HASH_SIG_SHA1_RSA_MASK) != 0);
}
else if (sigAlg == OID_SHA256_RSA_SIG)
{
yes = ((peerSigAlgs & HASH_SIG_SHA256_RSA_MASK) != 0);
}
else if (sigAlg == OID_SHA384_RSA_SIG)
{
yes = ((peerSigAlgs & HASH_SIG_SHA384_RSA_MASK) != 0);
}
else if (sigAlg == OID_SHA512_RSA_SIG)
{
yes = ((peerSigAlgs & HASH_SIG_SHA512_RSA_MASK) != 0);
}
else if (sigAlg == OID_SHA1_ECDSA_SIG)
{
yes = ((peerSigAlgs & HASH_SIG_SHA1_ECDSA_MASK) != 0);
}
else if (sigAlg == OID_SHA256_ECDSA_SIG)
{
yes = ((peerSigAlgs & HASH_SIG_SHA256_ECDSA_MASK) != 0);
}
else if (sigAlg == OID_SHA384_ECDSA_SIG)
{
yes = ((peerSigAlgs & HASH_SIG_SHA384_ECDSA_MASK) != 0);
}
else if (sigAlg == OID_SHA512_ECDSA_SIG)
{
yes = ((peerSigAlgs & HASH_SIG_SHA512_ECDSA_MASK) != 0);
}
else if (sigAlg == OID_SM3_SM2_SIG)
{
yes = ((peerSigAlgs & HASH_SIG_SM3_SM2_MASK) != 0);
}
else
{
return PS_FALSE; /* Unknown/unsupported sig alg. */
}
if (yes)
{
return PS_TRUE;
}
else
{
return PS_FALSE;
}
}
int32 psGenerateServerRandom(ssl_t *ssl)
{
if (psGetPrngLocked(ssl->sec.serverRandom,
SSL_HS_RANDOM_SIZE, ssl->userPtr) < 0)
{
return MATRIXSSL_ERROR;
}
return PS_SUCCESS;
}
int32_t sslInitHSHash(ssl_t *ssl)
{
if (ssl->tls13IncorrectDheKeyShare)
{
/* Don't allow second ClientHello after HelloRetryRequest
to reset the hash. */
return 0;
}
/* Always has to init all hashes since we don't know with what
version we end up with. */
tls13TranscriptHashInit(ssl);
return PS_SUCCESS;
}
int32 sslEncodeClosureAlert(ssl_t *ssl,
sslBuf_t *out,
uint32 *reqLen)
{
if (ssl->flags & SSL_FLAGS_ERROR)
{
return MATRIXSSL_ERROR;
}
return tls13EncodeAlert(ssl,
SSL_ALERT_CLOSE_NOTIFY,
out,
reqLen);
}
static
int32 encryptFlight(ssl_t *ssl,
unsigned char **end)
{
flightEncode_t *msg, *remove;
int32_t rc;
msg = ssl->flightEncode;
while (msg)
{
rc = tls13EncryptMessage(ssl, msg, end);
if (rc < 0)
{
psTraceInfo("encryptFlightTls13 failed\n");
clearFlightList(ssl);
return rc;
}
if (rc < 0)
{
psTraceIntInfo("Error encrypting record from flight %d\n", rc);
clearFlightList(ssl);
return rc;
}
remove = msg;
ssl->flightEncode = msg = msg->next;
psFree(remove, ssl->flightPool);
}
clearFlightList(ssl);
return PS_SUCCESS;
}
int32 sslEncodeResponse(ssl_t *ssl,
psBuf_t *out,
uint32 *requiredLen)
{
int32_t rc;
uint32 alertReqLen;
rc = tls13EncodeResponse(ssl, out, requiredLen);
if (rc == SSL_FULL)
{
*requiredLen = tls13EstimateNextFlightSize(ssl);
psTraceIntInfo("Need larger write buffer: %d\n", *requiredLen);
/* Return to matrixSslReceivedData for buffer enlargement.
Next time, we shall continue from where we left. */
ssl->tls13NextMsgRequiredLen = 0;
return SSL_FULL;
}
else if (rc < 0)
{
psTraceIntInfo("ERROR: Handshake flight creation failed %d\n", rc);
/* The TLS 1.3 code should set a suitable alert. */
psAssert(ssl->err != SSL_ALERT_NONE);
out->end = out->start;
alertReqLen = out->size;
/* Going recursive to send the alert. */
return sslEncodeResponse(ssl, out, &alertReqLen);
}
if (ssl->flightEncode)
{
rc = encryptFlight(ssl, &out->end);
if (rc < 0)
{
return rc;
}
}
return rc;
}
# endif /* USE_TLS_1_3_ONLY */