]> git.ipfire.org Git - people/ms/strongswan.git/commitdiff
Moved TLS record parsing/generation to tls.c
authorMartin Willi <martin@revosec.ch>
Mon, 23 Aug 2010 14:21:49 +0000 (16:21 +0200)
committerMartin Willi <martin@revosec.ch>
Tue, 24 Aug 2010 06:45:49 +0000 (08:45 +0200)
src/libcharon/plugins/eap_tls/eap_tls.c
src/libcharon/plugins/eap_ttls/eap_ttls.c
src/libtls/tls.c
src/libtls/tls.h

index 77458007eb47a3519da943a0dddb304dcc5c6c54..8b5d4cb19f8d0f018bb2edc7f3549afd5c026407 100644 (file)
@@ -95,16 +95,6 @@ typedef struct __attribute__((packed)) {
        u_int8_t flags;
 } eap_tls_packet_t;
 
-/**
- * TLS record
- */
-typedef struct __attribute__((packed)) {
-       u_int8_t type;
-       u_int16_t version;
-       u_int16_t length;
-       char data[];
-} tls_record_t;
-
 METHOD(eap_method_t, initiate, status_t,
        private_eap_tls_t *this, eap_payload_t **out)
 {
@@ -259,70 +249,18 @@ static eap_payload_t *read_buf(private_eap_tls_t *this, u_int8_t identifier)
  */
 static status_t process_buf(private_eap_tls_t *this)
 {
-       tls_record_t *in, out;
-       chunk_t data;
-       u_int16_t len;
        status_t status;
 
-       /* pass input buffer to upper layer, record for record */
-       data = this->input;
-       while (data.len > sizeof(tls_record_t))
+       status = this->tls->process(this->tls, this->input);
+       if (status != NEED_MORE)
        {
-               in = (tls_record_t*)data.ptr;
-               len = untoh16(&in->length);
-               DBG2(DBG_IKE, "received TLS %N record (%u bytes)",
-                        tls_content_type_names, in->type, sizeof(tls_record_t) + len);
-               if (len > data.len - sizeof(tls_record_t))
-               {
-                       DBG1(DBG_IKE, "TLS record length invalid");
-                       return FAILED;
-               }
-               if (untoh16(&in->version) < TLS_1_0)
-               {
-                       DBG1(DBG_IKE, "%N invalid with EAP-TLS",
-                                tls_version_names, untoh16(&in->version));
-                       return FAILED;
-               }
-
-               status = this->tls->process(this->tls, in->type,
-                                                                       chunk_create(in->data, len));
-               if (status != NEED_MORE)
-               {
-                       return status;
-               }
-               data = chunk_skip(data, len + sizeof(tls_record_t));
+               return status;
        }
        chunk_free(&this->input);
        this->inpos = 0;
 
-       /* read in records from upper layer, append to output buffer */
        chunk_free(&this->output);
-       while (TRUE)
-       {
-               tls_content_type_t type;
-               chunk_t header = chunk_from_thing(out);
-
-               status = this->tls->build(this->tls, &type, &data);
-               switch (status)
-               {
-                       case NEED_MORE:
-                               break;
-                       case INVALID_STATE:
-                               /* invalid state means we need more input from peer first */
-                               return NEED_MORE;
-                       case SUCCESS:
-                               return SUCCESS;
-                       case FAILED:
-                       default:
-                               return FAILED;
-               }
-               out.type = type;
-               htoun16(&out.version, this->tls->get_version(this->tls));
-               htoun16(&out.length, data.len);
-               this->output = chunk_cat("mcm", this->output, header, data);
-               DBG2(DBG_IKE, "sending TLS %N record (%u bytes)",
-                        tls_content_type_names, type, sizeof(tls_record_t) + data.len);
-       }
+       return this->tls->build(this->tls, &this->output);
 }
 
 METHOD(eap_method_t, process, status_t,
index 80994a37d4b4668598b949f8f57f33eafc9d9f04..d7372fe760ae1ade2f7dd0da9f0146021a71d15b 100644 (file)
@@ -262,70 +262,18 @@ static eap_payload_t *read_buf(private_eap_ttls_t *this, u_int8_t identifier)
  */
 static status_t process_buf(private_eap_ttls_t *this)
 {
-       tls_record_t *in, out;
-       chunk_t data;
-       u_int16_t len;
        status_t status;
 
-       /* pass input buffer to upper layer, record for record */
-       data = this->input;
-       while (data.len > sizeof(tls_record_t))
+       status = this->tls->process(this->tls, this->input);
+       if (status != NEED_MORE)
        {
-               in = (tls_record_t*)data.ptr;
-               len = untoh16(&in->length);
-               DBG2(DBG_IKE, "received TLS %N record (%u bytes)",
-                        tls_content_type_names, in->type, sizeof(tls_record_t) + len);
-               if (len > data.len - sizeof(tls_record_t))
-               {
-                       DBG1(DBG_IKE, "TLS record length invalid");
-                       return FAILED;
-               }
-               if (untoh16(&in->version) < TLS_1_0)
-               {
-                       DBG1(DBG_IKE, "%N invalid with EAP-TLS",
-                                tls_version_names, untoh16(&in->version));
-                       return FAILED;
-               }
-
-               status = this->tls->process(this->tls, in->type,
-                                                                       chunk_create(in->data, len));
-               if (status != NEED_MORE)
-               {
-                       return status;
-               }
-               data = chunk_skip(data, len + sizeof(tls_record_t));
+               return status;
        }
        chunk_free(&this->input);
        this->inpos = 0;
 
-       /* read in records from upper layer, append to output buffer */
        chunk_free(&this->output);
-       while (TRUE)
-       {
-               tls_content_type_t type;
-               chunk_t header = chunk_from_thing(out);
-
-               status = this->tls->build(this->tls, &type, &data);
-               switch (status)
-               {
-                       case NEED_MORE:
-                               break;
-                       case INVALID_STATE:
-                               /* invalid state means we need more input from peer first */
-                               return NEED_MORE;
-                       case SUCCESS:
-                               return SUCCESS;
-                       case FAILED:
-                       default:
-                               return FAILED;
-               }
-               out.type = type;
-               htoun16(&out.version, this->tls->get_version(this->tls));
-               htoun16(&out.length, data.len);
-               this->output = chunk_cat("mcm", this->output, header, data);
-               DBG2(DBG_IKE, "sending TLS %N record (%u bytes)",
-                        tls_content_type_names, type, sizeof(tls_record_t) + data.len);
-       }
+       return this->tls->build(this->tls, &this->output);
 }
 
 METHOD(eap_method_t, process, status_t,
index 42f71d753bd65d0e9dede0dc36b5cb1702c760f3..1f30f5a4ef63f1ecb397d0020391ff9a101ac18f 100644 (file)
@@ -15,6 +15,8 @@
 
 #include "tls.h"
 
+#include <debug.h>
+
 #include "tls_protection.h"
 #include "tls_compression.h"
 #include "tls_fragmentation.h"
@@ -127,16 +129,75 @@ struct private_tls_t {
        tls_application_t *application;
 };
 
+/**
+ * TLS record
+ */
+typedef struct __attribute__((packed)) {
+       u_int8_t type;
+       u_int16_t version;
+       u_int16_t length;
+       char data[];
+} tls_record_t;
+
 METHOD(tls_t, process, status_t,
-       private_tls_t *this, tls_content_type_t type, chunk_t data)
+       private_tls_t *this, chunk_t data)
 {
-       return this->protection->process(this->protection, type, data);
+       tls_record_t *record;
+       u_int16_t len;
+       status_t status;
+
+       while (data.len > sizeof(tls_record_t))
+       {
+               record = (tls_record_t*)data.ptr;
+               len = untoh16(&record->length);
+
+               DBG2(DBG_TLS, "received TLS %N record (%u bytes)",
+                        tls_content_type_names, record->type, sizeof(tls_record_t) + len);
+               if (len > data.len - sizeof(tls_record_t))
+               {
+                       DBG1(DBG_IKE, "TLS record length invalid");
+                       return FAILED;
+               }
+               status = this->protection->process(this->protection, record->type,
+                                                                                  chunk_create(record->data, len));
+               if (status != NEED_MORE)
+               {
+                       return status;
+               }
+               data = chunk_skip(data, len + sizeof(tls_record_t));
+       }
+
+       return NEED_MORE;
 }
 
 METHOD(tls_t, build, status_t,
-       private_tls_t *this, tls_content_type_t *type, chunk_t *data)
+       private_tls_t *this, chunk_t *data)
 {
-       return this->protection->build(this->protection, type, data);
+       tls_record_t record;
+       status_t status;
+
+       while (TRUE)
+       {
+               tls_content_type_t type;
+               chunk_t body;
+
+               status = this->protection->build(this->protection, &type, &body);
+               switch (status)
+               {
+                       case INVALID_STATE:
+                               return NEED_MORE;
+                       case NEED_MORE:
+                               break;
+                       default:
+                               return status;
+               }
+               record.type = type;
+               htoun16(&record.version, this->version);
+               htoun16(&record.length, body.len);
+               *data = chunk_cat("mcm", *data, chunk_from_thing(record), body);
+               DBG2(DBG_TLS, "sending TLS %N record (%u bytes)",
+                        tls_content_type_names, type, sizeof(tls_record_t) + body.len);
+       }
 }
 
 METHOD(tls_t, is_server, bool,
index 5c06686b744340263a385a71bccad2815cbd0aa9..36ca59201905bb1957daa58dfcb75d8b9c19e512 100644 (file)
@@ -106,29 +106,26 @@ enum tls_purpose_t {
 struct tls_t {
 
        /**
-        * Process a TLS record, pass it to upper layers.
+        * Process one or more TLS records, pass it to upper layers.
         *
-        * @param type          type of the TLS record to process
-        * @param data          associated TLS record data
+        * @param data          TLS record data, including headers
         * @return
         *                                      - SUCCESS if TLS negotiation complete
         *                                      - FAILED if TLS handshake failed
         *                                      - NEED_MORE if more invocations to process/build needed
         */
-       status_t (*process)(tls_t *this, tls_content_type_t type, chunk_t data);
+       status_t (*process)(tls_t *this, chunk_t data);
 
        /**
         * Query upper layer for TLS record, build protected record.
         *
-        * @param type          type of the built TLS record
         * @param data          allocated data of the built TLS record
         * @return
         *                                      - SUCCESS if TLS negotiation complete
         *                                      - FAILED if TLS handshake failed
-        *                                      - NEED_MORE if upper layers have more records to send
-        *                                      - INVALID_STATE if more input records required
+        *                                      - NEED_MORE if more input records required
         */
-       status_t (*build)(tls_t *this, tls_content_type_t *type, chunk_t *data);
+       status_t (*build)(tls_t *this, chunk_t *data);
 
        /**
         * Check if TLS stack is acting as a server.