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