tlsv1_server_read.c
Go to the documentation of this file.
00001 /*
00002  * TLSv1 server - read handshake message
00003  * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi>
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 2 as
00007  * published by the Free Software Foundation.
00008  *
00009  * Alternatively, this software may be distributed under the terms of BSD
00010  * license.
00011  *
00012  * See README and COPYING for more details.
00013  */
00014 
00015 #include "includes.h"
00016 
00017 #include "common.h"
00018 #include "crypto/md5.h"
00019 #include "crypto/sha1.h"
00020 #include "crypto/tls.h"
00021 #include "x509v3.h"
00022 #include "tlsv1_common.h"
00023 #include "tlsv1_record.h"
00024 #include "tlsv1_server.h"
00025 #include "tlsv1_server_i.h"
00026 
00027 
00028 static int tls_process_client_key_exchange(struct tlsv1_server *conn, u8 ct,
00029                                            const u8 *in_data, size_t *in_len);
00030 static int tls_process_change_cipher_spec(struct tlsv1_server *conn,
00031                                           u8 ct, const u8 *in_data,
00032                                           size_t *in_len);
00033 
00034 
00035 static int tls_process_client_hello(struct tlsv1_server *conn, u8 ct,
00036                                     const u8 *in_data, size_t *in_len)
00037 {
00038         const u8 *pos, *end, *c;
00039         size_t left, len, i, j;
00040         u16 cipher_suite;
00041         u16 num_suites;
00042         int compr_null_found;
00043         u16 ext_type, ext_len;
00044 
00045         if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
00046                 wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
00047                            "received content type 0x%x", ct);
00048                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00049                                    TLS_ALERT_UNEXPECTED_MESSAGE);
00050                 return -1;
00051         }
00052 
00053         pos = in_data;
00054         left = *in_len;
00055 
00056         if (left < 4)
00057                 goto decode_error;
00058 
00059         /* HandshakeType msg_type */
00060         if (*pos != TLS_HANDSHAKE_TYPE_CLIENT_HELLO) {
00061                 wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
00062                            "message %d (expected ClientHello)", *pos);
00063                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00064                                    TLS_ALERT_UNEXPECTED_MESSAGE);
00065                 return -1;
00066         }
00067         wpa_printf(MSG_DEBUG, "TLSv1: Received ClientHello");
00068         pos++;
00069         /* uint24 length */
00070         len = WPA_GET_BE24(pos);
00071         pos += 3;
00072         left -= 4;
00073 
00074         if (len > left)
00075                 goto decode_error;
00076 
00077         /* body - ClientHello */
00078 
00079         wpa_hexdump(MSG_MSGDUMP, "TLSv1: ClientHello", pos, len);
00080         end = pos + len;
00081 
00082         /* ProtocolVersion client_version */
00083         if (end - pos < 2)
00084                 goto decode_error;
00085         conn->client_version = WPA_GET_BE16(pos);
00086         wpa_printf(MSG_DEBUG, "TLSv1: Client version %d.%d",
00087                    conn->client_version >> 8, conn->client_version & 0xff);
00088         if (conn->client_version < TLS_VERSION) {
00089                 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected protocol version in "
00090                            "ClientHello");
00091                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00092                                    TLS_ALERT_PROTOCOL_VERSION);
00093                 return -1;
00094         }
00095         pos += 2;
00096 
00097         /* Random random */
00098         if (end - pos < TLS_RANDOM_LEN)
00099                 goto decode_error;
00100 
00101         os_memcpy(conn->client_random, pos, TLS_RANDOM_LEN);
00102         pos += TLS_RANDOM_LEN;
00103         wpa_hexdump(MSG_MSGDUMP, "TLSv1: client_random",
00104                     conn->client_random, TLS_RANDOM_LEN);
00105 
00106         /* SessionID session_id */
00107         if (end - pos < 1)
00108                 goto decode_error;
00109         if (end - pos < 1 + *pos || *pos > TLS_SESSION_ID_MAX_LEN)
00110                 goto decode_error;
00111         wpa_hexdump(MSG_MSGDUMP, "TLSv1: client session_id", pos + 1, *pos);
00112         pos += 1 + *pos;
00113         /* TODO: add support for session resumption */
00114 
00115         /* CipherSuite cipher_suites<2..2^16-1> */
00116         if (end - pos < 2)
00117                 goto decode_error;
00118         num_suites = WPA_GET_BE16(pos);
00119         pos += 2;
00120         if (end - pos < num_suites)
00121                 goto decode_error;
00122         wpa_hexdump(MSG_MSGDUMP, "TLSv1: client cipher suites",
00123                     pos, num_suites);
00124         if (num_suites & 1)
00125                 goto decode_error;
00126         num_suites /= 2;
00127 
00128         cipher_suite = 0;
00129         for (i = 0; !cipher_suite && i < conn->num_cipher_suites; i++) {
00130                 c = pos;
00131                 for (j = 0; j < num_suites; j++) {
00132                         u16 tmp = WPA_GET_BE16(c);
00133                         c += 2;
00134                         if (!cipher_suite && tmp == conn->cipher_suites[i]) {
00135                                 cipher_suite = tmp;
00136                                 break;
00137                         }
00138                 }
00139         }
00140         pos += num_suites * 2;
00141         if (!cipher_suite) {
00142                 wpa_printf(MSG_INFO, "TLSv1: No supported cipher suite "
00143                            "available");
00144                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00145                                    TLS_ALERT_ILLEGAL_PARAMETER);
00146                 return -1;
00147         }
00148 
00149         if (tlsv1_record_set_cipher_suite(&conn->rl, cipher_suite) < 0) {
00150                 wpa_printf(MSG_DEBUG, "TLSv1: Failed to set CipherSuite for "
00151                            "record layer");
00152                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00153                                    TLS_ALERT_INTERNAL_ERROR);
00154                 return -1;
00155         }
00156 
00157         conn->cipher_suite = cipher_suite;
00158 
00159         /* CompressionMethod compression_methods<1..2^8-1> */
00160         if (end - pos < 1)
00161                 goto decode_error;
00162         num_suites = *pos++;
00163         if (end - pos < num_suites)
00164                 goto decode_error;
00165         wpa_hexdump(MSG_MSGDUMP, "TLSv1: client compression_methods",
00166                     pos, num_suites);
00167         compr_null_found = 0;
00168         for (i = 0; i < num_suites; i++) {
00169                 if (*pos++ == TLS_COMPRESSION_NULL)
00170                         compr_null_found = 1;
00171         }
00172         if (!compr_null_found) {
00173                 wpa_printf(MSG_INFO, "TLSv1: Client does not accept NULL "
00174                            "compression");
00175                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00176                                    TLS_ALERT_ILLEGAL_PARAMETER);
00177                 return -1;
00178         }
00179 
00180         if (end - pos == 1) {
00181                 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected extra octet in the "
00182                             "end of ClientHello: 0x%02x", *pos);
00183                 goto decode_error;
00184         }
00185 
00186         if (end - pos >= 2) {
00187                 /* Extension client_hello_extension_list<0..2^16-1> */
00188                 ext_len = WPA_GET_BE16(pos);
00189                 pos += 2;
00190 
00191                 wpa_printf(MSG_DEBUG, "TLSv1: %u bytes of ClientHello "
00192                            "extensions", ext_len);
00193                 if (end - pos != ext_len) {
00194                         wpa_printf(MSG_DEBUG, "TLSv1: Invalid ClientHello "
00195                                    "extension list length %u (expected %u)",
00196                                    ext_len, (unsigned int) (end - pos));
00197                         goto decode_error;
00198                 }
00199 
00200                 /*
00201                  * struct {
00202                  *   ExtensionType extension_type (0..65535)
00203                  *   opaque extension_data<0..2^16-1>
00204                  * } Extension;
00205                  */
00206 
00207                 while (pos < end) {
00208                         if (end - pos < 2) {
00209                                 wpa_printf(MSG_DEBUG, "TLSv1: Invalid "
00210                                            "extension_type field");
00211                                 goto decode_error;
00212                         }
00213 
00214                         ext_type = WPA_GET_BE16(pos);
00215                         pos += 2;
00216 
00217                         if (end - pos < 2) {
00218                                 wpa_printf(MSG_DEBUG, "TLSv1: Invalid "
00219                                            "extension_data length field");
00220                                 goto decode_error;
00221                         }
00222 
00223                         ext_len = WPA_GET_BE16(pos);
00224                         pos += 2;
00225 
00226                         if (end - pos < ext_len) {
00227                                 wpa_printf(MSG_DEBUG, "TLSv1: Invalid "
00228                                            "extension_data field");
00229                                 goto decode_error;
00230                         }
00231 
00232                         wpa_printf(MSG_DEBUG, "TLSv1: ClientHello Extension "
00233                                    "type %u", ext_type);
00234                         wpa_hexdump(MSG_MSGDUMP, "TLSv1: ClientHello "
00235                                     "Extension data", pos, ext_len);
00236 
00237                         if (ext_type == TLS_EXT_SESSION_TICKET) {
00238                                 os_free(conn->session_ticket);
00239                                 conn->session_ticket = os_malloc(ext_len);
00240                                 if (conn->session_ticket) {
00241                                         os_memcpy(conn->session_ticket, pos,
00242                                                   ext_len);
00243                                         conn->session_ticket_len = ext_len;
00244                                 }
00245                         }
00246 
00247                         pos += ext_len;
00248                 }
00249         }
00250 
00251         *in_len = end - in_data;
00252 
00253         wpa_printf(MSG_DEBUG, "TLSv1: ClientHello OK - proceed to "
00254                    "ServerHello");
00255         conn->state = SERVER_HELLO;
00256 
00257         return 0;
00258 
00259 decode_error:
00260         wpa_printf(MSG_DEBUG, "TLSv1: Failed to decode ClientHello");
00261         tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00262                            TLS_ALERT_DECODE_ERROR);
00263         return -1;
00264 }
00265 
00266 
00267 static int tls_process_certificate(struct tlsv1_server *conn, u8 ct,
00268                                    const u8 *in_data, size_t *in_len)
00269 {
00270         const u8 *pos, *end;
00271         size_t left, len, list_len, cert_len, idx;
00272         u8 type;
00273         struct x509_certificate *chain = NULL, *last = NULL, *cert;
00274         int reason;
00275 
00276         if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
00277                 wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
00278                            "received content type 0x%x", ct);
00279                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00280                                    TLS_ALERT_UNEXPECTED_MESSAGE);
00281                 return -1;
00282         }
00283 
00284         pos = in_data;
00285         left = *in_len;
00286 
00287         if (left < 4) {
00288                 wpa_printf(MSG_DEBUG, "TLSv1: Too short Certificate message "
00289                            "(len=%lu)", (unsigned long) left);
00290                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00291                                    TLS_ALERT_DECODE_ERROR);
00292                 return -1;
00293         }
00294 
00295         type = *pos++;
00296         len = WPA_GET_BE24(pos);
00297         pos += 3;
00298         left -= 4;
00299 
00300         if (len > left) {
00301                 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected Certificate message "
00302                            "length (len=%lu != left=%lu)",
00303                            (unsigned long) len, (unsigned long) left);
00304                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00305                                    TLS_ALERT_DECODE_ERROR);
00306                 return -1;
00307         }
00308 
00309         if (type == TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE) {
00310                 if (conn->verify_peer) {
00311                         wpa_printf(MSG_DEBUG, "TLSv1: Client did not include "
00312                                    "Certificate");
00313                         tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00314                                            TLS_ALERT_UNEXPECTED_MESSAGE);
00315                         return -1;
00316                 }
00317 
00318                 return tls_process_client_key_exchange(conn, ct, in_data,
00319                                                        in_len);
00320         }
00321         if (type != TLS_HANDSHAKE_TYPE_CERTIFICATE) {
00322                 wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
00323                            "message %d (expected Certificate/"
00324                            "ClientKeyExchange)", type);
00325                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00326                                    TLS_ALERT_UNEXPECTED_MESSAGE);
00327                 return -1;
00328         }
00329 
00330         wpa_printf(MSG_DEBUG,
00331                    "TLSv1: Received Certificate (certificate_list len %lu)",
00332                    (unsigned long) len);
00333 
00334         /*
00335          * opaque ASN.1Cert<2^24-1>;
00336          *
00337          * struct {
00338          *     ASN.1Cert certificate_list<1..2^24-1>;
00339          * } Certificate;
00340          */
00341 
00342         end = pos + len;
00343 
00344         if (end - pos < 3) {
00345                 wpa_printf(MSG_DEBUG, "TLSv1: Too short Certificate "
00346                            "(left=%lu)", (unsigned long) left);
00347                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00348                                    TLS_ALERT_DECODE_ERROR);
00349                 return -1;
00350         }
00351 
00352         list_len = WPA_GET_BE24(pos);
00353         pos += 3;
00354 
00355         if ((size_t) (end - pos) != list_len) {
00356                 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected certificate_list "
00357                            "length (len=%lu left=%lu)",
00358                            (unsigned long) list_len,
00359                            (unsigned long) (end - pos));
00360                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00361                                    TLS_ALERT_DECODE_ERROR);
00362                 return -1;
00363         }
00364 
00365         idx = 0;
00366         while (pos < end) {
00367                 if (end - pos < 3) {
00368                         wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse "
00369                                    "certificate_list");
00370                         tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00371                                            TLS_ALERT_DECODE_ERROR);
00372                         x509_certificate_chain_free(chain);
00373                         return -1;
00374                 }
00375 
00376                 cert_len = WPA_GET_BE24(pos);
00377                 pos += 3;
00378 
00379                 if ((size_t) (end - pos) < cert_len) {
00380                         wpa_printf(MSG_DEBUG, "TLSv1: Unexpected certificate "
00381                                    "length (len=%lu left=%lu)",
00382                                    (unsigned long) cert_len,
00383                                    (unsigned long) (end - pos));
00384                         tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00385                                            TLS_ALERT_DECODE_ERROR);
00386                         x509_certificate_chain_free(chain);
00387                         return -1;
00388                 }
00389 
00390                 wpa_printf(MSG_DEBUG, "TLSv1: Certificate %lu (len %lu)",
00391                            (unsigned long) idx, (unsigned long) cert_len);
00392 
00393                 if (idx == 0) {
00394                         crypto_public_key_free(conn->client_rsa_key);
00395                         if (tls_parse_cert(pos, cert_len,
00396                                            &conn->client_rsa_key)) {
00397                                 wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse "
00398                                            "the certificate");
00399                                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00400                                                    TLS_ALERT_BAD_CERTIFICATE);
00401                                 x509_certificate_chain_free(chain);
00402                                 return -1;
00403                         }
00404                 }
00405 
00406                 cert = x509_certificate_parse(pos, cert_len);
00407                 if (cert == NULL) {
00408                         wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse "
00409                                    "the certificate");
00410                         tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00411                                            TLS_ALERT_BAD_CERTIFICATE);
00412                         x509_certificate_chain_free(chain);
00413                         return -1;
00414                 }
00415 
00416                 if (last == NULL)
00417                         chain = cert;
00418                 else
00419                         last->next = cert;
00420                 last = cert;
00421 
00422                 idx++;
00423                 pos += cert_len;
00424         }
00425 
00426         if (x509_certificate_chain_validate(conn->cred->trusted_certs, chain,
00427                                             &reason) < 0) {
00428                 int tls_reason;
00429                 wpa_printf(MSG_DEBUG, "TLSv1: Server certificate chain "
00430                            "validation failed (reason=%d)", reason);
00431                 switch (reason) {
00432                 case X509_VALIDATE_BAD_CERTIFICATE:
00433                         tls_reason = TLS_ALERT_BAD_CERTIFICATE;
00434                         break;
00435                 case X509_VALIDATE_UNSUPPORTED_CERTIFICATE:
00436                         tls_reason = TLS_ALERT_UNSUPPORTED_CERTIFICATE;
00437                         break;
00438                 case X509_VALIDATE_CERTIFICATE_REVOKED:
00439                         tls_reason = TLS_ALERT_CERTIFICATE_REVOKED;
00440                         break;
00441                 case X509_VALIDATE_CERTIFICATE_EXPIRED:
00442                         tls_reason = TLS_ALERT_CERTIFICATE_EXPIRED;
00443                         break;
00444                 case X509_VALIDATE_CERTIFICATE_UNKNOWN:
00445                         tls_reason = TLS_ALERT_CERTIFICATE_UNKNOWN;
00446                         break;
00447                 case X509_VALIDATE_UNKNOWN_CA:
00448                         tls_reason = TLS_ALERT_UNKNOWN_CA;
00449                         break;
00450                 default:
00451                         tls_reason = TLS_ALERT_BAD_CERTIFICATE;
00452                         break;
00453                 }
00454                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, tls_reason);
00455                 x509_certificate_chain_free(chain);
00456                 return -1;
00457         }
00458 
00459         x509_certificate_chain_free(chain);
00460 
00461         *in_len = end - in_data;
00462 
00463         conn->state = CLIENT_KEY_EXCHANGE;
00464 
00465         return 0;
00466 }
00467 
00468 
00469 static int tls_process_client_key_exchange_rsa(
00470         struct tlsv1_server *conn, const u8 *pos, const u8 *end)
00471 {
00472         u8 *out;
00473         size_t outlen, outbuflen;
00474         u16 encr_len;
00475         int res;
00476         int use_random = 0;
00477 
00478         if (end - pos < 2) {
00479                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00480                                    TLS_ALERT_DECODE_ERROR);
00481                 return -1;
00482         }
00483 
00484         encr_len = WPA_GET_BE16(pos);
00485         pos += 2;
00486 
00487         outbuflen = outlen = end - pos;
00488         out = os_malloc(outlen >= TLS_PRE_MASTER_SECRET_LEN ?
00489                         outlen : TLS_PRE_MASTER_SECRET_LEN);
00490         if (out == NULL) {
00491                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00492                                    TLS_ALERT_INTERNAL_ERROR);
00493                 return -1;
00494         }
00495 
00496         /*
00497          * struct {
00498          *   ProtocolVersion client_version;
00499          *   opaque random[46];
00500          * } PreMasterSecret;
00501          *
00502          * struct {
00503          *   public-key-encrypted PreMasterSecret pre_master_secret;
00504          * } EncryptedPreMasterSecret;
00505          */
00506 
00507         /*
00508          * Note: To avoid Bleichenbacher attack, we do not report decryption or
00509          * parsing errors from EncryptedPreMasterSecret processing to the
00510          * client. Instead, a random pre-master secret is used to force the
00511          * handshake to fail.
00512          */
00513 
00514         if (crypto_private_key_decrypt_pkcs1_v15(conn->cred->key,
00515                                                  pos, end - pos,
00516                                                  out, &outlen) < 0) {
00517                 wpa_printf(MSG_DEBUG, "TLSv1: Failed to decrypt "
00518                            "PreMasterSecret (encr_len=%d outlen=%lu)",
00519                            (int) (end - pos), (unsigned long) outlen);
00520                 use_random = 1;
00521         }
00522 
00523         if (outlen != TLS_PRE_MASTER_SECRET_LEN) {
00524                 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected PreMasterSecret "
00525                            "length %lu", (unsigned long) outlen);
00526                 use_random = 1;
00527         }
00528 
00529         if (WPA_GET_BE16(out) != conn->client_version) {
00530                 wpa_printf(MSG_DEBUG, "TLSv1: Client version in "
00531                            "ClientKeyExchange does not match with version in "
00532                            "ClientHello");
00533                 use_random = 1;
00534         }
00535 
00536         if (use_random) {
00537                 wpa_printf(MSG_DEBUG, "TLSv1: Using random premaster secret "
00538                            "to avoid revealing information about private key");
00539                 outlen = TLS_PRE_MASTER_SECRET_LEN;
00540                 if (os_get_random(out, outlen)) {
00541                         wpa_printf(MSG_DEBUG, "TLSv1: Failed to get random "
00542                                    "data");
00543                         tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00544                                            TLS_ALERT_INTERNAL_ERROR);
00545                         os_free(out);
00546                         return -1;
00547                 }
00548         }
00549 
00550         res = tlsv1_server_derive_keys(conn, out, outlen);
00551 
00552         /* Clear the pre-master secret since it is not needed anymore */
00553         os_memset(out, 0, outbuflen);
00554         os_free(out);
00555 
00556         if (res) {
00557                 wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive keys");
00558                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00559                                    TLS_ALERT_INTERNAL_ERROR);
00560                 return -1;
00561         }
00562 
00563         return 0;
00564 }
00565 
00566 
00567 static int tls_process_client_key_exchange_dh_anon(
00568         struct tlsv1_server *conn, const u8 *pos, const u8 *end)
00569 {
00570         const u8 *dh_yc;
00571         u16 dh_yc_len;
00572         u8 *shared;
00573         size_t shared_len;
00574         int res;
00575 
00576         /*
00577          * struct {
00578          *   select (PublicValueEncoding) {
00579          *     case implicit: struct { };
00580          *     case explicit: opaque dh_Yc<1..2^16-1>;
00581          *   } dh_public;
00582          * } ClientDiffieHellmanPublic;
00583          */
00584 
00585         wpa_hexdump(MSG_MSGDUMP, "TLSv1: ClientDiffieHellmanPublic",
00586                     pos, end - pos);
00587 
00588         if (end == pos) {
00589                 wpa_printf(MSG_DEBUG, "TLSv1: Implicit public value encoding "
00590                            "not supported");
00591                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00592                                    TLS_ALERT_INTERNAL_ERROR);
00593                 return -1;
00594         }
00595 
00596         if (end - pos < 3) {
00597                 wpa_printf(MSG_DEBUG, "TLSv1: Invalid client public value "
00598                            "length");
00599                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00600                                    TLS_ALERT_DECODE_ERROR);
00601                 return -1;
00602         }
00603 
00604         dh_yc_len = WPA_GET_BE16(pos);
00605         dh_yc = pos + 2;
00606 
00607         if (dh_yc + dh_yc_len > end) {
00608                 wpa_printf(MSG_DEBUG, "TLSv1: Client public value overflow "
00609                            "(length %d)", dh_yc_len);
00610                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00611                                    TLS_ALERT_DECODE_ERROR);
00612                 return -1;
00613         }
00614 
00615         wpa_hexdump(MSG_DEBUG, "TLSv1: DH Yc (client's public value)",
00616                     dh_yc, dh_yc_len);
00617 
00618         if (conn->cred == NULL || conn->cred->dh_p == NULL ||
00619             conn->dh_secret == NULL) {
00620                 wpa_printf(MSG_DEBUG, "TLSv1: No DH parameters available");
00621                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00622                                    TLS_ALERT_INTERNAL_ERROR);
00623                 return -1;
00624         }
00625 
00626         shared_len = conn->cred->dh_p_len;
00627         shared = os_malloc(shared_len);
00628         if (shared == NULL) {
00629                 wpa_printf(MSG_DEBUG, "TLSv1: Could not allocate memory for "
00630                            "DH");
00631                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00632                                    TLS_ALERT_INTERNAL_ERROR);
00633                 return -1;
00634         }
00635 
00636         /* shared = Yc^secret mod p */
00637         if (crypto_mod_exp(dh_yc, dh_yc_len, conn->dh_secret,
00638                            conn->dh_secret_len,
00639                            conn->cred->dh_p, conn->cred->dh_p_len,
00640                            shared, &shared_len)) {
00641                 os_free(shared);
00642                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00643                                    TLS_ALERT_INTERNAL_ERROR);
00644                 return -1;
00645         }
00646         wpa_hexdump_key(MSG_DEBUG, "TLSv1: Shared secret from DH key exchange",
00647                         shared, shared_len);
00648 
00649         os_memset(conn->dh_secret, 0, conn->dh_secret_len);
00650         os_free(conn->dh_secret);
00651         conn->dh_secret = NULL;
00652 
00653         res = tlsv1_server_derive_keys(conn, shared, shared_len);
00654 
00655         /* Clear the pre-master secret since it is not needed anymore */
00656         os_memset(shared, 0, shared_len);
00657         os_free(shared);
00658 
00659         if (res) {
00660                 wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive keys");
00661                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00662                                    TLS_ALERT_INTERNAL_ERROR);
00663                 return -1;
00664         }
00665 
00666         return 0;
00667 }
00668 
00669 
00670 static int tls_process_client_key_exchange(struct tlsv1_server *conn, u8 ct,
00671                                            const u8 *in_data, size_t *in_len)
00672 {
00673         const u8 *pos, *end;
00674         size_t left, len;
00675         u8 type;
00676         tls_key_exchange keyx;
00677         const struct tls_cipher_suite *suite;
00678 
00679         if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
00680                 wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
00681                            "received content type 0x%x", ct);
00682                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00683                                    TLS_ALERT_UNEXPECTED_MESSAGE);
00684                 return -1;
00685         }
00686 
00687         pos = in_data;
00688         left = *in_len;
00689 
00690         if (left < 4) {
00691                 wpa_printf(MSG_DEBUG, "TLSv1: Too short ClientKeyExchange "
00692                            "(Left=%lu)", (unsigned long) left);
00693                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00694                                    TLS_ALERT_DECODE_ERROR);
00695                 return -1;
00696         }
00697 
00698         type = *pos++;
00699         len = WPA_GET_BE24(pos);
00700         pos += 3;
00701         left -= 4;
00702 
00703         if (len > left) {
00704                 wpa_printf(MSG_DEBUG, "TLSv1: Mismatch in ClientKeyExchange "
00705                            "length (len=%lu != left=%lu)",
00706                            (unsigned long) len, (unsigned long) left);
00707                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00708                                    TLS_ALERT_DECODE_ERROR);
00709                 return -1;
00710         }
00711 
00712         end = pos + len;
00713 
00714         if (type != TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE) {
00715                 wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
00716                            "message %d (expected ClientKeyExchange)", type);
00717                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00718                                    TLS_ALERT_UNEXPECTED_MESSAGE);
00719                 return -1;
00720         }
00721 
00722         wpa_printf(MSG_DEBUG, "TLSv1: Received ClientKeyExchange");
00723 
00724         wpa_hexdump(MSG_DEBUG, "TLSv1: ClientKeyExchange", pos, len);
00725 
00726         suite = tls_get_cipher_suite(conn->rl.cipher_suite);
00727         if (suite == NULL)
00728                 keyx = TLS_KEY_X_NULL;
00729         else
00730                 keyx = suite->key_exchange;
00731 
00732         if (keyx == TLS_KEY_X_DH_anon &&
00733             tls_process_client_key_exchange_dh_anon(conn, pos, end) < 0)
00734                 return -1;
00735 
00736         if (keyx != TLS_KEY_X_DH_anon &&
00737             tls_process_client_key_exchange_rsa(conn, pos, end) < 0)
00738                 return -1;
00739 
00740         *in_len = end - in_data;
00741 
00742         conn->state = CERTIFICATE_VERIFY;
00743 
00744         return 0;
00745 }
00746 
00747 
00748 static int tls_process_certificate_verify(struct tlsv1_server *conn, u8 ct,
00749                                           const u8 *in_data, size_t *in_len)
00750 {
00751         const u8 *pos, *end;
00752         size_t left, len;
00753         u8 type;
00754         size_t hlen, buflen;
00755         u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN], *hpos, *buf;
00756         enum { SIGN_ALG_RSA, SIGN_ALG_DSA } alg = SIGN_ALG_RSA;
00757         u16 slen;
00758 
00759         if (ct == TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC) {
00760                 if (conn->verify_peer) {
00761                         wpa_printf(MSG_DEBUG, "TLSv1: Client did not include "
00762                                    "CertificateVerify");
00763                         tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00764                                            TLS_ALERT_UNEXPECTED_MESSAGE);
00765                         return -1;
00766                 }
00767 
00768                 return tls_process_change_cipher_spec(conn, ct, in_data,
00769                                                       in_len);
00770         }
00771 
00772         if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
00773                 wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
00774                            "received content type 0x%x", ct);
00775                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00776                                    TLS_ALERT_UNEXPECTED_MESSAGE);
00777                 return -1;
00778         }
00779 
00780         pos = in_data;
00781         left = *in_len;
00782 
00783         if (left < 4) {
00784                 wpa_printf(MSG_DEBUG, "TLSv1: Too short CertificateVerify "
00785                            "message (len=%lu)", (unsigned long) left);
00786                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00787                                    TLS_ALERT_DECODE_ERROR);
00788                 return -1;
00789         }
00790 
00791         type = *pos++;
00792         len = WPA_GET_BE24(pos);
00793         pos += 3;
00794         left -= 4;
00795 
00796         if (len > left) {
00797                 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected CertificateVerify "
00798                            "message length (len=%lu != left=%lu)",
00799                            (unsigned long) len, (unsigned long) left);
00800                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00801                                    TLS_ALERT_DECODE_ERROR);
00802                 return -1;
00803         }
00804 
00805         end = pos + len;
00806 
00807         if (type != TLS_HANDSHAKE_TYPE_CERTIFICATE_VERIFY) {
00808                 wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
00809                            "message %d (expected CertificateVerify)", type);
00810                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00811                                    TLS_ALERT_UNEXPECTED_MESSAGE);
00812                 return -1;
00813         }
00814 
00815         wpa_printf(MSG_DEBUG, "TLSv1: Received CertificateVerify");
00816 
00817         /*
00818          * struct {
00819          *   Signature signature;
00820          * } CertificateVerify;
00821          */
00822 
00823         hpos = hash;
00824 
00825         if (alg == SIGN_ALG_RSA) {
00826                 hlen = MD5_MAC_LEN;
00827                 if (conn->verify.md5_cert == NULL ||
00828                     crypto_hash_finish(conn->verify.md5_cert, hpos, &hlen) < 0)
00829                 {
00830                         tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00831                                            TLS_ALERT_INTERNAL_ERROR);
00832                         conn->verify.md5_cert = NULL;
00833                         crypto_hash_finish(conn->verify.sha1_cert, NULL, NULL);
00834                         conn->verify.sha1_cert = NULL;
00835                         return -1;
00836                 }
00837                 hpos += MD5_MAC_LEN;
00838         } else
00839                 crypto_hash_finish(conn->verify.md5_cert, NULL, NULL);
00840 
00841         conn->verify.md5_cert = NULL;
00842         hlen = SHA1_MAC_LEN;
00843         if (conn->verify.sha1_cert == NULL ||
00844             crypto_hash_finish(conn->verify.sha1_cert, hpos, &hlen) < 0) {
00845                 conn->verify.sha1_cert = NULL;
00846                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00847                                    TLS_ALERT_INTERNAL_ERROR);
00848                 return -1;
00849         }
00850         conn->verify.sha1_cert = NULL;
00851 
00852         if (alg == SIGN_ALG_RSA)
00853                 hlen += MD5_MAC_LEN;
00854 
00855         wpa_hexdump(MSG_MSGDUMP, "TLSv1: CertificateVerify hash", hash, hlen);
00856 
00857         if (end - pos < 2) {
00858                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00859                                    TLS_ALERT_DECODE_ERROR);
00860                 return -1;
00861         }
00862         slen = WPA_GET_BE16(pos);
00863         pos += 2;
00864         if (end - pos < slen) {
00865                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00866                                    TLS_ALERT_DECODE_ERROR);
00867                 return -1;
00868         }
00869 
00870         wpa_hexdump(MSG_MSGDUMP, "TLSv1: Signature", pos, end - pos);
00871         if (conn->client_rsa_key == NULL) {
00872                 wpa_printf(MSG_DEBUG, "TLSv1: No client public key to verify "
00873                            "signature");
00874                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00875                                    TLS_ALERT_INTERNAL_ERROR);
00876                 return -1;
00877         }
00878 
00879         buflen = end - pos;
00880         buf = os_malloc(end - pos);
00881         if (crypto_public_key_decrypt_pkcs1(conn->client_rsa_key,
00882                                             pos, end - pos, buf, &buflen) < 0)
00883         {
00884                 wpa_printf(MSG_DEBUG, "TLSv1: Failed to decrypt signature");
00885                 os_free(buf);
00886                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00887                                    TLS_ALERT_DECRYPT_ERROR);
00888                 return -1;
00889         }
00890 
00891         wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: Decrypted Signature",
00892                         buf, buflen);
00893 
00894         if (buflen != hlen || os_memcmp(buf, hash, buflen) != 0) {
00895                 wpa_printf(MSG_DEBUG, "TLSv1: Invalid Signature in "
00896                            "CertificateVerify - did not match with calculated "
00897                            "hash");
00898                 os_free(buf);
00899                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00900                                    TLS_ALERT_DECRYPT_ERROR);
00901                 return -1;
00902         }
00903 
00904         os_free(buf);
00905 
00906         *in_len = end - in_data;
00907 
00908         conn->state = CHANGE_CIPHER_SPEC;
00909 
00910         return 0;
00911 }
00912 
00913 
00914 static int tls_process_change_cipher_spec(struct tlsv1_server *conn,
00915                                           u8 ct, const u8 *in_data,
00916                                           size_t *in_len)
00917 {
00918         const u8 *pos;
00919         size_t left;
00920 
00921         if (ct != TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC) {
00922                 wpa_printf(MSG_DEBUG, "TLSv1: Expected ChangeCipherSpec; "
00923                            "received content type 0x%x", ct);
00924                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00925                                    TLS_ALERT_UNEXPECTED_MESSAGE);
00926                 return -1;
00927         }
00928 
00929         pos = in_data;
00930         left = *in_len;
00931 
00932         if (left < 1) {
00933                 wpa_printf(MSG_DEBUG, "TLSv1: Too short ChangeCipherSpec");
00934                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00935                                    TLS_ALERT_DECODE_ERROR);
00936                 return -1;
00937         }
00938 
00939         if (*pos != TLS_CHANGE_CIPHER_SPEC) {
00940                 wpa_printf(MSG_DEBUG, "TLSv1: Expected ChangeCipherSpec; "
00941                            "received data 0x%x", *pos);
00942                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00943                                    TLS_ALERT_UNEXPECTED_MESSAGE);
00944                 return -1;
00945         }
00946 
00947         wpa_printf(MSG_DEBUG, "TLSv1: Received ChangeCipherSpec");
00948         if (tlsv1_record_change_read_cipher(&conn->rl) < 0) {
00949                 wpa_printf(MSG_DEBUG, "TLSv1: Failed to change read cipher "
00950                            "for record layer");
00951                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00952                                    TLS_ALERT_INTERNAL_ERROR);
00953                 return -1;
00954         }
00955 
00956         *in_len = pos + 1 - in_data;
00957 
00958         conn->state = CLIENT_FINISHED;
00959 
00960         return 0;
00961 }
00962 
00963 
00964 static int tls_process_client_finished(struct tlsv1_server *conn, u8 ct,
00965                                        const u8 *in_data, size_t *in_len)
00966 {
00967         const u8 *pos, *end;
00968         size_t left, len, hlen;
00969         u8 verify_data[TLS_VERIFY_DATA_LEN];
00970         u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN];
00971 
00972         if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
00973                 wpa_printf(MSG_DEBUG, "TLSv1: Expected Finished; "
00974                            "received content type 0x%x", ct);
00975                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00976                                    TLS_ALERT_UNEXPECTED_MESSAGE);
00977                 return -1;
00978         }
00979 
00980         pos = in_data;
00981         left = *in_len;
00982 
00983         if (left < 4) {
00984                 wpa_printf(MSG_DEBUG, "TLSv1: Too short record (left=%lu) for "
00985                            "Finished",
00986                            (unsigned long) left);
00987                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00988                                    TLS_ALERT_DECODE_ERROR);
00989                 return -1;
00990         }
00991 
00992         if (pos[0] != TLS_HANDSHAKE_TYPE_FINISHED) {
00993                 wpa_printf(MSG_DEBUG, "TLSv1: Expected Finished; received "
00994                            "type 0x%x", pos[0]);
00995                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00996                                    TLS_ALERT_UNEXPECTED_MESSAGE);
00997                 return -1;
00998         }
00999 
01000         len = WPA_GET_BE24(pos + 1);
01001 
01002         pos += 4;
01003         left -= 4;
01004 
01005         if (len > left) {
01006                 wpa_printf(MSG_DEBUG, "TLSv1: Too short buffer for Finished "
01007                            "(len=%lu > left=%lu)",
01008                            (unsigned long) len, (unsigned long) left);
01009                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
01010                                    TLS_ALERT_DECODE_ERROR);
01011                 return -1;
01012         }
01013         end = pos + len;
01014         if (len != TLS_VERIFY_DATA_LEN) {
01015                 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected verify_data length "
01016                            "in Finished: %lu (expected %d)",
01017                            (unsigned long) len, TLS_VERIFY_DATA_LEN);
01018                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
01019                                    TLS_ALERT_DECODE_ERROR);
01020                 return -1;
01021         }
01022         wpa_hexdump(MSG_MSGDUMP, "TLSv1: verify_data in Finished",
01023                     pos, TLS_VERIFY_DATA_LEN);
01024 
01025         hlen = MD5_MAC_LEN;
01026         if (conn->verify.md5_client == NULL ||
01027             crypto_hash_finish(conn->verify.md5_client, hash, &hlen) < 0) {
01028                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
01029                                    TLS_ALERT_INTERNAL_ERROR);
01030                 conn->verify.md5_client = NULL;
01031                 crypto_hash_finish(conn->verify.sha1_client, NULL, NULL);
01032                 conn->verify.sha1_client = NULL;
01033                 return -1;
01034         }
01035         conn->verify.md5_client = NULL;
01036         hlen = SHA1_MAC_LEN;
01037         if (conn->verify.sha1_client == NULL ||
01038             crypto_hash_finish(conn->verify.sha1_client, hash + MD5_MAC_LEN,
01039                                &hlen) < 0) {
01040                 conn->verify.sha1_client = NULL;
01041                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
01042                                    TLS_ALERT_INTERNAL_ERROR);
01043                 return -1;
01044         }
01045         conn->verify.sha1_client = NULL;
01046 
01047         if (tls_prf(conn->master_secret, TLS_MASTER_SECRET_LEN,
01048                     "client finished", hash, MD5_MAC_LEN + SHA1_MAC_LEN,
01049                     verify_data, TLS_VERIFY_DATA_LEN)) {
01050                 wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive verify_data");
01051                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
01052                                    TLS_ALERT_DECRYPT_ERROR);
01053                 return -1;
01054         }
01055         wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (client)",
01056                         verify_data, TLS_VERIFY_DATA_LEN);
01057 
01058         if (os_memcmp(pos, verify_data, TLS_VERIFY_DATA_LEN) != 0) {
01059                 wpa_printf(MSG_INFO, "TLSv1: Mismatch in verify_data");
01060                 return -1;
01061         }
01062 
01063         wpa_printf(MSG_DEBUG, "TLSv1: Received Finished");
01064 
01065         *in_len = end - in_data;
01066 
01067         if (conn->use_session_ticket) {
01068                 /* Abbreviated handshake using session ticket; RFC 4507 */
01069                 wpa_printf(MSG_DEBUG, "TLSv1: Abbreviated handshake completed "
01070                            "successfully");
01071                 conn->state = ESTABLISHED;
01072         } else {
01073                 /* Full handshake */
01074                 conn->state = SERVER_CHANGE_CIPHER_SPEC;
01075         }
01076 
01077         return 0;
01078 }
01079 
01080 
01081 int tlsv1_server_process_handshake(struct tlsv1_server *conn, u8 ct,
01082                                    const u8 *buf, size_t *len)
01083 {
01084         if (ct == TLS_CONTENT_TYPE_ALERT) {
01085                 if (*len < 2) {
01086                         wpa_printf(MSG_DEBUG, "TLSv1: Alert underflow");
01087                         tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
01088                                            TLS_ALERT_DECODE_ERROR);
01089                         return -1;
01090                 }
01091                 wpa_printf(MSG_DEBUG, "TLSv1: Received alert %d:%d",
01092                            buf[0], buf[1]);
01093                 *len = 2;
01094                 conn->state = FAILED;
01095                 return -1;
01096         }
01097 
01098         switch (conn->state) {
01099         case CLIENT_HELLO:
01100                 if (tls_process_client_hello(conn, ct, buf, len))
01101                         return -1;
01102                 break;
01103         case CLIENT_CERTIFICATE:
01104                 if (tls_process_certificate(conn, ct, buf, len))
01105                         return -1;
01106                 break;
01107         case CLIENT_KEY_EXCHANGE:
01108                 if (tls_process_client_key_exchange(conn, ct, buf, len))
01109                         return -1;
01110                 break;
01111         case CERTIFICATE_VERIFY:
01112                 if (tls_process_certificate_verify(conn, ct, buf, len))
01113                         return -1;
01114                 break;
01115         case CHANGE_CIPHER_SPEC:
01116                 if (tls_process_change_cipher_spec(conn, ct, buf, len))
01117                         return -1;
01118                 break;
01119         case CLIENT_FINISHED:
01120                 if (tls_process_client_finished(conn, ct, buf, len))
01121                         return -1;
01122                 break;
01123         default:
01124                 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected state %d "
01125                            "while processing received message",
01126                            conn->state);
01127                 return -1;
01128         }
01129 
01130         if (ct == TLS_CONTENT_TYPE_HANDSHAKE)
01131                 tls_verify_hash_add(&conn->verify, buf, *len);
01132 
01133         return 0;
01134 }


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Apr 24 2014 15:34:36