Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/security/nss/lib/ssl/tls13hashstate.c
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is PRIVATE to SSL.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8
9
#include "pk11func.h"
10
#include "ssl.h"
11
#include "sslt.h"
12
#include "sslimpl.h"
13
#include "selfencrypt.h"
14
#include "tls13con.h"
15
#include "tls13err.h"
16
#include "tls13hashstate.h"
17
18
/*
19
 * The cookie is structured as a self-encrypted structure with the
20
 * inner value being.
21
 *
22
 * struct {
23
 *     uint8 indicator = 0xff;            // To disambiguate from tickets.
24
 *     uint16 cipherSuite;                // Selected cipher suite.
25
 *     uint16 keyShare;                   // Requested key share group (0=none)
26
 *     opaque applicationToken<0..65535>; // Application token
27
 *     opaque ch_hash[rest_of_buffer];    // H(ClientHello)
28
 * } CookieInner;
29
 */
30
SECStatus
31
tls13_MakeHrrCookie(sslSocket *ss, const sslNamedGroupDef *selectedGroup,
32
                    const PRUint8 *appToken, unsigned int appTokenLen,
33
                    PRUint8 *buf, unsigned int *len, unsigned int maxlen)
34
0
{
35
0
    SECStatus rv;
36
0
    SSL3Hashes hashes;
37
0
    PRUint8 cookie[1024];
38
0
    sslBuffer cookieBuf = SSL_BUFFER(cookie);
39
0
    static const PRUint8 indicator = 0xff;
40
0
41
0
    /* Encode header. */
42
0
    rv = sslBuffer_Append(&cookieBuf, &indicator, 1);
43
0
    if (rv != SECSuccess) {
44
0
        return SECFailure;
45
0
    }
46
0
    rv = sslBuffer_AppendNumber(&cookieBuf, ss->ssl3.hs.cipher_suite, 2);
47
0
    if (rv != SECSuccess) {
48
0
        return SECFailure;
49
0
    }
50
0
    rv = sslBuffer_AppendNumber(&cookieBuf,
51
0
                                selectedGroup ? selectedGroup->name : 0, 2);
52
0
    if (rv != SECSuccess) {
53
0
        return SECFailure;
54
0
    }
55
0
56
0
    /* Application token. */
57
0
    rv = sslBuffer_AppendVariable(&cookieBuf, appToken, appTokenLen, 2);
58
0
    if (rv != SECSuccess) {
59
0
        return SECFailure;
60
0
    }
61
0
62
0
    /* Compute and encode hashes. */
63
0
    rv = tls13_ComputeHandshakeHashes(ss, &hashes);
64
0
    if (rv != SECSuccess) {
65
0
        return SECFailure;
66
0
    }
67
0
    rv = sslBuffer_Append(&cookieBuf, hashes.u.raw, hashes.len);
68
0
    if (rv != SECSuccess) {
69
0
        return SECFailure;
70
0
    }
71
0
72
0
    /* Encrypt right into the buffer. */
73
0
    rv = ssl_SelfEncryptProtect(ss, cookieBuf.buf, cookieBuf.len,
74
0
                                buf, len, maxlen);
75
0
    if (rv != SECSuccess) {
76
0
        return SECFailure;
77
0
    }
78
0
79
0
    return SECSuccess;
80
0
}
81
82
/* Recover the hash state from the cookie. */
83
SECStatus
84
tls13_RecoverHashState(sslSocket *ss,
85
                       unsigned char *cookie, unsigned int cookieLen,
86
                       ssl3CipherSuite *previousCipherSuite,
87
                       const sslNamedGroupDef **previousGroup)
