1 /*
2 * Copyright 2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License").
5 * You may not use this file except in compliance with the License.
6 * A copy of the License is located at
7 *
8 * http://aws.amazon.com/apache2.0
9 *
10 * or in the "license" file accompanying this file. This file is distributed
11 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 * express or implied. See the License for the specific language governing
13 * permissions and limitations under the License.
14 */
15
16 /* Use usleep */
17 #ifndef __sun
18 #define _XOPEN_SOURCE 500
19 #endif /* __sun doesn't need XOPEN_SOURCE defined for usleep() in unistd.h. */
20 #include <unistd.h>
21
22 #include <errno.h>
23 #include <s2n.h>
24
25 #include "error/s2n_errno.h"
26
27 #include "tls/s2n_connection.h"
28 #include "tls/s2n_handshake.h"
29 #include "tls/s2n_record.h"
30 #include "tls/s2n_alerts.h"
31 #include "tls/s2n_tls.h"
32
33 #include "stuffer/s2n_stuffer.h"
34
35 #include "utils/s2n_safety.h"
36 #include "utils/s2n_blob.h"
37
38 int s2n_read_full_record(struct s2n_connection *conn, uint8_t *record_type, int *isSSLv2)
39 {
40 int r;
41
42 *isSSLv2 = 0;
43
44 /* If the record has already been decrypted, then leave it alone */
45 if (conn->in_status == PLAINTEXT) {
46 /* Only application data packets count as plaintext */
47 *record_type = TLS_APPLICATION_DATA;
48 return 0;
49 }
50
51 /* Read the record until we at least have a header */
52 while (s2n_stuffer_data_available(&conn->header_in) < S2N_TLS_RECORD_HEADER_LENGTH) {
53 r = s2n_stuffer_recv_from_fd(&conn->header_in, conn->readfd, S2N_TLS_RECORD_HEADER_LENGTH - s2n_stuffer_data_available(&conn->header_in));
54 if (r == 0) {
55 return -2;
56 }
57 if (r < 0) {
58 return -1;
59 }
60 conn->wire_bytes_in += r;
61 }
62
63 uint16_t fragment_length;
64
65 /* If the first bit is set then this is an SSLv2 record */
66 if (conn->header_in.blob.data[0] & 0x80) {
67 conn->header_in.blob.data[0] &= 0x7f;
68 *isSSLv2 = 1;
69
70 if (s2n_sslv2_record_header_parse(conn, record_type, &conn->client_protocol_version, &fragment_length) < 0) {
71 conn->closed = 1;
72 GUARD(s2n_connection_wipe(conn));
73 return -1;
74 }
75 } else {
76 if (s2n_record_header_parse(conn, record_type, &fragment_length) < 0) {
77 conn->closed = 1;
78 GUARD(s2n_connection_wipe(conn));
79 return -1;
80 }
81 }
82
83 /* Read enough to have the whole record */
84 while (s2n_stuffer_data_available(&conn->in) < fragment_length) {
85 r = s2n_stuffer_recv_from_fd(&conn->in, conn->readfd, fragment_length - s2n_stuffer_data_available(&conn->in));
86 if (r == 0) {
87 return -2;
88 }
89 if (r < 0) {
90 return -1;
91 }
92 conn->wire_bytes_in += r;
93 }
94
95 if (*isSSLv2) {
96 return 0;
97 }
98
99 /* Decrypt and parse the record */
100 if (s2n_record_parse(conn) < 0) {
101 conn->closed = 1;
102 GUARD(s2n_connection_wipe(conn));
103
104 if (conn->blinding == S2N_BUILT_IN_BLINDING) {
105 int delay;
106 GUARD(delay = s2n_connection_get_delay(conn));
107 GUARD(sleep(delay / 1000000));
108 GUARD(usleep(delay % 1000000));
109 }
110
111 return -1;
112 }
113
114 return 0;
115 }
116
117 ssize_t s2n_recv(struct s2n_connection *conn, void *buf, ssize_t size, int *more)
118 {
119 ssize_t bytes_read = 0;
120 struct s2n_blob out = {.data = (uint8_t *) buf };
121
122 if (conn->closed) {
123 return 0;
124 }
125
126 *more = 1;
127
128 while (size && !conn->closed) {
129 int isSSLv2 = 0;
130 uint8_t record_type;
131 errno = 0;
132 int r = s2n_read_full_record(conn, &record_type, &isSSLv2);
133 if (r < 0) {
134 if (errno == EWOULDBLOCK) {
135 if (bytes_read) {
136 return bytes_read;
137 }
138 return -1;
139 }
140 if (r == -2) {
141 conn->closed = 1;
142 GUARD(s2n_connection_wipe(conn));
143 return bytes_read;
144 }
145 return -1;
146 }
147
148 if (isSSLv2) {
149 S2N_ERROR(S2N_ERR_BAD_MESSAGE);
150 }
151
152 if (record_type != TLS_APPLICATION_DATA) {
153 if (record_type == TLS_ALERT) {
154 GUARD(s2n_process_alert_fragment(conn));
155 GUARD(s2n_flush(conn, more));
156 }
157
158 GUARD(s2n_stuffer_wipe(&conn->header_in));
159 GUARD(s2n_stuffer_wipe(&conn->in));
160 conn->in_status = ENCRYPTED;
161 continue;
162 }
163
164 out.size = size;
165 if (out.size > s2n_stuffer_data_available(&conn->in)) {
166 out.size = s2n_stuffer_data_available(&conn->in);
167 }
168
169 GUARD(s2n_stuffer_erase_and_read(&conn->in, &out));
170 bytes_read += out.size;
171
172 out.data += out.size;
173 size -= out.size;
174
175 /* Are we ready for more encrypted data? */
176 if (s2n_stuffer_data_available(&conn->in) == 0) {
177 GUARD(s2n_stuffer_wipe(&conn->header_in));
178 GUARD(s2n_stuffer_wipe(&conn->in));
179 conn->in_status = ENCRYPTED;
180 }
181
182 /* If we've read some data, return it */
183 if (bytes_read) {
184 break;
185 }
186 }
187
188 if (s2n_stuffer_data_available(&conn->in) == 0) {
189 *more = 0;
190 }
191
192 return bytes_read;
193 }