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