88
0
{
89
0
    SECStatus rv;
90
0
    unsigned char plaintext[1024];
91
0
    unsigned int plaintextLen = 0;
92
0
    sslBuffer messageBuf = SSL_BUFFER_EMPTY;
93
0
    PRUint64 sentinel;
94
0
    PRUint64 cipherSuite;
95
0
    PRUint64 group;
96
0
    const sslNamedGroupDef *selectedGroup;
97
0
    PRUint64 appTokenLen;
98
0
99
0
    rv = ssl_SelfEncryptUnprotect(ss, cookie, cookieLen,
100
0
                                  plaintext, &plaintextLen, sizeof(plaintext));
101
0
    if (rv != SECSuccess) {
102
0
        return SECFailure;
103
0
    }
104
0
105
0
    sslReader reader = SSL_READER(plaintext, plaintextLen);
106
0
107
0
    /* Should start with 0xff. */
108
0
    rv = sslRead_ReadNumber(&reader, 1, &sentinel);
109
0
    if ((rv != SECSuccess) || (sentinel != 0xff)) {
110
0
        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter);
111
0
        return SECFailure;
112
0
    }
113
0
    /* The cipher suite should be the same or there are some shenanigans. */
114
0
    rv = sslRead_ReadNumber(&reader, 2, &cipherSuite);
115
0
    if (rv != SECSuccess) {
116
0
        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter);
117
0
        return SECFailure;
118
0
    }
119
0
120
0
    /* The named group, if any. */
121
0
    rv = sslRead_ReadNumber(&reader, 2, &group);
122
0
    if (rv != SECSuccess) {
123
0
        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter);
124
0
        return SECFailure;
125
0
    }
126
0
    selectedGroup = ssl_LookupNamedGroup(group);
127
0
128
0
    /* Application token. */
129
0
    PORT_Assert(ss->xtnData.applicationToken.len == 0);
130
0
    rv = sslRead_ReadNumber(&reader, 2, &appTokenLen);
131
0
    if (rv != SECSuccess) {
132
0
        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter);
133
0
        return SECFailure;
134
0
    }
135
0
    if (SECITEM_AllocItem(NULL, &ss->xtnData.applicationToken,
136
0
                          appTokenLen) == NULL) {
137
0
        FATAL_ERROR(ss, PORT_GetError(), internal_error);
138
0
        return SECFailure;
139
0
    }
140
0
    ss->xtnData.applicationToken.len = appTokenLen;
141
0
    sslReadBuffer appTokenReader = { 0 };
142
0
    rv = sslRead_Read(&reader, appTokenLen, &appTokenReader);
143
0
    if (rv != SECSuccess) {
144
0
        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter);
145
0
        return SECFailure;
146
0
    }
147
0
    PORT_Assert(appTokenReader.len == appTokenLen);
148
0
    PORT_Memcpy(ss->xtnData.applicationToken.data, appTokenReader.buf, appTokenLen);
149
0
150
0
    /* The remainder is the hash. */
151
0
    unsigned int hashLen = SSL_READER_REMAINING(&reader);
152
0
    if (hashLen != tls13_GetHashSize(ss)) {
153
0
        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter);
154
0
        return SECFailure;
155
0
    }
156
0
157
0
    /* Now reinject the message. */
158
0
    SSL_ASSERT_HASHES_EMPTY(ss);
159
0
    rv = ssl_HashHandshakeMessageInt(ss, ssl_hs_message_hash, 0,
160
0
                                     SSL_READER_CURRENT(&reader), hashLen);
161
0
    if (rv != SECSuccess) {
162
0
        return SECFailure;
163
0
    }
164
0
165
0
    /* And finally reinject the HRR. */
166
0
    rv = tls13_ConstructHelloRetryRequest(ss, cipherSuite,
167
0
                                          selectedGroup,
168
0
                                          cookie, cookieLen,
169
0
                                          &messageBuf);
170
0
    if (rv != SECSuccess) {
171
0
        return SECFailure;
172
0
    }
173
0
174
0
    rv = ssl_HashHandshakeMessageInt(ss, ssl_hs_server_hello, 0,
175
0
                                     SSL_BUFFER_BASE(&messageBuf),
176
0
                                     SSL_BUFFER_LEN(&messageBuf));
177
0
    sslBuffer_Clear(&messageBuf);
178
0
    if (rv != SECSuccess) {
179
0
        return SECFailure;
180
0
    }
181
0
182
0
    *previousCipherSuite = cipherSuite;
183
0
    *previousGroup = selectedGroup;
184
0
    return SECSuccess;
185
0
}