/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is PRIVATE to SSL.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * 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 "ssl.h"
#include "sslimpl.h"
#include "sslproto.h"

/* Helper function to encode an unsigned integer into a buffer. */
static void
ssl_EncodeUintX(PRUint8 *to, PRUint64 value, unsigned int bytes)
{
    PRUint64 encoded;

    PORT_Assert(bytes > 0 && bytes <= sizeof(encoded));

    encoded = PR_htonll(value);
    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,
 * the caller must hold xmitBufLock or recvBufLock, as appropriate. */
SECStatus
sslBuffer_Grow(sslBuffer *b, unsigned int newLen)
{
    PORT_Assert(b);
    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;
        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 SECFailure; /* Code already set. */
    }
    if (len > 0) {
        PORT_Assert(data);
        PORT_Memcpy(SSL_BUFFER_NEXT(b), 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 SECFailure;
    }
    ssl_EncodeUintX(SSL_BUFFER_NEXT(b), v, size);
    b->len += size;
    return SECSuccess;
}

SECStatus
sslBuffer_AppendVariable(sslBuffer *b, const PRUint8 *data, unsigned int len,
                         unsigned int size)
{
    PORT_Assert(size <= 4 && size > 0);
    PORT_Assert(b);
    if (len >= (1ULL << (8 * size))) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }

    if (sslBuffer_Grow(b, b->len + len + size) != SECSuccess) {
        return SECFailure;
    }

    ssl_EncodeUintX(SSL_BUFFER_NEXT(b), len, size);
    b->len += size;
    if (len != 0) {
        PORT_Assert(data);
        /* We sometimes pass NULL, 0 and memcpy() doesn't want NULL. */
        PORT_Memcpy(SSL_BUFFER_NEXT(b), 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);
}

SECStatus
sslBuffer_Skip(sslBuffer *b, unsigned int size, unsigned int *savedOffset)
{
    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
sslBuffer_InsertLength(sslBuffer *b, unsigned int at, unsigned int size)
{
    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;
    }

    ssl_EncodeUintX(SSL_BUFFER_BASE(b) + at, len, size);
    return SECSuccess;
}

SECStatus
sslBuffer_InsertNumber(sslBuffer *b, unsigned int at,
                       PRUint64 v, unsigned int size)
{
    PORT_Assert(b->len >= at + size);
    PORT_Assert(b->space >= at + size);

    PORT_Assert(size <= 4 && size > 0);
    if (v >= (1ULL << (8 * size))) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }

    ssl_EncodeUintX(SSL_BUFFER_BASE(b) + at, v, size);
    return SECSuccess;
}

void
sslBuffer_Clear(sslBuffer *b)
{
    if (!b->fixed) {
        if (b->buf) {
            PORT_Free(b->buf);
            b->buf = NULL;
        }
        b->space = 0;
    }
    b->len = 0;
}

SECStatus
sslRead_Read(sslReader *reader, unsigned int count, sslReadBuffer *out)
{
    if (!reader || !out) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    if (reader->buf.len < reader->offset ||
        count > SSL_READER_REMAINING(reader)) {
        PORT_SetError(SEC_ERROR_BAD_DATA);
        return SECFailure;
    }

    out->buf = SSL_READER_CURRENT(reader);
    out->len = count;
    reader->offset += count;

    return SECSuccess;
}

SECStatus
sslRead_ReadVariable(sslReader *reader, unsigned int sizeLen, sslReadBuffer *out)
{
    PRUint64 variableLen = 0;
    SECStatus rv = sslRead_ReadNumber(reader, sizeLen, &variableLen);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_BAD_DATA);
        return SECFailure;
    }
    if (!variableLen) {
        // It is ok to have an empty variable.
        out->len = variableLen;
        return SECSuccess;
    }
    return sslRead_Read(reader, variableLen, out);
}

SECStatus
sslRead_ReadNumber(sslReader *reader, unsigned int bytes, PRUint64 *num)
{
    if (!reader || !num) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    if (reader->buf.len < reader->offset ||
        bytes > SSL_READER_REMAINING(reader) ||
        bytes > 8) {
        PORT_SetError(SEC_ERROR_BAD_DATA);
        return SECFailure;
    }
    unsigned int i;
    PRUint64 number = 0;
    for (i = 0; i < bytes; i++) {
        number = (number << 8) + reader->buf.buf[i + reader->offset];
    }

    reader->offset = reader->offset + bytes;
    *num = number;
    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

static SECStatus
ssl3_AppendHandshakeInternal(sslSocket *ss, const void *void_src, unsigned int bytes, PRBool suppressHash)
{
    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));
    // TODO: Move firstHsDone and version check into callers as a suppression.
    if (!suppressHash && (!ss->firstHsDone || ss->version < SSL_LIBRARY_VERSION_TLS_1_3)) {
        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_AppendHandshakeSuppressHash(sslSocket *ss, const void *void_src, unsigned int bytes)
{
    return ssl3_AppendHandshakeInternal(ss, void_src, bytes, PR_TRUE);
}

SECStatus
ssl3_AppendHandshake(sslSocket *ss, const void *void_src, unsigned int bytes)
{
    return ssl3_AppendHandshakeInternal(ss, void_src, bytes, PR_FALSE);
}

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);
}
