Commit 793a2fca authored by Martin Thomson's avatar Martin Thomson

Bug 1368980 - Refactor extension senders, r=ekr,ttaubert

--HG--
branch : NSS_TLS13_DRAFT19_BRANCH
extra : rebase_source : c2c4eae5bc13298513fac59b2f336af0047094e1
extra : amend_source : c598baccb0a630e2648d8b2d6733694c861f89b6
extra : source : 15572efbbc172c68ef8a307a7c2f61f5e7b17319
parent 83048fde
......@@ -6,7 +6,9 @@
#include "tls_parser.h"
#include "ssl.h"
extern "C" {
#include "sslimpl.h"
}
using namespace nss_test;
......
......@@ -351,30 +351,6 @@ unsigned char *SSLInt_CipherSpecToIv(PRBool isServer, ssl3CipherSpec *spec) {
return GetKeyingMaterial(isServer, spec)->write_iv;
}
SECStatus SSLInt_EnableShortHeaders(PRFileDesc *fd) {
sslSocket *ss;
ss = ssl_FindSocket(fd);
if (!ss) {
return SECFailure;
}
ss->opt.enableShortHeaders = PR_TRUE;
return SECSuccess;
}
SECStatus SSLInt_UsingShortHeaders(PRFileDesc *fd, PRBool *result) {
sslSocket *ss;
ss = ssl_FindSocket(fd);
if (!ss) {
return SECFailure;
}
*result = ss->ssl3.hs.shortHeaders;
return SECSuccess;
}
void SSLInt_SetTicketLifetime(uint32_t lifetime) {
ssl_ticket_lifetime = lifetime;
}
......
......@@ -48,8 +48,6 @@ PK11SymKey *SSLInt_CipherSpecToKey(PRBool isServer, ssl3CipherSpec *spec);
SSLCipherAlgorithm SSLInt_CipherSpecToAlgorithm(PRBool isServer,
ssl3CipherSpec *spec);
unsigned char *SSLInt_CipherSpecToIv(PRBool isServer, ssl3CipherSpec *spec);
SECStatus SSLInt_EnableShortHeaders(PRFileDesc *fd);
SECStatus SSLInt_UsingShortHeaders(PRFileDesc *fd, PRBool *result);
void SSLInt_SetTicketLifetime(uint32_t lifetime);
void SSLInt_SetMaxEarlyDataSize(uint32_t size);
SECStatus SSLInt_SetSocketMaxEarlyDataSize(PRFileDesc *fd, uint32_t size);
......
......@@ -315,14 +315,6 @@ TEST_F(TlsConnectStreamTls13, Tls13FailedWriteSecondFlight) {
client_->CheckErrorCode(SSL_ERROR_SOCKET_WRITE_FAILURE);
}
TEST_F(TlsConnectStreamTls13, NegotiateShortHeaders) {
client_->SetShortHeadersEnabled();
server_->SetShortHeadersEnabled();
client_->ExpectShortHeaders();
server_->ExpectShortHeaders();
Connect();
}
INSTANTIATE_TEST_CASE_P(
GenericStream, TlsConnectGeneric,
::testing::Combine(TlsConnectTestBase::kTlsVariantsStream,
......
......@@ -73,7 +73,6 @@ TlsAgent::TlsAgent(const std::string& name, Role role,
handshake_callback_(),
auth_certificate_callback_(),
sni_callback_(),
expect_short_headers_(false),
skip_version_checks_(false) {
memset(&info_, 0, sizeof(info_));
memset(&csinfo_, 0, sizeof(csinfo_));
......@@ -407,13 +406,6 @@ void TlsAgent::SetFallbackSCSVEnabled(bool en) {
EXPECT_EQ(SECSuccess, rv);
}
void TlsAgent::SetShortHeadersEnabled() {
EXPECT_TRUE(EnsureTlsSetup());
SECStatus rv = SSLInt_EnableShortHeaders(ssl_fd());
EXPECT_EQ(SECSuccess, rv);
}
void TlsAgent::SetVersionRange(uint16_t minver, uint16_t maxver) {
vrange_.min = minver;
vrange_.max = maxver;
......@@ -437,8 +429,6 @@ void TlsAgent::SetServerKeyBits(uint16_t bits) { server_key_bits_ = bits; }
void TlsAgent::ExpectReadWriteError() { expect_readwrite_error_ = true; }
void TlsAgent::ExpectShortHeaders() { expect_short_headers_ = true; }
void TlsAgent::SkipVersionChecks() { skip_version_checks_ = true; }
void TlsAgent::SetSignatureSchemes(const SSLSignatureScheme* schemes,
......@@ -764,10 +754,6 @@ void TlsAgent::Connected() {
}
}
PRBool short_headers;
rv = SSLInt_UsingShortHeaders(ssl_fd(), &short_headers);
EXPECT_EQ(SECSuccess, rv);
EXPECT_EQ((PRBool)expect_short_headers_, short_headers);
SetState(STATE_CONNECTED);
}
......
......@@ -126,7 +126,6 @@ class TlsAgent : public PollTarget {
void SetSessionCacheEnabled(bool en);
void Set0RttEnabled(bool en);
void SetFallbackSCSVEnabled(bool en);
void SetShortHeadersEnabled();
void SetVersionRange(uint16_t minver, uint16_t maxver);
void GetVersionRange(uint16_t* minver, uint16_t* maxver);
void CheckPreliminaryInfo();
......@@ -136,7 +135,6 @@ class TlsAgent : public PollTarget {
void ExpectReadWriteError();
void EnableFalseStart();
void ExpectResumption();
void ExpectShortHeaders();
void SkipVersionChecks();
void SetSignatureSchemes(const SSLSignatureScheme* schemes, size_t count);
void EnableAlpn(const uint8_t* val, size_t len);
......@@ -388,7 +386,6 @@ class TlsAgent : public PollTarget {
HandshakeCallbackFunction handshake_callback_;
AuthCertificateCallbackFunction auth_certificate_callback_;
SniCallbackFunction sni_callback_;
bool expect_short_headers_;
bool skip_version_checks_;
};
......
......@@ -346,7 +346,7 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
(fragment_offset == 0) &&
(fragment_length == message_length)) {
/* Complete next message. Process immediately */
ss->ssl3.hs.msg_type = (SSL3HandshakeType)type;
ss->ssl3.hs.msg_type = (SSLHandshakeType)type;
ss->ssl3.hs.msg_len = message_length;
rv = dtls_HandleHandshakeMessage(ss, buf.buf,
......@@ -391,7 +391,7 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
ss->ssl3.hs.recvdHighWater = 0;
PORT_Memset(ss->ssl3.hs.recvdFragments.buf, 0,
ss->ssl3.hs.recvdFragments.space);
ss->ssl3.hs.msg_type = (SSL3HandshakeType)type;
ss->ssl3.hs.msg_type = (SSLHandshakeType)type;
ss->ssl3.hs.msg_len = message_length;
}
......
......@@ -25,7 +25,7 @@ CSRCS = \
sslauth.c \
sslcon.c \
ssldef.c \
ssl3encode.c \
sslencode.c \
sslenum.c \
sslerr.c \
sslerrstrs.c \
......
......@@ -11,7 +11,7 @@
#include "pk11func.h"
#include "ssl.h"
#include "sslt.h"
#include "ssl3encode.h"
#include "sslencode.h"
#include "sslimpl.h"
#include "selfencrypt.h"
......
......@@ -17,7 +17,6 @@
'selfencrypt.c',
'ssl3con.c',
'ssl3ecc.c',
'ssl3encode.c',
'ssl3ext.c',
'ssl3exthandle.c',
'ssl3gthr.c',
......@@ -25,6 +24,7 @@
'sslcert.c',
'sslcon.c',
'ssldef.c',
'sslencode.c',
'sslenum.c',
'sslerr.c',
'sslerrstrs.c',
......
This diff is collapsed.
......@@ -219,7 +219,7 @@ ssl3_SendECDHClientKeyExchange(sslSocket *ss, SECKEYPublicKey *svrPubKey)
goto loser;
}
rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange,
rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_client_key_exchange,
pubKey->u.ec.publicValue.len + 1);
if (rv != SECSuccess) {
goto loser; /* err set by ssl3_AppendHandshake* */
......@@ -250,19 +250,6 @@ loser:
return SECFailure;
}
/* This function encodes the key_exchange field in
* the KeyShareEntry structure. */
SECStatus
tls13_EncodeECDHEKeyShareKEX(const sslSocket *ss, const SECKEYPublicKey *pubKey)
{
PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
PORT_Assert(pubKey->keyType == ecKey);
return ssl3_ExtAppendHandshake(ss, pubKey->u.ec.publicValue.data,
pubKey->u.ec.publicValue.len);
}
/*
** Called from ssl3_HandleClientKeyExchange()
*/
......@@ -731,7 +718,7 @@ ssl3_SendECDHServerKeyExchange(sslSocket *ss)
1 + pubKey->u.ec.publicValue.len +
(isTLS12 ? 2 : 0) + 2 + signed_hash.len;
rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length);
rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_server_key_exchange, length);
if (rv != SECSuccess) {
goto loser; /* err set by AppendHandshake. */
}
......@@ -870,20 +857,15 @@ ssl_IsDHEEnabled(const sslSocket *ss)
}
/* Send our Supported Groups extension. */
PRInt32
ssl_SendSupportedGroupsXtn(const sslSocket *ss,
TLSExtensionData *xtnData,
PRBool append, PRUint32 maxBytes)
SECStatus
ssl_SendSupportedGroupsXtn(const sslSocket *ss, TLSExtensionData *xtnData,
sslBuffer *buf, PRBool *added)
{
PRInt32 extension_length;
unsigned char enabledGroups[64];
unsigned int enabledGroupsLen = 0;
unsigned int i;
PRBool ec;
PRBool ff = PR_FALSE;
if (!ss)
return 0;
SECStatus rv;
sslBuffer tmpBuf = { NULL, 0, 0 };
/* We only send FF supported groups if we require DH named groups
* or if TLS 1.3 is a possibility. */
......@@ -892,13 +874,14 @@ ssl_SendSupportedGroupsXtn(const sslSocket *ss,
if (ss->opt.requireDHENamedGroups) {
ff = ssl_IsDHEEnabled(ss);
}
if (!ec && !ff)
return 0;
if (!ec && !ff) {
return SECSuccess;
}
} else {
ec = ff = PR_TRUE;
}
PORT_Assert(sizeof(enabledGroups) > SSL_NAMED_GROUP_COUNT * 2);
/* Reserve space for the length. */
for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) {
const sslNamedGroupDef *group = ss->namedGroupPreferences[i];
if (!group) {
......@@ -911,78 +894,55 @@ ssl_SendSupportedGroupsXtn(const sslSocket *ss,
continue;
}
if (append) {
(void)ssl_EncodeUintX(group->name, 2, &enabledGroups[enabledGroupsLen]);
}
enabledGroupsLen += 2;
}
if (enabledGroupsLen == 0) {
return 0;
}
extension_length =
2 /* extension type */ +
2 /* extension length */ +
2 /* enabled groups length */ +
enabledGroupsLen;
if (maxBytes < (PRUint32)extension_length) {
return 0;
}
if (append) {
SECStatus rv;
rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_supported_groups_xtn, 2);
if (rv != SECSuccess)
return -1;
rv = ssl3_ExtAppendHandshakeNumber(ss, extension_length - 4, 2);
if (rv != SECSuccess)
return -1;
rv = ssl3_ExtAppendHandshakeVariable(ss, enabledGroups,
enabledGroupsLen, 2);
if (rv != SECSuccess)
return -1;
if (!ss->sec.isServer) {
xtnData->advertised[xtnData->numAdvertised++] =
ssl_supported_groups_xtn;
rv = sslBuffer_AppendNumber(&tmpBuf, group->name, 2);
if (rv != SECSuccess) {
sslBuffer_Clear(&tmpBuf);
return SECFailure;
}
}
return extension_length;
if (!tmpBuf.len) {
sslBuffer_Clear(&tmpBuf);
/* We added nothing, don't send the extension. */
return SECSuccess;
}
rv = sslBuffer_AppendBufferVariable(buf, &tmpBuf, 2);
sslBuffer_Clear(&tmpBuf);
if (rv != SECSuccess) {
return SECFailure;
}
*added = PR_TRUE;
return SECSuccess;
}
/* Send our "canned" (precompiled) Supported Point Formats extension,
* which says that we only support uncompressed points.
*/
PRInt32
ssl3_SendSupportedPointFormatsXtn(
const sslSocket *ss,
TLSExtensionData *xtnData,
PRBool append,
PRUint32 maxBytes)
SECStatus
ssl3_SendSupportedPointFormatsXtn(const sslSocket *ss, TLSExtensionData *xtnData,
sslBuffer *buf, PRBool *added)
{
static const PRUint8 ecPtFmt[6] = {
0, 11, /* Extension type */
0, 2, /* octets that follow */
1, /* octets that follow */
0 /* uncompressed type only */
};
SECStatus rv;
/* No point in doing this unless we have a socket that supports ECC.
* Similarly, no point if we are going to do TLS 1.3 only or we have already
* picked TLS 1.3 (server) given that it doesn't use point formats. */
if (!ss || !ssl_IsECCEnabled(ss) ||
ss->vrange.min >= SSL_LIBRARY_VERSION_TLS_1_3 ||
(ss->sec.isServer && ss->version >= SSL_LIBRARY_VERSION_TLS_1_3))
return 0;
if (append && maxBytes >= (sizeof ecPtFmt)) {
SECStatus rv = ssl3_ExtAppendHandshake(ss, ecPtFmt, (sizeof ecPtFmt));
if (rv != SECSuccess)
return -1;
if (!ss->sec.isServer) {
xtnData->advertised[xtnData->numAdvertised++] =
ssl_ec_point_formats_xtn;
}
(ss->sec.isServer && ss->version >= SSL_LIBRARY_VERSION_TLS_1_3)) {
return SECSuccess;
}
return sizeof(ecPtFmt);
rv = sslBuffer_AppendNumber(buf, 1, 1); /* length */
if (rv != SECSuccess) {
return SECFailure;
}
rv = sslBuffer_AppendNumber(buf, 0, 1); /* uncompressed type only */
if (rv != SECSuccess) {
return SECFailure;
}
*added = PR_TRUE;
return SECSuccess;
}
This diff is collapsed.
......@@ -9,44 +9,31 @@
#ifndef __ssl3ext_h_
#define __ssl3ext_h_
#include "sslencode.h"
typedef enum {
sni_nametype_hostname
} SNINameType;
typedef struct TLSExtensionDataStr TLSExtensionData;
/* registerable callback function that either appends extension to buffer
/* Registerable callback function that either appends extension to buffer
* or returns length of data that it would have appended.
*/
typedef PRInt32 (*ssl3HelloExtensionSenderFunc)(const sslSocket *ss,
TLSExtensionData *xtnData,
PRBool append,
PRUint32 maxBytes);
/* registerable callback function that handles a received extension,
* of the given type.
*/
typedef SECStatus (*ssl3ExtensionHandlerFunc)(const sslSocket *ss,
TLSExtensionData *xtnData,
PRUint16 ex_type,
SECItem *data);
typedef SECStatus (*sslExtensionBuilderFunc)(const sslSocket *ss,
TLSExtensionData *xtnData,
sslBuffer *buf, PRBool *added);
/* row in a table of hello extension senders */
typedef struct {
PRInt32 ex_type;
ssl3HelloExtensionSenderFunc ex_sender;
} ssl3HelloExtensionSender;
/* row in a table of hello extension handlers */
typedef struct {
PRInt32 ex_type;
ssl3ExtensionHandlerFunc ex_handler;
} ssl3ExtensionHandler;
sslExtensionBuilderFunc ex_sender;
} sslExtensionBuilder;
struct TLSExtensionDataStr {
/* registered callbacks that send server hello extensions */
ssl3HelloExtensionSender serverHelloSenders[SSL_MAX_EXTENSIONS];
ssl3HelloExtensionSender encryptedExtensionsSenders[SSL_MAX_EXTENSIONS];
ssl3HelloExtensionSender certificateSenders[SSL_MAX_EXTENSIONS];
sslExtensionBuilder serverHelloSenders[SSL_MAX_EXTENSIONS];
sslExtensionBuilder encryptedExtensionsSenders[SSL_MAX_EXTENSIONS];
sslExtensionBuilder certificateSenders[SSL_MAX_EXTENSIONS];
/* Keep track of the extensions that are negotiated. */
PRUint16 numAdvertised;
......@@ -54,9 +41,6 @@ struct TLSExtensionDataStr {
PRUint16 advertised[SSL_MAX_EXTENSIONS];
PRUint16 negotiated[SSL_MAX_EXTENSIONS];
/* Amount of padding we need to add. */
PRUint16 paddingLen;
/* SessionTicket Extension related data. */
PRBool ticketTimestampVerified;
PRBool emptySessionTicket;
......@@ -102,9 +86,10 @@ struct TLSExtensionDataStr {
PRUint16 dtlsSRTPCipherSuite; /* 0 if not selected */
SECItem pskBinder; /* The PSK binder for the first PSK (TLS 1.3) */
unsigned long pskBinderPrefixLen; /* The length of the binder input. */
PRCList remoteKeyShares; /* The other side's public keys (TLS 1.3) */
unsigned int paddingOffset; /* Where to insert padding. 0 = end. */
SECItem pskBinder; /* The PSK binder for the first PSK (TLS 1.3) */
unsigned int pskBinderPrefixLen; /* The length of the binder input. */
PRCList remoteKeyShares; /* The other side's public keys (TLS 1.3) */
};
typedef struct TLSExtensionStr {
......@@ -115,11 +100,11 @@ typedef struct TLSExtensionStr {
SECStatus ssl3_HandleExtensions(sslSocket *ss,
PRUint8 **b, PRUint32 *length,
SSL3HandshakeType handshakeMessage);
SSLHandshakeType handshakeMessage);
SECStatus ssl3_ParseExtensions(sslSocket *ss,
PRUint8 **b, PRUint32 *length);
SECStatus ssl3_HandleParsedExtensions(sslSocket *ss,
SSL3HandshakeType handshakeMessage);
SSLHandshakeType handshakeMessage);
TLSExtension *ssl3_FindExtension(sslSocket *ss,
SSLExtensionType extension_type);
void ssl3_DestroyRemoteExtensions(PRCList *list);
......@@ -132,21 +117,15 @@ PRBool ssl3_ClientExtensionAdvertised(const sslSocket *ss, PRUint16 ex_type);
SECStatus ssl3_RegisterExtensionSender(const sslSocket *ss,
TLSExtensionData *xtnData,
PRUint16 ex_type,
ssl3HelloExtensionSenderFunc cb);
PRInt32 ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes,
const ssl3HelloExtensionSender *sender);
void ssl3_CalculatePaddingExtLen(sslSocket *ss,
unsigned int clientHelloLength);
sslExtensionBuilderFunc cb);
SECStatus ssl_ConstructExtensions(sslSocket *ss, sslBuffer *buf,
SSLHandshakeType message);
SECStatus ssl_SendEmptyExtension(const sslSocket *ss, TLSExtensionData *xtnData,
sslBuffer *buf, PRBool *append);
SECStatus ssl_InsertPaddingExtension(const sslSocket *ss, unsigned int prefixLen,
sslBuffer *buf);
/* Thunks to let us operate on const sslSocket* objects. */
SECStatus ssl3_ExtAppendHandshake(const sslSocket *ss, const void *void_src,
PRInt32 bytes);
SECStatus ssl3_ExtAppendHandshakeNumber(const sslSocket *ss, PRInt32 num,
PRInt32 lenSize);
SECStatus ssl3_ExtAppendHandshakeVariable(const sslSocket *ss,
const PRUint8 *src, PRInt32 bytes,
PRInt32 lenSize);
void ssl3_ExtSendAlert(const sslSocket *ss, SSL3AlertLevel level,
SSL3AlertDescription desc);
void ssl3_ExtDecodeError(const sslSocket *ss);
......
This diff is collapsed.
This diff is collapsed.
......@@ -98,7 +98,7 @@ ssl3_GatherData(sslSocket *ss, sslGather *gs, int flags, ssl2Gather *ssl2gs)
PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
if (gs->state == GS_INIT) {
gs->state = GS_HEADER;
gs->remainder = ss->ssl3.hs.shortHeaders ? 2 : 5;
gs->remainder = 5;
gs->offset = 0;
gs->writeOffset = 0;
gs->readOffset = 0;
......@@ -156,19 +156,7 @@ ssl3_GatherData(sslSocket *ss, sslGather *gs, int flags, ssl2Gather *ssl2gs)
/* Should have a non-SSLv2 record header in gs->hdr. Extract
* the length of the following encrypted data, and then
* read in the rest of the record into gs->inbuf. */
if (ss->ssl3.hs.shortHeaders) {
PRUint16 len = (gs->hdr[0] << 8) | gs->hdr[1];
if (!(len & 0x8000)) {
SSL_DBG(("%d: SSL3[%d]: incorrectly formatted header"));
SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
gs->state = GS_INIT;
PORT_SetError(SSL_ERROR_BAD_MAC_READ);
return SECFailure;
}
gs->remainder = len & ~0x8000;
} else {
gs->remainder = (gs->hdr[3] << 8) | gs->hdr[4];
}
gs->remainder = (gs->hdr[3] << 8) | gs->hdr[4];
} else {
/* Probably an SSLv2 record header. No need to handle any
* security escapes (gs->hdr[0] & 0x40) as we wouldn't get
......@@ -493,13 +481,8 @@ ssl3_GatherCompleteHandshake(sslSocket *ss, int flags)
* If it's a change cipher spec, alert, or handshake message,
* ss->gs.buf.len will be 0 when ssl3_HandleRecord returns SECSuccess.
*/
if (ss->ssl3.hs.shortHeaders) {
cText.type = content_application_data;
cText.version = SSL_LIBRARY_VERSION_TLS_1_0;
} else {
cText.type = (SSL3ContentType)ss->gs.hdr[0];
cText.version = (ss->gs.hdr[1] << 8) | ss->gs.hdr[2];
}
cText.type = (SSL3ContentType)ss->gs.hdr[0];
cText.version = (ss->gs.hdr[1] << 8) | ss->gs.hdr[2];
if (IS_DTLS(ss)) {
sslSequenceNumber seq_num;
......
......@@ -30,7 +30,6 @@ typedef PRUint16 ssl3CipherSuite;
#define SSL3_RANDOM_LENGTH 32
#define SSL3_RECORD_HEADER_LENGTH 5
#define TLS13_RECORD_HEADER_LENGTH_SHORT 2
/* SSL3_RECORD_HEADER_LENGTH + epoch/sequence_number */
#define DTLS_RECORD_HEADER_LENGTH 13
......@@ -126,26 +125,6 @@ typedef struct {
SSL3AlertDescription description;
} SSL3Alert;
typedef enum {
hello_request = 0,
client_hello = 1,
server_hello = 2,
hello_verify_request = 3,
new_session_ticket = 4,
end_of_early_data = 5,
hello_retry_request = 6,
encrypted_extensions = 8,
certificate = 11,
server_key_exchange = 12,
certificate_request = 13,
server_hello_done = 14,
certificate_verify = 15,
client_key_exchange = 16,
finished = 20,
certificate_status = 22,
next_proto = 67,
} SSL3HandshakeType;
typedef struct {
PRUint8 empty;
} SSL3HelloRequest;
......@@ -235,7 +214,7 @@ typedef struct {
union {
PRUint8 raw[64];
SSL3HashesIndividually s;
SECItem pointer_to_hash_input;
unsigned int transcriptLen;
} u;
} SSL3Hashes;
......
......@@ -6,10 +6,108 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nss.h"
#include "prnetdb.h"
#include "seccomon.h"
#include "secerr.h"
#include "ssl3encode.h"
#include "ssl.h"
#include "sslimpl.h"
/* Helper function to encode an unsigned integer into a buffer. */
PRUint8 *
ssl_EncodeUintX(PRUint64 value, unsigned int bytes, PRUint8 *to)
{
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;
}
/* Grow a buffer to hold newLen bytes of data. When used for recv/xmit buffers,
* the caller must hold xmitBufLock or recvBufLock, as appropriate. */
SECStatus
sslBuffer_Grow(sslBuffer *b, unsigned int newLen)
{
newLen = PR_MAX(newLen, b->len + 1024);
if (newLen > b->space) {
unsigned char *newBuf;
if (b->buf) {
newBuf = (unsigned char *)PORT_Realloc(b->buf, newLen);
} else {
newBuf = (unsigned char *)PORT_Alloc(newLen);
}
if (!newBuf) {
return SECFailure;
}
b->buf = newBuf;
b->space = newLen;
}
return SECSuccess;
}
SECStatus
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. */
}
PORT_Memcpy(b->buf + b->len, data, len);
b->len += len;
return SECSuccess;
}
SECStatus
sslBuffer_AppendNumber(sslBuffer *b, PRUint64 v, unsigned int size)
{
SECStatus rv = sslBuffer_Grow(b, b->len + size);
if (rv != SECSuccess) {
return rv;
}
(void)ssl_EncodeUintX(v, size, b->buf + b->len);
b->len += size;
return SECSuccess;
}
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;
}
(void)ssl_EncodeUintX(len, size, b->buf + b->len);
b->len += size;
PORT_Memcpy(b->buf + b->len, data, len);
b->len += len;
return SECSuccess;
}
SECStatus
sslBuffer_AppendBuffer(sslBuffer *b, const sslBuffer *append)
{
return sslBuffer_Append(b, append->buf, append->len);
}
SECStatus
sslBuffer_AppendBufferVariable(sslBuffer *b, const sslBuffer *append,
unsigned int size)
{
return sslBuffer_AppendVariable(b, append->buf, append->len, size);
}
void
sslBuffer_Clear(sslBuffer *b)
{
if (b->buf) {
PORT_Free(b->buf);
b->buf = NULL;
b->len = 0;
b->space = 0;
}
}
SECStatus
ssl3_AppendToItem(SECItem *item, const unsigned char *buf, PRUint32 bytes)
......@@ -29,7 +127,7 @@ SECStatus
ssl3_AppendNumberToItem(SECItem *item, PRUint32 num, PRInt32 lenSize)
{
SECStatus rv;
PRUint8 b[4];
PRUint8 b[sizeof(num)];
ssl_EncodeUintX(num, lenSize, b);
rv = ssl3_AppendToItem(item, &b[0], lenSize);
......@@ -70,16 +168,3 @@ ssl3_ConsumeNumberFromItem(SECItem *item, PRUint32 *num, PRUint32 bytes)
return SECSuccess;
}
/* Helper function to encode an unsigned integer into a buffer. */
PRUint8 *
ssl_EncodeUintX(PRUint64 value, unsigned int bytes, PRUint8 *to)
{
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;
}