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 #define _XOPEN_SOURCE 500
  18 #include <unistd.h>
  19 
  20 #include <errno.h>
  21 #include <s2n.h>
  22 
  23 #include "error/s2n_errno.h"
  24 
  25 #include "tls/s2n_connection.h"
  26 #include "tls/s2n_handshake.h"
  27 #include "tls/s2n_record.h"
  28 #include "tls/s2n_alerts.h"
  29 #include "tls/s2n_tls.h"
  30 
  31 #include "stuffer/s2n_stuffer.h"
  32 
  33 #include "utils/s2n_safety.h"
  34 #include "utils/s2n_blob.h"
  35 
  36 int s2n_read_full_record(struct s2n_connection *conn, uint8_t *record_type, int *isSSLv2)
  37 {
  38     int r;
  39 
  40     *isSSLv2 = 0;
  41 
  42     /* If the record has already been decrypted, then leave it alone */
  43     if (conn->in_status == PLAINTEXT) {
  44         /* Only application data packets count as plaintext */
  45         *record_type = TLS_APPLICATION_DATA;
  46         return 0;
  47     }
  48 
  49     /* Read the record until we at least have a header */
  50     while (s2n_stuffer_data_available(&conn->header_in) < S2N_TLS_RECORD_HEADER_LENGTH) {
  51         r = s2n_stuffer_recv_from_fd(&conn->header_in, conn->readfd, S2N_TLS_RECORD_HEADER_LENGTH - s2n_stuffer_data_available(&conn->header_in));
  52         if (r == 0) {
  53             return -2;
  54         }
  55         if (r < 0) {
  56             return -1;
  57         }
  58         conn->wire_bytes_in += r;
  59     }
  60 
  61     uint16_t fragment_length;
  62 
  63     /* If the first bit is set then this is an SSLv2 record */
  64     if (conn->header_in.blob.data[0] & 0x80) {
  65         conn->header_in.blob.data[0] &= 0x7f;
  66         *isSSLv2 = 1;
  67 
  68         if (s2n_sslv2_record_header_parse(conn, record_type, &conn->client_protocol_version, &fragment_length) < 0) {
  69             conn->closed = 1;
  70             GUARD(s2n_connection_wipe(conn));
  71             return -1;
  72         }
  73     } else {
  74         if (s2n_record_header_parse(conn, record_type, &fragment_length) < 0) {
  75             conn->closed = 1;
  76             GUARD(s2n_connection_wipe(conn));
  77             return -1;
  78         }
  79     }
  80 
  81     /* Read enough to have the whole record */
  82     while (s2n_stuffer_data_available(&conn->in) < fragment_length) {
  83         r = s2n_stuffer_recv_from_fd(&conn->in, conn->readfd, fragment_length - s2n_stuffer_data_available(&conn->in));
  84         if (r == 0) {
  85             return -2;
  86         }
  87         if (r < 0) {
  88             return -1;
  89         }
  90         conn->wire_bytes_in += r;
  91     }
  92 
  93     if (*isSSLv2) {
  94         return 0;
  95     }
  96 
  97     /* Decrypt and parse the record */
  98     if (s2n_record_parse(conn) < 0) {
  99         conn->closed = 1;
 100         GUARD(s2n_connection_wipe(conn));
 101 
 102         if (conn->blinding == S2N_BUILT_IN_BLINDING) {
 103             int delay;
 104             GUARD(delay = s2n_connection_get_delay(conn)); 
 105             GUARD(sleep(delay / 1000000));
 106             GUARD(usleep(delay % 1000000));
 107         }
 108 
 109         return -1;
 110     }
 111 
 112     return 0;
 113 }
 114 
 115 ssize_t s2n_recv(struct s2n_connection *conn, void *buf, ssize_t size, int *more)
 116 {
 117     ssize_t bytes_read = 0;
 118     struct s2n_blob out = {.data = (uint8_t *) buf };
 119 
 120     if (conn->closed) {
 121         return 0;
 122     }
 123 
 124     *more = 1;
 125 
 126     while (size && !conn->closed) {
 127         int isSSLv2 = 0;
 128         uint8_t record_type;
 129         errno = 0;
 130         int r = s2n_read_full_record(conn, &record_type, &isSSLv2);
 131         if (r < 0) {
 132             if (errno == EWOULDBLOCK) {
 133                 if (bytes_read) {
 134                     return bytes_read;
 135                 }
 136                 return -1;
 137             }
 138             if (r == -2) {
 139                 conn->closed = 1;
 140                 GUARD(s2n_connection_wipe(conn));
 141                 return bytes_read;
 142             }
 143             return -1;
 144         }
 145     
 146         if (isSSLv2) {
 147             S2N_ERROR(S2N_ERR_BAD_MESSAGE);
 148         }
 149         
 150         if (record_type != TLS_APPLICATION_DATA) {
 151             if (record_type == TLS_ALERT) {
 152                 GUARD(s2n_process_alert_fragment(conn));
 153                 GUARD(s2n_flush(conn, more));
 154             }
 155 
 156             GUARD(s2n_stuffer_wipe(&conn->header_in));
 157             GUARD(s2n_stuffer_wipe(&conn->in));
 158             conn->in_status = ENCRYPTED;
 159             continue;
 160         }
 161 
 162         out.size = size;
 163         if (out.size > s2n_stuffer_data_available(&conn->in)) {
 164             out.size = s2n_stuffer_data_available(&conn->in);
 165         }
 166 
 167         GUARD(s2n_stuffer_erase_and_read(&conn->in, &out));
 168         bytes_read += out.size;
 169 
 170         out.data += out.size;
 171         size -= out.size;
 172 
 173         /* Are we ready for more encrypted data? */
 174         if (s2n_stuffer_data_available(&conn->in) == 0) {
 175             GUARD(s2n_stuffer_wipe(&conn->header_in));
 176             GUARD(s2n_stuffer_wipe(&conn->in));
 177             conn->in_status = ENCRYPTED;
 178         }
 179 
 180         /* If we've read some data, return it */
 181         if (bytes_read) {
 182             break;
 183         }
 184     }
 185 
 186     if (s2n_stuffer_data_available(&conn->in) == 0) {
 187         *more = 0;
 188     }
 189 
 190     return bytes_read;
 191 }