tlsv1_client_read.c

Go to the documentation of this file.
00001 
00016 #include "includes.h"
00017 
00018 #include "common.h"
00019 #include "md5.h"
00020 #include "sha1.h"
00021 #include "x509v3.h"
00022 #include "tls.h"
00023 #include "tlsv1_common.h"
00024 #include "tlsv1_record.h"
00025 #include "tlsv1_client.h"
00026 #include "tlsv1_client_i.h"
00027 
00028 static int tls_process_server_key_exchange(struct tlsv1_client *conn, u8 ct,
00029                                            const u8 *in_data, size_t *in_len);
00030 static int tls_process_certificate_request(struct tlsv1_client *conn, u8 ct,
00031                                            const u8 *in_data, size_t *in_len);
00032 static int tls_process_server_hello_done(struct tlsv1_client *conn, u8 ct,
00033                                          const u8 *in_data, size_t *in_len);
00034 
00035 
00036 static int tls_process_server_hello(struct tlsv1_client *conn, u8 ct,
00037                                     const u8 *in_data, size_t *in_len)
00038 {
00039         const u8 *pos, *end;
00040         size_t left, len, i;
00041         u16 cipher_suite;
00042 
00043         if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
00044                 wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
00045                            "received content type 0x%x", ct);
00046                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00047                           TLS_ALERT_UNEXPECTED_MESSAGE);
00048                 return -1;
00049         }
00050 
00051         pos = in_data;
00052         left = *in_len;
00053 
00054         if (left < 4)
00055                 goto decode_error;
00056 
00057         /* HandshakeType msg_type */
00058         if (*pos != TLS_HANDSHAKE_TYPE_SERVER_HELLO) {
00059                 wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
00060                            "message %d (expected ServerHello)", *pos);
00061                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00062                           TLS_ALERT_UNEXPECTED_MESSAGE);
00063                 return -1;
00064         }
00065         wpa_printf(MSG_DEBUG, "TLSv1: Received ServerHello");
00066         pos++;
00067         /* uint24 length */
00068         len = WPA_GET_BE24(pos);
00069         pos += 3;
00070         left -= 4;
00071 
00072         if (len > left)
00073                 goto decode_error;
00074 
00075         /* body - ServerHello */
00076 
00077         wpa_hexdump(MSG_MSGDUMP, "TLSv1: ServerHello", pos, len);
00078         end = pos + len;
00079 
00080         /* ProtocolVersion server_version */
00081         if (end - pos < 2)
00082                 goto decode_error;
00083         if (WPA_GET_BE16(pos) != TLS_VERSION) {
00084                 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected protocol version in "
00085                            "ServerHello");
00086                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00087                           TLS_ALERT_PROTOCOL_VERSION);
00088                 return -1;
00089         }
00090         pos += 2;
00091 
00092         /* Random random */
00093         if (end - pos < TLS_RANDOM_LEN)
00094                 goto decode_error;
00095 
00096         os_memcpy(conn->server_random, pos, TLS_RANDOM_LEN);
00097         pos += TLS_RANDOM_LEN;
00098         wpa_hexdump(MSG_MSGDUMP, "TLSv1: server_random",
00099                     conn->server_random, TLS_RANDOM_LEN);
00100 
00101         /* SessionID session_id */
00102         if (end - pos < 1)
00103                 goto decode_error;
00104         if (end - pos < 1 + *pos || *pos > TLS_SESSION_ID_MAX_LEN)
00105                 goto decode_error;
00106         if (conn->session_id_len && conn->session_id_len == *pos &&
00107             os_memcmp(conn->session_id, pos + 1, conn->session_id_len) == 0) {
00108                 pos += 1 + conn->session_id_len;
00109                 wpa_printf(MSG_DEBUG, "TLSv1: Resuming old session");
00110                 conn->session_resumed = 1;
00111         } else {
00112                 conn->session_id_len = *pos;
00113                 pos++;
00114                 os_memcpy(conn->session_id, pos, conn->session_id_len);
00115                 pos += conn->session_id_len;
00116         }
00117         wpa_hexdump(MSG_MSGDUMP, "TLSv1: session_id",
00118                     conn->session_id, conn->session_id_len);
00119 
00120         /* CipherSuite cipher_suite */
00121         if (end - pos < 2)
00122                 goto decode_error;
00123         cipher_suite = WPA_GET_BE16(pos);
00124         pos += 2;
00125         for (i = 0; i < conn->num_cipher_suites; i++) {
00126                 if (cipher_suite == conn->cipher_suites[i])
00127                         break;
00128         }
00129         if (i == conn->num_cipher_suites) {
00130                 wpa_printf(MSG_INFO, "TLSv1: Server selected unexpected "
00131                            "cipher suite 0x%04x", cipher_suite);
00132                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00133                           TLS_ALERT_ILLEGAL_PARAMETER);
00134                 return -1;
00135         }
00136 
00137         if (conn->session_resumed && cipher_suite != conn->prev_cipher_suite) {
00138                 wpa_printf(MSG_DEBUG, "TLSv1: Server selected a different "
00139                            "cipher suite for a resumed connection (0x%04x != "
00140                            "0x%04x)", cipher_suite, conn->prev_cipher_suite);
00141                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00142                           TLS_ALERT_ILLEGAL_PARAMETER);
00143                 return -1;
00144         }
00145 
00146         if (tlsv1_record_set_cipher_suite(&conn->rl, cipher_suite) < 0) {
00147                 wpa_printf(MSG_DEBUG, "TLSv1: Failed to set CipherSuite for "
00148                            "record layer");
00149                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00150                           TLS_ALERT_INTERNAL_ERROR);
00151                 return -1;
00152         }
00153 
00154         conn->prev_cipher_suite = cipher_suite;
00155 
00156         /* CompressionMethod compression_method */
00157         if (end - pos < 1)
00158                 goto decode_error;
00159         if (*pos != TLS_COMPRESSION_NULL) {
00160                 wpa_printf(MSG_INFO, "TLSv1: Server selected unexpected "
00161                            "compression 0x%02x", *pos);
00162                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00163                           TLS_ALERT_ILLEGAL_PARAMETER);
00164                 return -1;
00165         }
00166         pos++;
00167 
00168         if (end != pos) {
00169                 /* TODO: ServerHello extensions */
00170                 wpa_hexdump(MSG_DEBUG, "TLSv1: Unexpected extra data in the "
00171                             "end of ServerHello", pos, end - pos);
00172                 goto decode_error;
00173         }
00174 
00175         if (conn->session_ticket_included && conn->session_ticket_cb) {
00176                 /* TODO: include SessionTicket extension if one was included in
00177                  * ServerHello */
00178                 int res = conn->session_ticket_cb(
00179                         conn->session_ticket_cb_ctx, NULL, 0,
00180                         conn->client_random, conn->server_random,
00181                         conn->master_secret);
00182                 if (res < 0) {
00183                         wpa_printf(MSG_DEBUG, "TLSv1: SessionTicket callback "
00184                                    "indicated failure");
00185                         tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00186                                   TLS_ALERT_HANDSHAKE_FAILURE);
00187                         return -1;
00188                 }
00189                 conn->use_session_ticket = !!res;
00190         }
00191 
00192         if ((conn->session_resumed || conn->use_session_ticket) &&
00193             tls_derive_keys(conn, NULL, 0)) {
00194                 wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive keys");
00195                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00196                           TLS_ALERT_INTERNAL_ERROR);
00197                 return -1;
00198         }
00199 
00200         *in_len = end - in_data;
00201 
00202         conn->state = (conn->session_resumed || conn->use_session_ticket) ?
00203                 SERVER_CHANGE_CIPHER_SPEC : SERVER_CERTIFICATE;
00204 
00205         return 0;
00206 
00207 decode_error:
00208         wpa_printf(MSG_DEBUG, "TLSv1: Failed to decode ServerHello");
00209         tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
00210         return -1;
00211 }
00212 
00213 
00214 static int tls_process_certificate(struct tlsv1_client *conn, u8 ct,
00215                                    const u8 *in_data, size_t *in_len)
00216 {
00217         const u8 *pos, *end;
00218         size_t left, len, list_len, cert_len, idx;
00219         u8 type;
00220         struct x509_certificate *chain = NULL, *last = NULL, *cert;
00221         int reason;
00222 
00223         if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
00224                 wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
00225                            "received content type 0x%x", ct);
00226                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00227                           TLS_ALERT_UNEXPECTED_MESSAGE);
00228                 return -1;
00229         }
00230 
00231         pos = in_data;
00232         left = *in_len;
00233 
00234         if (left < 4) {
00235                 wpa_printf(MSG_DEBUG, "TLSv1: Too short Certificate message "
00236                            "(len=%lu)", (unsigned long) left);
00237                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
00238                 return -1;
00239         }
00240 
00241         type = *pos++;
00242         len = WPA_GET_BE24(pos);
00243         pos += 3;
00244         left -= 4;
00245 
00246         if (len > left) {
00247                 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected Certificate message "
00248                            "length (len=%lu != left=%lu)",
00249                            (unsigned long) len, (unsigned long) left);
00250                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
00251                 return -1;
00252         }
00253 
00254         if (type == TLS_HANDSHAKE_TYPE_SERVER_KEY_EXCHANGE)
00255                 return tls_process_server_key_exchange(conn, ct, in_data,
00256                                                        in_len);
00257         if (type == TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST)
00258                 return tls_process_certificate_request(conn, ct, in_data,
00259                                                        in_len);
00260         if (type == TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE)
00261                 return tls_process_server_hello_done(conn, ct, in_data,
00262                                                      in_len);
00263         if (type != TLS_HANDSHAKE_TYPE_CERTIFICATE) {
00264                 wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
00265                            "message %d (expected Certificate/"
00266                            "ServerKeyExchange/CertificateRequest/"
00267                            "ServerHelloDone)", type);
00268                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00269                           TLS_ALERT_UNEXPECTED_MESSAGE);
00270                 return -1;
00271         }
00272 
00273         wpa_printf(MSG_DEBUG,
00274                    "TLSv1: Received Certificate (certificate_list len %lu)",
00275                    (unsigned long) len);
00276 
00277         /*
00278          * opaque ASN.1Cert<2^24-1>;
00279          *
00280          * struct {
00281          *     ASN.1Cert certificate_list<1..2^24-1>;
00282          * } Certificate;
00283          */
00284 
00285         end = pos + len;
00286 
00287         if (end - pos < 3) {
00288                 wpa_printf(MSG_DEBUG, "TLSv1: Too short Certificate "
00289                            "(left=%lu)", (unsigned long) left);
00290                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
00291                 return -1;
00292         }
00293 
00294         list_len = WPA_GET_BE24(pos);
00295         pos += 3;
00296 
00297         if ((size_t) (end - pos) != list_len) {
00298                 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected certificate_list "
00299                            "length (len=%lu left=%lu)",
00300                            (unsigned long) list_len,
00301                            (unsigned long) (end - pos));
00302                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
00303                 return -1;
00304         }
00305 
00306         idx = 0;
00307         while (pos < end) {
00308                 if (end - pos < 3) {
00309                         wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse "
00310                                    "certificate_list");
00311                         tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00312                                   TLS_ALERT_DECODE_ERROR);
00313                         x509_certificate_chain_free(chain);
00314                         return -1;
00315                 }
00316 
00317                 cert_len = WPA_GET_BE24(pos);
00318                 pos += 3;
00319 
00320                 if ((size_t) (end - pos) < cert_len) {
00321                         wpa_printf(MSG_DEBUG, "TLSv1: Unexpected certificate "
00322                                    "length (len=%lu left=%lu)",
00323                                    (unsigned long) cert_len,
00324                                    (unsigned long) (end - pos));
00325                         tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00326                                   TLS_ALERT_DECODE_ERROR);
00327                         x509_certificate_chain_free(chain);
00328                         return -1;
00329                 }
00330 
00331                 wpa_printf(MSG_DEBUG, "TLSv1: Certificate %lu (len %lu)",
00332                            (unsigned long) idx, (unsigned long) cert_len);
00333 
00334                 if (idx == 0) {
00335                         crypto_public_key_free(conn->server_rsa_key);
00336                         if (tls_parse_cert(pos, cert_len,
00337                                            &conn->server_rsa_key)) {
00338                                 wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse "
00339                                            "the certificate");
00340                                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00341                                           TLS_ALERT_BAD_CERTIFICATE);
00342                                 x509_certificate_chain_free(chain);
00343                                 return -1;
00344                         }
00345                 }
00346 
00347                 cert = x509_certificate_parse(pos, cert_len);
00348                 if (cert == NULL) {
00349                         wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse "
00350                                    "the certificate");
00351                         tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00352                                   TLS_ALERT_BAD_CERTIFICATE);
00353                         x509_certificate_chain_free(chain);
00354                         return -1;
00355                 }
00356 
00357                 if (last == NULL)
00358                         chain = cert;
00359                 else
00360                         last->next = cert;
00361                 last = cert;
00362 
00363                 idx++;
00364                 pos += cert_len;
00365         }
00366 
00367         if (conn->cred &&
00368             x509_certificate_chain_validate(conn->cred->trusted_certs, chain,
00369                                             &reason) < 0) {
00370                 int tls_reason;
00371                 wpa_printf(MSG_DEBUG, "TLSv1: Server certificate chain "
00372                            "validation failed (reason=%d)", reason);
00373                 switch (reason) {
00374                 case X509_VALIDATE_BAD_CERTIFICATE:
00375                         tls_reason = TLS_ALERT_BAD_CERTIFICATE;
00376                         break;
00377                 case X509_VALIDATE_UNSUPPORTED_CERTIFICATE:
00378                         tls_reason = TLS_ALERT_UNSUPPORTED_CERTIFICATE;
00379                         break;
00380                 case X509_VALIDATE_CERTIFICATE_REVOKED:
00381                         tls_reason = TLS_ALERT_CERTIFICATE_REVOKED;
00382                         break;
00383                 case X509_VALIDATE_CERTIFICATE_EXPIRED:
00384                         tls_reason = TLS_ALERT_CERTIFICATE_EXPIRED;
00385                         break;
00386                 case X509_VALIDATE_CERTIFICATE_UNKNOWN:
00387                         tls_reason = TLS_ALERT_CERTIFICATE_UNKNOWN;
00388                         break;
00389                 case X509_VALIDATE_UNKNOWN_CA:
00390                         tls_reason = TLS_ALERT_UNKNOWN_CA;
00391                         break;
00392                 default:
00393                         tls_reason = TLS_ALERT_BAD_CERTIFICATE;
00394                         break;
00395                 }
00396                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, tls_reason);
00397                 x509_certificate_chain_free(chain);
00398                 return -1;
00399         }
00400 
00401         x509_certificate_chain_free(chain);
00402 
00403         *in_len = end - in_data;
00404 
00405         conn->state = SERVER_KEY_EXCHANGE;
00406 
00407         return 0;
00408 }
00409 
00410 
00411 static int tlsv1_process_diffie_hellman(struct tlsv1_client *conn,
00412                                         const u8 *buf, size_t len)
00413 {
00414         const u8 *pos, *end;
00415 
00416         tlsv1_client_free_dh(conn);
00417 
00418         pos = buf;
00419         end = buf + len;
00420 
00421         if (end - pos < 3)
00422                 goto fail;
00423         conn->dh_p_len = WPA_GET_BE16(pos);
00424         pos += 2;
00425         if (conn->dh_p_len == 0 || end - pos < (int) conn->dh_p_len) {
00426                 wpa_printf(MSG_DEBUG, "TLSv1: Invalid dh_p length %lu",
00427                            (unsigned long) conn->dh_p_len);
00428                 goto fail;
00429         }
00430         conn->dh_p = os_malloc(conn->dh_p_len);
00431         if (conn->dh_p == NULL)
00432                 goto fail;
00433         os_memcpy(conn->dh_p, pos, conn->dh_p_len);
00434         pos += conn->dh_p_len;
00435         wpa_hexdump(MSG_DEBUG, "TLSv1: DH p (prime)",
00436                     conn->dh_p, conn->dh_p_len);
00437 
00438         if (end - pos < 3)
00439                 goto fail;
00440         conn->dh_g_len = WPA_GET_BE16(pos);
00441         pos += 2;
00442         if (conn->dh_g_len == 0 || end - pos < (int) conn->dh_g_len)
00443                 goto fail;
00444         conn->dh_g = os_malloc(conn->dh_g_len);
00445         if (conn->dh_g == NULL)
00446                 goto fail;
00447         os_memcpy(conn->dh_g, pos, conn->dh_g_len);
00448         pos += conn->dh_g_len;
00449         wpa_hexdump(MSG_DEBUG, "TLSv1: DH g (generator)",
00450                     conn->dh_g, conn->dh_g_len);
00451         if (conn->dh_g_len == 1 && conn->dh_g[0] < 2)
00452                 goto fail;
00453 
00454         if (end - pos < 3)
00455                 goto fail;
00456         conn->dh_ys_len = WPA_GET_BE16(pos);
00457         pos += 2;
00458         if (conn->dh_ys_len == 0 || end - pos < (int) conn->dh_ys_len)
00459                 goto fail;
00460         conn->dh_ys = os_malloc(conn->dh_ys_len);
00461         if (conn->dh_ys == NULL)
00462                 goto fail;
00463         os_memcpy(conn->dh_ys, pos, conn->dh_ys_len);
00464         pos += conn->dh_ys_len;
00465         wpa_hexdump(MSG_DEBUG, "TLSv1: DH Ys (server's public value)",
00466                     conn->dh_ys, conn->dh_ys_len);
00467 
00468         return 0;
00469 
00470 fail:
00471         wpa_printf(MSG_DEBUG, "TLSv1: Processing DH params failed");
00472         tlsv1_client_free_dh(conn);
00473         return -1;
00474 }
00475 
00476 
00477 static int tls_process_server_key_exchange(struct tlsv1_client *conn, u8 ct,
00478                                            const u8 *in_data, size_t *in_len)
00479 {
00480         const u8 *pos, *end;
00481         size_t left, len;
00482         u8 type;
00483         const struct tls_cipher_suite *suite;
00484 
00485         if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
00486                 wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
00487                            "received content type 0x%x", ct);
00488                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00489                           TLS_ALERT_UNEXPECTED_MESSAGE);
00490                 return -1;
00491         }
00492 
00493         pos = in_data;
00494         left = *in_len;
00495 
00496         if (left < 4) {
00497                 wpa_printf(MSG_DEBUG, "TLSv1: Too short ServerKeyExchange "
00498                            "(Left=%lu)", (unsigned long) left);
00499                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
00500                 return -1;
00501         }
00502 
00503         type = *pos++;
00504         len = WPA_GET_BE24(pos);
00505         pos += 3;
00506         left -= 4;
00507 
00508         if (len > left) {
00509                 wpa_printf(MSG_DEBUG, "TLSv1: Mismatch in ServerKeyExchange "
00510                            "length (len=%lu != left=%lu)",
00511                            (unsigned long) len, (unsigned long) left);
00512                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
00513                 return -1;
00514         }
00515 
00516         end = pos + len;
00517 
00518         if (type == TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST)
00519                 return tls_process_certificate_request(conn, ct, in_data,
00520                                                        in_len);
00521         if (type == TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE)
00522                 return tls_process_server_hello_done(conn, ct, in_data,
00523                                                      in_len);
00524         if (type != TLS_HANDSHAKE_TYPE_SERVER_KEY_EXCHANGE) {
00525                 wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
00526                            "message %d (expected ServerKeyExchange/"
00527                            "CertificateRequest/ServerHelloDone)", type);
00528                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00529                           TLS_ALERT_UNEXPECTED_MESSAGE);
00530                 return -1;
00531         }
00532 
00533         wpa_printf(MSG_DEBUG, "TLSv1: Received ServerKeyExchange");
00534 
00535         if (!tls_server_key_exchange_allowed(conn->rl.cipher_suite)) {
00536                 wpa_printf(MSG_DEBUG, "TLSv1: ServerKeyExchange not allowed "
00537                            "with the selected cipher suite");
00538                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00539                           TLS_ALERT_UNEXPECTED_MESSAGE);
00540                 return -1;
00541         }
00542 
00543         wpa_hexdump(MSG_DEBUG, "TLSv1: ServerKeyExchange", pos, len);
00544         suite = tls_get_cipher_suite(conn->rl.cipher_suite);
00545         if (suite && suite->key_exchange == TLS_KEY_X_DH_anon) {
00546                 if (tlsv1_process_diffie_hellman(conn, pos, len) < 0) {
00547                         tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00548                                   TLS_ALERT_DECODE_ERROR);
00549                         return -1;
00550                 }
00551         } else {
00552                 wpa_printf(MSG_DEBUG, "TLSv1: UnexpectedServerKeyExchange");
00553                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00554                           TLS_ALERT_UNEXPECTED_MESSAGE);
00555                 return -1;
00556         }
00557 
00558         *in_len = end - in_data;
00559 
00560         conn->state = SERVER_CERTIFICATE_REQUEST;
00561 
00562         return 0;
00563 }
00564 
00565 
00566 static int tls_process_certificate_request(struct tlsv1_client *conn, u8 ct,
00567                                            const u8 *in_data, size_t *in_len)
00568 {
00569         const u8 *pos, *end;
00570         size_t left, len;
00571         u8 type;
00572 
00573         if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
00574                 wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
00575                            "received content type 0x%x", ct);
00576                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00577                           TLS_ALERT_UNEXPECTED_MESSAGE);
00578                 return -1;
00579         }
00580 
00581         pos = in_data;
00582         left = *in_len;
00583 
00584         if (left < 4) {
00585                 wpa_printf(MSG_DEBUG, "TLSv1: Too short CertificateRequest "
00586                            "(left=%lu)", (unsigned long) left);
00587                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
00588                 return -1;
00589         }
00590 
00591         type = *pos++;
00592         len = WPA_GET_BE24(pos);
00593         pos += 3;
00594         left -= 4;
00595 
00596         if (len > left) {
00597                 wpa_printf(MSG_DEBUG, "TLSv1: Mismatch in CertificateRequest "
00598                            "length (len=%lu != left=%lu)",
00599                            (unsigned long) len, (unsigned long) left);
00600                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
00601                 return -1;
00602         }
00603 
00604         end = pos + len;
00605 
00606         if (type == TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE)
00607                 return tls_process_server_hello_done(conn, ct, in_data,
00608                                                      in_len);
00609         if (type != TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST) {
00610                 wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
00611                            "message %d (expected CertificateRequest/"
00612                            "ServerHelloDone)", type);
00613                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00614                           TLS_ALERT_UNEXPECTED_MESSAGE);
00615                 return -1;
00616         }
00617 
00618         wpa_printf(MSG_DEBUG, "TLSv1: Received CertificateRequest");
00619 
00620         conn->certificate_requested = 1;
00621 
00622         *in_len = end - in_data;
00623 
00624         conn->state = SERVER_HELLO_DONE;
00625 
00626         return 0;
00627 }
00628 
00629 
00630 static int tls_process_server_hello_done(struct tlsv1_client *conn, u8 ct,
00631                                          const u8 *in_data, size_t *in_len)
00632 {
00633         const u8 *pos, *end;
00634         size_t left, len;
00635         u8 type;
00636 
00637         if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
00638                 wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
00639                            "received content type 0x%x", ct);
00640                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00641                           TLS_ALERT_UNEXPECTED_MESSAGE);
00642                 return -1;
00643         }
00644 
00645         pos = in_data;
00646         left = *in_len;
00647 
00648         if (left < 4) {
00649                 wpa_printf(MSG_DEBUG, "TLSv1: Too short ServerHelloDone "
00650                            "(left=%lu)", (unsigned long) left);
00651                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
00652                 return -1;
00653         }
00654 
00655         type = *pos++;
00656         len = WPA_GET_BE24(pos);
00657         pos += 3;
00658         left -= 4;
00659 
00660         if (len > left) {
00661                 wpa_printf(MSG_DEBUG, "TLSv1: Mismatch in ServerHelloDone "
00662                            "length (len=%lu != left=%lu)",
00663                            (unsigned long) len, (unsigned long) left);
00664                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
00665                 return -1;
00666         }
00667         end = pos + len;
00668 
00669         if (type != TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE) {
00670                 wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
00671                            "message %d (expected ServerHelloDone)", type);
00672                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00673                           TLS_ALERT_UNEXPECTED_MESSAGE);
00674                 return -1;
00675         }
00676 
00677         wpa_printf(MSG_DEBUG, "TLSv1: Received ServerHelloDone");
00678 
00679         *in_len = end - in_data;
00680 
00681         conn->state = CLIENT_KEY_EXCHANGE;
00682 
00683         return 0;
00684 }
00685 
00686 
00687 static int tls_process_server_change_cipher_spec(struct tlsv1_client *conn,
00688                                                  u8 ct, const u8 *in_data,
00689                                                  size_t *in_len)
00690 {
00691         const u8 *pos;
00692         size_t left;
00693 
00694         if (ct != TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC) {
00695                 wpa_printf(MSG_DEBUG, "TLSv1: Expected ChangeCipherSpec; "
00696                            "received content type 0x%x", ct);
00697                 if (conn->use_session_ticket) {
00698                         int res;
00699                         wpa_printf(MSG_DEBUG, "TLSv1: Server may have "
00700                                    "rejected SessionTicket");
00701                         conn->use_session_ticket = 0;
00702 
00703                         /* Notify upper layers that SessionTicket failed */
00704                         res = conn->session_ticket_cb(
00705                                 conn->session_ticket_cb_ctx, NULL, 0, NULL,
00706                                 NULL, NULL);
00707                         if (res < 0) {
00708                                 wpa_printf(MSG_DEBUG, "TLSv1: SessionTicket "
00709                                            "callback indicated failure");
00710                                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00711                                           TLS_ALERT_HANDSHAKE_FAILURE);
00712                                 return -1;
00713                         }
00714 
00715                         conn->state = SERVER_CERTIFICATE;
00716                         return tls_process_certificate(conn, ct, in_data,
00717                                                        in_len);
00718                 }
00719                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00720                           TLS_ALERT_UNEXPECTED_MESSAGE);
00721                 return -1;
00722         }
00723 
00724         pos = in_data;
00725         left = *in_len;
00726 
00727         if (left < 1) {
00728                 wpa_printf(MSG_DEBUG, "TLSv1: Too short ChangeCipherSpec");
00729                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
00730                 return -1;
00731         }
00732 
00733         if (*pos != TLS_CHANGE_CIPHER_SPEC) {
00734                 wpa_printf(MSG_DEBUG, "TLSv1: Expected ChangeCipherSpec; "
00735                            "received data 0x%x", *pos);
00736                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00737                           TLS_ALERT_UNEXPECTED_MESSAGE);
00738                 return -1;
00739         }
00740 
00741         wpa_printf(MSG_DEBUG, "TLSv1: Received ChangeCipherSpec");
00742         if (tlsv1_record_change_read_cipher(&conn->rl) < 0) {
00743                 wpa_printf(MSG_DEBUG, "TLSv1: Failed to change read cipher "
00744                            "for record layer");
00745                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00746                           TLS_ALERT_INTERNAL_ERROR);
00747                 return -1;
00748         }
00749 
00750         *in_len = pos + 1 - in_data;
00751 
00752         conn->state = SERVER_FINISHED;
00753 
00754         return 0;
00755 }
00756 
00757 
00758 static int tls_process_server_finished(struct tlsv1_client *conn, u8 ct,
00759                                        const u8 *in_data, size_t *in_len)
00760 {
00761         const u8 *pos, *end;
00762         size_t left, len, hlen;
00763         u8 verify_data[TLS_VERIFY_DATA_LEN];
00764         u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN];
00765 
00766         if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
00767                 wpa_printf(MSG_DEBUG, "TLSv1: Expected Finished; "
00768                            "received content type 0x%x", ct);
00769                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00770                           TLS_ALERT_UNEXPECTED_MESSAGE);
00771                 return -1;
00772         }
00773 
00774         pos = in_data;
00775         left = *in_len;
00776 
00777         if (left < 4) {
00778                 wpa_printf(MSG_DEBUG, "TLSv1: Too short record (left=%lu) for "
00779                            "Finished",
00780                            (unsigned long) left);
00781                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00782                           TLS_ALERT_DECODE_ERROR);
00783                 return -1;
00784         }
00785 
00786         if (pos[0] != TLS_HANDSHAKE_TYPE_FINISHED) {
00787                 wpa_printf(MSG_DEBUG, "TLSv1: Expected Finished; received "
00788                            "type 0x%x", pos[0]);
00789                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00790                           TLS_ALERT_UNEXPECTED_MESSAGE);
00791                 return -1;
00792         }
00793 
00794         len = WPA_GET_BE24(pos + 1);
00795 
00796         pos += 4;
00797         left -= 4;
00798 
00799         if (len > left) {
00800                 wpa_printf(MSG_DEBUG, "TLSv1: Too short buffer for Finished "
00801                            "(len=%lu > left=%lu)",
00802                            (unsigned long) len, (unsigned long) left);
00803                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00804                           TLS_ALERT_DECODE_ERROR);
00805                 return -1;
00806         }
00807         end = pos + len;
00808         if (len != TLS_VERIFY_DATA_LEN) {
00809                 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected verify_data length "
00810                            "in Finished: %lu (expected %d)",
00811                            (unsigned long) len, TLS_VERIFY_DATA_LEN);
00812                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00813                           TLS_ALERT_DECODE_ERROR);
00814                 return -1;
00815         }
00816         wpa_hexdump(MSG_MSGDUMP, "TLSv1: verify_data in Finished",
00817                     pos, TLS_VERIFY_DATA_LEN);
00818 
00819         hlen = MD5_MAC_LEN;
00820         if (conn->verify.md5_server == NULL ||
00821             crypto_hash_finish(conn->verify.md5_server, hash, &hlen) < 0) {
00822                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00823                           TLS_ALERT_INTERNAL_ERROR);
00824                 conn->verify.md5_server = NULL;
00825                 crypto_hash_finish(conn->verify.sha1_server, NULL, NULL);
00826                 conn->verify.sha1_server = NULL;
00827                 return -1;
00828         }
00829         conn->verify.md5_server = NULL;
00830         hlen = SHA1_MAC_LEN;
00831         if (conn->verify.sha1_server == NULL ||
00832             crypto_hash_finish(conn->verify.sha1_server, hash + MD5_MAC_LEN,
00833                                &hlen) < 0) {
00834                 conn->verify.sha1_server = NULL;
00835                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00836                           TLS_ALERT_INTERNAL_ERROR);
00837                 return -1;
00838         }
00839         conn->verify.sha1_server = NULL;
00840 
00841         if (tls_prf(conn->master_secret, TLS_MASTER_SECRET_LEN,
00842                     "server finished", hash, MD5_MAC_LEN + SHA1_MAC_LEN,
00843                     verify_data, TLS_VERIFY_DATA_LEN)) {
00844                 wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive verify_data");
00845                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00846                           TLS_ALERT_DECRYPT_ERROR);
00847                 return -1;
00848         }
00849         wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (server)",
00850                         verify_data, TLS_VERIFY_DATA_LEN);
00851 
00852         if (os_memcmp(pos, verify_data, TLS_VERIFY_DATA_LEN) != 0) {
00853                 wpa_printf(MSG_INFO, "TLSv1: Mismatch in verify_data");
00854                 return -1;
00855         }
00856 
00857         wpa_printf(MSG_DEBUG, "TLSv1: Received Finished");
00858 
00859         *in_len = end - in_data;
00860 
00861         conn->state = (conn->session_resumed || conn->use_session_ticket) ?
00862                 CHANGE_CIPHER_SPEC : ACK_FINISHED;
00863 
00864         return 0;
00865 }
00866 
00867 
00868 static int tls_process_application_data(struct tlsv1_client *conn, u8 ct,
00869                                         const u8 *in_data, size_t *in_len,
00870                                         u8 **out_data, size_t *out_len)
00871 {
00872         const u8 *pos;
00873         size_t left;
00874 
00875         if (ct != TLS_CONTENT_TYPE_APPLICATION_DATA) {
00876                 wpa_printf(MSG_DEBUG, "TLSv1: Expected Application Data; "
00877                            "received content type 0x%x", ct);
00878                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00879                           TLS_ALERT_UNEXPECTED_MESSAGE);
00880                 return -1;
00881         }
00882 
00883         pos = in_data;
00884         left = *in_len;
00885 
00886         wpa_hexdump(MSG_DEBUG, "TLSv1: Application Data included in Handshake",
00887                     pos, left);
00888 
00889         *out_data = os_malloc(left);
00890         if (*out_data) {
00891                 os_memcpy(*out_data, pos, left);
00892                 *out_len = left;
00893         }
00894 
00895         return 0;
00896 }
00897 
00898 
00899 int tlsv1_client_process_handshake(struct tlsv1_client *conn, u8 ct,
00900                                    const u8 *buf, size_t *len,
00901                                    u8 **out_data, size_t *out_len)
00902 {
00903         if (ct == TLS_CONTENT_TYPE_ALERT) {
00904                 if (*len < 2) {
00905                         wpa_printf(MSG_DEBUG, "TLSv1: Alert underflow");
00906                         tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00907                                   TLS_ALERT_DECODE_ERROR);
00908                         return -1;
00909                 }
00910                 wpa_printf(MSG_DEBUG, "TLSv1: Received alert %d:%d",
00911                            buf[0], buf[1]);
00912                 *len = 2;
00913                 conn->state = FAILED;
00914                 return -1;
00915         }
00916 
00917         if (ct == TLS_CONTENT_TYPE_HANDSHAKE && *len >= 4 &&
00918             buf[0] == TLS_HANDSHAKE_TYPE_HELLO_REQUEST) {
00919                 size_t hr_len = WPA_GET_BE24(buf + 1);
00920                 if (hr_len > *len - 4) {
00921                         wpa_printf(MSG_DEBUG, "TLSv1: HelloRequest underflow");
00922                         tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00923                                   TLS_ALERT_DECODE_ERROR);
00924                         return -1;
00925                 }
00926                 wpa_printf(MSG_DEBUG, "TLSv1: Ignored HelloRequest");
00927                 *len = 4 + hr_len;
00928                 return 0;
00929         }
00930 
00931         switch (conn->state) {
00932         case SERVER_HELLO:
00933                 if (tls_process_server_hello(conn, ct, buf, len))
00934                         return -1;
00935                 break;
00936         case SERVER_CERTIFICATE:
00937                 if (tls_process_certificate(conn, ct, buf, len))
00938                         return -1;
00939                 break;
00940         case SERVER_KEY_EXCHANGE:
00941                 if (tls_process_server_key_exchange(conn, ct, buf, len))
00942                         return -1;
00943                 break;
00944         case SERVER_CERTIFICATE_REQUEST:
00945                 if (tls_process_certificate_request(conn, ct, buf, len))
00946                         return -1;
00947                 break;
00948         case SERVER_HELLO_DONE:
00949                 if (tls_process_server_hello_done(conn, ct, buf, len))
00950                         return -1;
00951                 break;
00952         case SERVER_CHANGE_CIPHER_SPEC:
00953                 if (tls_process_server_change_cipher_spec(conn, ct, buf, len))
00954                         return -1;
00955                 break;
00956         case SERVER_FINISHED:
00957                 if (tls_process_server_finished(conn, ct, buf, len))
00958                         return -1;
00959                 break;
00960         case ACK_FINISHED:
00961                 if (out_data &&
00962                     tls_process_application_data(conn, ct, buf, len, out_data,
00963                                                  out_len))
00964                         return -1;
00965                 break;
00966         default:
00967                 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected state %d "
00968                            "while processing received message",
00969                            conn->state);
00970                 return -1;
00971         }
00972 
00973         if (ct == TLS_CONTENT_TYPE_HANDSHAKE)
00974                 tls_verify_hash_add(&conn->verify, buf, *len);
00975 
00976         return 0;
00977 }
00978 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on Sat Nov 21 23:16:53 2009 for hostapd by  doxygen 1.6.1