Commit a9aee608 authored by Martin Thomson's avatar Martin Thomson

Bug 1385203 - Use sslBuffer for encoding more widely, r=ekr

This removes ssl3_Append[Number]ToItem and switches more places to using
buffers.  The advantage with that, aside from a consistent interface, is that
encoding using sslBuffer is length checked.  A new field is added to the struct
so that it can be used for encoding directly onto the stack rather than relying
on reallocation when the space limit is reached.

New macros are added so that the internals of sslBuffer aren't accessed
directly.  Not all instances of these accesses have been fixed.

Differential Revision: https://nss-review.dev.mozaws.net/D390

--HG--
branch : NSS_TLS13_DRAFT19_BRANCH
extra : rebase_source : 60595ab46e30d80dc8bd13a341053edd5cd907b6
extra : amend_source : 25edd67ac2d8bda91a4f927c8671cabd257ccba7
parent 0b670220
......@@ -758,12 +758,14 @@ TEST_F(TlsConnectTest, SendSessionTicketMassiveToken) {
Connect();
// It should be safe to set length with a NULL token because the length should
// be checked before reading token.
EXPECT_EQ(SECFailure, SSL_SendSessionTicket(server_->ssl_fd(), NULL, 0xffff))
<< "no special tickets in TLS 1.2";
EXPECT_EQ(SECFailure, SSL_SendSessionTicket(server_->ssl_fd(), NULL, 0x1ffff))
<< "this is clearly too big";
EXPECT_EQ(SEC_ERROR_INVALID_ARGS, PORT_GetError());
EXPECT_EQ(SECFailure, SSL_SendSessionTicket(server_->ssl_fd(), NULL, 0x1ffff))
<< "no special tickets in TLS 1.2";
static const uint8_t big_token[0xffff] = {1};
EXPECT_EQ(SECFailure, SSL_SendSessionTicket(server_->ssl_fd(), big_token,
sizeof(big_token)))
<< "this is too big, but that's not immediately obvious";
EXPECT_EQ(SEC_ERROR_INVALID_ARGS, PORT_GetError());
}
......
......@@ -121,12 +121,11 @@ ssl_SelfEncryptProtectInt(
PRUint8 *out, unsigned int *outLen, unsigned int maxOutLen)
{
unsigned int len;
unsigned int lenOffset;
unsigned char iv[AES_BLOCK_SIZE];
SECItem ivItem = { siBuffer, iv, sizeof(iv) };
unsigned char mac[SHA256_LENGTH]; /* SHA-256 */
unsigned int macLen;
SECItem outItem = { siBuffer, out, maxOutLen };
SECItem lengthBytesItem;
/* Write directly to out. */
sslBuffer buf = SSL_BUFFER_FIXED(out, maxOutLen);
SECStatus rv;
/* Generate a random IV */
......@@ -137,52 +136,54 @@ ssl_SelfEncryptProtectInt(
}
/* Add header. */
rv = ssl3_AppendToItem(&outItem, keyName, SELF_ENCRYPT_KEY_NAME_LEN);
rv = sslBuffer_Append(&buf, keyName, SELF_ENCRYPT_KEY_NAME_LEN);
if (rv != SECSuccess) {
return SECFailure;
}
rv = ssl3_AppendToItem(&outItem, iv, sizeof(iv));
rv = sslBuffer_Append(&buf, iv, sizeof(iv));
if (rv != SECSuccess) {
return SECFailure;
}
/* Skip forward by two so we can encode the ciphertext in place. */
lengthBytesItem = outItem;
rv = ssl3_AppendNumberToItem(&outItem, 0, 2);
/* Leave space for the length of the ciphertext. */
rv = sslBuffer_Skip(&buf, 2, &lenOffset);
if (rv != SECSuccess) {
return SECFailure;
}
/* Encode the ciphertext in place. */
rv = PK11_Encrypt(encKey, CKM_AES_CBC_PAD, &ivItem,
outItem.data, &len, outItem.len, in, inLen);
SSL_BUFFER_NEXT(&buf), &len,
SSL_BUFFER_SPACE(&buf), in, inLen);
if (rv != SECSuccess) {
return SECFailure;
}
rv = sslBuffer_Skip(&buf, len, NULL);
if (rv != SECSuccess) {
return SECFailure;
}
outItem.data += len;
outItem.len -= len;
/* Now encode the ciphertext length. */
rv = ssl3_AppendNumberToItem(&lengthBytesItem, len, 2);
rv = sslBuffer_InsertLength(&buf, lenOffset, 2);
if (rv != SECSuccess) {
return SECFailure;
}
/* MAC the entire output buffer and append the MAC to the end. */
/* MAC the entire output buffer into the output. */
PORT_Assert(buf.space - buf.len >= SHA256_LENGTH);
rv = ssl_MacBuffer(macKey, CKM_SHA256_HMAC,
out, outItem.data - out,
mac, &macLen, sizeof(mac));
SSL_BUFFER_BASE(&buf), /* input */
SSL_BUFFER_LEN(&buf),
SSL_BUFFER_NEXT(&buf), &len, /* output */
SHA256_LENGTH);
if (rv != SECSuccess) {
return SECFailure;
}
PORT_Assert(macLen == sizeof(mac));
rv = ssl3_AppendToItem(&outItem, mac, macLen);
rv = sslBuffer_Skip(&buf, len, NULL);
if (rv != SECSuccess) {
return SECFailure;
}
*outLen = outItem.data - out;
*outLen = SSL_BUFFER_LEN(&buf);
return SECSuccess;
}
......@@ -270,16 +271,14 @@ ssl_SelfEncryptUnprotectInt(
#endif
/* Predict the size of the encrypted data, including padding */
SECStatus
ssl_SelfEncryptGetProtectedSize(unsigned int inLen, unsigned int *outLen)
unsigned int
ssl_SelfEncryptGetProtectedSize(unsigned int inLen)
{
*outLen = SELF_ENCRYPT_KEY_NAME_LEN +
return SELF_ENCRYPT_KEY_NAME_LEN +
AES_BLOCK_SIZE +
2 +
((inLen / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE + /* Padded */
SHA256_LENGTH;
return SECSuccess;
}
SECStatus
......
......@@ -13,8 +13,7 @@
typedef struct sslSocketStr sslSocket;
SECStatus ssl_SelfEncryptGetProtectedSize(unsigned int inLen,
unsigned int *outLen);
unsigned int ssl_SelfEncryptGetProtectedSize(unsigned int inLen);
SECStatus ssl_SelfEncryptProtect(
sslSocket *ss, const PRUint8 *in, unsigned int inLen,
PRUint8 *out, unsigned int *outLen, unsigned int maxOutLen);
......
This diff is collapsed.
......@@ -864,8 +864,9 @@ ssl_SendSupportedGroupsXtn(const sslSocket *ss, TLSExtensionData *xtnData,
unsigned int i;
PRBool ec;
PRBool ff = PR_FALSE;
PRBool found = PR_FALSE;
SECStatus rv;
sslBuffer tmpBuf = { NULL, 0, 0 };
unsigned int lengthOffset;
/* We only send FF supported groups if we require DH named groups
* or if TLS 1.3 is a possibility. */
......@@ -881,7 +882,12 @@ ssl_SendSupportedGroupsXtn(const sslSocket *ss, TLSExtensionData *xtnData,
ec = ff = PR_TRUE;
}
/* Reserve space for the length. */
/* Mark the location of the length. */
rv = sslBuffer_Skip(buf, 2, &lengthOffset);
if (rv != SECSuccess) {
return SECFailure;
}
for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) {
const sslNamedGroupDef *group = ss->namedGroupPreferences[i];
if (!group) {
......@@ -894,21 +900,19 @@ ssl_SendSupportedGroupsXtn(const sslSocket *ss, TLSExtensionData *xtnData,
continue;
}
rv = sslBuffer_AppendNumber(&tmpBuf, group->name, 2);
found = PR_TRUE;
rv = sslBuffer_AppendNumber(buf, group->name, 2);
if (rv != SECSuccess) {
sslBuffer_Clear(&tmpBuf);
return SECFailure;
}
}
if (!tmpBuf.len) {
sslBuffer_Clear(&tmpBuf);
if (!found) {
/* We added nothing, don't send the extension. */
return SECSuccess;
}
rv = sslBuffer_AppendBufferVariable(buf, &tmpBuf, 2);
sslBuffer_Clear(&tmpBuf);
rv = sslBuffer_InsertLength(buf, lengthOffset, 2);
if (rv != SECSuccess) {
return SECFailure;
}
......
This diff is collapsed.
......@@ -12,16 +12,16 @@
#include "sslimpl.h"
/* Helper function to encode an unsigned integer into a buffer. */
PRUint8 *
ssl_EncodeUintX(PRUint64 value, unsigned int bytes, PRUint8 *to)
static void
ssl_EncodeUintX(PRUint8 *to, PRUint64 value, unsigned int bytes)
{
PRUint64 encoded;
PORT_Assert(bytes > 0 && bytes <= sizeof(encoded));
encoded = PR_htonll(value);
memcpy(to, ((unsigned char *)(&encoded)) + (sizeof(encoded) - bytes), bytes);
return to + bytes;
PORT_Memcpy(to, ((unsigned char *)(&encoded)) + (sizeof(encoded) - bytes),
bytes);
}
/* Grow a buffer to hold newLen bytes of data. When used for recv/xmit buffers,
......@@ -29,6 +29,15 @@ ssl_EncodeUintX(PRUint64 value, unsigned int bytes, PRUint8 *to)
SECStatus
sslBuffer_Grow(sslBuffer *b, unsigned int newLen)
{
if (b->fixed) {
PORT_Assert(newLen <= b->space);
if (newLen > b->space) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
return SECSuccess;
}
newLen = PR_MAX(newLen, b->len + 1024);
if (newLen > b->space) {
unsigned char *newBuf;
......@@ -51,9 +60,9 @@ sslBuffer_Append(sslBuffer *b, const void *data, unsigned int len)
{
SECStatus rv = sslBuffer_Grow(b, b->len + len);
if (rv != SECSuccess) {
return rv; /* Code already set. */
return SECFailure; /* Code already set. */
}
PORT_Memcpy(b->buf + b->len, data, len);
PORT_Memcpy(SSL_BUFFER_NEXT(b), data, len);
b->len += len;
return SECSuccess;
}
......@@ -63,9 +72,9 @@ sslBuffer_AppendNumber(sslBuffer *b, PRUint64 v, unsigned int size)
{
SECStatus rv = sslBuffer_Grow(b, b->len + size);
if (rv != SECSuccess) {
return rv;
return SECFailure;
}
(void)ssl_EncodeUintX(v, size, b->buf + b->len);
ssl_EncodeUintX(SSL_BUFFER_NEXT(b), v, size);
b->len += size;
return SECSuccess;
}
......@@ -74,13 +83,19 @@ SECStatus
sslBuffer_AppendVariable(sslBuffer *b, const PRUint8 *data, unsigned int len,
unsigned int size)
{
SECStatus rv = sslBuffer_Grow(b, b->len + len + size);
if (rv != SECSuccess) {
return rv;
PORT_Assert(size <= 4 && size > 0);
if (len >= (1ULL << (8 * size))) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
(void)ssl_EncodeUintX(len, size, b->buf + b->len);
if (sslBuffer_Grow(b, b->len + len + size) != SECSuccess) {
return SECFailure;
}
ssl_EncodeUintX(SSL_BUFFER_NEXT(b), len, size);
b->len += size;
PORT_Memcpy(b->buf + b->len, data, len);
PORT_Memcpy(SSL_BUFFER_NEXT(b), data, len);
b->len += len;
return SECSuccess;
}
......@@ -98,44 +113,63 @@ sslBuffer_AppendBufferVariable(sslBuffer *b, const sslBuffer *append,
return sslBuffer_AppendVariable(b, append->buf, append->len, size);
}
void
sslBuffer_Clear(sslBuffer *b)
SECStatus
sslBuffer_Skip(sslBuffer *b, unsigned int size, unsigned int *savedOffset)
{
if (b->buf) {
PORT_Free(b->buf);
b->buf = NULL;
b->len = 0;
b->space = 0;
if (sslBuffer_Grow(b, b->len + size) != SECSuccess) {
return SECFailure;
}
if (savedOffset) {
*savedOffset = b->len;
}
b->len += size;
return SECSuccess;
}
/* A common problem is that a buffer is used to construct a variable length
* structure of unknown length. The length field for that structure is then
* populated afterwards. This function makes this process a little easier.
*
* To use this, before encoding the variable length structure, skip the spot
* where the length would be using sslBuffer_Skip(). After encoding the
* structure, and before encoding anything else, call this function passing the
* value returned from sslBuffer_Skip() as |at| to have the length inserted.
*/
SECStatus
ssl3_AppendToItem(SECItem *item, const PRUint8 *buf, unsigned int size)
sslBuffer_InsertLength(sslBuffer *b, unsigned int at, unsigned int size)
{
if (size > item->len) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
unsigned int len;
PORT_Assert(b->len >= at + size);
PORT_Assert(b->space >= at + size);
len = b->len - (at + size);
PORT_Assert(size <= 4 && size > 0);
if (len >= (1ULL << (8 * size))) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
PORT_Memcpy(item->data, buf, size);
item->data += size;
item->len -= size;
ssl_EncodeUintX(SSL_BUFFER_BASE(b) + at, len, size);
return SECSuccess;
}
SECStatus
ssl3_AppendNumberToItem(SECItem *item, PRUint64 num, unsigned int size)
void
sslBuffer_Clear(sslBuffer *b)
{
SECStatus rv;
PRUint8 b[sizeof(num)];
ssl_EncodeUintX(num, size, b);
rv = ssl3_AppendToItem(item, &b[0], size);
return rv;
if (!b->fixed) {
if (b->buf) {
PORT_Free(b->buf);
b->buf = NULL;
}
b->space = 0;
}
b->len = 0;
}
SECStatus
ssl3_ConsumeFromItem(SECItem *item, PRUint8 **buf, unsigned int size)
ssl3_ConsumeFromItem(SECItem *item, unsigned char **buf, unsigned int size)
{
if (size > item->len) {
PORT_SetError(SEC_ERROR_BAD_DATA);
......@@ -168,3 +202,95 @@ ssl3_ConsumeNumberFromItem(SECItem *item, PRUint32 *num, unsigned int size)
return SECSuccess;
}
/**************************************************************************
* Append Handshake functions.
* All these functions set appropriate error codes.
* Most rely on ssl3_AppendHandshake to set the error code.
**************************************************************************/
#define MAX_SEND_BUF_LENGTH 32000 /* watch for 16-bit integer overflow */
#define MIN_SEND_BUF_LENGTH 4000
SECStatus
ssl3_AppendHandshake(sslSocket *ss, const void *void_src, unsigned int bytes)
{
unsigned char *src = (unsigned char *)void_src;
int room = ss->sec.ci.sendBuf.space - ss->sec.ci.sendBuf.len;
SECStatus rv;
PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); /* protects sendBuf. */
if (!bytes)
return SECSuccess;
if (ss->sec.ci.sendBuf.space < MAX_SEND_BUF_LENGTH && room < bytes) {
rv = sslBuffer_Grow(&ss->sec.ci.sendBuf, PR_MAX(MIN_SEND_BUF_LENGTH,
PR_MIN(MAX_SEND_BUF_LENGTH, ss->sec.ci.sendBuf.len + bytes)));
if (rv != SECSuccess)
return SECFailure; /* sslBuffer_Grow sets a memory error code. */
room = ss->sec.ci.sendBuf.space - ss->sec.ci.sendBuf.len;
}
PRINT_BUF(60, (ss, "Append to Handshake", (unsigned char *)void_src, bytes));
rv = ssl3_UpdateHandshakeHashes(ss, src, bytes);
if (rv != SECSuccess)
return SECFailure; /* error code set by ssl3_UpdateHandshakeHashes */
while (bytes > room) {
if (room > 0)
PORT_Memcpy(ss->sec.ci.sendBuf.buf + ss->sec.ci.sendBuf.len, src,
room);
ss->sec.ci.sendBuf.len += room;
rv = ssl3_FlushHandshake(ss, ssl_SEND_FLAG_FORCE_INTO_BUFFER);
if (rv != SECSuccess) {
return SECFailure; /* error code set by ssl3_FlushHandshake */
}
bytes -= room;
src += room;
room = ss->sec.ci.sendBuf.space;
PORT_Assert(ss->sec.ci.sendBuf.len == 0);
}
PORT_Memcpy(ss->sec.ci.sendBuf.buf + ss->sec.ci.sendBuf.len, src, bytes);
ss->sec.ci.sendBuf.len += bytes;
return SECSuccess;
}
SECStatus
ssl3_AppendHandshakeNumber(sslSocket *ss, PRUint64 num, unsigned int lenSize)
{
PRUint8 b[sizeof(num)];
SSL_TRC(60, ("%d: number:", SSL_GETPID()));
ssl_EncodeUintX(b, num, lenSize);
return ssl3_AppendHandshake(ss, b, lenSize);
}
SECStatus
ssl3_AppendHandshakeVariable(sslSocket *ss, const PRUint8 *src,
unsigned int bytes, unsigned int lenSize)
{
SECStatus rv;
PORT_Assert((bytes < (1 << 8) && lenSize == 1) ||
(bytes < (1L << 16) && lenSize == 2) ||
(bytes < (1L << 24) && lenSize == 3));
SSL_TRC(60, ("%d: append variable:", SSL_GETPID()));
rv = ssl3_AppendHandshakeNumber(ss, bytes, lenSize);
if (rv != SECSuccess) {
return SECFailure; /* error code set by AppendHandshake. */
}
SSL_TRC(60, ("data:"));
return ssl3_AppendHandshake(ss, src, bytes);
}
SECStatus
ssl3_AppendBufferToHandshake(sslSocket *ss, sslBuffer *buf)
{
return ssl3_AppendHandshake(ss, buf->buf, buf->len);
}
SECStatus
ssl3_AppendBufferToHandshakeVariable(sslSocket *ss, sslBuffer *buf,
unsigned int lenSize)
{
return ssl3_AppendHandshakeVariable(ss, buf->buf, buf->len, lenSize);
}
......@@ -9,17 +9,30 @@
#ifndef __sslencode_h_
#define __sslencode_h_
PRUint8 *ssl_EncodeUintX(PRUint64 value, unsigned int bytes, PRUint8 *to);
/*
** A buffer object.
*/
/* A buffer object, used for assembling messages. */
typedef struct sslBufferStr {
PRUint8 *buf;
unsigned int len;
unsigned int space;
/* Set to true if the storage for the buffer is fixed, such as a stack
* variable or a view on another buffer. Growing a fixed buffer fails. */
PRBool fixed;
} sslBuffer;
#define SSL_BUFFER_EMPTY \
{ \
NULL, 0, 0, PR_FALSE \
}
#define SSL_BUFFER_FIXED(b, maxlen) \
{ \
b, 0, maxlen, PR_TRUE \
}
#define SSL_BUFFER(b) SSL_BUFFER_FIXED(b, sizeof(b))
#define SSL_BUFFER_BASE(b) ((b)->buf)
#define SSL_BUFFER_LEN(b) ((b)->len)
#define SSL_BUFFER_NEXT(b) ((b)->buf + (b)->len)
#define SSL_BUFFER_SPACE(b) ((b)->space - (b)->len)
SECStatus sslBuffer_Grow(sslBuffer *b, unsigned int newLen);
SECStatus sslBuffer_Append(sslBuffer *b, const void *data, unsigned int len);
SECStatus sslBuffer_AppendNumber(sslBuffer *b, PRUint64 v, unsigned int size);
......@@ -28,17 +41,32 @@ SECStatus sslBuffer_AppendVariable(sslBuffer *b, const PRUint8 *data,
SECStatus sslBuffer_AppendBuffer(sslBuffer *b, const sslBuffer *append);
SECStatus sslBuffer_AppendBufferVariable(sslBuffer *b, const sslBuffer *append,
unsigned int size);
SECStatus sslBuffer_Skip(sslBuffer *b, unsigned int size,
unsigned int *savedOffset);
SECStatus sslBuffer_InsertLength(sslBuffer *b, unsigned int at,
unsigned int size);
void sslBuffer_Clear(sslBuffer *b);
/* All of these functions modify the underlying SECItem, and so should
* be performed on a shallow copy.*/
SECStatus ssl3_AppendToItem(SECItem *item,
const PRUint8 *buf, PRUint32 bytes);
SECStatus ssl3_AppendNumberToItem(SECItem *item,
PRUint64 num, unsigned int size);
SECStatus ssl3_ConsumeFromItem(SECItem *item,
PRUint8 **buf, unsigned int size);
SECStatus ssl3_ConsumeNumberFromItem(SECItem *item,
PRUint32 *num, unsigned int size);
/* These are used for building the handshake. */
typedef struct sslSocketStr sslSocket;
SECStatus ssl3_AppendHandshake(sslSocket *ss, const void *void_src,
unsigned int bytes);
SECStatus ssl3_AppendHandshakeHeader(sslSocket *ss,
SSLHandshakeType t, unsigned int length);
SECStatus ssl3_AppendHandshakeNumber(sslSocket *ss, PRUint64 num,
unsigned int lenSize);
SECStatus ssl3_AppendHandshakeVariable(sslSocket *ss, const PRUint8 *src,
unsigned int bytes, unsigned int lenSize);
SECStatus ssl3_AppendBufferToHandshake(sslSocket *ss, sslBuffer *buf);
SECStatus ssl3_AppendBufferToHandshakeVariable(sslSocket *ss, sslBuffer *buf,
unsigned int lenSize);
#endif /* __sslencode_h_ */
......@@ -1671,17 +1671,6 @@ extern SECStatus ssl3_ComputeCommonKeyHash(SSLHashType hashAlg,
SSL3Hashes *hashes);
extern void ssl3_DestroyCipherSpec(ssl3CipherSpec *spec, PRBool freeSrvName);
extern SECStatus ssl3_InitPendingCipherSpec(sslSocket *ss, PK11SymKey *pms);
extern SECStatus ssl3_AppendHandshake(sslSocket *ss, const void *void_src,
unsigned int bytes);
extern SECStatus ssl3_AppendHandshakeHeader(sslSocket *ss,
SSLHandshakeType t, unsigned int length);
extern SECStatus ssl3_AppendHandshakeNumber(sslSocket *ss, PRUint64 num,
unsigned int lenSize);
extern SECStatus ssl3_AppendHandshakeVariable(sslSocket *ss, const PRUint8 *src,
unsigned int bytes, unsigned int lenSize);
extern SECStatus ssl3_AppendBufferToHandshake(sslSocket *ss, sslBuffer *buf);
extern SECStatus ssl3_AppendBufferToHandshakeVariable(sslSocket *ss, sslBuffer *buf,
unsigned int lenSize);
extern SECStatus ssl3_AppendSignatureAndHashAlgorithm(
sslSocket *ss, const SSLSignatureAndHashAlg *sigAndHash);
extern SECStatus ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRUint32 bytes,
......@@ -1814,8 +1803,7 @@ SECStatus ssl3_SendCertificateStatus(sslSocket *ss);
SECStatus ssl3_AuthCertificate(sslSocket *ss);
SECStatus ssl_ReadCertificateStatus(sslSocket *ss, PRUint8 *b,
PRUint32 length);
SECStatus ssl3_EncodeSigAlgs(const sslSocket *ss, PRUint8 *buf,
unsigned maxLen, PRUint32 *len);
SECStatus ssl3_EncodeSigAlgs(const sslSocket *ss, sslBuffer *buf);
SECStatus ssl_GetCertificateRequestCAs(const sslSocket *ss,
unsigned int *calenp,
const SECItem **namesp,
......
......@@ -1644,7 +1644,7 @@ tls13_ConstructHelloRetryRequest(sslSocket *ss,
sslBuffer *buffer)
{
SECStatus rv;
sslBuffer extensionsBuf = { NULL, 0, 0 };
sslBuffer extensionsBuf = SSL_BUFFER_EMPTY;
PORT_Assert(buffer->len == 0);
rv = sslBuffer_AppendNumber(buffer,
......@@ -1668,7 +1668,8 @@ tls13_ConstructHelloRetryRequest(sslSocket *ss,
if (rv != SECSuccess) {
goto loser;
}
PORT_Assert(extensionsBuf.len > 0); /* These can't be empty. */
/* These extensions can't be empty. */
PORT_Assert(SSL_BUFFER_LEN(&extensionsBuf) > 0);
/* Clean up cookie so we're not pointing at random memory. */
ss->xtnData.cookie.data = NULL;
......@@ -1695,7 +1696,7 @@ tls13_SendHelloRetryRequest(sslSocket *ss,
SECStatus rv;
unsigned int cookieLen;
PRUint8 cookie[1024];
sslBuffer messageBuf = { NULL, 0, 0 };
sslBuffer messageBuf = SSL_BUFFER_EMPTY;
SSL_TRC(3, ("%d: TLS13[%d]: send hello retry request handshake",
SSL_GETPID(), ss->fd));
......@@ -1723,7 +1724,7 @@ tls13_SendHelloRetryRequest(sslSocket *ss,
/* And send it. */
ssl_GetXmitBufLock(ss);
rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_hello_retry_request,
messageBuf.len);
SSL_BUFFER_LEN(&messageBuf));
if (rv != SECSuccess) {
goto loser;
}
......@@ -1824,7 +1825,7 @@ static SECStatus
tls13_SendCertificateRequest(sslSocket *ss)
{
SECStatus rv;
sslBuffer extensionBuf = { NULL, 0, 0 };
sslBuffer extensionBuf = SSL_BUFFER_EMPTY;
SSL_TRC(3, ("%d: TLS13[%d]: begin send certificate_request",
SSL_GETPID(), ss->fd));
......@@ -1833,12 +1834,13 @@ tls13_SendCertificateRequest(sslSocket *ss)
if (rv != SECSuccess) {
return SECFailure; /* Code already set. */
}
PORT_Assert(extensionBuf.len > 0); /* These can't be empty. */
/* We should always have at least one of these. */
PORT_Assert(SSL_BUFFER_LEN(&extensionBuf) > 0);
rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_certificate_request,
1 + 0 + /* empty request context */
2 + /* extension length */
extensionBuf.len /* extensions */);
SSL_BUFFER_LEN(&extensionBuf));
if (rv != SECSuccess) {
goto loser; /* err set by AppendHandshake. */
}
......@@ -2402,7 +2404,7 @@ tls13_SendCertificate(sslSocket *ss)
int certChainLen = 0;
int i;
SECItem context = { siBuffer, NULL, 0 };
sslBuffer extensionBuf = { NULL, 0, 0 };
sslBuffer extensionBuf = SSL_BUFFER_EMPTY;
SSL_TRC(3, ("%d: TLS1.3[%d]: send certificate handshake",
SSL_GETPID(), ss->fd));
......@@ -2442,7 +2444,7 @@ tls13_SendCertificate(sslSocket *ss)
return SECFailure; /* code already set */
}
/* extensionBuf.len is only added once, for the leaf cert. */
certChainLen += extensionBuf.len;
certChainLen += SSL_BUFFER_LEN(&extensionBuf);
}
rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_certificate,
......@@ -3404,7 +3406,7 @@ tls13_HandleEncryptedExtensions(sslSocket *ss, PRUint8 *b, PRUint32 length)
static SECStatus
tls13_SendEncryptedExtensions(sslSocket *ss)
{
sslBuffer extensions = { NULL, 0, 0 };
sslBuffer extensions = SSL_BUFFER_EMPTY;
SECStatus rv;
SSL_TRC(3, ("%d: TLS13[%d]: send encrypted extensions handshake",
......@@ -3419,7 +3421,7 @@ tls13_SendEncryptedExtensions(sslSocket *ss)
}
rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_encrypted_extensions,
extensions.len + 2);
SSL_BUFFER_LEN(&extensions) + 2);
if (rv != SECSuccess) {
LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
goto loser;
......@@ -4158,6 +4160,7 @@ tls13_SendNewSessionTicket(sslSocket *ss, const PRUint8 *appToken,
NewSessionTicket ticket = { 0 };
PRUint32 max_early_data_size_len = 0;
PRUint8 ticketNonce[sizeof(ss->ssl3.hs.ticketNonce)];
sslBuffer ticketNonceBuf = SSL_BUFFER(ticketNonce);
SSL_TRC(3, ("%d: TLS13[%d]: send new session ticket message %d",
SSL_GETPID(), ss->fd, ss->ssl3.hs.ticketNonce));
......@@ -4175,8 +4178,11 @@ tls13_SendNewSessionTicket(sslSocket *ss, const PRUint8 *appToken,
if (rv != SECSuccess)
goto loser;
(void)ssl_EncodeUintX(ss->ssl3.hs.ticketNonce, sizeof(ticketNonce),
ticketNonce);
rv = sslBuffer_AppendNumber(&ticketNonceBuf, ss->ssl3.hs.ticketNonce,
sizeof(ticketNonce));
if (rv != SECSuccess) {
goto loser;
}
++ss->ssl3.hs.ticketNonce;
rv = tls13_HkdfExpandLabel(ss->ssl3.hs.resumptionMasterSecret,
tls13_GetHash(ss),
......@@ -4511,15 +4517,14 @@ tls13_ExtensionStatus(PRUint16 extension, SSLHandshakeType message)
* number and that's what we put here. The TLS 1.3 AEAD functions
* just use this input as the sequence number and not as additional
* data. */
static void
static SECStatus
tls13_FormatAdditionalData(PRUint8 *aad, unsigned int length,
sslSequenceNumber seqNum)
{
PRUint8 *ptr = aad;
sslBuffer buf = SSL_BUFFER_FIXED(aad, length);
PORT_Assert(length == 8);
ptr = ssl_EncodeUintX(seqNum, 8, ptr);
PORT_Assert((ptr - aad) == length);
return sslBuffer_AppendNumber(&buf, seqNum, length);
}
PRInt32
......@@ -4579,7 +4584,10 @@ tls13_ProtectRecord(sslSocket *ss,
/* Add the content type at the end. */
wrBuf->buf[contentLen] = type;
tls13_FormatAdditionalData(aad, sizeof(aad), cwSpec->write_seq_num);
rv = tls13_FormatAdditionalData(aad, sizeof(aad), cwSpec->write_seq_num);
if (rv != SECSuccess) {
return SECFailure;
}
rv = cwSpec->aead(
ss->sec.isServer ? &cwSpec->server : &cwSpec->client,
PR_FALSE, /* do encrypt */
......@@ -4653,9 +4661,12 @@ tls13_UnprotectRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *plaintext
/* Decrypt */
PORT_Assert(cipher_def->type == type_aead);
tls13_FormatAdditionalData(aad, sizeof(aad),
rv = tls13_FormatAdditionalData(aad, sizeof(aad),
IS_DTLS(ss) ? cText->seq_num
: crSpec->read_seq_num);
if (rv != SECSuccess) {
return SECFailure;
}
rv = crSpec->aead(
ss->sec.isServer ? &crSpec->client : &crSpec->server,
PR_TRUE, /* do decrypt */
......
......@@ -77,7 +77,8 @@ SECStatus tls13_HandlePostHelloHandshakeMessage(sslSocket *ss, PRUint8 *b,
SECStatus tls13_ConstructHelloRetryRequest(sslSocket *ss,
ssl3CipherSuite cipherSuite,
const sslNamedGroupDef *selectedGroup,
PRUint8 *cookie, unsigned int cookieLen