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) { ...@@ -758,12 +758,14 @@ TEST_F(TlsConnectTest, SendSessionTicketMassiveToken) {
Connect(); Connect();
// It should be safe to set length with a NULL token because the length should // It should be safe to set length with a NULL token because the length should
// be checked before reading token. // be checked before reading token.
EXPECT_EQ(SECFailure, SSL_SendSessionTicket(server_->ssl_fd(), NULL, 0xffff)) EXPECT_EQ(SECFailure, SSL_SendSessionTicket(server_->ssl_fd(), NULL, 0x1ffff))
<< "no special tickets in TLS 1.2"; << "this is clearly too big";
EXPECT_EQ(SEC_ERROR_INVALID_ARGS, PORT_GetError()); EXPECT_EQ(SEC_ERROR_INVALID_ARGS, PORT_GetError());
EXPECT_EQ(SECFailure, SSL_SendSessionTicket(server_->ssl_fd(), NULL, 0x1ffff)) static const uint8_t big_token[0xffff] = {1};
<< "no special tickets in TLS 1.2"; 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()); EXPECT_EQ(SEC_ERROR_INVALID_ARGS, PORT_GetError());
} }
......
...@@ -121,12 +121,11 @@ ssl_SelfEncryptProtectInt( ...@@ -121,12 +121,11 @@ ssl_SelfEncryptProtectInt(
PRUint8 *out, unsigned int *outLen, unsigned int maxOutLen) PRUint8 *out, unsigned int *outLen, unsigned int maxOutLen)
{ {
unsigned int len; unsigned int len;
unsigned int lenOffset;
unsigned char iv[AES_BLOCK_SIZE]; unsigned char iv[AES_BLOCK_SIZE];
SECItem ivItem = { siBuffer, iv, sizeof(iv) }; SECItem ivItem = { siBuffer, iv, sizeof(iv) };
unsigned char mac[SHA256_LENGTH]; /* SHA-256 */ /* Write directly to out. */
unsigned int macLen; sslBuffer buf = SSL_BUFFER_FIXED(out, maxOutLen);
SECItem outItem = { siBuffer, out, maxOutLen };
SECItem lengthBytesItem;
SECStatus rv; SECStatus rv;
/* Generate a random IV */ /* Generate a random IV */
...@@ -137,52 +136,54 @@ ssl_SelfEncryptProtectInt( ...@@ -137,52 +136,54 @@ ssl_SelfEncryptProtectInt(
} }
/* Add header. */ /* 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) { if (rv != SECSuccess) {
return SECFailure; return SECFailure;
} }
rv = ssl3_AppendToItem(&outItem, iv, sizeof(iv)); rv = sslBuffer_Append(&buf, iv, sizeof(iv));
if (rv != SECSuccess) { if (rv != SECSuccess) {
return SECFailure; return SECFailure;
} }
/* Skip forward by two so we can encode the ciphertext in place. */ /* Leave space for the length of the ciphertext. */
lengthBytesItem = outItem; rv = sslBuffer_Skip(&buf, 2, &lenOffset);
rv = ssl3_AppendNumberToItem(&outItem, 0, 2);
if (rv != SECSuccess) { if (rv != SECSuccess) {
return SECFailure; return SECFailure;
} }
/* Encode the ciphertext in place. */
rv = PK11_Encrypt(encKey, CKM_AES_CBC_PAD, &ivItem, 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) { if (rv != SECSuccess) {
return SECFailure; return SECFailure;
} }
outItem.data += len; rv = sslBuffer_InsertLength(&buf, lenOffset, 2);
outItem.len -= len;
/* Now encode the ciphertext length. */
rv = ssl3_AppendNumberToItem(&lengthBytesItem, len, 2);
if (rv != SECSuccess) { if (rv != SECSuccess) {
return SECFailure; 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, rv = ssl_MacBuffer(macKey, CKM_SHA256_HMAC,
out, outItem.data - out, SSL_BUFFER_BASE(&buf), /* input */
mac, &macLen, sizeof(mac)); SSL_BUFFER_LEN(&buf),
SSL_BUFFER_NEXT(&buf), &len, /* output */
SHA256_LENGTH);
if (rv != SECSuccess) { if (rv != SECSuccess) {
return SECFailure; return SECFailure;
} }
PORT_Assert(macLen == sizeof(mac)); rv = sslBuffer_Skip(&buf, len, NULL);
rv = ssl3_AppendToItem(&outItem, mac, macLen);
if (rv != SECSuccess) { if (rv != SECSuccess) {
return SECFailure; return SECFailure;
} }
*outLen = outItem.data - out; *outLen = SSL_BUFFER_LEN(&buf);
return SECSuccess; return SECSuccess;
} }
...@@ -270,16 +271,14 @@ ssl_SelfEncryptUnprotectInt( ...@@ -270,16 +271,14 @@ ssl_SelfEncryptUnprotectInt(
#endif #endif
/* Predict the size of the encrypted data, including padding */ /* Predict the size of the encrypted data, including padding */
SECStatus unsigned int
ssl_SelfEncryptGetProtectedSize(unsigned int inLen, unsigned int *outLen) ssl_SelfEncryptGetProtectedSize(unsigned int inLen)
{ {
*outLen = SELF_ENCRYPT_KEY_NAME_LEN + return SELF_ENCRYPT_KEY_NAME_LEN +
AES_BLOCK_SIZE + AES_BLOCK_SIZE +
2 + 2 +
((inLen / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE + /* Padded */ ((inLen / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE + /* Padded */
SHA256_LENGTH; SHA256_LENGTH;
return SECSuccess;
} }
SECStatus SECStatus
......
...@@ -13,8 +13,7 @@ ...@@ -13,8 +13,7 @@
typedef struct sslSocketStr sslSocket; typedef struct sslSocketStr sslSocket;
SECStatus ssl_SelfEncryptGetProtectedSize(unsigned int inLen, unsigned int ssl_SelfEncryptGetProtectedSize(unsigned int inLen);
unsigned int *outLen);
SECStatus ssl_SelfEncryptProtect( SECStatus ssl_SelfEncryptProtect(
sslSocket *ss, const PRUint8 *in, unsigned int inLen, sslSocket *ss, const PRUint8 *in, unsigned int inLen,
PRUint8 *out, unsigned int *outLen, unsigned int maxOutLen); PRUint8 *out, unsigned int *outLen, unsigned int maxOutLen);
......
This diff is collapsed.
...@@ -864,8 +864,9 @@ ssl_SendSupportedGroupsXtn(const sslSocket *ss, TLSExtensionData *xtnData, ...@@ -864,8 +864,9 @@ ssl_SendSupportedGroupsXtn(const sslSocket *ss, TLSExtensionData *xtnData,
unsigned int i; unsigned int i;
PRBool ec; PRBool ec;
PRBool ff = PR_FALSE; PRBool ff = PR_FALSE;
PRBool found = PR_FALSE;
SECStatus rv; SECStatus rv;
sslBuffer tmpBuf = { NULL, 0, 0 }; unsigned int lengthOffset;
/* We only send FF supported groups if we require DH named groups /* We only send FF supported groups if we require DH named groups
* or if TLS 1.3 is a possibility. */ * or if TLS 1.3 is a possibility. */
...@@ -881,7 +882,12 @@ ssl_SendSupportedGroupsXtn(const sslSocket *ss, TLSExtensionData *xtnData, ...@@ -881,7 +882,12 @@ ssl_SendSupportedGroupsXtn(const sslSocket *ss, TLSExtensionData *xtnData,
ec = ff = PR_TRUE; 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) { for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) {
const sslNamedGroupDef *group = ss->namedGroupPreferences[i]; const sslNamedGroupDef *group = ss->namedGroupPreferences[i];
if (!group) { if (!group) {
...@@ -894,21 +900,19 @@ ssl_SendSupportedGroupsXtn(const sslSocket *ss, TLSExtensionData *xtnData, ...@@ -894,21 +900,19 @@ ssl_SendSupportedGroupsXtn(const sslSocket *ss, TLSExtensionData *xtnData,
continue; continue;
} }
rv = sslBuffer_AppendNumber(&tmpBuf, group->name, 2); found = PR_TRUE;
rv = sslBuffer_AppendNumber(buf, group->name, 2);
if (rv != SECSuccess) { if (rv != SECSuccess) {
sslBuffer_Clear(&tmpBuf);
return SECFailure; return SECFailure;
} }
} }
if (!tmpBuf.len) { if (!found) {
sslBuffer_Clear(&tmpBuf);
/* We added nothing, don't send the extension. */ /* We added nothing, don't send the extension. */
return SECSuccess; return SECSuccess;
} }
rv = sslBuffer_AppendBufferVariable(buf, &tmpBuf, 2); rv = sslBuffer_InsertLength(buf, lengthOffset, 2);
sslBuffer_Clear(&tmpBuf);
if (rv != SECSuccess) { if (rv != SECSuccess) {
return SECFailure; return SECFailure;
} }
......
This diff is collapsed.
...@@ -12,16 +12,16 @@ ...@@ -12,16 +12,16 @@
#include "sslimpl.h" #include "sslimpl.h"
/* Helper function to encode an unsigned integer into a buffer. */ /* Helper function to encode an unsigned integer into a buffer. */
PRUint8 * static void
ssl_EncodeUintX(PRUint64 value, unsigned int bytes, PRUint8 *to) ssl_EncodeUintX(PRUint8 *to, PRUint64 value, unsigned int bytes)
{ {
PRUint64 encoded; PRUint64 encoded;
PORT_Assert(bytes > 0 && bytes <= sizeof(encoded)); PORT_Assert(bytes > 0 && bytes <= sizeof(encoded));
encoded = PR_htonll(value); encoded = PR_htonll(value);
memcpy(to, ((unsigned char *)(&encoded)) + (sizeof(encoded) - bytes), bytes); PORT_Memcpy(to, ((unsigned char *)(&encoded)) + (sizeof(encoded) - bytes),
return to + bytes; bytes);
} }
/* Grow a buffer to hold newLen bytes of data. When used for recv/xmit buffers, /* 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) ...@@ -29,6 +29,15 @@ ssl_EncodeUintX(PRUint64 value, unsigned int bytes, PRUint8 *to)
SECStatus SECStatus
sslBuffer_Grow(sslBuffer *b, unsigned int newLen) 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); newLen = PR_MAX(newLen, b->len + 1024);
if (newLen > b->space) { if (newLen > b->space) {
unsigned char *newBuf; unsigned char *newBuf;
...@@ -51,9 +60,9 @@ sslBuffer_Append(sslBuffer *b, const void *data, unsigned int len) ...@@ -51,9 +60,9 @@ sslBuffer_Append(sslBuffer *b, const void *data, unsigned int len)
{ {
SECStatus rv = sslBuffer_Grow(b, b->len + len); SECStatus rv = sslBuffer_Grow(b, b->len + len);
if (rv != SECSuccess) { 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; b->len += len;
return SECSuccess; return SECSuccess;
} }
...@@ -63,9 +72,9 @@ sslBuffer_AppendNumber(sslBuffer *b, PRUint64 v, unsigned int size) ...@@ -63,9 +72,9 @@ sslBuffer_AppendNumber(sslBuffer *b, PRUint64 v, unsigned int size)
{ {
SECStatus rv = sslBuffer_Grow(b, b->len + size); SECStatus rv = sslBuffer_Grow(b, b->len + size);
if (rv != SECSuccess) { 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; b->len += size;
return SECSuccess; return SECSuccess;
} }
...@@ -74,13 +83,19 @@ SECStatus ...@@ -74,13 +83,19 @@ SECStatus
sslBuffer_AppendVariable(sslBuffer *b, const PRUint8 *data, unsigned int len, sslBuffer_AppendVariable(sslBuffer *b, const PRUint8 *data, unsigned int len,
unsigned int size) unsigned int size)
{ {
SECStatus rv = sslBuffer_Grow(b, b->len + len + size); PORT_Assert(size <= 4 && size > 0);
if (rv != SECSuccess) { if (len >= (1ULL << (8 * size))) {
return rv; PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
if (sslBuffer_Grow(b, b->len + len + size) != SECSuccess) {
return SECFailure;
} }
(void)ssl_EncodeUintX(len, size, b->buf + b->len);
ssl_EncodeUintX(SSL_BUFFER_NEXT(b), len, size);
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; b->len += len;
return SECSuccess; return SECSuccess;
} }
...@@ -98,44 +113,63 @@ sslBuffer_AppendBufferVariable(sslBuffer *b, const sslBuffer *append, ...@@ -98,44 +113,63 @@ sslBuffer_AppendBufferVariable(sslBuffer *b, const sslBuffer *append,
return sslBuffer_AppendVariable(b, append->buf, append->len, size); return sslBuffer_AppendVariable(b, append->buf, append->len, size);
} }
void SECStatus
sslBuffer_Clear(sslBuffer *b) sslBuffer_Skip(sslBuffer *b, unsigned int size, unsigned int *savedOffset)
{ {
if (b->buf) { if (sslBuffer_Grow(b, b->len + size) != SECSuccess) {
PORT_Free(b->buf); return SECFailure;
b->buf = NULL; }
b->len = 0;
b->space = 0; 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 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) { unsigned int len;
PORT_SetError(SEC_ERROR_INVALID_ARGS);
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; return SECFailure;
} }
PORT_Memcpy(item->data, buf, size); ssl_EncodeUintX(SSL_BUFFER_BASE(b) + at, len, size);
item->data += size;
item->len -= size;
return SECSuccess; return SECSuccess;
} }
SECStatus void
ssl3_AppendNumberToItem(SECItem *item, PRUint64 num, unsigned int size) sslBuffer_Clear(sslBuffer *b)
{ {
SECStatus rv; if (!b->fixed) {
PRUint8 b[sizeof(num)]; if (b->buf) {
PORT_Free(b->buf);
ssl_EncodeUintX(num, size, b); b->buf = NULL;
rv = ssl3_AppendToItem(item, &b[0], size); }
return rv; b->space = 0;
}
b->len = 0;
} }
SECStatus SECStatus
ssl3_ConsumeFromItem(SECItem *item, PRUint8 **buf, unsigned int size) ssl3_ConsumeFromItem(SECItem *item, unsigned char **buf, unsigned int size)
{ {
if (size > item->len) { if (size > item->len) {
PORT_SetError(SEC_ERROR_BAD_DATA); PORT_SetError(SEC_ERROR_BAD_DATA);
...@@ -168,3 +202,95 @@ ssl3_ConsumeNumberFromItem(SECItem *item, PRUint32 *num, unsigned int size) ...@@ -168,3 +202,95 @@ ssl3_ConsumeNumberFromItem(SECItem *item, PRUint32 *num, unsigned int size)
return SECSuccess; 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 @@ ...@@ -9,17 +9,30 @@
#ifndef __sslencode_h_ #ifndef __sslencode_h_
#define __sslencode_h_ #define __sslencode_h_
PRUint8 *ssl_EncodeUintX(PRUint64 value, unsigned int bytes, PRUint8 *to); /* A buffer object, used for assembling messages. */
/*
** A buffer object.
*/
typedef struct sslBufferStr { typedef struct sslBufferStr {
PRUint8 *buf; PRUint8 *buf;
unsigned int len; unsigned int len;
unsigned int space; 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; } 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_Grow(sslBuffer *b, unsigned int newLen);
SECStatus sslBuffer_Append(sslBuffer *b, const void *data, unsigned int len); SECStatus sslBuffer_Append(sslBuffer *b, const void *data, unsigned int len);
SECStatus sslBuffer_AppendNumber(sslBuffer *b, PRUint64 v, unsigned int size); SECStatus sslBuffer_AppendNumber(sslBuffer *b, PRUint64 v, unsigned int size);
...@@ -28,17 +41,32 @@ SECStatus sslBuffer_AppendVariable(sslBuffer *b, const PRUint8 *data, ...@@ -28,17 +41,32 @@ SECStatus sslBuffer_AppendVariable(sslBuffer *b, const PRUint8 *data,
SECStatus sslBuffer_AppendBuffer(sslBuffer *b, const sslBuffer *append); SECStatus sslBuffer_AppendBuffer(sslBuffer *b, const sslBuffer *append);
SECStatus sslBuffer_AppendBufferVariable(sslBuffer *b, const sslBuffer *append, SECStatus sslBuffer_AppendBufferVariable(sslBuffer *b, const sslBuffer *append,
unsigned int size); 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); void sslBuffer_Clear(sslBuffer *b);
/* All of these functions modify the underlying SECItem, and so should /* All of these functions modify the underlying SECItem, and so should
* be performed on a shallow copy.*/ * 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, SECStatus ssl3_ConsumeFromItem(SECItem *item,
PRUint8 **buf, unsigned int size); PRUint8 **buf, unsigned int size);
SECStatus ssl3_ConsumeNumberFromItem(SECItem *item, SECStatus ssl3_ConsumeNumberFromItem(SECItem *item,
PRUint32 *num, unsigned int size); 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_ */ #endif /* __sslencode_h_ */
...@@ -1671,17 +1671,6 @@ extern SECStatus ssl3_ComputeCommonKeyHash(SSLHashType hashAlg, ...@@ -1671,17 +1671,6 @@ extern SECStatus ssl3_ComputeCommonKeyHash(SSLHashType hashAlg,
SSL3Hashes *hashes); SSL3Hashes *hashes);
extern void ssl3_DestroyCipherSpec(ssl3CipherSpec *spec, PRBool freeSrvName); extern void ssl3_DestroyCipherSpec(ssl3CipherSpec *spec, PRBool freeSrvName);
extern SECStatus ssl3_InitPendingCipherSpec(sslSocket *ss, PK11SymKey *pms); 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( extern SECStatus ssl3_AppendSignatureAndHashAlgorithm(
sslSocket *ss, const SSLSignatureAndHashAlg *sigAndHash); sslSocket *ss, const SSLSignatureAndHashAlg *sigAndHash);
extern SECStatus ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRUint32 bytes, extern SECStatus ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRUint32 bytes,
...@@ -1814,8 +1803,7 @@ SECStatus ssl3_SendCertificateStatus(sslSocket *ss); ...@@ -1814,8 +1803,7 @@ SECStatus ssl3_SendCertificateStatus(sslSocket *ss);
SECStatus ssl3_AuthCertificate(sslSocket *ss); SECStatus ssl3_AuthCertificate(sslSocket *ss);
SECStatus ssl_ReadCertificateStatus(sslSocket *ss, PRUint8 *b, SECStatus ssl_ReadCertificateStatus(sslSocket *ss, PRUint8 *b,
PRUint32 length); PRUint32 length);
SECStatus ssl3_EncodeSigAlgs(const sslSocket *ss, PRUint8 *buf, SECStatus ssl3_EncodeSigAlgs(const sslSocket *ss, sslBuffer *buf);
unsigned maxLen, PRUint32 *len);
SECStatus ssl_GetCertificateRequestCAs(const sslSocket *ss, SECStatus ssl_GetCertificateRequestCAs(const sslSocket *ss,
unsigned int *calenp, unsigned int *calenp,
const SECItem **namesp, const SECItem **namesp,
......
...@@ -1644,7 +1644,7 @@ tls13_ConstructHelloRetryRequest(sslSocket *ss, ...@@ -1644,7 +1644,7 @@ tls13_ConstructHelloRetryRequest(sslSocket *ss,
sslBuffer *buffer) sslBuffer *buffer)
{ {
SECStatus rv; SECStatus rv;
sslBuffer extensionsBuf = { NULL, 0, 0 }; sslBuffer extensionsBuf = SSL_BUFFER_EMPTY;
PORT_Assert(buffer->len == 0); PORT_Assert(buffer->len == 0);
rv = sslBuffer_AppendNumber(buffer, rv = sslBuffer_AppendNumber(buffer,
...@@ -1668,7 +1668,8 @@ tls13_ConstructHelloRetryRequest(sslSocket *ss, ...@@ -1668,7 +1668,8 @@ tls13_ConstructHelloRetryRequest(sslSocket *ss,
if (rv != SECSuccess) { if (rv != SECSuccess) {
goto loser; 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);