A super trimmed down TLS stack, GPL licensed

Dependents:   MiniTLS-HTTPS-Example

MiniTLS - A super trimmed down TLS/SSL Library for embedded devices Author: Donatien Garnier Copyright (C) 2013-2014 AppNearMe Ltd

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

tls/tls_socket_defs.h

Committer:
MiniTLS
Date:
2014-06-10
Revision:
4:cbaf466d717d

File content as of revision 4:cbaf466d717d:

/*
MiniTLS - A super trimmed down TLS/SSL Library for embedded devices
Author: Donatien Garnier
Copyright (C) 2013-2014 AppNearMe Ltd

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*//**
 * \file tls_socket_defs.h
 * \copyright Copyright (c) AppNearMe Ltd 2013
 * \author Donatien Garnier
 */

#ifndef TLS_SOCKET_DEFS_H_
#define TLS_SOCKET_DEFS_H_

#ifdef __cplusplus
extern "C" {
#endif

#include "core/fwk.h"
#include "inc/minitls_config.h"

typedef struct __tls_socket tls_socket_t;

//We support SSL 3 and TLS 1.0, 1.1 and 1.2

#define TLS_1_2_VERSION_MAJOR 3
#define TLS_1_2_VERSION_MINOR 3

#define TLS_1_1_VERSION_MAJOR 3
#define TLS_1_1_VERSION_MINOR 2

#define TLS_1_0_VERSION_MAJOR 3
#define TLS_1_0_VERSION_MINOR 1

#define SSL_3_VERSION_MAJOR 3
#define SSL_3_VERSION_MINOR 0

typedef enum __tls_handshake_state
{
  TLS_HANDSHAKE_INIT = 0,
  TLS_HANDSHAKE_HELLO_SENT,
  TLS_HANDSHAKE_HELLO_RECEIVED,
  TLS_HANDSHAKE_HELLO_RECEIVED_SESSION_RESUMPTION,
  TLS_HANDSHAKE_CERTIFICATE_RECEIVED,
  TLS_HANDSHAKE_SERVER_KEY_EXCHANGE_RECEIVED,
  TLS_HANDSHAKE_CERTIFICATE_REQUEST_RECEIVED,
  TLS_HANDSHAKE_HELLO_DONE_RECEIVED,
  TLS_HANDSHAKE_CERTIFICATE_SENT,
  TLS_HANDSHAKE_CLIENT_KEY_EXCHANGE_SENT,
  TLS_HANDSHAKE_CERTIFICATE_VERIFY_SENT,
  TLS_HANDSHAKE_FINISHED_SENT,
  TLS_HANDSHAKE_FINISHED_RECEIVED,
  TLS_HANDSHAKE_FAILED,
  TLS_HANDSHAKE_DONE,
} tls_handshake_state_t;

#define HANDSHAKE_RANDOM_SIZE 32
#define HANDSHAKE_MASTER_KEY_SIZE 48

#include "crypto/crypto_md5.h"
#include "crypto/crypto_sha1.h"
#include "crypto/crypto_sha256.h"
#include "crypto/crypto_ecc.h"

#include "tls_security.h"

struct __tls_handshake
{
  tls_socket_t* tls_socket;
  tls_handshake_state_t state;
  uint8_t random_client[HANDSHAKE_RANDOM_SIZE];
  uint8_t random_server[HANDSHAKE_RANDOM_SIZE];

//  tls_security_t target_security;

  bool certificate_requested;

  union
  {
#if CRYPTO_ECC
    struct {
      //Ephemeral key parameters
      const crypto_ecc_curve_t* curve;
      crypto_ecc_public_key_t server_key; //This is the static key
      crypto_ecc_private_key_t client_key;
    } ecc;
#endif
#if CRYPTO_RSA
    struct {
      //No ephemeral key parameters
    } rsa;
#endif
  } key_exchange;

  struct //Cannot use an union as we need to compute hash before knowing which SSL/TLS version to use (ServerHello)
  {
#if MINITLS_CFG_PROTOCOL_TLS_1_2
    crypto_sha256_t sha256;
#endif
#if (MINITLS_CFG_PROTOCOL_TLS_1_1 || MINITLS_CFG_PROTOCOL_TLS_1_0 || MINITLS_CFG_PROTOCOL_SSL_3)
    struct
    {
      crypto_md5_t md5;
      crypto_sha1_t sha1;
    } md5_sha1;
#endif
  } hash; //Hash of the whole handshake exchange

  tls_security_type_t target_security;
};

typedef struct __tls_handshake tls_handshake_t;


typedef enum __tls_security
{
  TLS_SECURITY_NONE,
  TLS_SECURITY_INTIALIZED,
  TLS_SECURITY_ACTIVE
} tls_security_state_t;

typedef struct  __tls_protocol_version
{
  uint8_t major;
  uint8_t minor;
} tls_protocol_version_t;


#include "tls_security.h"

#include "crypto/crypto_hmac_sha1.h"
#include "crypto/crypto_aes_128_cbc.h"
#include "crypto/crypto_arc4.h"

struct __tls_record
{
  bool handshake_done;

  int socket_fd;

  int read_timeout;
  int write_timeout;
  size_t max_fragment_size; //Size to negotiate using RFC extension - supported by GNUTLS but not OpenSSL

  tls_protocol_version_t version;
  buffer_t buffer;
  /*
  buffer_t buffer_tx_fragment_header;
  buffer_t buffer_tx_iv_header;
  */

  tls_socket_t* tls_socket;

  tls_security_state_t security_rx_state;
  tls_security_state_t security_tx_state;

  tls_security_type_t security_type;

  union
  {
#if CRYPTO_AES_128
    crypto_aes_128_t aes_128;
#endif
#if CRYPTO_ARC4
    crypto_arc4_t arc4;
#endif
  } cipher_rx;

  union
  {
#if CRYPTO_AES_128
    crypto_aes_128_t aes_128;
#endif
#if CRYPTO_ARC4
    crypto_arc4_t arc4;
#endif
  } cipher_tx;

  uint64_t sequence_number_rx;
  uint64_t sequence_number_tx;

  //Keys
  uint8_t client_write_mac_key[TLS_HMAC_SHA1_KEY_SIZE];
  uint8_t server_write_mac_key[TLS_HMAC_SHA1_KEY_SIZE];
  uint8_t client_write_cipher_key[AES_128_KEY_SIZE]; //TODO ARC4 key size 16 as well
  uint8_t server_write_cipher_key[AES_128_KEY_SIZE];
};

typedef struct __tls_record tls_record_t;

typedef enum __tls_content_type
{
    TLS_CHANGE_CIPHER_SPEC = 20,
    TLS_ALERT = 21,
    TLS_HANDSHAKE = 22,
    TLS_APPLICATION_DATA = 23,
    __TLS_MAX = 255
} tls_content_type_t;

#define SESSION_ID_MAX_SIZE 32

typedef struct  __tls_session
{
  uint8_t master_key[HANDSHAKE_MASTER_KEY_SIZE];
  size_t session_id_length;
  uint8_t session_id[SESSION_ID_MAX_SIZE];
}
tls_session_t;

#include "minitls.h"

typedef struct __tls_socket_event tls_socket_event_t;
typedef struct __tls_socket_event_list tls_socket_event_list_t;
struct __tls_socket
{
  tls_record_t record;
  tls_handshake_t handshake;
  minitls_t* minitls;

  //Session info
  tls_session_t session;

  //Internal sauce
  tls_socket_event_t* events;
  buffer_t* read_buffer; //Passed by record layer
  buffer_t write_buffer;
  rtos_mtx_t* mtx;
};

//typedef void (*tls_socket_event_cb_t)(tls_socket_t* socket, bool read, bool write, void* param);
struct __tls_socket_event_list
{
  tls_socket_event_t* head;
  rtos_sem_t* sem;
};

struct __tls_socket_event
{
  tls_socket_t* socket;
  bool read;
  bool write;
  bool fired;
  tls_socket_event_list_t* list;
  tls_socket_event_t* socket_list_next;
  tls_socket_event_t* event_list_next;
};


#ifdef __cplusplus
}
#endif

#endif /* TLS_SOCKET_DEFS_H_ */