This is a fork of the mbed port of axTLS

Dependents:   TLS_axTLS-Example HTTPSClientExample

Overview

This library is a fork from the mbed port of axTLS. It attempts to :

  • reduce the usage of dynamic memory
  • verify certificates with key size up to 2048 bits
  • provide a simple interface

Encryption

This library uses either RC4 or AES for encryption.

Memory usage

During the establishment of a connection, about 10KB of memory is allocated dynamically (it depends on certificates). Once the connection is established, the memory consumption is relatively low. This means that your program must not use too much static memory or allocate memory before you establish a TLS connection.

Certificates

Certificates are the major source of problem and will often be the reason why your program will crash. Due to memory constraint, there are some limitations on certificates :

  • Each certificate must not be bigger than 2KB
  • TLS client can only handle a chain of up to three certificates (excluding the root certificate). This means that the server must not send more than three certificates.

Also, this library can only load certificates following these specifications :

  • encoded in binary DER format (PKCS1)
  • The public key must use RSA only

Once the connection is established, you should free all loaded certificates by calling CertificateManager::clear(). This will free a few kilobytes (it depends on your certificates). In addition, to enable certificate verification during the connection, this library has a "precomputed mode". This mode uses much less memory than a normal certificate verification.

Normal mode

You need to copy the root certificate in binary-DER format on the mbed. Then in your code, let's say that your root certificate is saved on the mbed as "root.der", assuming that you include CertificateManager.h and that you created a LocalFileSystem, you can load this certificate as this ;

Load root certificate

CertificateManager::add("/local/root.der");
CertificateManager::load();

Do not forget that this mode takes quite a lot of memory ( the memory peak is high while verifying certificates) and will only work if the key size is not bigger than 1024 bits (otherwise it will crash while verifying certificates).

Precomputed mode

In this mode, you need to save the entire chain of certificates (in binary-DER format) including the root certificate on the mbed. In practice, this means that you must first retrieve all certificates that the server sends during a connection and then find the right root certificate. In your code, you must call CertificateManager::add for each certificate and in the right order : from the server certificate to the root certificate. Here is how you shoud load certificates in this mode :

Loadcertificates in precomputed mode

CertificateManager::add("/local/server1.der");
CertificateManager::add("/local/server2.der");
CertificateManager::add("/local/server3.der");
CertificateManager::add("/local/root.der");
CertificateManager::load(true);

Using this mode, you should be able to verify certificates with key size up to 2048 bits.

How do I find these certificates ?

I posted an entry in my notebook detailing how to get certificates from a server. You should be able to get all certificates you need except the root certificate. Here is a way how to get the root certificate on windows :

  1. Open (double-click) the last certificate sent by the server
  2. Go to details panel and click on the entry called Issuer. The first line gives you the name of this certificate and the second line indicates the company who created this certificate
  3. Open firefox
  4. Go to options, advanced panel and click on View Certificates
  5. Go to Authorities panel
  6. Choose the certificate whose name match the issuer of the last certificate sent by the server
  7. Export this certificate to binary-DER format.

Connect to mbed.org !

Import programTLS_axTLS-Example

Establishing a connection to mbed.org using TLS

Committer:
feb11
Date:
Thu Sep 12 15:18:04 2013 +0000
Revision:
0:85fceccc1a7c
intial import

Who changed what in which revision?

UserRevisionLine numberNew contents of line
feb11 0:85fceccc1a7c 1 /*
feb11 0:85fceccc1a7c 2 * Copyright (c) 2007, Cameron Rich
feb11 0:85fceccc1a7c 3 *
feb11 0:85fceccc1a7c 4 * All rights reserved.
feb11 0:85fceccc1a7c 5 *
feb11 0:85fceccc1a7c 6 * Redistribution and use in source and binary forms, with or without
feb11 0:85fceccc1a7c 7 * modification, are permitted provided that the following conditions are met:
feb11 0:85fceccc1a7c 8 *
feb11 0:85fceccc1a7c 9 * * Redistributions of source code must retain the above copyright notice,
feb11 0:85fceccc1a7c 10 * this list of conditions and the following disclaimer.
feb11 0:85fceccc1a7c 11 * * Redistributions in binary form must reproduce the above copyright notice,
feb11 0:85fceccc1a7c 12 * this list of conditions and the following disclaimer in the documentation
feb11 0:85fceccc1a7c 13 * and/or other materials provided with the distribution.
feb11 0:85fceccc1a7c 14 * * Neither the name of the axTLS project nor the names of its contributors
feb11 0:85fceccc1a7c 15 * may be used to endorse or promote products derived from this software
feb11 0:85fceccc1a7c 16 * without specific prior written permission.
feb11 0:85fceccc1a7c 17 *
feb11 0:85fceccc1a7c 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
feb11 0:85fceccc1a7c 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
feb11 0:85fceccc1a7c 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
feb11 0:85fceccc1a7c 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
feb11 0:85fceccc1a7c 22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
feb11 0:85fceccc1a7c 23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
feb11 0:85fceccc1a7c 24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
feb11 0:85fceccc1a7c 25 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
feb11 0:85fceccc1a7c 26 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
feb11 0:85fceccc1a7c 27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
feb11 0:85fceccc1a7c 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
feb11 0:85fceccc1a7c 29 */
feb11 0:85fceccc1a7c 30
feb11 0:85fceccc1a7c 31 /**
feb11 0:85fceccc1a7c 32 * Common ssl/tlsv1 code to both the client and server implementations.
feb11 0:85fceccc1a7c 33 */
feb11 0:85fceccc1a7c 34
feb11 0:85fceccc1a7c 35
feb11 0:85fceccc1a7c 36 #include <string.h>
feb11 0:85fceccc1a7c 37 #include <stdlib.h>
feb11 0:85fceccc1a7c 38 #include <stdio.h>
feb11 0:85fceccc1a7c 39 #include <stdarg.h>
feb11 0:85fceccc1a7c 40 #include <errno.h>
feb11 0:85fceccc1a7c 41
feb11 0:85fceccc1a7c 42
feb11 0:85fceccc1a7c 43
feb11 0:85fceccc1a7c 44 #include "lwip/sockets.h"
feb11 0:85fceccc1a7c 45 #include "os_port.h"
feb11 0:85fceccc1a7c 46 #include "ssl.h"
feb11 0:85fceccc1a7c 47 #include "arch.h"
feb11 0:85fceccc1a7c 48 #include "../../cert_manager.h"
feb11 0:85fceccc1a7c 49
feb11 0:85fceccc1a7c 50 /* The session expiry time */
feb11 0:85fceccc1a7c 51 #define SSL_EXPIRY_TIME (CONFIG_SSL_EXPIRY_TIME*3600)
feb11 0:85fceccc1a7c 52
feb11 0:85fceccc1a7c 53 static const uint8_t g_hello_request[] = { HS_HELLO_REQUEST, 0, 0, 0 };
feb11 0:85fceccc1a7c 54 static const uint8_t g_chg_cipher_spec_pkt[] = { 1 };
feb11 0:85fceccc1a7c 55 static const char * server_finished = "server finished";
feb11 0:85fceccc1a7c 56 static const char * client_finished = "client finished";
feb11 0:85fceccc1a7c 57
feb11 0:85fceccc1a7c 58 static int do_handshake(SSL *ssl, uint8_t *buf, int read_len);
feb11 0:85fceccc1a7c 59 static int set_key_block(SSL *ssl, int is_write);
feb11 0:85fceccc1a7c 60 static int verify_digest(SSL *ssl, int mode, const uint8_t *buf, int read_len);
feb11 0:85fceccc1a7c 61 static void *crypt_new(SSL *ssl, uint8_t *key, uint8_t *iv, int is_decrypt);
feb11 0:85fceccc1a7c 62 static int send_raw_packet(SSL *ssl, uint8_t protocol);
feb11 0:85fceccc1a7c 63
feb11 0:85fceccc1a7c 64 /**
feb11 0:85fceccc1a7c 65 * The server will pick the cipher based on the order that the order that the
feb11 0:85fceccc1a7c 66 * ciphers are listed. This order is defined at compile time.
feb11 0:85fceccc1a7c 67 */
feb11 0:85fceccc1a7c 68 #ifdef CONFIG_SSL_SKELETON_MODE
feb11 0:85fceccc1a7c 69 const uint8_t ssl_prot_prefs[NUM_PROTOCOLS] =
feb11 0:85fceccc1a7c 70 { SSL_RC4_128_SHA };
feb11 0:85fceccc1a7c 71 #else
feb11 0:85fceccc1a7c 72 static void session_free(SSL_SESSION *ssl_sessions[], int sess_index);
feb11 0:85fceccc1a7c 73
feb11 0:85fceccc1a7c 74 const uint8_t ssl_prot_prefs[NUM_PROTOCOLS] =
feb11 0:85fceccc1a7c 75 #ifdef CONFIG_SSL_PROT_LOW /* low security, fast speed */
feb11 0:85fceccc1a7c 76 { SSL_RC4_128_SHA , SSL_AES128_SHA /*, SSL_AES256_SHA, SSL_RC4_128_MD5*/ };
feb11 0:85fceccc1a7c 77 #elif CONFIG_SSL_PROT_MEDIUM /* medium security, medium speed */
feb11 0:85fceccc1a7c 78 { SSL_RC4_128_SHA SSL_AES128_SHA, SSL_AES256_SHA, SSL_RC4_128_SHA, SSL_RC4_128_MD5*/ };
feb11 0:85fceccc1a7c 79 #else /* CONFIG_SSL_PROT_HIGH */ /* high security, low speed */
feb11 0:85fceccc1a7c 80 { SSL_RC4_128_SHA SSL_AES256_SHA, SSL_AES128_SHA, SSL_RC4_128_SHA, SSL_RC4_128_MD5*/ };
feb11 0:85fceccc1a7c 81 #endif
feb11 0:85fceccc1a7c 82 #endif /* CONFIG_SSL_SKELETON_MODE */
feb11 0:85fceccc1a7c 83
feb11 0:85fceccc1a7c 84 /**
feb11 0:85fceccc1a7c 85 * The cipher map containing all the essentials for each cipher.
feb11 0:85fceccc1a7c 86 */
feb11 0:85fceccc1a7c 87 #ifdef CONFIG_SSL_SKELETON_MODE
feb11 0:85fceccc1a7c 88 static const cipher_info_t cipher_info[NUM_PROTOCOLS] =
feb11 0:85fceccc1a7c 89 {
feb11 0:85fceccc1a7c 90 { /* RC4-SHA */
feb11 0:85fceccc1a7c 91 SSL_RC4_128_SHA, /* RC4-SHA */
feb11 0:85fceccc1a7c 92 16, /* key size */
feb11 0:85fceccc1a7c 93 0, /* iv size */
feb11 0:85fceccc1a7c 94 2*(SHA1_SIZE+16), /* key block size */
feb11 0:85fceccc1a7c 95 0, /* no padding */
feb11 0:85fceccc1a7c 96 SHA1_SIZE, /* digest size */
feb11 0:85fceccc1a7c 97 hmac_sha1, /* hmac algorithm */
feb11 0:85fceccc1a7c 98 (crypt_func)RC4_crypt, /* encrypt */
feb11 0:85fceccc1a7c 99 (crypt_func)RC4_crypt /* decrypt */
feb11 0:85fceccc1a7c 100 },
feb11 0:85fceccc1a7c 101 };
feb11 0:85fceccc1a7c 102 #else
feb11 0:85fceccc1a7c 103 static const cipher_info_t cipher_info[NUM_PROTOCOLS] =
feb11 0:85fceccc1a7c 104 {
feb11 0:85fceccc1a7c 105 { /* AES128-SHA */
feb11 0:85fceccc1a7c 106 SSL_AES128_SHA, /* AES128-SHA */
feb11 0:85fceccc1a7c 107 16, /* key size */
feb11 0:85fceccc1a7c 108 16, /* iv size */
feb11 0:85fceccc1a7c 109 2*(SHA1_SIZE+16+16), /* key block size */
feb11 0:85fceccc1a7c 110 16, /* block padding size */
feb11 0:85fceccc1a7c 111 SHA1_SIZE, /* digest size */
feb11 0:85fceccc1a7c 112 hmac_sha1, /* hmac algorithm */
feb11 0:85fceccc1a7c 113 (crypt_func)AES_cbc_encrypt, /* encrypt */
feb11 0:85fceccc1a7c 114 (crypt_func)AES_cbc_decrypt /* decrypt */
feb11 0:85fceccc1a7c 115 },
feb11 0:85fceccc1a7c 116 { /* AES256-SHA */
feb11 0:85fceccc1a7c 117 SSL_AES256_SHA, /* AES256-SHA */
feb11 0:85fceccc1a7c 118 32, /* key size */
feb11 0:85fceccc1a7c 119 16, /* iv size */
feb11 0:85fceccc1a7c 120 2*(SHA1_SIZE+32+16), /* key block size */
feb11 0:85fceccc1a7c 121 16, /* block padding size */
feb11 0:85fceccc1a7c 122 SHA1_SIZE, /* digest size */
feb11 0:85fceccc1a7c 123 hmac_sha1, /* hmac algorithm */
feb11 0:85fceccc1a7c 124 (crypt_func)AES_cbc_encrypt, /* encrypt */
feb11 0:85fceccc1a7c 125 (crypt_func)AES_cbc_decrypt /* decrypt */
feb11 0:85fceccc1a7c 126 },
feb11 0:85fceccc1a7c 127 { /* RC4-SHA */
feb11 0:85fceccc1a7c 128 SSL_RC4_128_SHA, /* RC4-SHA */
feb11 0:85fceccc1a7c 129 16, /* key size */
feb11 0:85fceccc1a7c 130 0, /* iv size */
feb11 0:85fceccc1a7c 131 2*(SHA1_SIZE+16), /* key block size */
feb11 0:85fceccc1a7c 132 0, /* no padding */
feb11 0:85fceccc1a7c 133 SHA1_SIZE, /* digest size */
feb11 0:85fceccc1a7c 134 hmac_sha1, /* hmac algorithm */
feb11 0:85fceccc1a7c 135 (crypt_func)RC4_crypt, /* encrypt */
feb11 0:85fceccc1a7c 136 (crypt_func)RC4_crypt /* decrypt */
feb11 0:85fceccc1a7c 137 },
feb11 0:85fceccc1a7c 138 /*
feb11 0:85fceccc1a7c 139 * This protocol is from SSLv2 days and is unlikely to be used - but was
feb11 0:85fceccc1a7c 140 * useful for testing different possible digest algorithms.
feb11 0:85fceccc1a7c 141 */
feb11 0:85fceccc1a7c 142 { /* RC4-MD5 */
feb11 0:85fceccc1a7c 143 SSL_RC4_128_MD5, /* RC4-MD5 */
feb11 0:85fceccc1a7c 144 16, /* key size */
feb11 0:85fceccc1a7c 145 0, /* iv size */
feb11 0:85fceccc1a7c 146 2*(MD5_SIZE+16), /* key block size */
feb11 0:85fceccc1a7c 147 0, /* no padding */
feb11 0:85fceccc1a7c 148 MD5_SIZE, /* digest size */
feb11 0:85fceccc1a7c 149 hmac_md5, /* hmac algorithm */
feb11 0:85fceccc1a7c 150 (crypt_func)RC4_crypt, /* encrypt */
feb11 0:85fceccc1a7c 151 (crypt_func)RC4_crypt /* decrypt */
feb11 0:85fceccc1a7c 152 },
feb11 0:85fceccc1a7c 153 };
feb11 0:85fceccc1a7c 154 #endif
feb11 0:85fceccc1a7c 155
feb11 0:85fceccc1a7c 156 static void prf(const uint8_t *sec, int sec_len, uint8_t *seed, int seed_len,
feb11 0:85fceccc1a7c 157 uint8_t *out, int olen);
feb11 0:85fceccc1a7c 158 static const cipher_info_t *get_cipher_info(uint8_t cipher);
feb11 0:85fceccc1a7c 159 static void increment_read_sequence(SSL *ssl);
feb11 0:85fceccc1a7c 160 static void increment_write_sequence(SSL *ssl);
feb11 0:85fceccc1a7c 161 static void add_hmac_digest(SSL *ssl, int snd, uint8_t *hmac_header,
feb11 0:85fceccc1a7c 162 const uint8_t *buf, int buf_len, uint8_t *hmac_buf);
feb11 0:85fceccc1a7c 163
feb11 0:85fceccc1a7c 164 /* win32 VC6.0 doesn't have variadic macros */
feb11 0:85fceccc1a7c 165 #if defined(WIN32) && !defined(CONFIG_SSL_FULL_MODE)
feb11 0:85fceccc1a7c 166 void DISPLAY_BYTES(SSL *ssl, const char *format,
feb11 0:85fceccc1a7c 167 const uint8_t *data, int size, ...) {}
feb11 0:85fceccc1a7c 168 #endif
feb11 0:85fceccc1a7c 169
feb11 0:85fceccc1a7c 170 /**
feb11 0:85fceccc1a7c 171 * Establish a new client/server context.
feb11 0:85fceccc1a7c 172 */
feb11 0:85fceccc1a7c 173 EXP_FUNC SSL_CTX *STDCALL ssl_ctx_new(SSL_CTX *ssl_ctx, uint32_t options, int num_sessions)
feb11 0:85fceccc1a7c 174 {
feb11 0:85fceccc1a7c 175 ssl_ctx->options = options;
feb11 0:85fceccc1a7c 176 RNG_initialize();
feb11 0:85fceccc1a7c 177
feb11 0:85fceccc1a7c 178 // if (load_key_certs(ssl_ctx) < 0)
feb11 0:85fceccc1a7c 179 // {
feb11 0:85fceccc1a7c 180 // printf("error loading key certs\r\n");
feb11 0:85fceccc1a7c 181 //free(ssl_ctx); /* can't load our key/certificate pair, so die */
feb11 0:85fceccc1a7c 182 // return NULL;
feb11 0:85fceccc1a7c 183 // }
feb11 0:85fceccc1a7c 184
feb11 0:85fceccc1a7c 185 #ifndef CONFIG_SSL_SKELETON_MODE
feb11 0:85fceccc1a7c 186 ssl_ctx->num_sessions = num_sessions;
feb11 0:85fceccc1a7c 187 #endif
feb11 0:85fceccc1a7c 188
feb11 0:85fceccc1a7c 189 SSL_CTX_MUTEX_INIT(ssl_ctx->mutex);
feb11 0:85fceccc1a7c 190
feb11 0:85fceccc1a7c 191 #ifndef CONFIG_SSL_SKELETON_MODE
feb11 0:85fceccc1a7c 192 if (num_sessions)
feb11 0:85fceccc1a7c 193 {
feb11 0:85fceccc1a7c 194 ssl_ctx->ssl_sessions = (SSL_SESSION **)
feb11 0:85fceccc1a7c 195 calloc(1, num_sessions*sizeof(SSL_SESSION *));
feb11 0:85fceccc1a7c 196 }
feb11 0:85fceccc1a7c 197 #endif
feb11 0:85fceccc1a7c 198
feb11 0:85fceccc1a7c 199 return ssl_ctx;
feb11 0:85fceccc1a7c 200 }
feb11 0:85fceccc1a7c 201
feb11 0:85fceccc1a7c 202 /*
feb11 0:85fceccc1a7c 203 * Remove a client/server context.
feb11 0:85fceccc1a7c 204 */
feb11 0:85fceccc1a7c 205 EXP_FUNC void STDCALL ssl_ctx_free(SSL_CTX *ssl_ctx)
feb11 0:85fceccc1a7c 206 {
feb11 0:85fceccc1a7c 207 SSL *ssl;
feb11 0:85fceccc1a7c 208 int i;
feb11 0:85fceccc1a7c 209
feb11 0:85fceccc1a7c 210 if (ssl_ctx == NULL)
feb11 0:85fceccc1a7c 211 return;
feb11 0:85fceccc1a7c 212
feb11 0:85fceccc1a7c 213 ssl = ssl_ctx->head;
feb11 0:85fceccc1a7c 214
feb11 0:85fceccc1a7c 215 /* clear out all the ssl entries */
feb11 0:85fceccc1a7c 216 while (ssl)
feb11 0:85fceccc1a7c 217 {
feb11 0:85fceccc1a7c 218 SSL *next = ssl->next;
feb11 0:85fceccc1a7c 219 ssl_free(ssl);
feb11 0:85fceccc1a7c 220 ssl = next;
feb11 0:85fceccc1a7c 221 }
feb11 0:85fceccc1a7c 222
feb11 0:85fceccc1a7c 223 #ifndef CONFIG_SSL_SKELETON_MODE
feb11 0:85fceccc1a7c 224 /* clear out all the sessions */
feb11 0:85fceccc1a7c 225 for (i = 0; i < ssl_ctx->num_sessions; i++)
feb11 0:85fceccc1a7c 226 session_free(ssl_ctx->ssl_sessions, i);
feb11 0:85fceccc1a7c 227
feb11 0:85fceccc1a7c 228 free(ssl_ctx->ssl_sessions);
feb11 0:85fceccc1a7c 229 #endif
feb11 0:85fceccc1a7c 230
feb11 0:85fceccc1a7c 231 i = 0;
feb11 0:85fceccc1a7c 232
feb11 0:85fceccc1a7c 233 #ifdef CONFIG_SSL_CERT_VERIFICATION
feb11 0:85fceccc1a7c 234 remove_ca_certs(ssl_ctx->ca_cert_ctx);
feb11 0:85fceccc1a7c 235 #endif
feb11 0:85fceccc1a7c 236
feb11 0:85fceccc1a7c 237 ssl_ctx->chain_length = 0;
feb11 0:85fceccc1a7c 238 SSL_CTX_MUTEX_DESTROY(ssl_ctx->mutex);
feb11 0:85fceccc1a7c 239 RSA_free(ssl_ctx->rsa_ctx);
feb11 0:85fceccc1a7c 240 RNG_terminate();
feb11 0:85fceccc1a7c 241 }
feb11 0:85fceccc1a7c 242
feb11 0:85fceccc1a7c 243 /*
feb11 0:85fceccc1a7c 244 * Free any used resources used by this connection.
feb11 0:85fceccc1a7c 245 */
feb11 0:85fceccc1a7c 246 EXP_FUNC void STDCALL ssl_free(SSL *ssl)
feb11 0:85fceccc1a7c 247 {
feb11 0:85fceccc1a7c 248 SSL_CTX *ssl_ctx;
feb11 0:85fceccc1a7c 249
feb11 0:85fceccc1a7c 250 if (ssl == NULL) /* just ignore null pointers */
feb11 0:85fceccc1a7c 251 return;
feb11 0:85fceccc1a7c 252
feb11 0:85fceccc1a7c 253 /* only notify if we weren't notified first */
feb11 0:85fceccc1a7c 254 /* spec says we must notify when we are dying */
feb11 0:85fceccc1a7c 255 if (!IS_SET_SSL_FLAG(SSL_SENT_CLOSE_NOTIFY))
feb11 0:85fceccc1a7c 256 send_alert(ssl, SSL_ALERT_CLOSE_NOTIFY);
feb11 0:85fceccc1a7c 257
feb11 0:85fceccc1a7c 258 ssl_ctx = ssl->ssl_ctx;
feb11 0:85fceccc1a7c 259
feb11 0:85fceccc1a7c 260 SSL_CTX_LOCK(ssl_ctx->mutex);
feb11 0:85fceccc1a7c 261
feb11 0:85fceccc1a7c 262 /* adjust the server SSL list */
feb11 0:85fceccc1a7c 263 if (ssl->prev)
feb11 0:85fceccc1a7c 264 ssl->prev->next = ssl->next;
feb11 0:85fceccc1a7c 265 else
feb11 0:85fceccc1a7c 266 ssl_ctx->head = ssl->next;
feb11 0:85fceccc1a7c 267
feb11 0:85fceccc1a7c 268 if (ssl->next)
feb11 0:85fceccc1a7c 269 ssl->next->prev = ssl->prev;
feb11 0:85fceccc1a7c 270 else
feb11 0:85fceccc1a7c 271 ssl_ctx->tail = ssl->prev;
feb11 0:85fceccc1a7c 272
feb11 0:85fceccc1a7c 273 SSL_CTX_UNLOCK(ssl_ctx->mutex);
feb11 0:85fceccc1a7c 274
feb11 0:85fceccc1a7c 275 /* may already be free - but be sure */
feb11 0:85fceccc1a7c 276 free(ssl->encrypt_ctx);
feb11 0:85fceccc1a7c 277 free(ssl->decrypt_ctx);
feb11 0:85fceccc1a7c 278 disposable_free(ssl);
feb11 0:85fceccc1a7c 279
feb11 0:85fceccc1a7c 280 #ifdef CONFIG_SSL_CERT_VERIFICATION
feb11 0:85fceccc1a7c 281 x509_free(ssl->x509_ctx);
feb11 0:85fceccc1a7c 282 #endif
feb11 0:85fceccc1a7c 283 //free(ssl->ssl_ctx);
feb11 0:85fceccc1a7c 284 //free(ssl);
feb11 0:85fceccc1a7c 285 }
feb11 0:85fceccc1a7c 286
feb11 0:85fceccc1a7c 287 /*
feb11 0:85fceccc1a7c 288 * Write application data to the client
feb11 0:85fceccc1a7c 289 */
feb11 0:85fceccc1a7c 290 EXP_FUNC int STDCALL ssl_write(SSL *ssl, const uint8_t *out_data, int out_len)
feb11 0:85fceccc1a7c 291 {
feb11 0:85fceccc1a7c 292 int n = out_len, nw, i, tot = 0;
feb11 0:85fceccc1a7c 293
feb11 0:85fceccc1a7c 294 /* maximum size of a TLS packet is around 16kB, so fragment */
feb11 0:85fceccc1a7c 295 do
feb11 0:85fceccc1a7c 296 {
feb11 0:85fceccc1a7c 297 nw = n;
feb11 0:85fceccc1a7c 298
feb11 0:85fceccc1a7c 299 if (nw > RT_MAX_PLAIN_LENGTH) /* fragment if necessary */
feb11 0:85fceccc1a7c 300 nw = RT_MAX_PLAIN_LENGTH;
feb11 0:85fceccc1a7c 301
feb11 0:85fceccc1a7c 302 if ((i = send_packet(ssl, PT_APP_PROTOCOL_DATA,
feb11 0:85fceccc1a7c 303 &out_data[tot], nw)) <= 0)
feb11 0:85fceccc1a7c 304 {
feb11 0:85fceccc1a7c 305 out_len = i; /* an error */
feb11 0:85fceccc1a7c 306 break;
feb11 0:85fceccc1a7c 307 }
feb11 0:85fceccc1a7c 308
feb11 0:85fceccc1a7c 309 tot += i;
feb11 0:85fceccc1a7c 310 n -= i;
feb11 0:85fceccc1a7c 311 } while (n > 0);
feb11 0:85fceccc1a7c 312
feb11 0:85fceccc1a7c 313 return out_len;
feb11 0:85fceccc1a7c 314 }
feb11 0:85fceccc1a7c 315
feb11 0:85fceccc1a7c 316
feb11 0:85fceccc1a7c 317 #ifdef CONFIG_SSL_CERT_VERIFICATION
feb11 0:85fceccc1a7c 318
feb11 0:85fceccc1a7c 319 /*
feb11 0:85fceccc1a7c 320 * Retrieve an X.509 distinguished name component
feb11 0:85fceccc1a7c 321 */
feb11 0:85fceccc1a7c 322 EXP_FUNC const char * STDCALL ssl_get_cert_dn(const SSL *ssl, int component)
feb11 0:85fceccc1a7c 323 {
feb11 0:85fceccc1a7c 324 if (ssl->x509_ctx == NULL)
feb11 0:85fceccc1a7c 325 return NULL;
feb11 0:85fceccc1a7c 326
feb11 0:85fceccc1a7c 327 switch (component)
feb11 0:85fceccc1a7c 328 {
feb11 0:85fceccc1a7c 329 case SSL_X509_CERT_COMMON_NAME:
feb11 0:85fceccc1a7c 330 return ssl->x509_ctx->cert_dn[X509_COMMON_NAME];
feb11 0:85fceccc1a7c 331
feb11 0:85fceccc1a7c 332 case SSL_X509_CERT_ORGANIZATION:
feb11 0:85fceccc1a7c 333 return ssl->x509_ctx->cert_dn[X509_ORGANIZATION];
feb11 0:85fceccc1a7c 334
feb11 0:85fceccc1a7c 335 case SSL_X509_CERT_ORGANIZATIONAL_NAME:
feb11 0:85fceccc1a7c 336 return ssl->x509_ctx->cert_dn[X509_ORGANIZATIONAL_UNIT];
feb11 0:85fceccc1a7c 337
feb11 0:85fceccc1a7c 338 case SSL_X509_CA_CERT_COMMON_NAME:
feb11 0:85fceccc1a7c 339 return ssl->x509_ctx->ca_cert_dn[X509_COMMON_NAME];
feb11 0:85fceccc1a7c 340
feb11 0:85fceccc1a7c 341 case SSL_X509_CA_CERT_ORGANIZATION:
feb11 0:85fceccc1a7c 342 return ssl->x509_ctx->ca_cert_dn[X509_ORGANIZATION];
feb11 0:85fceccc1a7c 343
feb11 0:85fceccc1a7c 344 case SSL_X509_CA_CERT_ORGANIZATIONAL_NAME:
feb11 0:85fceccc1a7c 345 return ssl->x509_ctx->ca_cert_dn[X509_ORGANIZATIONAL_UNIT];
feb11 0:85fceccc1a7c 346
feb11 0:85fceccc1a7c 347 default:
feb11 0:85fceccc1a7c 348 return NULL;
feb11 0:85fceccc1a7c 349 }
feb11 0:85fceccc1a7c 350 }
feb11 0:85fceccc1a7c 351
feb11 0:85fceccc1a7c 352 /*
feb11 0:85fceccc1a7c 353 * Retrieve a "Subject Alternative Name" from a v3 certificate
feb11 0:85fceccc1a7c 354 */
feb11 0:85fceccc1a7c 355 EXP_FUNC const char * STDCALL ssl_get_cert_subject_alt_dnsname(const SSL *ssl,
feb11 0:85fceccc1a7c 356 int dnsindex)
feb11 0:85fceccc1a7c 357 {
feb11 0:85fceccc1a7c 358 int i;
feb11 0:85fceccc1a7c 359
feb11 0:85fceccc1a7c 360 if (ssl->x509_ctx == NULL || ssl->x509_ctx->subject_alt_dnsnames == NULL)
feb11 0:85fceccc1a7c 361 return NULL;
feb11 0:85fceccc1a7c 362
feb11 0:85fceccc1a7c 363 for (i = 0; i < dnsindex; ++i)
feb11 0:85fceccc1a7c 364 {
feb11 0:85fceccc1a7c 365 if (ssl->x509_ctx->subject_alt_dnsnames[i] == NULL)
feb11 0:85fceccc1a7c 366 return NULL;
feb11 0:85fceccc1a7c 367 }
feb11 0:85fceccc1a7c 368
feb11 0:85fceccc1a7c 369 return ssl->x509_ctx->subject_alt_dnsnames[dnsindex];
feb11 0:85fceccc1a7c 370 }
feb11 0:85fceccc1a7c 371
feb11 0:85fceccc1a7c 372 #endif /* CONFIG_SSL_CERT_VERIFICATION */
feb11 0:85fceccc1a7c 373
feb11 0:85fceccc1a7c 374 /*
feb11 0:85fceccc1a7c 375 * Find an ssl object based on the client's file descriptor.
feb11 0:85fceccc1a7c 376 */
feb11 0:85fceccc1a7c 377 EXP_FUNC SSL * STDCALL ssl_find(SSL_CTX *ssl_ctx, int client_fd)
feb11 0:85fceccc1a7c 378 {
feb11 0:85fceccc1a7c 379 SSL *ssl;
feb11 0:85fceccc1a7c 380
feb11 0:85fceccc1a7c 381 SSL_CTX_LOCK(ssl_ctx->mutex);
feb11 0:85fceccc1a7c 382 ssl = ssl_ctx->head;
feb11 0:85fceccc1a7c 383
feb11 0:85fceccc1a7c 384 /* search through all the ssl entries */
feb11 0:85fceccc1a7c 385 while (ssl)
feb11 0:85fceccc1a7c 386 {
feb11 0:85fceccc1a7c 387 if (ssl->client_fd == client_fd)
feb11 0:85fceccc1a7c 388 {
feb11 0:85fceccc1a7c 389 SSL_CTX_UNLOCK(ssl_ctx->mutex);
feb11 0:85fceccc1a7c 390 return ssl;
feb11 0:85fceccc1a7c 391 }
feb11 0:85fceccc1a7c 392
feb11 0:85fceccc1a7c 393 ssl = ssl->next;
feb11 0:85fceccc1a7c 394 }
feb11 0:85fceccc1a7c 395
feb11 0:85fceccc1a7c 396 SSL_CTX_UNLOCK(ssl_ctx->mutex);
feb11 0:85fceccc1a7c 397 return NULL;
feb11 0:85fceccc1a7c 398 }
feb11 0:85fceccc1a7c 399
feb11 0:85fceccc1a7c 400 /*
feb11 0:85fceccc1a7c 401 * Force the client to perform its handshake again.
feb11 0:85fceccc1a7c 402 */
feb11 0:85fceccc1a7c 403 EXP_FUNC int STDCALL ssl_renegotiate(SSL *ssl)
feb11 0:85fceccc1a7c 404 {
feb11 0:85fceccc1a7c 405 int ret = SSL_OK;
feb11 0:85fceccc1a7c 406
feb11 0:85fceccc1a7c 407 disposable_new(ssl);
feb11 0:85fceccc1a7c 408 #ifdef CONFIG_SSL_ENABLE_CLIENT
feb11 0:85fceccc1a7c 409 if (IS_SET_SSL_FLAG(SSL_IS_CLIENT))
feb11 0:85fceccc1a7c 410 {
feb11 0:85fceccc1a7c 411 ret = do_client_connect(ssl);
feb11 0:85fceccc1a7c 412 }
feb11 0:85fceccc1a7c 413 else
feb11 0:85fceccc1a7c 414 #endif
feb11 0:85fceccc1a7c 415 {
feb11 0:85fceccc1a7c 416 send_packet(ssl, PT_HANDSHAKE_PROTOCOL,
feb11 0:85fceccc1a7c 417 g_hello_request, sizeof(g_hello_request));
feb11 0:85fceccc1a7c 418 SET_SSL_FLAG(SSL_NEED_RECORD);
feb11 0:85fceccc1a7c 419 }
feb11 0:85fceccc1a7c 420
feb11 0:85fceccc1a7c 421 return ret;
feb11 0:85fceccc1a7c 422 }
feb11 0:85fceccc1a7c 423
feb11 0:85fceccc1a7c 424 /**
feb11 0:85fceccc1a7c 425 * @brief Get what we need for key info.
feb11 0:85fceccc1a7c 426 * @param cipher [in] The cipher information we are after
feb11 0:85fceccc1a7c 427 * @param key_size [out] The key size for the cipher
feb11 0:85fceccc1a7c 428 * @param iv_size [out] The iv size for the cipher
feb11 0:85fceccc1a7c 429 * @return The amount of key information we need.
feb11 0:85fceccc1a7c 430 */
feb11 0:85fceccc1a7c 431 static const cipher_info_t *get_cipher_info(uint8_t cipher)
feb11 0:85fceccc1a7c 432 {
feb11 0:85fceccc1a7c 433 int i;
feb11 0:85fceccc1a7c 434
feb11 0:85fceccc1a7c 435 for (i = 0; i < NUM_PROTOCOLS; i++)
feb11 0:85fceccc1a7c 436 {
feb11 0:85fceccc1a7c 437 if (cipher_info[i].cipher == cipher)
feb11 0:85fceccc1a7c 438 {
feb11 0:85fceccc1a7c 439 return &cipher_info[i];
feb11 0:85fceccc1a7c 440 }
feb11 0:85fceccc1a7c 441 }
feb11 0:85fceccc1a7c 442
feb11 0:85fceccc1a7c 443 return NULL; /* error */
feb11 0:85fceccc1a7c 444 }
feb11 0:85fceccc1a7c 445
feb11 0:85fceccc1a7c 446 /*
feb11 0:85fceccc1a7c 447 * Get a new ssl context for a new connection.
feb11 0:85fceccc1a7c 448 */
feb11 0:85fceccc1a7c 449 SSL *ssl_new(SSL *ssl, int client_fd)
feb11 0:85fceccc1a7c 450 {
feb11 0:85fceccc1a7c 451 SSL_CTX* ssl_ctx = ssl->ssl_ctx;
feb11 0:85fceccc1a7c 452 ssl->need_bytes = SSL_RECORD_SIZE; /* need a record */
feb11 0:85fceccc1a7c 453 ssl->client_fd = 0;
feb11 0:85fceccc1a7c 454 ssl->flag = SSL_NEED_RECORD;
feb11 0:85fceccc1a7c 455 ssl->bm_data = ssl->bm_all_data + BM_RECORD_OFFSET;
feb11 0:85fceccc1a7c 456 ssl->bm_remaining_bytes = 0;
feb11 0:85fceccc1a7c 457 ssl->hs_status = SSL_NOT_OK; /* not connected */
feb11 0:85fceccc1a7c 458 #ifdef CONFIG_ENABLE_VERIFICATION
feb11 0:85fceccc1a7c 459 ssl->ca_cert_ctx = ssl_ctx->ca_cert_ctx;
feb11 0:85fceccc1a7c 460 #endif
feb11 0:85fceccc1a7c 461 disposable_new(ssl);
feb11 0:85fceccc1a7c 462
feb11 0:85fceccc1a7c 463 /* a bit hacky but saves a few bytes of memory */
feb11 0:85fceccc1a7c 464 ssl->flag |= ssl_ctx->options;
feb11 0:85fceccc1a7c 465 SSL_CTX_LOCK(ssl_ctx->mutex);
feb11 0:85fceccc1a7c 466
feb11 0:85fceccc1a7c 467 if (ssl_ctx->head == NULL)
feb11 0:85fceccc1a7c 468 {
feb11 0:85fceccc1a7c 469 ssl_ctx->head = ssl;
feb11 0:85fceccc1a7c 470 ssl_ctx->tail = ssl;
feb11 0:85fceccc1a7c 471 }
feb11 0:85fceccc1a7c 472 else
feb11 0:85fceccc1a7c 473 {
feb11 0:85fceccc1a7c 474 ssl->prev = ssl_ctx->tail;
feb11 0:85fceccc1a7c 475 ssl_ctx->tail->next = ssl;
feb11 0:85fceccc1a7c 476 ssl_ctx->tail = ssl;
feb11 0:85fceccc1a7c 477 }
feb11 0:85fceccc1a7c 478 ssl->encrypt_ctx = NULL;
feb11 0:85fceccc1a7c 479 ssl->decrypt_ctx = NULL;
feb11 0:85fceccc1a7c 480
feb11 0:85fceccc1a7c 481 SSL_CTX_UNLOCK(ssl_ctx->mutex);
feb11 0:85fceccc1a7c 482 return ssl;
feb11 0:85fceccc1a7c 483 }
feb11 0:85fceccc1a7c 484
feb11 0:85fceccc1a7c 485 /*
feb11 0:85fceccc1a7c 486 * Add a private key to a context.
feb11 0:85fceccc1a7c 487 */
feb11 0:85fceccc1a7c 488 int add_private_key(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj)
feb11 0:85fceccc1a7c 489 {
feb11 0:85fceccc1a7c 490 int ret = SSL_OK;
feb11 0:85fceccc1a7c 491
feb11 0:85fceccc1a7c 492 /* get the private key details */
feb11 0:85fceccc1a7c 493 if (asn1_get_private_key(ssl_obj->buf, ssl_obj->len, &ssl_ctx->rsa_ctx))
feb11 0:85fceccc1a7c 494 {
feb11 0:85fceccc1a7c 495 ret = SSL_ERROR_INVALID_KEY;
feb11 0:85fceccc1a7c 496 goto error;
feb11 0:85fceccc1a7c 497 }
feb11 0:85fceccc1a7c 498
feb11 0:85fceccc1a7c 499 error:
feb11 0:85fceccc1a7c 500 return ret;
feb11 0:85fceccc1a7c 501 }
feb11 0:85fceccc1a7c 502
feb11 0:85fceccc1a7c 503 /**
feb11 0:85fceccc1a7c 504 * Increment the read sequence number (as a 64 bit endian indepenent #)
feb11 0:85fceccc1a7c 505 */
feb11 0:85fceccc1a7c 506 static void increment_read_sequence(SSL *ssl)
feb11 0:85fceccc1a7c 507 {
feb11 0:85fceccc1a7c 508 int i;
feb11 0:85fceccc1a7c 509
feb11 0:85fceccc1a7c 510 for (i = 7; i >= 0; i--)
feb11 0:85fceccc1a7c 511 {
feb11 0:85fceccc1a7c 512 if (++ssl->read_sequence[i])
feb11 0:85fceccc1a7c 513 break;
feb11 0:85fceccc1a7c 514 }
feb11 0:85fceccc1a7c 515 }
feb11 0:85fceccc1a7c 516
feb11 0:85fceccc1a7c 517 /**
feb11 0:85fceccc1a7c 518 * Increment the read sequence number (as a 64 bit endian indepenent #)
feb11 0:85fceccc1a7c 519 */
feb11 0:85fceccc1a7c 520 static void increment_write_sequence(SSL *ssl)
feb11 0:85fceccc1a7c 521 {
feb11 0:85fceccc1a7c 522 int i;
feb11 0:85fceccc1a7c 523
feb11 0:85fceccc1a7c 524 for (i = 7; i >= 0; i--)
feb11 0:85fceccc1a7c 525 {
feb11 0:85fceccc1a7c 526 if (++ssl->write_sequence[i])
feb11 0:85fceccc1a7c 527 break;
feb11 0:85fceccc1a7c 528 }
feb11 0:85fceccc1a7c 529 }
feb11 0:85fceccc1a7c 530
feb11 0:85fceccc1a7c 531 /**
feb11 0:85fceccc1a7c 532 * Work out the HMAC digest in a packet.
feb11 0:85fceccc1a7c 533 */
feb11 0:85fceccc1a7c 534 static void add_hmac_digest(SSL *ssl, int mode, uint8_t *hmac_header,
feb11 0:85fceccc1a7c 535 const uint8_t *buf, int buf_len, uint8_t *hmac_buf)
feb11 0:85fceccc1a7c 536 {
feb11 0:85fceccc1a7c 537 int hmac_len = buf_len + 8 + SSL_RECORD_SIZE;
feb11 0:85fceccc1a7c 538 uint8_t *t_buf = (uint8_t *)alloca(hmac_len+10);
feb11 0:85fceccc1a7c 539
feb11 0:85fceccc1a7c 540 memcpy(t_buf, (mode == SSL_SERVER_WRITE || mode == SSL_CLIENT_WRITE) ?
feb11 0:85fceccc1a7c 541 ssl->write_sequence : ssl->read_sequence, 8);
feb11 0:85fceccc1a7c 542 memcpy(&t_buf[8], hmac_header, SSL_RECORD_SIZE);
feb11 0:85fceccc1a7c 543 memcpy(&t_buf[8+SSL_RECORD_SIZE], buf, buf_len);
feb11 0:85fceccc1a7c 544
feb11 0:85fceccc1a7c 545 ssl->cipher_info->hmac(t_buf, hmac_len,
feb11 0:85fceccc1a7c 546 (mode == SSL_SERVER_WRITE || mode == SSL_CLIENT_READ) ?
feb11 0:85fceccc1a7c 547 ssl->server_mac : ssl->client_mac,
feb11 0:85fceccc1a7c 548 ssl->cipher_info->digest_size, hmac_buf);
feb11 0:85fceccc1a7c 549
feb11 0:85fceccc1a7c 550 #if 0
feb11 0:85fceccc1a7c 551 print_blob("record", hmac_header, SSL_RECORD_SIZE);
feb11 0:85fceccc1a7c 552 print_blob("buf", buf, buf_len);
feb11 0:85fceccc1a7c 553 if (mode == SSL_SERVER_WRITE || mode == SSL_CLIENT_WRITE)
feb11 0:85fceccc1a7c 554 {
feb11 0:85fceccc1a7c 555 print_blob("write seq", ssl->write_sequence, 8);
feb11 0:85fceccc1a7c 556 }
feb11 0:85fceccc1a7c 557 else
feb11 0:85fceccc1a7c 558 {
feb11 0:85fceccc1a7c 559 print_blob("read seq", ssl->read_sequence, 8);
feb11 0:85fceccc1a7c 560 }
feb11 0:85fceccc1a7c 561
feb11 0:85fceccc1a7c 562 if (mode == SSL_SERVER_WRITE || mode == SSL_CLIENT_READ)
feb11 0:85fceccc1a7c 563 {
feb11 0:85fceccc1a7c 564 print_blob("server mac",
feb11 0:85fceccc1a7c 565 ssl->server_mac, ssl->cipher_info->digest_size);
feb11 0:85fceccc1a7c 566 }
feb11 0:85fceccc1a7c 567 else
feb11 0:85fceccc1a7c 568 {
feb11 0:85fceccc1a7c 569 print_blob("client mac",
feb11 0:85fceccc1a7c 570 ssl->client_mac, ssl->cipher_info->digest_size);
feb11 0:85fceccc1a7c 571 }
feb11 0:85fceccc1a7c 572 print_blob("hmac", hmac_buf, SHA1_SIZE);
feb11 0:85fceccc1a7c 573 #endif
feb11 0:85fceccc1a7c 574 }
feb11 0:85fceccc1a7c 575
feb11 0:85fceccc1a7c 576 /**
feb11 0:85fceccc1a7c 577 * Verify that the digest of a packet is correct.
feb11 0:85fceccc1a7c 578 */
feb11 0:85fceccc1a7c 579 static int verify_digest(SSL *ssl, int mode, const uint8_t *buf, int read_len)
feb11 0:85fceccc1a7c 580 {
feb11 0:85fceccc1a7c 581 uint8_t hmac_buf[SHA1_SIZE];
feb11 0:85fceccc1a7c 582 int hmac_offset;
feb11 0:85fceccc1a7c 583
feb11 0:85fceccc1a7c 584 if (ssl->cipher_info->padding_size)
feb11 0:85fceccc1a7c 585 {
feb11 0:85fceccc1a7c 586 int last_blk_size = buf[read_len-1], i;
feb11 0:85fceccc1a7c 587 hmac_offset = read_len-last_blk_size-ssl->cipher_info->digest_size-1;
feb11 0:85fceccc1a7c 588 /* guard against a timing attack - make sure we do the digest */
feb11 0:85fceccc1a7c 589 if (hmac_offset < 0)
feb11 0:85fceccc1a7c 590 {
feb11 0:85fceccc1a7c 591 hmac_offset = 0;
feb11 0:85fceccc1a7c 592 }
feb11 0:85fceccc1a7c 593 else
feb11 0:85fceccc1a7c 594 {
feb11 0:85fceccc1a7c 595 /* already looked at last byte */
feb11 0:85fceccc1a7c 596 for (i = 1; i < last_blk_size; i++)
feb11 0:85fceccc1a7c 597 {
feb11 0:85fceccc1a7c 598 if (buf[read_len-i] != last_blk_size)
feb11 0:85fceccc1a7c 599 {
feb11 0:85fceccc1a7c 600 hmac_offset = 0;
feb11 0:85fceccc1a7c 601 break;
feb11 0:85fceccc1a7c 602 }
feb11 0:85fceccc1a7c 603 }
feb11 0:85fceccc1a7c 604 }
feb11 0:85fceccc1a7c 605 }
feb11 0:85fceccc1a7c 606 else /* stream cipher */
feb11 0:85fceccc1a7c 607 {
feb11 0:85fceccc1a7c 608 hmac_offset = read_len - ssl->cipher_info->digest_size;
feb11 0:85fceccc1a7c 609
feb11 0:85fceccc1a7c 610 if (hmac_offset < 0)
feb11 0:85fceccc1a7c 611 {
feb11 0:85fceccc1a7c 612 hmac_offset = 0;
feb11 0:85fceccc1a7c 613 }
feb11 0:85fceccc1a7c 614 }
feb11 0:85fceccc1a7c 615
feb11 0:85fceccc1a7c 616 /* sanity check the offset */
feb11 0:85fceccc1a7c 617 ssl->hmac_header[3] = hmac_offset >> 8; /* insert size */
feb11 0:85fceccc1a7c 618 ssl->hmac_header[4] = hmac_offset & 0xff;
feb11 0:85fceccc1a7c 619 add_hmac_digest(ssl, mode, ssl->hmac_header, buf, hmac_offset, hmac_buf);
feb11 0:85fceccc1a7c 620
feb11 0:85fceccc1a7c 621 if (memcmp(hmac_buf, &buf[hmac_offset], ssl->cipher_info->digest_size))
feb11 0:85fceccc1a7c 622 {
feb11 0:85fceccc1a7c 623 return SSL_ERROR_INVALID_HMAC;
feb11 0:85fceccc1a7c 624 }
feb11 0:85fceccc1a7c 625
feb11 0:85fceccc1a7c 626 return hmac_offset;
feb11 0:85fceccc1a7c 627 }
feb11 0:85fceccc1a7c 628
feb11 0:85fceccc1a7c 629 /**
feb11 0:85fceccc1a7c 630 * Add a packet to the end of our sent and received packets, so that we may use
feb11 0:85fceccc1a7c 631 * it to calculate the hash at the end.
feb11 0:85fceccc1a7c 632 */
feb11 0:85fceccc1a7c 633 void add_packet(SSL *ssl, const uint8_t *pkt, int len)
feb11 0:85fceccc1a7c 634 {
feb11 0:85fceccc1a7c 635 MD5_Update(&ssl->dc->md5_ctx, pkt, len);
feb11 0:85fceccc1a7c 636 SHA1_Update(&ssl->dc->sha1_ctx, pkt, len);
feb11 0:85fceccc1a7c 637 }
feb11 0:85fceccc1a7c 638
feb11 0:85fceccc1a7c 639 /**
feb11 0:85fceccc1a7c 640 * Work out the MD5 PRF.
feb11 0:85fceccc1a7c 641 */
feb11 0:85fceccc1a7c 642 static void p_hash_md5(const uint8_t *sec, int sec_len,
feb11 0:85fceccc1a7c 643 uint8_t *seed, int seed_len, uint8_t *out, int olen)
feb11 0:85fceccc1a7c 644 {
feb11 0:85fceccc1a7c 645 uint8_t a1[128];
feb11 0:85fceccc1a7c 646
feb11 0:85fceccc1a7c 647 /* A(1) */
feb11 0:85fceccc1a7c 648 hmac_md5(seed, seed_len, sec, sec_len, a1);
feb11 0:85fceccc1a7c 649 memcpy(&a1[MD5_SIZE], seed, seed_len);
feb11 0:85fceccc1a7c 650 hmac_md5(a1, MD5_SIZE+seed_len, sec, sec_len, out);
feb11 0:85fceccc1a7c 651
feb11 0:85fceccc1a7c 652 while (olen > MD5_SIZE)
feb11 0:85fceccc1a7c 653 {
feb11 0:85fceccc1a7c 654 uint8_t a2[MD5_SIZE];
feb11 0:85fceccc1a7c 655 out += MD5_SIZE;
feb11 0:85fceccc1a7c 656 olen -= MD5_SIZE;
feb11 0:85fceccc1a7c 657
feb11 0:85fceccc1a7c 658 /* A(N) */
feb11 0:85fceccc1a7c 659 hmac_md5(a1, MD5_SIZE, sec, sec_len, a2);
feb11 0:85fceccc1a7c 660 memcpy(a1, a2, MD5_SIZE);
feb11 0:85fceccc1a7c 661
feb11 0:85fceccc1a7c 662 /* work out the actual hash */
feb11 0:85fceccc1a7c 663 hmac_md5(a1, MD5_SIZE+seed_len, sec, sec_len, out);
feb11 0:85fceccc1a7c 664 }
feb11 0:85fceccc1a7c 665 }
feb11 0:85fceccc1a7c 666
feb11 0:85fceccc1a7c 667 /**
feb11 0:85fceccc1a7c 668 * Work out the SHA1 PRF.
feb11 0:85fceccc1a7c 669 */
feb11 0:85fceccc1a7c 670 static void p_hash_sha1(const uint8_t *sec, int sec_len,
feb11 0:85fceccc1a7c 671 uint8_t *seed, int seed_len, uint8_t *out, int olen)
feb11 0:85fceccc1a7c 672 {
feb11 0:85fceccc1a7c 673 uint8_t a1[128];
feb11 0:85fceccc1a7c 674
feb11 0:85fceccc1a7c 675 /* A(1) */
feb11 0:85fceccc1a7c 676 hmac_sha1(seed, seed_len, sec, sec_len, a1);
feb11 0:85fceccc1a7c 677 memcpy(&a1[SHA1_SIZE], seed, seed_len);
feb11 0:85fceccc1a7c 678 hmac_sha1(a1, SHA1_SIZE+seed_len, sec, sec_len, out);
feb11 0:85fceccc1a7c 679
feb11 0:85fceccc1a7c 680 while (olen > SHA1_SIZE)
feb11 0:85fceccc1a7c 681 {
feb11 0:85fceccc1a7c 682 uint8_t a2[SHA1_SIZE];
feb11 0:85fceccc1a7c 683 out += SHA1_SIZE;
feb11 0:85fceccc1a7c 684 olen -= SHA1_SIZE;
feb11 0:85fceccc1a7c 685
feb11 0:85fceccc1a7c 686 /* A(N) */
feb11 0:85fceccc1a7c 687 hmac_sha1(a1, SHA1_SIZE, sec, sec_len, a2);
feb11 0:85fceccc1a7c 688 memcpy(a1, a2, SHA1_SIZE);
feb11 0:85fceccc1a7c 689
feb11 0:85fceccc1a7c 690 /* work out the actual hash */
feb11 0:85fceccc1a7c 691 hmac_sha1(a1, SHA1_SIZE+seed_len, sec, sec_len, out);
feb11 0:85fceccc1a7c 692 }
feb11 0:85fceccc1a7c 693 }
feb11 0:85fceccc1a7c 694
feb11 0:85fceccc1a7c 695 /**
feb11 0:85fceccc1a7c 696 * Work out the PRF.
feb11 0:85fceccc1a7c 697 */
feb11 0:85fceccc1a7c 698 static void prf(const uint8_t *sec, int sec_len, uint8_t *seed, int seed_len,
feb11 0:85fceccc1a7c 699 uint8_t *out, int olen)
feb11 0:85fceccc1a7c 700 {
feb11 0:85fceccc1a7c 701 int len, i;
feb11 0:85fceccc1a7c 702 const uint8_t *S1, *S2;
feb11 0:85fceccc1a7c 703 uint8_t xbuf[256]; /* needs to be > the amount of key data */
feb11 0:85fceccc1a7c 704 uint8_t ybuf[256]; /* needs to be > the amount of key data */
feb11 0:85fceccc1a7c 705
feb11 0:85fceccc1a7c 706 len = sec_len/2;
feb11 0:85fceccc1a7c 707 S1 = sec;
feb11 0:85fceccc1a7c 708 S2 = &sec[len];
feb11 0:85fceccc1a7c 709 len += (sec_len & 1); /* add for odd, make longer */
feb11 0:85fceccc1a7c 710
feb11 0:85fceccc1a7c 711 p_hash_md5(S1, len, seed, seed_len, xbuf, olen);
feb11 0:85fceccc1a7c 712 p_hash_sha1(S2, len, seed, seed_len, ybuf, olen);
feb11 0:85fceccc1a7c 713
feb11 0:85fceccc1a7c 714 for (i = 0; i < olen; i++)
feb11 0:85fceccc1a7c 715 out[i] = xbuf[i] ^ ybuf[i];
feb11 0:85fceccc1a7c 716 }
feb11 0:85fceccc1a7c 717
feb11 0:85fceccc1a7c 718 /**
feb11 0:85fceccc1a7c 719 * Generate a master secret based on the client/server random data and the
feb11 0:85fceccc1a7c 720 * premaster secret.
feb11 0:85fceccc1a7c 721 */
feb11 0:85fceccc1a7c 722 void generate_master_secret(SSL *ssl, const uint8_t *premaster_secret)
feb11 0:85fceccc1a7c 723 {
feb11 0:85fceccc1a7c 724 uint8_t buf[128]; /* needs to be > 13+32+32 in size */
feb11 0:85fceccc1a7c 725 strcpy((char *)buf, "master secret");
feb11 0:85fceccc1a7c 726 memcpy(&buf[13], ssl->dc->client_random, SSL_RANDOM_SIZE);
feb11 0:85fceccc1a7c 727 memcpy(&buf[45], ssl->dc->server_random, SSL_RANDOM_SIZE);
feb11 0:85fceccc1a7c 728 prf(premaster_secret, SSL_SECRET_SIZE, buf, 77, ssl->dc->master_secret,
feb11 0:85fceccc1a7c 729 SSL_SECRET_SIZE);
feb11 0:85fceccc1a7c 730 }
feb11 0:85fceccc1a7c 731
feb11 0:85fceccc1a7c 732 /**
feb11 0:85fceccc1a7c 733 * Generate a 'random' blob of data used for the generation of keys.
feb11 0:85fceccc1a7c 734 */
feb11 0:85fceccc1a7c 735 static void generate_key_block(uint8_t *client_random, uint8_t *server_random,
feb11 0:85fceccc1a7c 736 uint8_t *master_secret, uint8_t *key_block, int key_block_size)
feb11 0:85fceccc1a7c 737 {
feb11 0:85fceccc1a7c 738 uint8_t buf[128];
feb11 0:85fceccc1a7c 739 strcpy((char *)buf, "key expansion");
feb11 0:85fceccc1a7c 740 memcpy(&buf[13], server_random, SSL_RANDOM_SIZE);
feb11 0:85fceccc1a7c 741 memcpy(&buf[45], client_random, SSL_RANDOM_SIZE);
feb11 0:85fceccc1a7c 742 prf(master_secret, SSL_SECRET_SIZE, buf, 77, key_block, key_block_size);
feb11 0:85fceccc1a7c 743 }
feb11 0:85fceccc1a7c 744
feb11 0:85fceccc1a7c 745 /**
feb11 0:85fceccc1a7c 746 * Calculate the digest used in the finished message. This function also
feb11 0:85fceccc1a7c 747 * doubles up as a certificate verify function.
feb11 0:85fceccc1a7c 748 */
feb11 0:85fceccc1a7c 749 void finished_digest(SSL *ssl, const char *label, uint8_t *digest)
feb11 0:85fceccc1a7c 750 {
feb11 0:85fceccc1a7c 751 uint8_t mac_buf[128];
feb11 0:85fceccc1a7c 752 uint8_t *q = mac_buf;
feb11 0:85fceccc1a7c 753 MD5_CTX md5_ctx = ssl->dc->md5_ctx;
feb11 0:85fceccc1a7c 754 SHA1_CTX sha1_ctx = ssl->dc->sha1_ctx;
feb11 0:85fceccc1a7c 755
feb11 0:85fceccc1a7c 756 if (label)
feb11 0:85fceccc1a7c 757 {
feb11 0:85fceccc1a7c 758 strcpy((char *)q, label);
feb11 0:85fceccc1a7c 759 q += strlen(label);
feb11 0:85fceccc1a7c 760 }
feb11 0:85fceccc1a7c 761
feb11 0:85fceccc1a7c 762 MD5_Final(q, &md5_ctx);
feb11 0:85fceccc1a7c 763 q += MD5_SIZE;
feb11 0:85fceccc1a7c 764
feb11 0:85fceccc1a7c 765 SHA1_Final(q, &sha1_ctx);
feb11 0:85fceccc1a7c 766 q += SHA1_SIZE;
feb11 0:85fceccc1a7c 767
feb11 0:85fceccc1a7c 768 if (label)
feb11 0:85fceccc1a7c 769 {
feb11 0:85fceccc1a7c 770 prf(ssl->dc->master_secret, SSL_SECRET_SIZE, mac_buf, (int)(q-mac_buf),
feb11 0:85fceccc1a7c 771 digest, SSL_FINISHED_HASH_SIZE);
feb11 0:85fceccc1a7c 772 }
feb11 0:85fceccc1a7c 773 else /* for use in a certificate verify */
feb11 0:85fceccc1a7c 774 {
feb11 0:85fceccc1a7c 775 memcpy(digest, mac_buf, MD5_SIZE + SHA1_SIZE);
feb11 0:85fceccc1a7c 776 }
feb11 0:85fceccc1a7c 777
feb11 0:85fceccc1a7c 778 #if 0
feb11 0:85fceccc1a7c 779 printf("label: %s\r\n", label);
feb11 0:85fceccc1a7c 780 print_blob("master secret", ssl->dc->master_secret, 48);
feb11 0:85fceccc1a7c 781 print_blob("mac_buf", mac_buf, q-mac_buf);
feb11 0:85fceccc1a7c 782 print_blob("finished digest", digest, SSL_FINISHED_HASH_SIZE);
feb11 0:85fceccc1a7c 783 #endif
feb11 0:85fceccc1a7c 784 }
feb11 0:85fceccc1a7c 785
feb11 0:85fceccc1a7c 786 /**
feb11 0:85fceccc1a7c 787 * Retrieve (and initialise) the context of a cipher.
feb11 0:85fceccc1a7c 788 */
feb11 0:85fceccc1a7c 789 static void *crypt_new(SSL *ssl, uint8_t *key, uint8_t *iv, int is_decrypt)
feb11 0:85fceccc1a7c 790 {
feb11 0:85fceccc1a7c 791 switch (ssl->cipher)
feb11 0:85fceccc1a7c 792 {
feb11 0:85fceccc1a7c 793 #ifndef CONFIG_SSL_SKELETON_MODE
feb11 0:85fceccc1a7c 794 case SSL_AES128_SHA:
feb11 0:85fceccc1a7c 795 {
feb11 0:85fceccc1a7c 796 AES_CTX *aes_ctx = (AES_CTX *)malloc(sizeof(AES_CTX));
feb11 0:85fceccc1a7c 797 AES_set_key(aes_ctx, key, iv, AES_MODE_128);
feb11 0:85fceccc1a7c 798
feb11 0:85fceccc1a7c 799 if (is_decrypt)
feb11 0:85fceccc1a7c 800 {
feb11 0:85fceccc1a7c 801 AES_convert_key(aes_ctx);
feb11 0:85fceccc1a7c 802 }
feb11 0:85fceccc1a7c 803
feb11 0:85fceccc1a7c 804 return (void *)aes_ctx;
feb11 0:85fceccc1a7c 805 }
feb11 0:85fceccc1a7c 806
feb11 0:85fceccc1a7c 807 case SSL_AES256_SHA:
feb11 0:85fceccc1a7c 808 {
feb11 0:85fceccc1a7c 809 AES_CTX *aes_ctx = (AES_CTX *)malloc(sizeof(AES_CTX));
feb11 0:85fceccc1a7c 810 AES_set_key(aes_ctx, key, iv, AES_MODE_256);
feb11 0:85fceccc1a7c 811
feb11 0:85fceccc1a7c 812 if (is_decrypt)
feb11 0:85fceccc1a7c 813 {
feb11 0:85fceccc1a7c 814 AES_convert_key(aes_ctx);
feb11 0:85fceccc1a7c 815 }
feb11 0:85fceccc1a7c 816
feb11 0:85fceccc1a7c 817 return (void *)aes_ctx;
feb11 0:85fceccc1a7c 818 }
feb11 0:85fceccc1a7c 819
feb11 0:85fceccc1a7c 820 case SSL_RC4_128_MD5:
feb11 0:85fceccc1a7c 821 #endif
feb11 0:85fceccc1a7c 822 case SSL_RC4_128_SHA:
feb11 0:85fceccc1a7c 823 {
feb11 0:85fceccc1a7c 824 RC4_CTX *rc4_ctx = (RC4_CTX *)malloc(sizeof(RC4_CTX));
feb11 0:85fceccc1a7c 825 RC4_setup(rc4_ctx, key, 16);
feb11 0:85fceccc1a7c 826 return (void *)rc4_ctx;
feb11 0:85fceccc1a7c 827 }
feb11 0:85fceccc1a7c 828 }
feb11 0:85fceccc1a7c 829
feb11 0:85fceccc1a7c 830 return NULL; /* its all gone wrong */
feb11 0:85fceccc1a7c 831 }
feb11 0:85fceccc1a7c 832
feb11 0:85fceccc1a7c 833
feb11 0:85fceccc1a7c 834 /**
feb11 0:85fceccc1a7c 835 * Send a packet over the socket.
feb11 0:85fceccc1a7c 836 */
feb11 0:85fceccc1a7c 837 static int send_raw_packet(SSL *ssl, uint8_t protocol)
feb11 0:85fceccc1a7c 838 {
feb11 0:85fceccc1a7c 839 uint8_t *rec_buf = ssl->bm_all_data;
feb11 0:85fceccc1a7c 840 int pkt_size = SSL_RECORD_SIZE+ssl->bm_index;
feb11 0:85fceccc1a7c 841 int sent = 0;
feb11 0:85fceccc1a7c 842 int ret = SSL_OK;
feb11 0:85fceccc1a7c 843 rec_buf[0] = protocol;
feb11 0:85fceccc1a7c 844 rec_buf[1] = 0x03; /* version = 3.1 or higher */
feb11 0:85fceccc1a7c 845 rec_buf[2] = ssl->version & 0x0f;
feb11 0:85fceccc1a7c 846 rec_buf[3] = ssl->bm_index >> 8;
feb11 0:85fceccc1a7c 847 rec_buf[4] = ssl->bm_index & 0xff;
feb11 0:85fceccc1a7c 848
feb11 0:85fceccc1a7c 849 DISPLAY_BYTES(ssl, "sending %d bytes", ssl->bm_all_data,
feb11 0:85fceccc1a7c 850 pkt_size, pkt_size);
feb11 0:85fceccc1a7c 851
feb11 0:85fceccc1a7c 852
feb11 0:85fceccc1a7c 853
feb11 0:85fceccc1a7c 854 while (sent < pkt_size)
feb11 0:85fceccc1a7c 855 {
feb11 0:85fceccc1a7c 856 ret = SOCKET_WRITE(ssl->client_fd,
feb11 0:85fceccc1a7c 857 &ssl->bm_all_data[sent], pkt_size-sent);
feb11 0:85fceccc1a7c 858 if (ret >= 0)
feb11 0:85fceccc1a7c 859 sent += ret;
feb11 0:85fceccc1a7c 860 else
feb11 0:85fceccc1a7c 861 {
feb11 0:85fceccc1a7c 862
feb11 0:85fceccc1a7c 863 #ifdef WIN32
feb11 0:85fceccc1a7c 864 if (GetLastError() != WSAEWOULDBLOCK)
feb11 0:85fceccc1a7c 865 #else
feb11 0:85fceccc1a7c 866 if (errno != EAGAIN && errno != EWOULDBLOCK)
feb11 0:85fceccc1a7c 867 #endif
feb11 0:85fceccc1a7c 868 {
feb11 0:85fceccc1a7c 869 printf("send_raw_packet 1\n");
feb11 0:85fceccc1a7c 870 return SSL_ERROR_CONN_LOST;
feb11 0:85fceccc1a7c 871 }
feb11 0:85fceccc1a7c 872 }
feb11 0:85fceccc1a7c 873
feb11 0:85fceccc1a7c 874 /* keep going until the write buffer has some space */
feb11 0:85fceccc1a7c 875 if (sent != pkt_size)
feb11 0:85fceccc1a7c 876 {
feb11 0:85fceccc1a7c 877 fd_set wfds;
feb11 0:85fceccc1a7c 878 FD_ZERO(&wfds);
feb11 0:85fceccc1a7c 879 FD_SET(ssl->client_fd, &wfds);
feb11 0:85fceccc1a7c 880
feb11 0:85fceccc1a7c 881 /* block and wait for it */
feb11 0:85fceccc1a7c 882 if (lwip_select(FD_SETSIZE, NULL, &wfds, NULL, NULL) < 0)
feb11 0:85fceccc1a7c 883 {
feb11 0:85fceccc1a7c 884 printf("send_raw_packet 2\n");
feb11 0:85fceccc1a7c 885 return SSL_ERROR_CONN_LOST;
feb11 0:85fceccc1a7c 886 }
feb11 0:85fceccc1a7c 887 }
feb11 0:85fceccc1a7c 888 }
feb11 0:85fceccc1a7c 889 fd_set wfds;
feb11 0:85fceccc1a7c 890 FD_ZERO(&wfds);
feb11 0:85fceccc1a7c 891 FD_SET(ssl->client_fd, &wfds);
feb11 0:85fceccc1a7c 892
feb11 0:85fceccc1a7c 893 /* block and wait for it */
feb11 0:85fceccc1a7c 894 if (lwip_select(FD_SETSIZE, NULL, &wfds, NULL, NULL) < 0)
feb11 0:85fceccc1a7c 895 {
feb11 0:85fceccc1a7c 896 printf("send_raw_packet 3\n");
feb11 0:85fceccc1a7c 897 return SSL_ERROR_CONN_LOST;
feb11 0:85fceccc1a7c 898 }
feb11 0:85fceccc1a7c 899
feb11 0:85fceccc1a7c 900 SET_SSL_FLAG(SSL_NEED_RECORD); /* reset for next time */
feb11 0:85fceccc1a7c 901 ssl->bm_index = 0;
feb11 0:85fceccc1a7c 902
feb11 0:85fceccc1a7c 903 if (protocol != PT_APP_PROTOCOL_DATA)
feb11 0:85fceccc1a7c 904 {
feb11 0:85fceccc1a7c 905 /* always return SSL_OK during handshake */
feb11 0:85fceccc1a7c 906 ret = SSL_OK;
feb11 0:85fceccc1a7c 907 }
feb11 0:85fceccc1a7c 908
feb11 0:85fceccc1a7c 909 return ret;
feb11 0:85fceccc1a7c 910 }
feb11 0:85fceccc1a7c 911
feb11 0:85fceccc1a7c 912 /**
feb11 0:85fceccc1a7c 913 * Send an encrypted packet with padding bytes if necessary.
feb11 0:85fceccc1a7c 914 */
feb11 0:85fceccc1a7c 915 int send_packet(SSL *ssl, uint8_t protocol, const uint8_t *in, int length)
feb11 0:85fceccc1a7c 916 {
feb11 0:85fceccc1a7c 917 int ret, msg_length = 0;
feb11 0:85fceccc1a7c 918
feb11 0:85fceccc1a7c 919 /* if our state is bad, don't bother */
feb11 0:85fceccc1a7c 920 if (ssl->hs_status == SSL_ERROR_DEAD)
feb11 0:85fceccc1a7c 921 {
feb11 0:85fceccc1a7c 922 printf("bad hs_status\n");
feb11 0:85fceccc1a7c 923 return SSL_ERROR_CONN_LOST;
feb11 0:85fceccc1a7c 924 }
feb11 0:85fceccc1a7c 925 if (in) /* has the buffer already been initialised? */
feb11 0:85fceccc1a7c 926 {
feb11 0:85fceccc1a7c 927 memcpy(ssl->bm_data, in, length);
feb11 0:85fceccc1a7c 928 }
feb11 0:85fceccc1a7c 929
feb11 0:85fceccc1a7c 930 msg_length += length;
feb11 0:85fceccc1a7c 931
feb11 0:85fceccc1a7c 932 if (IS_SET_SSL_FLAG(SSL_TX_ENCRYPTED))
feb11 0:85fceccc1a7c 933 {
feb11 0:85fceccc1a7c 934 int mode = IS_SET_SSL_FLAG(SSL_IS_CLIENT) ?
feb11 0:85fceccc1a7c 935 SSL_CLIENT_WRITE : SSL_SERVER_WRITE;
feb11 0:85fceccc1a7c 936 uint8_t hmac_header[SSL_RECORD_SIZE] =
feb11 0:85fceccc1a7c 937 {
feb11 0:85fceccc1a7c 938 protocol,
feb11 0:85fceccc1a7c 939 0x03, /* version = 3.1 or higher */
feb11 0:85fceccc1a7c 940 ssl->version & 0x0f,
feb11 0:85fceccc1a7c 941 msg_length >> 8,
feb11 0:85fceccc1a7c 942 msg_length & 0xff
feb11 0:85fceccc1a7c 943 };
feb11 0:85fceccc1a7c 944
feb11 0:85fceccc1a7c 945 if (protocol == PT_HANDSHAKE_PROTOCOL)
feb11 0:85fceccc1a7c 946 {
feb11 0:85fceccc1a7c 947 DISPLAY_STATE(ssl, 1, ssl->bm_data[0], 0);
feb11 0:85fceccc1a7c 948
feb11 0:85fceccc1a7c 949 if (ssl->bm_data[0] != HS_HELLO_REQUEST)
feb11 0:85fceccc1a7c 950 {
feb11 0:85fceccc1a7c 951 add_packet(ssl, ssl->bm_data, msg_length);
feb11 0:85fceccc1a7c 952 }
feb11 0:85fceccc1a7c 953 }
feb11 0:85fceccc1a7c 954
feb11 0:85fceccc1a7c 955 /* add the packet digest */
feb11 0:85fceccc1a7c 956 add_hmac_digest(ssl, mode, hmac_header, ssl->bm_data, msg_length,
feb11 0:85fceccc1a7c 957 &ssl->bm_data[msg_length]);
feb11 0:85fceccc1a7c 958 msg_length += ssl->cipher_info->digest_size;
feb11 0:85fceccc1a7c 959
feb11 0:85fceccc1a7c 960 /* add padding? */
feb11 0:85fceccc1a7c 961 if (ssl->cipher_info->padding_size)
feb11 0:85fceccc1a7c 962 {
feb11 0:85fceccc1a7c 963 int last_blk_size = msg_length%ssl->cipher_info->padding_size;
feb11 0:85fceccc1a7c 964 int pad_bytes = ssl->cipher_info->padding_size - last_blk_size;
feb11 0:85fceccc1a7c 965
feb11 0:85fceccc1a7c 966 /* ensure we always have at least 1 padding byte */
feb11 0:85fceccc1a7c 967 if (pad_bytes == 0)
feb11 0:85fceccc1a7c 968 pad_bytes += ssl->cipher_info->padding_size;
feb11 0:85fceccc1a7c 969
feb11 0:85fceccc1a7c 970 memset(&ssl->bm_data[msg_length], pad_bytes-1, pad_bytes);
feb11 0:85fceccc1a7c 971 msg_length += pad_bytes;
feb11 0:85fceccc1a7c 972 }
feb11 0:85fceccc1a7c 973
feb11 0:85fceccc1a7c 974 DISPLAY_BYTES(ssl, "unencrypted write", ssl->bm_data, msg_length);
feb11 0:85fceccc1a7c 975 increment_write_sequence(ssl);
feb11 0:85fceccc1a7c 976
feb11 0:85fceccc1a7c 977 /* add the explicit IV for TLS1.1 */
feb11 0:85fceccc1a7c 978 if (ssl->version >= SSL_PROTOCOL_VERSION1_1 &&
feb11 0:85fceccc1a7c 979 ssl->cipher_info->iv_size)
feb11 0:85fceccc1a7c 980 {
feb11 0:85fceccc1a7c 981 uint8_t iv_size = ssl->cipher_info->iv_size;
feb11 0:85fceccc1a7c 982 uint8_t *t_buf = alloca(msg_length + iv_size);
feb11 0:85fceccc1a7c 983 memcpy(t_buf + iv_size, ssl->bm_data, msg_length);
feb11 0:85fceccc1a7c 984 get_random(iv_size, t_buf);
feb11 0:85fceccc1a7c 985 msg_length += iv_size;
feb11 0:85fceccc1a7c 986 memcpy(ssl->bm_data, t_buf, msg_length);
feb11 0:85fceccc1a7c 987 }
feb11 0:85fceccc1a7c 988
feb11 0:85fceccc1a7c 989 /* now encrypt the packet */
feb11 0:85fceccc1a7c 990 ssl->cipher_info->encrypt(ssl->encrypt_ctx, ssl->bm_data,
feb11 0:85fceccc1a7c 991 ssl->bm_data, msg_length);
feb11 0:85fceccc1a7c 992 }
feb11 0:85fceccc1a7c 993 else if (protocol == PT_HANDSHAKE_PROTOCOL)
feb11 0:85fceccc1a7c 994 {
feb11 0:85fceccc1a7c 995 DISPLAY_STATE(ssl, 1, ssl->bm_data[0], 0);
feb11 0:85fceccc1a7c 996
feb11 0:85fceccc1a7c 997 if (ssl->bm_data[0] != HS_HELLO_REQUEST)
feb11 0:85fceccc1a7c 998 {
feb11 0:85fceccc1a7c 999 add_packet(ssl, ssl->bm_data, length);
feb11 0:85fceccc1a7c 1000 }
feb11 0:85fceccc1a7c 1001 }
feb11 0:85fceccc1a7c 1002
feb11 0:85fceccc1a7c 1003 ssl->bm_index = msg_length;
feb11 0:85fceccc1a7c 1004 if ((ret = send_raw_packet(ssl, protocol)) <= 0)
feb11 0:85fceccc1a7c 1005 return ret;
feb11 0:85fceccc1a7c 1006
feb11 0:85fceccc1a7c 1007 return length; /* just return what we wanted to send */
feb11 0:85fceccc1a7c 1008 }
feb11 0:85fceccc1a7c 1009
feb11 0:85fceccc1a7c 1010 /**
feb11 0:85fceccc1a7c 1011 * Work out the cipher keys we are going to use for this session based on the
feb11 0:85fceccc1a7c 1012 * master secret.
feb11 0:85fceccc1a7c 1013 */
feb11 0:85fceccc1a7c 1014 static int set_key_block(SSL *ssl, int is_write)
feb11 0:85fceccc1a7c 1015 {
feb11 0:85fceccc1a7c 1016 const cipher_info_t *ciph_info = get_cipher_info(ssl->cipher);
feb11 0:85fceccc1a7c 1017 uint8_t *q;
feb11 0:85fceccc1a7c 1018 uint8_t client_key[32], server_key[32]; /* big enough for AES256 */
feb11 0:85fceccc1a7c 1019 uint8_t client_iv[16], server_iv[16]; /* big enough for AES128/256 */
feb11 0:85fceccc1a7c 1020 int is_client = IS_SET_SSL_FLAG(SSL_IS_CLIENT);
feb11 0:85fceccc1a7c 1021
feb11 0:85fceccc1a7c 1022 if (ciph_info == NULL)
feb11 0:85fceccc1a7c 1023 return -1;
feb11 0:85fceccc1a7c 1024
feb11 0:85fceccc1a7c 1025 uint8_t key_tmp[MAX_KEYBLOCK_SIZE] = {0};
feb11 0:85fceccc1a7c 1026 /* only do once in a handshake */
feb11 0:85fceccc1a7c 1027 if (memcmp(ssl->dc->key_block, key_tmp, MAX_KEYBLOCK_SIZE) == 0)
feb11 0:85fceccc1a7c 1028 {
feb11 0:85fceccc1a7c 1029 #if 0
feb11 0:85fceccc1a7c 1030 print_blob("client", ssl->dc->client_random, 32);
feb11 0:85fceccc1a7c 1031 print_blob("server", ssl->dc->server_random, 32);
feb11 0:85fceccc1a7c 1032 print_blob("master", ssl->dc->master_secret, SSL_SECRET_SIZE);
feb11 0:85fceccc1a7c 1033 #endif
feb11 0:85fceccc1a7c 1034 generate_key_block(ssl->dc->client_random, ssl->dc->server_random,
feb11 0:85fceccc1a7c 1035 ssl->dc->master_secret, ssl->dc->key_block,
feb11 0:85fceccc1a7c 1036 ciph_info->key_block_size);
feb11 0:85fceccc1a7c 1037 #if 0
feb11 0:85fceccc1a7c 1038 print_blob("keyblock", ssl->dc->key_block, ciph_info->key_block_size);
feb11 0:85fceccc1a7c 1039 #endif
feb11 0:85fceccc1a7c 1040 }
feb11 0:85fceccc1a7c 1041
feb11 0:85fceccc1a7c 1042 q = ssl->dc->key_block;
feb11 0:85fceccc1a7c 1043
feb11 0:85fceccc1a7c 1044 if ((is_client && is_write) || (!is_client && !is_write))
feb11 0:85fceccc1a7c 1045 {
feb11 0:85fceccc1a7c 1046 memcpy(ssl->client_mac, q, ciph_info->digest_size);
feb11 0:85fceccc1a7c 1047 }
feb11 0:85fceccc1a7c 1048
feb11 0:85fceccc1a7c 1049 q += ciph_info->digest_size;
feb11 0:85fceccc1a7c 1050
feb11 0:85fceccc1a7c 1051 if ((!is_client && is_write) || (is_client && !is_write))
feb11 0:85fceccc1a7c 1052 {
feb11 0:85fceccc1a7c 1053 memcpy(ssl->server_mac, q, ciph_info->digest_size);
feb11 0:85fceccc1a7c 1054 }
feb11 0:85fceccc1a7c 1055
feb11 0:85fceccc1a7c 1056 q += ciph_info->digest_size;
feb11 0:85fceccc1a7c 1057 memcpy(client_key, q, ciph_info->key_size);
feb11 0:85fceccc1a7c 1058 q += ciph_info->key_size;
feb11 0:85fceccc1a7c 1059 memcpy(server_key, q, ciph_info->key_size);
feb11 0:85fceccc1a7c 1060 q += ciph_info->key_size;
feb11 0:85fceccc1a7c 1061
feb11 0:85fceccc1a7c 1062 #ifndef CONFIG_SSL_SKELETON_MODE
feb11 0:85fceccc1a7c 1063 if (ciph_info->iv_size) /* RC4 has no IV, AES does */
feb11 0:85fceccc1a7c 1064 {
feb11 0:85fceccc1a7c 1065 memcpy(client_iv, q, ciph_info->iv_size);
feb11 0:85fceccc1a7c 1066 q += ciph_info->iv_size;
feb11 0:85fceccc1a7c 1067 memcpy(server_iv, q, ciph_info->iv_size);
feb11 0:85fceccc1a7c 1068 q += ciph_info->iv_size;
feb11 0:85fceccc1a7c 1069 }
feb11 0:85fceccc1a7c 1070 #endif
feb11 0:85fceccc1a7c 1071
feb11 0:85fceccc1a7c 1072 if( (is_write ? ssl->encrypt_ctx : ssl->decrypt_ctx) != NULL)
feb11 0:85fceccc1a7c 1073 free(is_write ? ssl->encrypt_ctx : ssl->decrypt_ctx);
feb11 0:85fceccc1a7c 1074
feb11 0:85fceccc1a7c 1075 /* now initialise the ciphers */
feb11 0:85fceccc1a7c 1076 if (is_client)
feb11 0:85fceccc1a7c 1077 {
feb11 0:85fceccc1a7c 1078 finished_digest(ssl, server_finished, ssl->dc->final_finish_mac);
feb11 0:85fceccc1a7c 1079
feb11 0:85fceccc1a7c 1080 if (is_write)
feb11 0:85fceccc1a7c 1081 ssl->encrypt_ctx = crypt_new(ssl, client_key, client_iv, 0);
feb11 0:85fceccc1a7c 1082 else
feb11 0:85fceccc1a7c 1083 ssl->decrypt_ctx = crypt_new(ssl, server_key, server_iv, 1);
feb11 0:85fceccc1a7c 1084 }
feb11 0:85fceccc1a7c 1085 else
feb11 0:85fceccc1a7c 1086 {
feb11 0:85fceccc1a7c 1087 finished_digest(ssl, client_finished, ssl->dc->final_finish_mac);
feb11 0:85fceccc1a7c 1088
feb11 0:85fceccc1a7c 1089 if (is_write)
feb11 0:85fceccc1a7c 1090 ssl->encrypt_ctx = crypt_new(ssl, server_key, server_iv, 0);
feb11 0:85fceccc1a7c 1091 else
feb11 0:85fceccc1a7c 1092 ssl->decrypt_ctx = crypt_new(ssl, client_key, client_iv, 1);
feb11 0:85fceccc1a7c 1093 }
feb11 0:85fceccc1a7c 1094
feb11 0:85fceccc1a7c 1095 ssl->cipher_info = ciph_info;
feb11 0:85fceccc1a7c 1096 return 0;
feb11 0:85fceccc1a7c 1097 }
feb11 0:85fceccc1a7c 1098
feb11 0:85fceccc1a7c 1099 /**
feb11 0:85fceccc1a7c 1100 * Blocking read
feb11 0:85fceccc1a7c 1101 * data must be valid buffer of size length at least
feb11 0:85fceccc1a7c 1102 * length
feb11 0:85fceccc1a7c 1103 */
feb11 0:85fceccc1a7c 1104 int basic_read2(SSL *ssl, uint8_t *data, uint32_t length)
feb11 0:85fceccc1a7c 1105 {
feb11 0:85fceccc1a7c 1106 if(data == NULL)
feb11 0:85fceccc1a7c 1107 return -1;
feb11 0:85fceccc1a7c 1108
feb11 0:85fceccc1a7c 1109 int ret = 0;
feb11 0:85fceccc1a7c 1110
feb11 0:85fceccc1a7c 1111 do
feb11 0:85fceccc1a7c 1112 {
feb11 0:85fceccc1a7c 1113 fd_set rfds;
feb11 0:85fceccc1a7c 1114 FD_ZERO(&rfds);
feb11 0:85fceccc1a7c 1115 FD_SET(ssl->client_fd, &rfds);
feb11 0:85fceccc1a7c 1116
feb11 0:85fceccc1a7c 1117 /* block and wait for it */
feb11 0:85fceccc1a7c 1118 if (lwip_select(FD_SETSIZE, &rfds, NULL, NULL, NULL) < 0)
feb11 0:85fceccc1a7c 1119 return SSL_ERROR_CONN_LOST;
feb11 0:85fceccc1a7c 1120
feb11 0:85fceccc1a7c 1121 int read_len = SOCKET_READ(ssl->client_fd, &data[ret], length-ret);
feb11 0:85fceccc1a7c 1122
feb11 0:85fceccc1a7c 1123 if (read_len < 0)
feb11 0:85fceccc1a7c 1124 {
feb11 0:85fceccc1a7c 1125
feb11 0:85fceccc1a7c 1126 #ifdef WIN32
feb11 0:85fceccc1a7c 1127 if (GetLastError() == WSAEWOULDBLOCK)
feb11 0:85fceccc1a7c 1128 #else
feb11 0:85fceccc1a7c 1129 if (errno == EAGAIN || errno == EWOULDBLOCK)
feb11 0:85fceccc1a7c 1130 #endif
feb11 0:85fceccc1a7c 1131 continue;
feb11 0:85fceccc1a7c 1132 }
feb11 0:85fceccc1a7c 1133
feb11 0:85fceccc1a7c 1134 /* connection has gone, so die */
feb11 0:85fceccc1a7c 1135 if (read_len <= 0)
feb11 0:85fceccc1a7c 1136 {
feb11 0:85fceccc1a7c 1137 printf("SSL_ERROR_CONN_LOST\n");
feb11 0:85fceccc1a7c 1138 ssl->hs_status = SSL_ERROR_DEAD; /* make sure it stays dead */
feb11 0:85fceccc1a7c 1139 return SSL_ERROR_CONN_LOST;
feb11 0:85fceccc1a7c 1140 }
feb11 0:85fceccc1a7c 1141
feb11 0:85fceccc1a7c 1142 ret += read_len;
feb11 0:85fceccc1a7c 1143
feb11 0:85fceccc1a7c 1144 }while(ret < length);
feb11 0:85fceccc1a7c 1145 DISPLAY_BYTES(ssl, "received %d bytes", data, ret, ret);
feb11 0:85fceccc1a7c 1146 return ret;
feb11 0:85fceccc1a7c 1147 }
feb11 0:85fceccc1a7c 1148
feb11 0:85fceccc1a7c 1149 int read_record(SSL *ssl)
feb11 0:85fceccc1a7c 1150 {
feb11 0:85fceccc1a7c 1151 if(!IS_SET_SSL_FLAG(SSL_NEED_RECORD))
feb11 0:85fceccc1a7c 1152 return 0;
feb11 0:85fceccc1a7c 1153 uint8_t record[SSL_RECORD_SIZE];
feb11 0:85fceccc1a7c 1154 int ret = basic_read2(ssl, record, SSL_RECORD_SIZE);
feb11 0:85fceccc1a7c 1155 if(ret != SSL_RECORD_SIZE)
feb11 0:85fceccc1a7c 1156 return ret;
feb11 0:85fceccc1a7c 1157
feb11 0:85fceccc1a7c 1158 /* check for sslv2 "client hello" */
feb11 0:85fceccc1a7c 1159 if (record[0] & 0x80 && record[2] == 1)
feb11 0:85fceccc1a7c 1160 {
feb11 0:85fceccc1a7c 1161 #ifdef CONFIG_SSL_ENABLE_V23_HANDSHAKE
feb11 0:85fceccc1a7c 1162 uint8_t version = (record[3] << 4) + record[4];
feb11 0:85fceccc1a7c 1163 DISPLAY_BYTES(ssl, "ssl2 record", record, 5);
feb11 0:85fceccc1a7c 1164
feb11 0:85fceccc1a7c 1165 /* should be v3.1 (TLSv1) or better */
feb11 0:85fceccc1a7c 1166 ssl->version = ssl->client_version = version;
feb11 0:85fceccc1a7c 1167
feb11 0:85fceccc1a7c 1168 if (version > SSL_PROTOCOL_VERSION_MAX)
feb11 0:85fceccc1a7c 1169 {
feb11 0:85fceccc1a7c 1170 /* use client's version */
feb11 0:85fceccc1a7c 1171 ssl->version = SSL_PROTOCOL_VERSION_MAX;
feb11 0:85fceccc1a7c 1172 }
feb11 0:85fceccc1a7c 1173 else if (version < SSL_PROTOCOL_MIN_VERSION)
feb11 0:85fceccc1a7c 1174 {
feb11 0:85fceccc1a7c 1175 ret = SSL_ERROR_INVALID_VERSION;
feb11 0:85fceccc1a7c 1176 ssl_display_error(ret);
feb11 0:85fceccc1a7c 1177 return ret;
feb11 0:85fceccc1a7c 1178 }
feb11 0:85fceccc1a7c 1179
feb11 0:85fceccc1a7c 1180 add_packet(ssl, &record[2], 3);
feb11 0:85fceccc1a7c 1181 ret = process_sslv23_client_hello(ssl);
feb11 0:85fceccc1a7c 1182 #else
feb11 0:85fceccc1a7c 1183 printf("Error: no SSLv23 handshaking allowed\n"); TTY_FLUSH();
feb11 0:85fceccc1a7c 1184 ret = SSL_ERROR_NOT_SUPPORTED;
feb11 0:85fceccc1a7c 1185 #endif
feb11 0:85fceccc1a7c 1186 return ret;
feb11 0:85fceccc1a7c 1187 }
feb11 0:85fceccc1a7c 1188
feb11 0:85fceccc1a7c 1189 ssl->need_bytes = (record[3] << 8) + record[4];
feb11 0:85fceccc1a7c 1190
feb11 0:85fceccc1a7c 1191 memcpy(ssl->hmac_header, record, 3); /* store for hmac */
feb11 0:85fceccc1a7c 1192 ssl->record_type = record[0];
feb11 0:85fceccc1a7c 1193 CLR_SSL_FLAG(SSL_NEED_RECORD);
feb11 0:85fceccc1a7c 1194 if(ssl->record_type == PT_APP_PROTOCOL_DATA)
feb11 0:85fceccc1a7c 1195 {
feb11 0:85fceccc1a7c 1196 ssl->need_bytes -= ssl->cipher_info->digest_size;
feb11 0:85fceccc1a7c 1197 if(ssl->cipher == SSL_AES256_SHA || ssl->cipher == SSL_AES128_SHA)
feb11 0:85fceccc1a7c 1198 {
feb11 0:85fceccc1a7c 1199 // discard IV
feb11 0:85fceccc1a7c 1200 basic_read2(ssl, ssl->bm_all_data + ssl->bm_index, AES_BLOCKSIZE);
feb11 0:85fceccc1a7c 1201 ssl->bm_remaining_bytes = basic_decrypt(ssl, ssl->bm_all_data + ssl->bm_index, AES_BLOCKSIZE);
feb11 0:85fceccc1a7c 1202 ssl->need_bytes -= AES_BLOCKSIZE;
feb11 0:85fceccc1a7c 1203 }
feb11 0:85fceccc1a7c 1204
feb11 0:85fceccc1a7c 1205 }
feb11 0:85fceccc1a7c 1206 return SSL_OK;
feb11 0:85fceccc1a7c 1207 }
feb11 0:85fceccc1a7c 1208
feb11 0:85fceccc1a7c 1209 int basic_decrypt(SSL *ssl, uint8_t *buf, int len)
feb11 0:85fceccc1a7c 1210 {
feb11 0:85fceccc1a7c 1211 if (IS_SET_SSL_FLAG(SSL_RX_ENCRYPTED))
feb11 0:85fceccc1a7c 1212 {
feb11 0:85fceccc1a7c 1213 ssl->cipher_info->decrypt(ssl->decrypt_ctx, buf, buf, len);
feb11 0:85fceccc1a7c 1214
feb11 0:85fceccc1a7c 1215 if (ssl->version >= SSL_PROTOCOL_VERSION1_1 &&
feb11 0:85fceccc1a7c 1216 ssl->cipher_info->iv_size)
feb11 0:85fceccc1a7c 1217 {
feb11 0:85fceccc1a7c 1218 buf += ssl->cipher_info->iv_size;
feb11 0:85fceccc1a7c 1219 len -= ssl->cipher_info->iv_size;
feb11 0:85fceccc1a7c 1220 }
feb11 0:85fceccc1a7c 1221
feb11 0:85fceccc1a7c 1222 if(ssl->record_type != PT_APP_PROTOCOL_DATA)
feb11 0:85fceccc1a7c 1223 len = verify_digest(ssl,
feb11 0:85fceccc1a7c 1224 IS_SET_SSL_FLAG(SSL_IS_CLIENT) ? SSL_CLIENT_READ : SSL_SERVER_READ, buf, len);
feb11 0:85fceccc1a7c 1225
feb11 0:85fceccc1a7c 1226 /* does the hmac work? */
feb11 0:85fceccc1a7c 1227 if (len < 0)
feb11 0:85fceccc1a7c 1228 {
feb11 0:85fceccc1a7c 1229 return len;
feb11 0:85fceccc1a7c 1230 }
feb11 0:85fceccc1a7c 1231
feb11 0:85fceccc1a7c 1232 DISPLAY_BYTES(ssl, "decrypted", buf, len);
feb11 0:85fceccc1a7c 1233 increment_read_sequence(ssl);
feb11 0:85fceccc1a7c 1234 }
feb11 0:85fceccc1a7c 1235 return len;
feb11 0:85fceccc1a7c 1236 }
feb11 0:85fceccc1a7c 1237
feb11 0:85fceccc1a7c 1238 int ssl_read(SSL *ssl, uint8_t *in_data, int len)
feb11 0:85fceccc1a7c 1239 {
feb11 0:85fceccc1a7c 1240 if(len <= 0 || in_data == NULL)
feb11 0:85fceccc1a7c 1241 return 0;
feb11 0:85fceccc1a7c 1242
feb11 0:85fceccc1a7c 1243 if(IS_SET_SSL_FLAG(SSL_NEED_RECORD))
feb11 0:85fceccc1a7c 1244 {
feb11 0:85fceccc1a7c 1245 read_record(ssl);
feb11 0:85fceccc1a7c 1246 }
feb11 0:85fceccc1a7c 1247
feb11 0:85fceccc1a7c 1248 return process_data(ssl, in_data, len);
feb11 0:85fceccc1a7c 1249 }
feb11 0:85fceccc1a7c 1250
feb11 0:85fceccc1a7c 1251 int process_data(SSL* ssl, uint8_t *in_data, int len)
feb11 0:85fceccc1a7c 1252 {
feb11 0:85fceccc1a7c 1253 int ret = 0;
feb11 0:85fceccc1a7c 1254 /* The main part of the SSL packet */
feb11 0:85fceccc1a7c 1255 switch (ssl->record_type)
feb11 0:85fceccc1a7c 1256 {
feb11 0:85fceccc1a7c 1257 case PT_HANDSHAKE_PROTOCOL:
feb11 0:85fceccc1a7c 1258
feb11 0:85fceccc1a7c 1259 if (ssl->dc != NULL)
feb11 0:85fceccc1a7c 1260 {
feb11 0:85fceccc1a7c 1261 ssl->dc->bm_proc_index = 0;
feb11 0:85fceccc1a7c 1262 ret = do_handshake(ssl, NULL, 0);
feb11 0:85fceccc1a7c 1263 SET_SSL_FLAG(SSL_NEED_RECORD);
feb11 0:85fceccc1a7c 1264 return ret;
feb11 0:85fceccc1a7c 1265 }
feb11 0:85fceccc1a7c 1266 else /* no client renegotiation allowed */
feb11 0:85fceccc1a7c 1267 {
feb11 0:85fceccc1a7c 1268 SET_SSL_FLAG(SSL_NEED_RECORD);
feb11 0:85fceccc1a7c 1269 return SSL_ERROR_NO_CLIENT_RENOG;
feb11 0:85fceccc1a7c 1270 }
feb11 0:85fceccc1a7c 1271
feb11 0:85fceccc1a7c 1272 case PT_CHANGE_CIPHER_SPEC:
feb11 0:85fceccc1a7c 1273
feb11 0:85fceccc1a7c 1274 if(basic_read2(ssl, ssl->bm_data, ssl->need_bytes) != ssl->need_bytes)
feb11 0:85fceccc1a7c 1275 return -1;
feb11 0:85fceccc1a7c 1276
feb11 0:85fceccc1a7c 1277 ret = basic_decrypt(ssl, ssl->bm_data, ssl->need_bytes);
feb11 0:85fceccc1a7c 1278 if(ret < 0)
feb11 0:85fceccc1a7c 1279 return -1;
feb11 0:85fceccc1a7c 1280
feb11 0:85fceccc1a7c 1281 if (ssl->next_state != HS_FINISHED)
feb11 0:85fceccc1a7c 1282 {
feb11 0:85fceccc1a7c 1283 return SSL_ERROR_INVALID_HANDSHAKE;
feb11 0:85fceccc1a7c 1284 }
feb11 0:85fceccc1a7c 1285
feb11 0:85fceccc1a7c 1286 /* all encrypted from now on */
feb11 0:85fceccc1a7c 1287 SET_SSL_FLAG(SSL_RX_ENCRYPTED);
feb11 0:85fceccc1a7c 1288 if (set_key_block(ssl, 0) < 0)
feb11 0:85fceccc1a7c 1289 {
feb11 0:85fceccc1a7c 1290 return SSL_ERROR_INVALID_HANDSHAKE;
feb11 0:85fceccc1a7c 1291 }
feb11 0:85fceccc1a7c 1292
feb11 0:85fceccc1a7c 1293 memset(ssl->read_sequence, 0, 8);
feb11 0:85fceccc1a7c 1294 SET_SSL_FLAG(SSL_NEED_RECORD);
feb11 0:85fceccc1a7c 1295 break;
feb11 0:85fceccc1a7c 1296
feb11 0:85fceccc1a7c 1297 case PT_APP_PROTOCOL_DATA:
feb11 0:85fceccc1a7c 1298 if(len <= 0)
feb11 0:85fceccc1a7c 1299 return 0;
feb11 0:85fceccc1a7c 1300 if(ssl->need_bytes == 0)
feb11 0:85fceccc1a7c 1301 return 0;
feb11 0:85fceccc1a7c 1302 if (in_data)
feb11 0:85fceccc1a7c 1303 {
feb11 0:85fceccc1a7c 1304 uint16_t index = ssl->bm_index % 2048;
feb11 0:85fceccc1a7c 1305 if(ssl->bm_remaining_bytes == 0)
feb11 0:85fceccc1a7c 1306 {
feb11 0:85fceccc1a7c 1307 int read_len = len;
feb11 0:85fceccc1a7c 1308 if(read_len > 2048-index)
feb11 0:85fceccc1a7c 1309 read_len = 2048-index;
feb11 0:85fceccc1a7c 1310 if(read_len > ssl->need_bytes)
feb11 0:85fceccc1a7c 1311 read_len = ssl->need_bytes;
feb11 0:85fceccc1a7c 1312
feb11 0:85fceccc1a7c 1313 // check if using a block cipher
feb11 0:85fceccc1a7c 1314 if(ssl->cipher == SSL_AES256_SHA || ssl->cipher == SSL_AES128_SHA)
feb11 0:85fceccc1a7c 1315 {
feb11 0:85fceccc1a7c 1316 read_len = AES_BLOCKSIZE;
feb11 0:85fceccc1a7c 1317 }
feb11 0:85fceccc1a7c 1318
feb11 0:85fceccc1a7c 1319 int ret = basic_read2(ssl, ssl->bm_all_data + index, read_len);
feb11 0:85fceccc1a7c 1320 if(ret != read_len)
feb11 0:85fceccc1a7c 1321 return 0;
feb11 0:85fceccc1a7c 1322
feb11 0:85fceccc1a7c 1323 ssl->bm_remaining_bytes = basic_decrypt(ssl, ssl->bm_all_data + index, read_len);
feb11 0:85fceccc1a7c 1324
feb11 0:85fceccc1a7c 1325 if(ssl->cipher == SSL_AES256_SHA || ssl->cipher == SSL_AES128_SHA)
feb11 0:85fceccc1a7c 1326 {
feb11 0:85fceccc1a7c 1327 ssl->bm_remaining_bytes = AES_BLOCKSIZE;
feb11 0:85fceccc1a7c 1328 }
feb11 0:85fceccc1a7c 1329 if(ssl->need_bytes < ssl->bm_remaining_bytes)
feb11 0:85fceccc1a7c 1330 {
feb11 0:85fceccc1a7c 1331 ssl->bm_remaining_bytes = ssl->need_bytes;
feb11 0:85fceccc1a7c 1332 ssl->need_bytes = 0;
feb11 0:85fceccc1a7c 1333 }
feb11 0:85fceccc1a7c 1334 else
feb11 0:85fceccc1a7c 1335 ssl->need_bytes -= ssl->bm_remaining_bytes;
feb11 0:85fceccc1a7c 1336 }
feb11 0:85fceccc1a7c 1337 if(len > ssl->bm_remaining_bytes)
feb11 0:85fceccc1a7c 1338 len = ssl->bm_remaining_bytes;
feb11 0:85fceccc1a7c 1339 memcpy(in_data, ssl->bm_all_data+index, len);
feb11 0:85fceccc1a7c 1340 ssl->bm_index += len;
feb11 0:85fceccc1a7c 1341 ssl->bm_remaining_bytes -= len;
feb11 0:85fceccc1a7c 1342
feb11 0:85fceccc1a7c 1343 if(ssl->need_bytes == 0)
feb11 0:85fceccc1a7c 1344 {
feb11 0:85fceccc1a7c 1345 // skip digest
feb11 0:85fceccc1a7c 1346 uint8_t buf_tmp[SHA1_SIZE];
feb11 0:85fceccc1a7c 1347 if(ssl->cipher == SSL_AES256_SHA || ssl->cipher == SSL_AES128_SHA)
feb11 0:85fceccc1a7c 1348 {
feb11 0:85fceccc1a7c 1349 basic_read2(ssl, buf_tmp, AES_BLOCKSIZE);
feb11 0:85fceccc1a7c 1350 basic_decrypt(ssl, buf_tmp, AES_BLOCKSIZE);
feb11 0:85fceccc1a7c 1351 }
feb11 0:85fceccc1a7c 1352 else
feb11 0:85fceccc1a7c 1353 {
feb11 0:85fceccc1a7c 1354 basic_read2(ssl, buf_tmp, ssl->cipher_info->digest_size);
feb11 0:85fceccc1a7c 1355 basic_decrypt(ssl, buf_tmp, ssl->cipher_info->digest_size);
feb11 0:85fceccc1a7c 1356 }
feb11 0:85fceccc1a7c 1357 SET_SSL_FLAG(SSL_NEED_RECORD);
feb11 0:85fceccc1a7c 1358 }
feb11 0:85fceccc1a7c 1359 if(ssl->bm_index >= 2048)
feb11 0:85fceccc1a7c 1360 ssl->bm_index = 0;
feb11 0:85fceccc1a7c 1361 return len;
feb11 0:85fceccc1a7c 1362 }
feb11 0:85fceccc1a7c 1363 return 0;
feb11 0:85fceccc1a7c 1364
feb11 0:85fceccc1a7c 1365 case PT_ALERT_PROTOCOL:
feb11 0:85fceccc1a7c 1366 if(basic_read2(ssl, ssl->bm_data, ssl->need_bytes) != ssl->need_bytes)
feb11 0:85fceccc1a7c 1367 return -1;
feb11 0:85fceccc1a7c 1368 ret = basic_decrypt(ssl, ssl->bm_data, ssl->need_bytes);
feb11 0:85fceccc1a7c 1369 if(ret < 0)
feb11 0:85fceccc1a7c 1370 return -1;
feb11 0:85fceccc1a7c 1371
feb11 0:85fceccc1a7c 1372 SET_SSL_FLAG(SSL_NEED_RECORD);
feb11 0:85fceccc1a7c 1373
feb11 0:85fceccc1a7c 1374 /* return the alert # with alert bit set */
feb11 0:85fceccc1a7c 1375 if(ssl->bm_data[0] == SSL_ALERT_TYPE_WARNING &&
feb11 0:85fceccc1a7c 1376 ssl->bm_data[1] == SSL_ALERT_CLOSE_NOTIFY)
feb11 0:85fceccc1a7c 1377 {
feb11 0:85fceccc1a7c 1378 send_alert(ssl, SSL_ALERT_CLOSE_NOTIFY);
feb11 0:85fceccc1a7c 1379 SET_SSL_FLAG(SSL_SENT_CLOSE_NOTIFY);
feb11 0:85fceccc1a7c 1380 return SSL_CLOSE_NOTIFY;
feb11 0:85fceccc1a7c 1381 }
feb11 0:85fceccc1a7c 1382 else
feb11 0:85fceccc1a7c 1383 {
feb11 0:85fceccc1a7c 1384 ret = -ssl->bm_data[1];
feb11 0:85fceccc1a7c 1385 DISPLAY_ALERT(ssl, -ret);
feb11 0:85fceccc1a7c 1386 return ret;
feb11 0:85fceccc1a7c 1387 }
feb11 0:85fceccc1a7c 1388
feb11 0:85fceccc1a7c 1389 default:
feb11 0:85fceccc1a7c 1390 return SSL_ERROR_INVALID_PROT_MSG;
feb11 0:85fceccc1a7c 1391
feb11 0:85fceccc1a7c 1392 }
feb11 0:85fceccc1a7c 1393 return ret;
feb11 0:85fceccc1a7c 1394 }
feb11 0:85fceccc1a7c 1395
feb11 0:85fceccc1a7c 1396
feb11 0:85fceccc1a7c 1397 /**
feb11 0:85fceccc1a7c 1398 * Do some basic checking of data and then perform the appropriate handshaking.
feb11 0:85fceccc1a7c 1399 */
feb11 0:85fceccc1a7c 1400 static int do_handshake(SSL *ssl, uint8_t *buf, int read_len)
feb11 0:85fceccc1a7c 1401 {
feb11 0:85fceccc1a7c 1402 uint8_t hs_hdr[SSL_HS_HDR_SIZE];
feb11 0:85fceccc1a7c 1403 if (IS_SET_SSL_FLAG(SSL_RX_ENCRYPTED))
feb11 0:85fceccc1a7c 1404 {
feb11 0:85fceccc1a7c 1405 if(basic_read2(ssl, ssl->bm_data, ssl->need_bytes) != ssl->need_bytes)
feb11 0:85fceccc1a7c 1406 return -1;
feb11 0:85fceccc1a7c 1407 ssl->need_bytes = basic_decrypt(ssl, ssl->bm_data, ssl->need_bytes);
feb11 0:85fceccc1a7c 1408 buf = ssl->bm_data;
feb11 0:85fceccc1a7c 1409 if(ssl->cipher == SSL_AES256_SHA || ssl->cipher == SSL_AES128_SHA)
feb11 0:85fceccc1a7c 1410 {
feb11 0:85fceccc1a7c 1411 buf += ssl->cipher_info->iv_size;
feb11 0:85fceccc1a7c 1412 add_packet(ssl, ssl->bm_data, ssl->cipher_info->iv_size);
feb11 0:85fceccc1a7c 1413 }
feb11 0:85fceccc1a7c 1414 }
feb11 0:85fceccc1a7c 1415 else
feb11 0:85fceccc1a7c 1416 {
feb11 0:85fceccc1a7c 1417 if(basic_read2(ssl, hs_hdr, SSL_HS_HDR_SIZE) != SSL_HS_HDR_SIZE)
feb11 0:85fceccc1a7c 1418 return -1;
feb11 0:85fceccc1a7c 1419 buf = hs_hdr;
feb11 0:85fceccc1a7c 1420 }
feb11 0:85fceccc1a7c 1421
feb11 0:85fceccc1a7c 1422 int hs_len = (buf[2]<<8) + buf[3];
feb11 0:85fceccc1a7c 1423 uint8_t handshake_type = buf[0];
feb11 0:85fceccc1a7c 1424 int ret = SSL_OK;
feb11 0:85fceccc1a7c 1425 int is_client = IS_SET_SSL_FLAG(SSL_IS_CLIENT);
feb11 0:85fceccc1a7c 1426
feb11 0:85fceccc1a7c 1427 /* some integrity checking on the handshake */
feb11 0:85fceccc1a7c 1428 //PARANOIA_CHECK(read_len-SSL_HS_HDR_SIZE, hs_len);
feb11 0:85fceccc1a7c 1429 if (handshake_type != ssl->next_state)
feb11 0:85fceccc1a7c 1430 {
feb11 0:85fceccc1a7c 1431 /* handle a special case on the client */
feb11 0:85fceccc1a7c 1432 if (!is_client || handshake_type != HS_CERT_REQ ||
feb11 0:85fceccc1a7c 1433 ssl->next_state != HS_SERVER_HELLO_DONE)
feb11 0:85fceccc1a7c 1434 {
feb11 0:85fceccc1a7c 1435 return SSL_ERROR_INVALID_HANDSHAKE;
feb11 0:85fceccc1a7c 1436 }
feb11 0:85fceccc1a7c 1437 }
feb11 0:85fceccc1a7c 1438
feb11 0:85fceccc1a7c 1439 //hs_len += SSL_HS_HDR_SIZE; /* adjust for when adding packets */
feb11 0:85fceccc1a7c 1440 ssl->bm_index = hs_len+SSL_HS_HDR_SIZE; /* store the size and check later */
feb11 0:85fceccc1a7c 1441 DISPLAY_STATE(ssl, 0, handshake_type, 0);
feb11 0:85fceccc1a7c 1442
feb11 0:85fceccc1a7c 1443 if (handshake_type != HS_CERT_VERIFY && handshake_type != HS_HELLO_REQUEST)
feb11 0:85fceccc1a7c 1444 {
feb11 0:85fceccc1a7c 1445 add_packet(ssl, buf, SSL_HS_HDR_SIZE);
feb11 0:85fceccc1a7c 1446 }
feb11 0:85fceccc1a7c 1447
feb11 0:85fceccc1a7c 1448 if(!IS_SET_SSL_FLAG(SSL_RX_ENCRYPTED))
feb11 0:85fceccc1a7c 1449 {
feb11 0:85fceccc1a7c 1450 if(hs_len != 0 && handshake_type != HS_CERTIFICATE)
feb11 0:85fceccc1a7c 1451 {
feb11 0:85fceccc1a7c 1452 if(basic_read2(ssl, ssl->bm_data, hs_len) != hs_len)
feb11 0:85fceccc1a7c 1453 return -1;
feb11 0:85fceccc1a7c 1454 hs_len = basic_decrypt(ssl, ssl->bm_data, hs_len);
feb11 0:85fceccc1a7c 1455 if(hs_len < 0)
feb11 0:85fceccc1a7c 1456 return -1;
feb11 0:85fceccc1a7c 1457
feb11 0:85fceccc1a7c 1458 buf = ssl->bm_data;
feb11 0:85fceccc1a7c 1459 if (handshake_type != HS_CERT_VERIFY && handshake_type != HS_HELLO_REQUEST)
feb11 0:85fceccc1a7c 1460 add_packet(ssl, buf, hs_len);
feb11 0:85fceccc1a7c 1461 }
feb11 0:85fceccc1a7c 1462 }
feb11 0:85fceccc1a7c 1463
feb11 0:85fceccc1a7c 1464 else if (handshake_type != HS_CERT_VERIFY && handshake_type != HS_HELLO_REQUEST)
feb11 0:85fceccc1a7c 1465 {
feb11 0:85fceccc1a7c 1466 add_packet(ssl,buf+SSL_HS_HDR_SIZE, hs_len);
feb11 0:85fceccc1a7c 1467 }
feb11 0:85fceccc1a7c 1468
feb11 0:85fceccc1a7c 1469 #if defined(CONFIG_SSL_ENABLE_CLIENT)
feb11 0:85fceccc1a7c 1470 ret = is_client ?
feb11 0:85fceccc1a7c 1471 do_clnt_handshake(ssl, handshake_type, buf, hs_len) :
feb11 0:85fceccc1a7c 1472 do_svr_handshake(ssl, handshake_type, buf, hs_len);
feb11 0:85fceccc1a7c 1473 #else
feb11 0:85fceccc1a7c 1474 ret = do_svr_handshake(ssl, handshake_type, buf, hs_len);
feb11 0:85fceccc1a7c 1475 #endif
feb11 0:85fceccc1a7c 1476
feb11 0:85fceccc1a7c 1477
feb11 0:85fceccc1a7c 1478 return ret;
feb11 0:85fceccc1a7c 1479 }
feb11 0:85fceccc1a7c 1480
feb11 0:85fceccc1a7c 1481 /**
feb11 0:85fceccc1a7c 1482 * Sends the change cipher spec message. We have just read a finished message
feb11 0:85fceccc1a7c 1483 * from the client.
feb11 0:85fceccc1a7c 1484 */
feb11 0:85fceccc1a7c 1485 int send_change_cipher_spec(SSL *ssl)
feb11 0:85fceccc1a7c 1486 {
feb11 0:85fceccc1a7c 1487 int ret = send_packet(ssl, PT_CHANGE_CIPHER_SPEC,
feb11 0:85fceccc1a7c 1488 g_chg_cipher_spec_pkt, sizeof(g_chg_cipher_spec_pkt));
feb11 0:85fceccc1a7c 1489 SET_SSL_FLAG(SSL_TX_ENCRYPTED);
feb11 0:85fceccc1a7c 1490 if (ret >= 0 && set_key_block(ssl, 1) < 0)
feb11 0:85fceccc1a7c 1491 ret = SSL_ERROR_INVALID_HANDSHAKE;
feb11 0:85fceccc1a7c 1492
feb11 0:85fceccc1a7c 1493 memset(ssl->write_sequence, 0, 8);
feb11 0:85fceccc1a7c 1494 return ret;
feb11 0:85fceccc1a7c 1495 }
feb11 0:85fceccc1a7c 1496
feb11 0:85fceccc1a7c 1497 /**
feb11 0:85fceccc1a7c 1498 * Send a "finished" message
feb11 0:85fceccc1a7c 1499 */
feb11 0:85fceccc1a7c 1500 int send_finished(SSL *ssl)
feb11 0:85fceccc1a7c 1501 {
feb11 0:85fceccc1a7c 1502
feb11 0:85fceccc1a7c 1503 #ifdef CONFIG_SSL_CERT_VERIFICATION
feb11 0:85fceccc1a7c 1504 if(IS_SET_SSL_FLAG(SSL_IS_CLIENT))
feb11 0:85fceccc1a7c 1505 {
feb11 0:85fceccc1a7c 1506 x509_free(ssl->x509_ctx);
feb11 0:85fceccc1a7c 1507 ssl->x509_ctx = NULL;
feb11 0:85fceccc1a7c 1508 }
feb11 0:85fceccc1a7c 1509 #endif
feb11 0:85fceccc1a7c 1510
feb11 0:85fceccc1a7c 1511 uint8_t buf[SSL_FINISHED_HASH_SIZE+4] = {
feb11 0:85fceccc1a7c 1512 HS_FINISHED, 0, 0, SSL_FINISHED_HASH_SIZE };
feb11 0:85fceccc1a7c 1513
feb11 0:85fceccc1a7c 1514 /* now add the finished digest mac (12 bytes) */
feb11 0:85fceccc1a7c 1515 finished_digest(ssl,
feb11 0:85fceccc1a7c 1516 IS_SET_SSL_FLAG(SSL_IS_CLIENT) ?
feb11 0:85fceccc1a7c 1517 client_finished : server_finished, &buf[4]);
feb11 0:85fceccc1a7c 1518
feb11 0:85fceccc1a7c 1519 #ifndef CONFIG_SSL_SKELETON_MODE
feb11 0:85fceccc1a7c 1520 /* store in the session cache */
feb11 0:85fceccc1a7c 1521 if (!IS_SET_SSL_FLAG(SSL_SESSION_RESUME) && ssl->ssl_ctx->num_sessions)
feb11 0:85fceccc1a7c 1522 {
feb11 0:85fceccc1a7c 1523 memcpy(ssl->session->master_secret,
feb11 0:85fceccc1a7c 1524 ssl->dc->master_secret, SSL_SECRET_SIZE);
feb11 0:85fceccc1a7c 1525 }
feb11 0:85fceccc1a7c 1526 #endif
feb11 0:85fceccc1a7c 1527
feb11 0:85fceccc1a7c 1528 return send_packet(ssl, PT_HANDSHAKE_PROTOCOL,
feb11 0:85fceccc1a7c 1529 buf, SSL_FINISHED_HASH_SIZE+4);
feb11 0:85fceccc1a7c 1530 }
feb11 0:85fceccc1a7c 1531
feb11 0:85fceccc1a7c 1532 /**
feb11 0:85fceccc1a7c 1533 * Send an alert message.
feb11 0:85fceccc1a7c 1534 * Return 1 if the alert was an "error".
feb11 0:85fceccc1a7c 1535 */
feb11 0:85fceccc1a7c 1536 int send_alert(SSL *ssl, int error_code)
feb11 0:85fceccc1a7c 1537 {
feb11 0:85fceccc1a7c 1538 int alert_num = 0;
feb11 0:85fceccc1a7c 1539 int is_warning = 0;
feb11 0:85fceccc1a7c 1540 uint8_t buf[2];
feb11 0:85fceccc1a7c 1541
feb11 0:85fceccc1a7c 1542 /* Don't bother we're already dead */
feb11 0:85fceccc1a7c 1543 if (ssl->hs_status == SSL_ERROR_DEAD)
feb11 0:85fceccc1a7c 1544 {
feb11 0:85fceccc1a7c 1545 return SSL_ERROR_CONN_LOST;
feb11 0:85fceccc1a7c 1546 }
feb11 0:85fceccc1a7c 1547
feb11 0:85fceccc1a7c 1548 #ifdef CONFIG_SSL_FULL_MODE
feb11 0:85fceccc1a7c 1549 if (IS_SET_SSL_FLAG(SSL_DISPLAY_STATES))
feb11 0:85fceccc1a7c 1550 ssl_display_error(error_code);
feb11 0:85fceccc1a7c 1551 #endif
feb11 0:85fceccc1a7c 1552
feb11 0:85fceccc1a7c 1553 switch (error_code)
feb11 0:85fceccc1a7c 1554 {
feb11 0:85fceccc1a7c 1555 case SSL_ALERT_CLOSE_NOTIFY:
feb11 0:85fceccc1a7c 1556 is_warning = 1;
feb11 0:85fceccc1a7c 1557 alert_num = SSL_ALERT_CLOSE_NOTIFY;
feb11 0:85fceccc1a7c 1558 break;
feb11 0:85fceccc1a7c 1559
feb11 0:85fceccc1a7c 1560 case SSL_ERROR_CONN_LOST: /* don't send alert just yet */
feb11 0:85fceccc1a7c 1561 is_warning = 1;
feb11 0:85fceccc1a7c 1562 break;
feb11 0:85fceccc1a7c 1563
feb11 0:85fceccc1a7c 1564 case SSL_ERROR_INVALID_HANDSHAKE:
feb11 0:85fceccc1a7c 1565 case SSL_ERROR_INVALID_PROT_MSG:
feb11 0:85fceccc1a7c 1566 alert_num = SSL_ALERT_HANDSHAKE_FAILURE;
feb11 0:85fceccc1a7c 1567 break;
feb11 0:85fceccc1a7c 1568
feb11 0:85fceccc1a7c 1569 case SSL_ERROR_INVALID_HMAC:
feb11 0:85fceccc1a7c 1570 case SSL_ERROR_FINISHED_INVALID:
feb11 0:85fceccc1a7c 1571 alert_num = SSL_ALERT_BAD_RECORD_MAC;
feb11 0:85fceccc1a7c 1572 break;
feb11 0:85fceccc1a7c 1573
feb11 0:85fceccc1a7c 1574 case SSL_ERROR_INVALID_VERSION:
feb11 0:85fceccc1a7c 1575 alert_num = SSL_ALERT_INVALID_VERSION;
feb11 0:85fceccc1a7c 1576 break;
feb11 0:85fceccc1a7c 1577
feb11 0:85fceccc1a7c 1578 case SSL_ERROR_INVALID_SESSION:
feb11 0:85fceccc1a7c 1579 case SSL_ERROR_NO_CIPHER:
feb11 0:85fceccc1a7c 1580 case SSL_ERROR_INVALID_KEY:
feb11 0:85fceccc1a7c 1581 alert_num = SSL_ALERT_ILLEGAL_PARAMETER;
feb11 0:85fceccc1a7c 1582 break;
feb11 0:85fceccc1a7c 1583
feb11 0:85fceccc1a7c 1584 case SSL_ERROR_BAD_CERTIFICATE:
feb11 0:85fceccc1a7c 1585 alert_num = SSL_ALERT_BAD_CERTIFICATE;
feb11 0:85fceccc1a7c 1586 break;
feb11 0:85fceccc1a7c 1587
feb11 0:85fceccc1a7c 1588 case SSL_ERROR_NO_CLIENT_RENOG:
feb11 0:85fceccc1a7c 1589 alert_num = SSL_ALERT_NO_RENEGOTIATION;
feb11 0:85fceccc1a7c 1590 break;
feb11 0:85fceccc1a7c 1591
feb11 0:85fceccc1a7c 1592 default:
feb11 0:85fceccc1a7c 1593 /* a catch-all for any badly verified certificates */
feb11 0:85fceccc1a7c 1594 alert_num = (error_code <= SSL_X509_OFFSET) ?
feb11 0:85fceccc1a7c 1595 SSL_ALERT_BAD_CERTIFICATE : SSL_ALERT_UNEXPECTED_MESSAGE;
feb11 0:85fceccc1a7c 1596 break;
feb11 0:85fceccc1a7c 1597 }
feb11 0:85fceccc1a7c 1598
feb11 0:85fceccc1a7c 1599 buf[0] = is_warning ? 1 : 2;
feb11 0:85fceccc1a7c 1600 buf[1] = alert_num;
feb11 0:85fceccc1a7c 1601
feb11 0:85fceccc1a7c 1602 send_packet(ssl, PT_ALERT_PROTOCOL, buf, sizeof(buf));
feb11 0:85fceccc1a7c 1603 DISPLAY_ALERT(ssl, alert_num);
feb11 0:85fceccc1a7c 1604 return is_warning ? 0 : 1;
feb11 0:85fceccc1a7c 1605 }
feb11 0:85fceccc1a7c 1606
feb11 0:85fceccc1a7c 1607 /**
feb11 0:85fceccc1a7c 1608 * Process a client finished message.
feb11 0:85fceccc1a7c 1609 */
feb11 0:85fceccc1a7c 1610 int process_finished(SSL *ssl, uint8_t *buf, int hs_len)
feb11 0:85fceccc1a7c 1611 {
feb11 0:85fceccc1a7c 1612 int is_client = IS_SET_SSL_FLAG(SSL_IS_CLIENT);
feb11 0:85fceccc1a7c 1613 int ret = SSL_OK;
feb11 0:85fceccc1a7c 1614 int resume = IS_SET_SSL_FLAG(SSL_SESSION_RESUME);
feb11 0:85fceccc1a7c 1615
feb11 0:85fceccc1a7c 1616 PARANOIA_CHECK(ssl->bm_index, SSL_FINISHED_HASH_SIZE);
feb11 0:85fceccc1a7c 1617
feb11 0:85fceccc1a7c 1618 /* check that we all work before we continue */
feb11 0:85fceccc1a7c 1619 if (memcmp(ssl->dc->final_finish_mac, &buf[4], SSL_FINISHED_HASH_SIZE))
feb11 0:85fceccc1a7c 1620 {
feb11 0:85fceccc1a7c 1621 return SSL_ERROR_FINISHED_INVALID;
feb11 0:85fceccc1a7c 1622 }
feb11 0:85fceccc1a7c 1623 if ((!is_client && !resume) || (is_client && resume))
feb11 0:85fceccc1a7c 1624 {
feb11 0:85fceccc1a7c 1625 if ((ret = send_change_cipher_spec(ssl)) == SSL_OK)
feb11 0:85fceccc1a7c 1626 ret = send_finished(ssl);
feb11 0:85fceccc1a7c 1627 }
feb11 0:85fceccc1a7c 1628
feb11 0:85fceccc1a7c 1629 /* if we ever renegotiate */
feb11 0:85fceccc1a7c 1630 ssl->next_state = is_client ? HS_HELLO_REQUEST : HS_CLIENT_HELLO;
feb11 0:85fceccc1a7c 1631 ssl->hs_status = ret; /* set the final handshake status */
feb11 0:85fceccc1a7c 1632 error:
feb11 0:85fceccc1a7c 1633 return ret;
feb11 0:85fceccc1a7c 1634 }
feb11 0:85fceccc1a7c 1635
feb11 0:85fceccc1a7c 1636 /**
feb11 0:85fceccc1a7c 1637 * Send a certificate.
feb11 0:85fceccc1a7c 1638 */
feb11 0:85fceccc1a7c 1639 int send_certificate(SSL *ssl)
feb11 0:85fceccc1a7c 1640 {
feb11 0:85fceccc1a7c 1641 int i = 0;
feb11 0:85fceccc1a7c 1642 uint8_t *buf = ssl->bm_data;
feb11 0:85fceccc1a7c 1643 int offset = 7;
feb11 0:85fceccc1a7c 1644 int chain_length;
feb11 0:85fceccc1a7c 1645
feb11 0:85fceccc1a7c 1646 buf[0] = HS_CERTIFICATE;
feb11 0:85fceccc1a7c 1647 buf[1] = 0;
feb11 0:85fceccc1a7c 1648 buf[4] = 0;
feb11 0:85fceccc1a7c 1649
feb11 0:85fceccc1a7c 1650 while (i < ssl->ssl_ctx->chain_length)
feb11 0:85fceccc1a7c 1651 {
feb11 0:85fceccc1a7c 1652 SSL_CERT *cert = &ssl->ssl_ctx->certs[i];
feb11 0:85fceccc1a7c 1653 buf[offset++] = 0;
feb11 0:85fceccc1a7c 1654 buf[offset++] = cert->size >> 8; /* cert 1 length */
feb11 0:85fceccc1a7c 1655 buf[offset++] = cert->size & 0xff;
feb11 0:85fceccc1a7c 1656 memcpy(&buf[offset], cert->buf, cert->size);
feb11 0:85fceccc1a7c 1657 offset += cert->size;
feb11 0:85fceccc1a7c 1658 i++;
feb11 0:85fceccc1a7c 1659 }
feb11 0:85fceccc1a7c 1660
feb11 0:85fceccc1a7c 1661 chain_length = offset - 7;
feb11 0:85fceccc1a7c 1662 buf[5] = chain_length >> 8; /* cert chain length */
feb11 0:85fceccc1a7c 1663 buf[6] = chain_length & 0xff;
feb11 0:85fceccc1a7c 1664 chain_length += 3;
feb11 0:85fceccc1a7c 1665 buf[2] = chain_length >> 8; /* handshake length */
feb11 0:85fceccc1a7c 1666 buf[3] = chain_length & 0xff;
feb11 0:85fceccc1a7c 1667 ssl->bm_index = offset;
feb11 0:85fceccc1a7c 1668 return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, offset);
feb11 0:85fceccc1a7c 1669 }
feb11 0:85fceccc1a7c 1670
feb11 0:85fceccc1a7c 1671 /**
feb11 0:85fceccc1a7c 1672 * Create a blob of memory that we'll get rid of once the handshake is
feb11 0:85fceccc1a7c 1673 * complete.
feb11 0:85fceccc1a7c 1674 */
feb11 0:85fceccc1a7c 1675 void disposable_new(SSL *ssl)
feb11 0:85fceccc1a7c 1676 {
feb11 0:85fceccc1a7c 1677 if (ssl->dc == NULL)
feb11 0:85fceccc1a7c 1678 {
feb11 0:85fceccc1a7c 1679 ssl->dc = (DISPOSABLE_CTX *)calloc(1, sizeof(DISPOSABLE_CTX));
feb11 0:85fceccc1a7c 1680 memset(ssl->dc->key_block, 0, MAX_KEYBLOCK_SIZE);
feb11 0:85fceccc1a7c 1681 MD5_Init(&ssl->dc->md5_ctx);
feb11 0:85fceccc1a7c 1682 SHA1_Init(&ssl->dc->sha1_ctx);
feb11 0:85fceccc1a7c 1683 }
feb11 0:85fceccc1a7c 1684 }
feb11 0:85fceccc1a7c 1685
feb11 0:85fceccc1a7c 1686 /**
feb11 0:85fceccc1a7c 1687 * Remove the temporary blob of memory.
feb11 0:85fceccc1a7c 1688 */
feb11 0:85fceccc1a7c 1689 void disposable_free(SSL *ssl)
feb11 0:85fceccc1a7c 1690 {
feb11 0:85fceccc1a7c 1691 if (ssl->dc)
feb11 0:85fceccc1a7c 1692 {
feb11 0:85fceccc1a7c 1693 //free(ssl->dc->key_block);
feb11 0:85fceccc1a7c 1694 memset(ssl->dc, 0, sizeof(DISPOSABLE_CTX));
feb11 0:85fceccc1a7c 1695 free(ssl->dc);
feb11 0:85fceccc1a7c 1696 ssl->dc = NULL;
feb11 0:85fceccc1a7c 1697 }
feb11 0:85fceccc1a7c 1698
feb11 0:85fceccc1a7c 1699 }
feb11 0:85fceccc1a7c 1700
feb11 0:85fceccc1a7c 1701 #ifndef CONFIG_SSL_SKELETON_MODE /* no session resumption in this mode */
feb11 0:85fceccc1a7c 1702 /**
feb11 0:85fceccc1a7c 1703 * Find if an existing session has the same session id. If so, use the
feb11 0:85fceccc1a7c 1704 * master secret from this session for session resumption.
feb11 0:85fceccc1a7c 1705 */
feb11 0:85fceccc1a7c 1706 SSL_SESSION *ssl_session_update(int max_sessions, SSL_SESSION *ssl_sessions[],
feb11 0:85fceccc1a7c 1707 SSL *ssl, const uint8_t *session_id)
feb11 0:85fceccc1a7c 1708 {
feb11 0:85fceccc1a7c 1709 time_t tm = time(NULL);
feb11 0:85fceccc1a7c 1710 time_t oldest_sess_time = tm;
feb11 0:85fceccc1a7c 1711 SSL_SESSION *oldest_sess = NULL;
feb11 0:85fceccc1a7c 1712 int i;
feb11 0:85fceccc1a7c 1713
feb11 0:85fceccc1a7c 1714 /* no sessions? Then bail */
feb11 0:85fceccc1a7c 1715 if (max_sessions == 0)
feb11 0:85fceccc1a7c 1716 return NULL;
feb11 0:85fceccc1a7c 1717
feb11 0:85fceccc1a7c 1718 SSL_CTX_LOCK(ssl->ssl_ctx->mutex);
feb11 0:85fceccc1a7c 1719 if (session_id)
feb11 0:85fceccc1a7c 1720 {
feb11 0:85fceccc1a7c 1721 for (i = 0; i < max_sessions; i++)
feb11 0:85fceccc1a7c 1722 {
feb11 0:85fceccc1a7c 1723 if (ssl_sessions[i])
feb11 0:85fceccc1a7c 1724 {
feb11 0:85fceccc1a7c 1725 /* kill off any expired sessions (including those in
feb11 0:85fceccc1a7c 1726 the future) */
feb11 0:85fceccc1a7c 1727 if ((tm > ssl_sessions[i]->conn_time + SSL_EXPIRY_TIME) ||
feb11 0:85fceccc1a7c 1728 (tm < ssl_sessions[i]->conn_time))
feb11 0:85fceccc1a7c 1729 {
feb11 0:85fceccc1a7c 1730 session_free(ssl_sessions, i);
feb11 0:85fceccc1a7c 1731 continue;
feb11 0:85fceccc1a7c 1732 }
feb11 0:85fceccc1a7c 1733
feb11 0:85fceccc1a7c 1734 /* if the session id matches, it must still be less than
feb11 0:85fceccc1a7c 1735 the expiry time */
feb11 0:85fceccc1a7c 1736 if (memcmp(ssl_sessions[i]->session_id, session_id,
feb11 0:85fceccc1a7c 1737 SSL_SESSION_ID_SIZE) == 0)
feb11 0:85fceccc1a7c 1738 {
feb11 0:85fceccc1a7c 1739 ssl->session_index = i;
feb11 0:85fceccc1a7c 1740 memcpy(ssl->dc->master_secret,
feb11 0:85fceccc1a7c 1741 ssl_sessions[i]->master_secret, SSL_SECRET_SIZE);
feb11 0:85fceccc1a7c 1742 SET_SSL_FLAG(SSL_SESSION_RESUME);
feb11 0:85fceccc1a7c 1743 SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
feb11 0:85fceccc1a7c 1744 return ssl_sessions[i]; /* a session was found */
feb11 0:85fceccc1a7c 1745 }
feb11 0:85fceccc1a7c 1746 }
feb11 0:85fceccc1a7c 1747 }
feb11 0:85fceccc1a7c 1748 }
feb11 0:85fceccc1a7c 1749
feb11 0:85fceccc1a7c 1750 /* If we've got here, no matching session was found - so create one */
feb11 0:85fceccc1a7c 1751 for (i = 0; i < max_sessions; i++)
feb11 0:85fceccc1a7c 1752 {
feb11 0:85fceccc1a7c 1753 if (ssl_sessions[i] == NULL)
feb11 0:85fceccc1a7c 1754 {
feb11 0:85fceccc1a7c 1755 /* perfect, this will do */
feb11 0:85fceccc1a7c 1756 ssl_sessions[i] = (SSL_SESSION *)calloc(1, sizeof(SSL_SESSION));
feb11 0:85fceccc1a7c 1757 ssl_sessions[i]->conn_time = tm;
feb11 0:85fceccc1a7c 1758 ssl->session_index = i;
feb11 0:85fceccc1a7c 1759 SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
feb11 0:85fceccc1a7c 1760 return ssl_sessions[i]; /* return the session object */
feb11 0:85fceccc1a7c 1761 }
feb11 0:85fceccc1a7c 1762 else if (ssl_sessions[i]->conn_time <= oldest_sess_time)
feb11 0:85fceccc1a7c 1763 {
feb11 0:85fceccc1a7c 1764 /* find the oldest session */
feb11 0:85fceccc1a7c 1765 oldest_sess_time = ssl_sessions[i]->conn_time;
feb11 0:85fceccc1a7c 1766 oldest_sess = ssl_sessions[i];
feb11 0:85fceccc1a7c 1767 ssl->session_index = i;
feb11 0:85fceccc1a7c 1768 }
feb11 0:85fceccc1a7c 1769 }
feb11 0:85fceccc1a7c 1770
feb11 0:85fceccc1a7c 1771 /* ok, we've used up all of our sessions. So blow the oldest session away */
feb11 0:85fceccc1a7c 1772 oldest_sess->conn_time = tm;
feb11 0:85fceccc1a7c 1773 memset(oldest_sess->session_id, 0, sizeof(SSL_SESSION_ID_SIZE));
feb11 0:85fceccc1a7c 1774 memset(oldest_sess->master_secret, 0, sizeof(SSL_SECRET_SIZE));
feb11 0:85fceccc1a7c 1775 SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
feb11 0:85fceccc1a7c 1776 return oldest_sess;
feb11 0:85fceccc1a7c 1777 }
feb11 0:85fceccc1a7c 1778
feb11 0:85fceccc1a7c 1779 /**
feb11 0:85fceccc1a7c 1780 * Free an existing session.
feb11 0:85fceccc1a7c 1781 */
feb11 0:85fceccc1a7c 1782 static void session_free(SSL_SESSION *ssl_sessions[], int sess_index)
feb11 0:85fceccc1a7c 1783 {
feb11 0:85fceccc1a7c 1784 if (ssl_sessions[sess_index])
feb11 0:85fceccc1a7c 1785 {
feb11 0:85fceccc1a7c 1786 free(ssl_sessions[sess_index]);
feb11 0:85fceccc1a7c 1787 ssl_sessions[sess_index] = NULL;
feb11 0:85fceccc1a7c 1788 }
feb11 0:85fceccc1a7c 1789 }
feb11 0:85fceccc1a7c 1790
feb11 0:85fceccc1a7c 1791 /**
feb11 0:85fceccc1a7c 1792 * This ssl object doesn't want this session anymore.
feb11 0:85fceccc1a7c 1793 */
feb11 0:85fceccc1a7c 1794 void kill_ssl_session(SSL_SESSION **ssl_sessions, SSL *ssl)
feb11 0:85fceccc1a7c 1795 {
feb11 0:85fceccc1a7c 1796 SSL_CTX_LOCK(ssl->ssl_ctx->mutex);
feb11 0:85fceccc1a7c 1797
feb11 0:85fceccc1a7c 1798 if (ssl->ssl_ctx->num_sessions)
feb11 0:85fceccc1a7c 1799 {
feb11 0:85fceccc1a7c 1800 session_free(ssl_sessions, ssl->session_index);
feb11 0:85fceccc1a7c 1801 ssl->session = NULL;
feb11 0:85fceccc1a7c 1802 }
feb11 0:85fceccc1a7c 1803
feb11 0:85fceccc1a7c 1804 SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
feb11 0:85fceccc1a7c 1805 }
feb11 0:85fceccc1a7c 1806 #endif /* CONFIG_SSL_SKELETON_MODE */
feb11 0:85fceccc1a7c 1807
feb11 0:85fceccc1a7c 1808 /*
feb11 0:85fceccc1a7c 1809 * Get the session id for a handshake. This will be a 32 byte sequence.
feb11 0:85fceccc1a7c 1810 */
feb11 0:85fceccc1a7c 1811 EXP_FUNC const uint8_t * STDCALL ssl_get_session_id(const SSL *ssl)
feb11 0:85fceccc1a7c 1812 {
feb11 0:85fceccc1a7c 1813 return ssl->session_id;
feb11 0:85fceccc1a7c 1814 }
feb11 0:85fceccc1a7c 1815
feb11 0:85fceccc1a7c 1816 /*
feb11 0:85fceccc1a7c 1817 * Get the session id size for a handshake.
feb11 0:85fceccc1a7c 1818 */
feb11 0:85fceccc1a7c 1819 EXP_FUNC uint8_t STDCALL ssl_get_session_id_size(const SSL *ssl)
feb11 0:85fceccc1a7c 1820 {
feb11 0:85fceccc1a7c 1821 return ssl->sess_id_size;
feb11 0:85fceccc1a7c 1822 }
feb11 0:85fceccc1a7c 1823
feb11 0:85fceccc1a7c 1824 /*
feb11 0:85fceccc1a7c 1825 * Return the cipher id (in the SSL form).
feb11 0:85fceccc1a7c 1826 */
feb11 0:85fceccc1a7c 1827 EXP_FUNC uint8_t STDCALL ssl_get_cipher_id(const SSL *ssl)
feb11 0:85fceccc1a7c 1828 {
feb11 0:85fceccc1a7c 1829 return ssl->cipher;
feb11 0:85fceccc1a7c 1830 }
feb11 0:85fceccc1a7c 1831
feb11 0:85fceccc1a7c 1832 /*
feb11 0:85fceccc1a7c 1833 * Return the status of the handshake.
feb11 0:85fceccc1a7c 1834 */
feb11 0:85fceccc1a7c 1835 EXP_FUNC int STDCALL ssl_handshake_status(const SSL *ssl)
feb11 0:85fceccc1a7c 1836 {
feb11 0:85fceccc1a7c 1837 return ssl->hs_status;
feb11 0:85fceccc1a7c 1838 }
feb11 0:85fceccc1a7c 1839
feb11 0:85fceccc1a7c 1840 /*
feb11 0:85fceccc1a7c 1841 * Retrieve various parameters about the SSL engine.
feb11 0:85fceccc1a7c 1842 */
feb11 0:85fceccc1a7c 1843 EXP_FUNC int STDCALL ssl_get_config(int offset)
feb11 0:85fceccc1a7c 1844 {
feb11 0:85fceccc1a7c 1845 switch (offset)
feb11 0:85fceccc1a7c 1846 {
feb11 0:85fceccc1a7c 1847 /* return the appropriate build mode */
feb11 0:85fceccc1a7c 1848 case SSL_BUILD_MODE:
feb11 0:85fceccc1a7c 1849 #if defined(CONFIG_SSL_FULL_MODE)
feb11 0:85fceccc1a7c 1850 return SSL_BUILD_FULL_MODE;
feb11 0:85fceccc1a7c 1851 #elif defined(CONFIG_SSL_ENABLE_CLIENT)
feb11 0:85fceccc1a7c 1852 return SSL_BUILD_ENABLE_CLIENT;
feb11 0:85fceccc1a7c 1853 #elif defined(CONFIG_ENABLE_VERIFICATION)
feb11 0:85fceccc1a7c 1854 return SSL_BUILD_ENABLE_VERIFICATION;
feb11 0:85fceccc1a7c 1855 #elif defined(CONFIG_SSL_SERVER_ONLY )
feb11 0:85fceccc1a7c 1856 return SSL_BUILD_SERVER_ONLY;
feb11 0:85fceccc1a7c 1857 #else
feb11 0:85fceccc1a7c 1858 return SSL_BUILD_SKELETON_MODE;
feb11 0:85fceccc1a7c 1859 #endif
feb11 0:85fceccc1a7c 1860
feb11 0:85fceccc1a7c 1861 case SSL_MAX_CERT_CFG_OFFSET:
feb11 0:85fceccc1a7c 1862 return CONFIG_SSL_MAX_CERTS;
feb11 0:85fceccc1a7c 1863
feb11 0:85fceccc1a7c 1864 #ifdef CONFIG_SSL_CERT_VERIFICATION
feb11 0:85fceccc1a7c 1865 case SSL_MAX_CA_CERT_CFG_OFFSET:
feb11 0:85fceccc1a7c 1866 return CONFIG_X509_MAX_CA_CERTS;
feb11 0:85fceccc1a7c 1867 #endif
feb11 0:85fceccc1a7c 1868 #ifdef CONFIG_SSL_HAS_PEM
feb11 0:85fceccc1a7c 1869 case SSL_HAS_PEM:
feb11 0:85fceccc1a7c 1870 return 1;
feb11 0:85fceccc1a7c 1871 #endif
feb11 0:85fceccc1a7c 1872 default:
feb11 0:85fceccc1a7c 1873 return 0;
feb11 0:85fceccc1a7c 1874 }
feb11 0:85fceccc1a7c 1875 }
feb11 0:85fceccc1a7c 1876
feb11 0:85fceccc1a7c 1877 #ifdef CONFIG_SSL_CERT_VERIFICATION
feb11 0:85fceccc1a7c 1878 /**
feb11 0:85fceccc1a7c 1879 * Authenticate a received certificate.
feb11 0:85fceccc1a7c 1880 */
feb11 0:85fceccc1a7c 1881 EXP_FUNC int STDCALL ssl_verify_cert(const SSL *ssl, PrecomputedCertificate *cert)
feb11 0:85fceccc1a7c 1882 {
feb11 0:85fceccc1a7c 1883 int ret;
feb11 0:85fceccc1a7c 1884 SSL_CTX_LOCK(ssl->ssl_ctx->mutex);
feb11 0:85fceccc1a7c 1885 ret = x509_verify(cert);
feb11 0:85fceccc1a7c 1886 SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
feb11 0:85fceccc1a7c 1887 if (ret) /* modify into an SSL error type */
feb11 0:85fceccc1a7c 1888 {
feb11 0:85fceccc1a7c 1889 printf("%s\n", x509_display_error(ret));
feb11 0:85fceccc1a7c 1890 ret = SSL_X509_ERROR(ret);
feb11 0:85fceccc1a7c 1891 }
feb11 0:85fceccc1a7c 1892 return ret;
feb11 0:85fceccc1a7c 1893 }
feb11 0:85fceccc1a7c 1894
feb11 0:85fceccc1a7c 1895 int read_certificate(SSL *ssl)
feb11 0:85fceccc1a7c 1896 {
feb11 0:85fceccc1a7c 1897 uint8_t cert_hdr[3];
feb11 0:85fceccc1a7c 1898
feb11 0:85fceccc1a7c 1899 if(basic_read2(ssl, cert_hdr, 3) != 3)
feb11 0:85fceccc1a7c 1900 return SSL_NOT_OK;
feb11 0:85fceccc1a7c 1901
feb11 0:85fceccc1a7c 1902
feb11 0:85fceccc1a7c 1903 add_packet(ssl, cert_hdr, 3);
feb11 0:85fceccc1a7c 1904
feb11 0:85fceccc1a7c 1905 uint16_t cert_size = (cert_hdr[1]<<8) + cert_hdr[2];
feb11 0:85fceccc1a7c 1906 if(cert_size > RT_MAX_PLAIN_LENGTH)
feb11 0:85fceccc1a7c 1907 return SSL_NOT_OK;
feb11 0:85fceccc1a7c 1908
feb11 0:85fceccc1a7c 1909 if(basic_read2(ssl, ssl->bm_data, cert_size) != cert_size)
feb11 0:85fceccc1a7c 1910 return SSL_NOT_OK;
feb11 0:85fceccc1a7c 1911
feb11 0:85fceccc1a7c 1912 add_packet(ssl, ssl->bm_data, cert_size);
feb11 0:85fceccc1a7c 1913
feb11 0:85fceccc1a7c 1914 return cert_size+3; // cert_size + header_size
feb11 0:85fceccc1a7c 1915 }
feb11 0:85fceccc1a7c 1916
feb11 0:85fceccc1a7c 1917
feb11 0:85fceccc1a7c 1918 static void load_cert(PrecomputedCertificate *pc, X509_CTX *cert)
feb11 0:85fceccc1a7c 1919 {
feb11 0:85fceccc1a7c 1920
feb11 0:85fceccc1a7c 1921 for(int i = 0; i < X509_NUM_DN_TYPES; ++i)
feb11 0:85fceccc1a7c 1922 {
feb11 0:85fceccc1a7c 1923 pc->cert_dn[i] = malloc(strlen(cert->cert_dn[i])+1);
feb11 0:85fceccc1a7c 1924 pc->ca_cert_dn[i] = malloc(strlen(cert->ca_cert_dn[i])+1);
feb11 0:85fceccc1a7c 1925 strcpy(pc->cert_dn[i], cert->cert_dn[i]);
feb11 0:85fceccc1a7c 1926 strcpy(pc->ca_cert_dn[i], cert->ca_cert_dn[i]);
feb11 0:85fceccc1a7c 1927 }
feb11 0:85fceccc1a7c 1928
feb11 0:85fceccc1a7c 1929 pc->sig_len = cert->sig_len;
feb11 0:85fceccc1a7c 1930 pc->sig = malloc(cert->sig_len);
feb11 0:85fceccc1a7c 1931 memcpy(pc->sig, cert->signature, cert->sig_len);
feb11 0:85fceccc1a7c 1932
feb11 0:85fceccc1a7c 1933 uint8_t buffer[256];
feb11 0:85fceccc1a7c 1934 int paddingLength = 0;
feb11 0:85fceccc1a7c 1935
feb11 0:85fceccc1a7c 1936 bi_permanent(cert->digest);
feb11 0:85fceccc1a7c 1937 bi_export(cert->rsa_ctx->bi_ctx, cert->digest, buffer, 256);
feb11 0:85fceccc1a7c 1938 bi_depermanent(cert->digest);
feb11 0:85fceccc1a7c 1939 while(paddingLength < 256 && buffer[paddingLength] == 0) paddingLength++;
feb11 0:85fceccc1a7c 1940 pc->digest_len = 256 - paddingLength;
feb11 0:85fceccc1a7c 1941 pc->digest = malloc(pc->digest_len);
feb11 0:85fceccc1a7c 1942 memcpy(pc->digest, &buffer[paddingLength], pc->digest_len);
feb11 0:85fceccc1a7c 1943
feb11 0:85fceccc1a7c 1944 paddingLength = 0;
feb11 0:85fceccc1a7c 1945 bi_export(cert->rsa_ctx->bi_ctx, cert->rsa_ctx->e, buffer, 256);
feb11 0:85fceccc1a7c 1946 while(paddingLength < 256 && buffer[paddingLength] == 0) paddingLength++;
feb11 0:85fceccc1a7c 1947 pc->expn_len = 256 - paddingLength;
feb11 0:85fceccc1a7c 1948 pc->expn = malloc(pc->expn_len);
feb11 0:85fceccc1a7c 1949 memcpy(pc->expn, &buffer[paddingLength], pc->expn_len);
feb11 0:85fceccc1a7c 1950
feb11 0:85fceccc1a7c 1951 paddingLength = 0;
feb11 0:85fceccc1a7c 1952 bi_export(cert->rsa_ctx->bi_ctx, cert->rsa_ctx->m, buffer, 256);
feb11 0:85fceccc1a7c 1953 while(paddingLength < 256 && buffer[paddingLength] == 0) paddingLength++;
feb11 0:85fceccc1a7c 1954 pc->mod_len = 256 - paddingLength;
feb11 0:85fceccc1a7c 1955 pc->mod = malloc(pc->mod_len);
feb11 0:85fceccc1a7c 1956 memcpy(pc->mod, &buffer[paddingLength], pc->mod_len);
feb11 0:85fceccc1a7c 1957 }
feb11 0:85fceccc1a7c 1958
feb11 0:85fceccc1a7c 1959 /**
feb11 0:85fceccc1a7c 1960 * Process a certificate message.
feb11 0:85fceccc1a7c 1961 */
feb11 0:85fceccc1a7c 1962 int process_certificate(SSL *ssl, X509_CTX **x509_ctx)
feb11 0:85fceccc1a7c 1963 {
feb11 0:85fceccc1a7c 1964 int ret = SSL_OK;
feb11 0:85fceccc1a7c 1965
feb11 0:85fceccc1a7c 1966 uint8_t cert_hdr[3];
feb11 0:85fceccc1a7c 1967 if(basic_read2(ssl, cert_hdr, 3) != 3)
feb11 0:85fceccc1a7c 1968 {
feb11 0:85fceccc1a7c 1969 ret = SSL_NOT_OK;
feb11 0:85fceccc1a7c 1970 return ret;
feb11 0:85fceccc1a7c 1971 }
feb11 0:85fceccc1a7c 1972
feb11 0:85fceccc1a7c 1973 add_packet(ssl, cert_hdr, 3);
feb11 0:85fceccc1a7c 1974 int len = 5;
feb11 0:85fceccc1a7c 1975 int cert_size;
feb11 0:85fceccc1a7c 1976 int total_cert_size = (cert_hdr[1]<<8) + cert_hdr[2];
feb11 0:85fceccc1a7c 1977 int is_client = IS_SET_SSL_FLAG(SSL_IS_CLIENT);
feb11 0:85fceccc1a7c 1978 X509_CTX *cert = NULL;
feb11 0:85fceccc1a7c 1979 len += 2;
feb11 0:85fceccc1a7c 1980 PrecomputedCertificate pc[3];
feb11 0:85fceccc1a7c 1981 memset(pc, 0, 3*sizeof(PrecomputedCertificate));
feb11 0:85fceccc1a7c 1982 int pc_index = 0;
feb11 0:85fceccc1a7c 1983 PARANOIA_CHECK(total_cert_size, 3);
feb11 0:85fceccc1a7c 1984
feb11 0:85fceccc1a7c 1985
feb11 0:85fceccc1a7c 1986 while (len < total_cert_size)
feb11 0:85fceccc1a7c 1987 {
feb11 0:85fceccc1a7c 1988 cert_size = read_certificate(ssl);
feb11 0:85fceccc1a7c 1989 if(cert_size < 0)
feb11 0:85fceccc1a7c 1990 {
feb11 0:85fceccc1a7c 1991 ret = cert_size;
feb11 0:85fceccc1a7c 1992 goto error;
feb11 0:85fceccc1a7c 1993 }
feb11 0:85fceccc1a7c 1994 if(cert->sig_len * 8 > 2048)
feb11 0:85fceccc1a7c 1995 {
feb11 0:85fceccc1a7c 1996 ret = SSL_X509_ERROR(X509_KEY_SIZE_TOO_BIG);
feb11 0:85fceccc1a7c 1997 goto error;
feb11 0:85fceccc1a7c 1998 }
feb11 0:85fceccc1a7c 1999
feb11 0:85fceccc1a7c 2000 if (x509_new(ssl->bm_data, NULL, &cert))
feb11 0:85fceccc1a7c 2001 return SSL_ERROR_BAD_CERTIFICATE;
feb11 0:85fceccc1a7c 2002
feb11 0:85fceccc1a7c 2003 if (is_client && !IS_SET_SSL_FLAG(SSL_SERVER_VERIFY_LATER))
feb11 0:85fceccc1a7c 2004 {
feb11 0:85fceccc1a7c 2005 /* check the not before date */
feb11 0:85fceccc1a7c 2006 struct timeval tv;
feb11 0:85fceccc1a7c 2007 gettimeofday(&tv, NULL);
feb11 0:85fceccc1a7c 2008 if (tv.tv_sec < cert->not_before)
feb11 0:85fceccc1a7c 2009 {
feb11 0:85fceccc1a7c 2010 ret = SSL_X509_ERROR(X509_VFY_ERROR_NOT_YET_VALID);
feb11 0:85fceccc1a7c 2011 x509_free(cert);
feb11 0:85fceccc1a7c 2012 goto error;
feb11 0:85fceccc1a7c 2013 }
feb11 0:85fceccc1a7c 2014 /* check the not after date */
feb11 0:85fceccc1a7c 2015 if (tv.tv_sec > cert->not_after)
feb11 0:85fceccc1a7c 2016 {
feb11 0:85fceccc1a7c 2017 ret = SSL_X509_ERROR(X509_VFY_ERROR_EXPIRED);
feb11 0:85fceccc1a7c 2018 x509_free(cert);
feb11 0:85fceccc1a7c 2019 goto error;
feb11 0:85fceccc1a7c 2020 }
feb11 0:85fceccc1a7c 2021
feb11 0:85fceccc1a7c 2022 if(pc_index > 2)
feb11 0:85fceccc1a7c 2023 {
feb11 0:85fceccc1a7c 2024 x509_free(cert);
feb11 0:85fceccc1a7c 2025 goto error;
feb11 0:85fceccc1a7c 2026 }
feb11 0:85fceccc1a7c 2027
feb11 0:85fceccc1a7c 2028 load_cert(&pc[pc_index], cert);
feb11 0:85fceccc1a7c 2029
feb11 0:85fceccc1a7c 2030 if(pc_index != 0)
feb11 0:85fceccc1a7c 2031 pc[pc_index-1].next = &pc[pc_index];
feb11 0:85fceccc1a7c 2032
feb11 0:85fceccc1a7c 2033 pc_index++;
feb11 0:85fceccc1a7c 2034 }
feb11 0:85fceccc1a7c 2035 if(len > 7)
feb11 0:85fceccc1a7c 2036 {
feb11 0:85fceccc1a7c 2037 cert->next = NULL;
feb11 0:85fceccc1a7c 2038 x509_free(cert);
feb11 0:85fceccc1a7c 2039 }
feb11 0:85fceccc1a7c 2040 else
feb11 0:85fceccc1a7c 2041 {
feb11 0:85fceccc1a7c 2042 *x509_ctx = cert;
feb11 0:85fceccc1a7c 2043 cert = cert->next;
feb11 0:85fceccc1a7c 2044 }
feb11 0:85fceccc1a7c 2045 len += cert_size;
feb11 0:85fceccc1a7c 2046 }
feb11 0:85fceccc1a7c 2047 (*x509_ctx)->next = NULL;
feb11 0:85fceccc1a7c 2048 /* if we are client we can do the verify now or later */
feb11 0:85fceccc1a7c 2049 if (is_client && !IS_SET_SSL_FLAG(SSL_SERVER_VERIFY_LATER))
feb11 0:85fceccc1a7c 2050 {
feb11 0:85fceccc1a7c 2051 ret = ssl_verify_cert(ssl, pc);
feb11 0:85fceccc1a7c 2052 }
feb11 0:85fceccc1a7c 2053
feb11 0:85fceccc1a7c 2054 ssl->next_state = is_client ? HS_SERVER_HELLO_DONE : HS_CLIENT_KEY_XCHG;
feb11 0:85fceccc1a7c 2055 ssl->dc->bm_proc_index += len;
feb11 0:85fceccc1a7c 2056
feb11 0:85fceccc1a7c 2057 error:
feb11 0:85fceccc1a7c 2058 for(int i = 0; i < pc_index; ++i)
feb11 0:85fceccc1a7c 2059 {
feb11 0:85fceccc1a7c 2060 for(int j = 0; j < X509_NUM_DN_TYPES; ++j)
feb11 0:85fceccc1a7c 2061 {
feb11 0:85fceccc1a7c 2062 free(pc[i].cert_dn[j]);
feb11 0:85fceccc1a7c 2063 free(pc[i].ca_cert_dn[j]);
feb11 0:85fceccc1a7c 2064 }
feb11 0:85fceccc1a7c 2065 free(pc[i].sig);
feb11 0:85fceccc1a7c 2066 free(pc[i].digest);
feb11 0:85fceccc1a7c 2067 free(pc[i].expn);
feb11 0:85fceccc1a7c 2068 free(pc[i].mod);
feb11 0:85fceccc1a7c 2069 }
feb11 0:85fceccc1a7c 2070 return ret;
feb11 0:85fceccc1a7c 2071 }
feb11 0:85fceccc1a7c 2072
feb11 0:85fceccc1a7c 2073 #endif /* CONFIG_SSL_CERT_VERIFICATION */
feb11 0:85fceccc1a7c 2074
feb11 0:85fceccc1a7c 2075 /**
feb11 0:85fceccc1a7c 2076 * Debugging routine to display SSL handshaking stuff.
feb11 0:85fceccc1a7c 2077 */
feb11 0:85fceccc1a7c 2078 #ifdef CONFIG_SSL_FULL_MODE
feb11 0:85fceccc1a7c 2079 /**
feb11 0:85fceccc1a7c 2080 * Debugging routine to display SSL states.
feb11 0:85fceccc1a7c 2081 */
feb11 0:85fceccc1a7c 2082 void DISPLAY_STATE(SSL *ssl, int is_send, uint8_t state, int not_ok)
feb11 0:85fceccc1a7c 2083 {
feb11 0:85fceccc1a7c 2084 const char *str;
feb11 0:85fceccc1a7c 2085
feb11 0:85fceccc1a7c 2086 if (!IS_SET_SSL_FLAG(SSL_DISPLAY_STATES))
feb11 0:85fceccc1a7c 2087 return;
feb11 0:85fceccc1a7c 2088
feb11 0:85fceccc1a7c 2089 printf(not_ok ? "Error - invalid State:\t" : "State:\t");
feb11 0:85fceccc1a7c 2090 printf(is_send ? "sending " : "receiving ");
feb11 0:85fceccc1a7c 2091
feb11 0:85fceccc1a7c 2092 switch (state)
feb11 0:85fceccc1a7c 2093 {
feb11 0:85fceccc1a7c 2094 case HS_HELLO_REQUEST:
feb11 0:85fceccc1a7c 2095 str = "Hello Request (0)";
feb11 0:85fceccc1a7c 2096 break;
feb11 0:85fceccc1a7c 2097
feb11 0:85fceccc1a7c 2098 case HS_CLIENT_HELLO:
feb11 0:85fceccc1a7c 2099 str = "Client Hello (1)";
feb11 0:85fceccc1a7c 2100 break;
feb11 0:85fceccc1a7c 2101
feb11 0:85fceccc1a7c 2102 case HS_SERVER_HELLO:
feb11 0:85fceccc1a7c 2103 str = "Server Hello (2)";
feb11 0:85fceccc1a7c 2104 break;
feb11 0:85fceccc1a7c 2105
feb11 0:85fceccc1a7c 2106 case HS_CERTIFICATE:
feb11 0:85fceccc1a7c 2107 str = "Certificate (11)";
feb11 0:85fceccc1a7c 2108 break;
feb11 0:85fceccc1a7c 2109
feb11 0:85fceccc1a7c 2110 case HS_SERVER_KEY_XCHG:
feb11 0:85fceccc1a7c 2111 str = "Certificate Request (12)";
feb11 0:85fceccc1a7c 2112 break;
feb11 0:85fceccc1a7c 2113
feb11 0:85fceccc1a7c 2114 case HS_CERT_REQ:
feb11 0:85fceccc1a7c 2115 str = "Certificate Request (13)";
feb11 0:85fceccc1a7c 2116 break;
feb11 0:85fceccc1a7c 2117
feb11 0:85fceccc1a7c 2118 case HS_SERVER_HELLO_DONE:
feb11 0:85fceccc1a7c 2119 str = "Server Hello Done (14)";
feb11 0:85fceccc1a7c 2120 break;
feb11 0:85fceccc1a7c 2121
feb11 0:85fceccc1a7c 2122 case HS_CERT_VERIFY:
feb11 0:85fceccc1a7c 2123 str = "Certificate Verify (15)";
feb11 0:85fceccc1a7c 2124 break;
feb11 0:85fceccc1a7c 2125
feb11 0:85fceccc1a7c 2126 case HS_CLIENT_KEY_XCHG:
feb11 0:85fceccc1a7c 2127 str = "Client Key Exchange (16)";
feb11 0:85fceccc1a7c 2128 break;
feb11 0:85fceccc1a7c 2129
feb11 0:85fceccc1a7c 2130 case HS_FINISHED:
feb11 0:85fceccc1a7c 2131 str = "Finished (16)";
feb11 0:85fceccc1a7c 2132 break;
feb11 0:85fceccc1a7c 2133
feb11 0:85fceccc1a7c 2134 default:
feb11 0:85fceccc1a7c 2135 str = "Error (Unknown)";
feb11 0:85fceccc1a7c 2136
feb11 0:85fceccc1a7c 2137 break;
feb11 0:85fceccc1a7c 2138 }
feb11 0:85fceccc1a7c 2139
feb11 0:85fceccc1a7c 2140 printf("%s\r\n", str);
feb11 0:85fceccc1a7c 2141 TTY_FLUSH();
feb11 0:85fceccc1a7c 2142 }
feb11 0:85fceccc1a7c 2143
feb11 0:85fceccc1a7c 2144 /**
feb11 0:85fceccc1a7c 2145 * Debugging routine to display RSA objects
feb11 0:85fceccc1a7c 2146 */
feb11 0:85fceccc1a7c 2147 void DISPLAY_RSA(SSL *ssl, const RSA_CTX *rsa_ctx)
feb11 0:85fceccc1a7c 2148 {
feb11 0:85fceccc1a7c 2149 if (!IS_SET_SSL_FLAG(SSL_DISPLAY_RSA))
feb11 0:85fceccc1a7c 2150 return;
feb11 0:85fceccc1a7c 2151
feb11 0:85fceccc1a7c 2152 RSA_print(rsa_ctx);
feb11 0:85fceccc1a7c 2153 TTY_FLUSH();
feb11 0:85fceccc1a7c 2154 }
feb11 0:85fceccc1a7c 2155
feb11 0:85fceccc1a7c 2156 /**
feb11 0:85fceccc1a7c 2157 * Debugging routine to display SSL handshaking bytes.
feb11 0:85fceccc1a7c 2158 */
feb11 0:85fceccc1a7c 2159 void DISPLAY_BYTES(SSL *ssl, const char *format,
feb11 0:85fceccc1a7c 2160 const uint8_t *data, int size, ...)
feb11 0:85fceccc1a7c 2161 {
feb11 0:85fceccc1a7c 2162 va_list(ap);
feb11 0:85fceccc1a7c 2163
feb11 0:85fceccc1a7c 2164 if (!IS_SET_SSL_FLAG(SSL_DISPLAY_BYTES))
feb11 0:85fceccc1a7c 2165 return;
feb11 0:85fceccc1a7c 2166
feb11 0:85fceccc1a7c 2167 va_start(ap, size);
feb11 0:85fceccc1a7c 2168 print_blob(format, data, size, va_arg(ap, char *));
feb11 0:85fceccc1a7c 2169 va_end(ap);
feb11 0:85fceccc1a7c 2170 TTY_FLUSH();
feb11 0:85fceccc1a7c 2171 }
feb11 0:85fceccc1a7c 2172
feb11 0:85fceccc1a7c 2173 /**
feb11 0:85fceccc1a7c 2174 * Debugging routine to display SSL handshaking errors.
feb11 0:85fceccc1a7c 2175 */
feb11 0:85fceccc1a7c 2176 EXP_FUNC void STDCALL ssl_display_error(int error_code)
feb11 0:85fceccc1a7c 2177 {
feb11 0:85fceccc1a7c 2178 if (error_code == SSL_OK)
feb11 0:85fceccc1a7c 2179 return;
feb11 0:85fceccc1a7c 2180
feb11 0:85fceccc1a7c 2181 printf("Error: ");
feb11 0:85fceccc1a7c 2182
feb11 0:85fceccc1a7c 2183 /* X509 error? */
feb11 0:85fceccc1a7c 2184 if (error_code < SSL_X509_OFFSET)
feb11 0:85fceccc1a7c 2185 {
feb11 0:85fceccc1a7c 2186 printf("%s\r\n", x509_display_error(error_code - SSL_X509_OFFSET));
feb11 0:85fceccc1a7c 2187 return;
feb11 0:85fceccc1a7c 2188 }
feb11 0:85fceccc1a7c 2189
feb11 0:85fceccc1a7c 2190 /* SSL alert error code */
feb11 0:85fceccc1a7c 2191 if (error_code > SSL_ERROR_CONN_LOST)
feb11 0:85fceccc1a7c 2192 {
feb11 0:85fceccc1a7c 2193 printf("SSL error %d\n", -error_code);
feb11 0:85fceccc1a7c 2194 return;
feb11 0:85fceccc1a7c 2195 }
feb11 0:85fceccc1a7c 2196
feb11 0:85fceccc1a7c 2197 switch (error_code)
feb11 0:85fceccc1a7c 2198 {
feb11 0:85fceccc1a7c 2199 case SSL_ERROR_DEAD:
feb11 0:85fceccc1a7c 2200 printf("connection dead");
feb11 0:85fceccc1a7c 2201 break;
feb11 0:85fceccc1a7c 2202
feb11 0:85fceccc1a7c 2203 case SSL_ERROR_INVALID_HANDSHAKE:
feb11 0:85fceccc1a7c 2204 printf("invalid handshake");
feb11 0:85fceccc1a7c 2205 break;
feb11 0:85fceccc1a7c 2206
feb11 0:85fceccc1a7c 2207 case SSL_ERROR_INVALID_PROT_MSG:
feb11 0:85fceccc1a7c 2208 printf("invalid protocol message");
feb11 0:85fceccc1a7c 2209 break;
feb11 0:85fceccc1a7c 2210
feb11 0:85fceccc1a7c 2211 case SSL_ERROR_INVALID_HMAC:
feb11 0:85fceccc1a7c 2212 printf("invalid mac");
feb11 0:85fceccc1a7c 2213 break;
feb11 0:85fceccc1a7c 2214
feb11 0:85fceccc1a7c 2215 case SSL_ERROR_INVALID_VERSION:
feb11 0:85fceccc1a7c 2216 printf("invalid version");
feb11 0:85fceccc1a7c 2217 break;
feb11 0:85fceccc1a7c 2218
feb11 0:85fceccc1a7c 2219 case SSL_ERROR_INVALID_SESSION:
feb11 0:85fceccc1a7c 2220 printf("invalid session");
feb11 0:85fceccc1a7c 2221 break;
feb11 0:85fceccc1a7c 2222
feb11 0:85fceccc1a7c 2223 case SSL_ERROR_NO_CIPHER:
feb11 0:85fceccc1a7c 2224 printf("no cipher");
feb11 0:85fceccc1a7c 2225 break;
feb11 0:85fceccc1a7c 2226
feb11 0:85fceccc1a7c 2227 case SSL_ERROR_CONN_LOST:
feb11 0:85fceccc1a7c 2228 printf("connection lost");
feb11 0:85fceccc1a7c 2229 break;
feb11 0:85fceccc1a7c 2230
feb11 0:85fceccc1a7c 2231 case SSL_ERROR_BAD_CERTIFICATE:
feb11 0:85fceccc1a7c 2232 printf("bad certificate");
feb11 0:85fceccc1a7c 2233 break;
feb11 0:85fceccc1a7c 2234
feb11 0:85fceccc1a7c 2235 case SSL_ERROR_INVALID_KEY:
feb11 0:85fceccc1a7c 2236 printf("invalid key");
feb11 0:85fceccc1a7c 2237 break;
feb11 0:85fceccc1a7c 2238
feb11 0:85fceccc1a7c 2239 case SSL_ERROR_FINISHED_INVALID:
feb11 0:85fceccc1a7c 2240 printf("finished invalid");
feb11 0:85fceccc1a7c 2241 break;
feb11 0:85fceccc1a7c 2242
feb11 0:85fceccc1a7c 2243 case SSL_ERROR_NO_CERT_DEFINED:
feb11 0:85fceccc1a7c 2244 printf("no certificate defined");
feb11 0:85fceccc1a7c 2245 break;
feb11 0:85fceccc1a7c 2246
feb11 0:85fceccc1a7c 2247 case SSL_ERROR_NO_CLIENT_RENOG:
feb11 0:85fceccc1a7c 2248 printf("client renegotiation not supported");
feb11 0:85fceccc1a7c 2249 break;
feb11 0:85fceccc1a7c 2250
feb11 0:85fceccc1a7c 2251 case SSL_ERROR_NOT_SUPPORTED:
feb11 0:85fceccc1a7c 2252 printf("Option not supported");
feb11 0:85fceccc1a7c 2253 break;
feb11 0:85fceccc1a7c 2254
feb11 0:85fceccc1a7c 2255 default:
feb11 0:85fceccc1a7c 2256 printf("undefined as yet - %d", error_code);
feb11 0:85fceccc1a7c 2257 break;
feb11 0:85fceccc1a7c 2258 }
feb11 0:85fceccc1a7c 2259
feb11 0:85fceccc1a7c 2260 printf("\r\n");
feb11 0:85fceccc1a7c 2261 TTY_FLUSH();
feb11 0:85fceccc1a7c 2262 }
feb11 0:85fceccc1a7c 2263
feb11 0:85fceccc1a7c 2264 /**
feb11 0:85fceccc1a7c 2265 * Debugging routine to display alerts.
feb11 0:85fceccc1a7c 2266 */
feb11 0:85fceccc1a7c 2267 void DISPLAY_ALERT(SSL *ssl, int alert)
feb11 0:85fceccc1a7c 2268 {
feb11 0:85fceccc1a7c 2269 if (!IS_SET_SSL_FLAG(SSL_DISPLAY_STATES))
feb11 0:85fceccc1a7c 2270 return;
feb11 0:85fceccc1a7c 2271
feb11 0:85fceccc1a7c 2272 printf("Alert: ");
feb11 0:85fceccc1a7c 2273
feb11 0:85fceccc1a7c 2274 switch (alert)
feb11 0:85fceccc1a7c 2275 {
feb11 0:85fceccc1a7c 2276 case SSL_ALERT_CLOSE_NOTIFY:
feb11 0:85fceccc1a7c 2277 printf("close notify");
feb11 0:85fceccc1a7c 2278 break;
feb11 0:85fceccc1a7c 2279
feb11 0:85fceccc1a7c 2280 case SSL_ALERT_INVALID_VERSION:
feb11 0:85fceccc1a7c 2281 printf("invalid version");
feb11 0:85fceccc1a7c 2282 break;
feb11 0:85fceccc1a7c 2283
feb11 0:85fceccc1a7c 2284 case SSL_ALERT_BAD_CERTIFICATE:
feb11 0:85fceccc1a7c 2285 printf("bad certificate");
feb11 0:85fceccc1a7c 2286 break;
feb11 0:85fceccc1a7c 2287
feb11 0:85fceccc1a7c 2288 case SSL_ALERT_UNEXPECTED_MESSAGE:
feb11 0:85fceccc1a7c 2289 printf("unexpected message");
feb11 0:85fceccc1a7c 2290 break;
feb11 0:85fceccc1a7c 2291
feb11 0:85fceccc1a7c 2292 case SSL_ALERT_BAD_RECORD_MAC:
feb11 0:85fceccc1a7c 2293 printf("bad record mac");
feb11 0:85fceccc1a7c 2294 break;
feb11 0:85fceccc1a7c 2295
feb11 0:85fceccc1a7c 2296 case SSL_ALERT_HANDSHAKE_FAILURE:
feb11 0:85fceccc1a7c 2297 printf("handshake failure");
feb11 0:85fceccc1a7c 2298 break;
feb11 0:85fceccc1a7c 2299
feb11 0:85fceccc1a7c 2300 case SSL_ALERT_ILLEGAL_PARAMETER:
feb11 0:85fceccc1a7c 2301 printf("illegal parameter");
feb11 0:85fceccc1a7c 2302 break;
feb11 0:85fceccc1a7c 2303
feb11 0:85fceccc1a7c 2304 case SSL_ALERT_DECODE_ERROR:
feb11 0:85fceccc1a7c 2305 printf("decode error");
feb11 0:85fceccc1a7c 2306 break;
feb11 0:85fceccc1a7c 2307
feb11 0:85fceccc1a7c 2308 case SSL_ALERT_DECRYPT_ERROR:
feb11 0:85fceccc1a7c 2309 printf("decrypt error");
feb11 0:85fceccc1a7c 2310 break;
feb11 0:85fceccc1a7c 2311
feb11 0:85fceccc1a7c 2312 case SSL_ALERT_NO_RENEGOTIATION:
feb11 0:85fceccc1a7c 2313 printf("no renegotiation");
feb11 0:85fceccc1a7c 2314 break;
feb11 0:85fceccc1a7c 2315
feb11 0:85fceccc1a7c 2316 default:
feb11 0:85fceccc1a7c 2317 printf("alert - (unknown %d)", alert);
feb11 0:85fceccc1a7c 2318 break;
feb11 0:85fceccc1a7c 2319 }
feb11 0:85fceccc1a7c 2320
feb11 0:85fceccc1a7c 2321 printf("\r\n");
feb11 0:85fceccc1a7c 2322 TTY_FLUSH();
feb11 0:85fceccc1a7c 2323 }
feb11 0:85fceccc1a7c 2324
feb11 0:85fceccc1a7c 2325 #endif /* CONFIG_SSL_FULL_MODE */
feb11 0:85fceccc1a7c 2326
feb11 0:85fceccc1a7c 2327 /**
feb11 0:85fceccc1a7c 2328 * Return the version of this library.
feb11 0:85fceccc1a7c 2329 */
feb11 0:85fceccc1a7c 2330 EXP_FUNC const char * STDCALL ssl_version()
feb11 0:85fceccc1a7c 2331 {
feb11 0:85fceccc1a7c 2332 static const char * axtls_version = AXTLS_VERSION;
feb11 0:85fceccc1a7c 2333 return axtls_version;
feb11 0:85fceccc1a7c 2334 }
feb11 0:85fceccc1a7c 2335
feb11 0:85fceccc1a7c 2336 /**
feb11 0:85fceccc1a7c 2337 * Enable the various language bindings to work regardless of the
feb11 0:85fceccc1a7c 2338 * configuration - they just return an error statement and a bad return code.
feb11 0:85fceccc1a7c 2339 */
feb11 0:85fceccc1a7c 2340 #if !defined(CONFIG_SSL_FULL_MODE)
feb11 0:85fceccc1a7c 2341 EXP_FUNC void STDCALL ssl_display_error(int error_code) {}
feb11 0:85fceccc1a7c 2342 #endif
feb11 0:85fceccc1a7c 2343
feb11 0:85fceccc1a7c 2344 #ifdef CONFIG_BINDINGS
feb11 0:85fceccc1a7c 2345 #if !defined(CONFIG_SSL_ENABLE_CLIENT)
feb11 0:85fceccc1a7c 2346 EXP_FUNC SSL * STDCALL ssl_client_new(SSL_CTX *ssl_ctx, int client_fd, const
feb11 0:85fceccc1a7c 2347 uint8_t *session_id, uint8_t sess_id_size)
feb11 0:85fceccc1a7c 2348 {
feb11 0:85fceccc1a7c 2349 printf(unsupported_str);
feb11 0:85fceccc1a7c 2350 return NULL;
feb11 0:85fceccc1a7c 2351 }
feb11 0:85fceccc1a7c 2352 #endif
feb11 0:85fceccc1a7c 2353
feb11 0:85fceccc1a7c 2354 #if !defined(CONFIG_SSL_CERT_VERIFICATION)
feb11 0:85fceccc1a7c 2355 EXP_FUNC int STDCALL ssl_verify_cert(const SSL *ssl, PrecomputedCertificate *cert)
feb11 0:85fceccc1a7c 2356 {
feb11 0:85fceccc1a7c 2357 printf(unsupported_str);
feb11 0:85fceccc1a7c 2358 return -1;
feb11 0:85fceccc1a7c 2359 }
feb11 0:85fceccc1a7c 2360
feb11 0:85fceccc1a7c 2361
feb11 0:85fceccc1a7c 2362 EXP_FUNC const char * STDCALL ssl_get_cert_dn(const SSL *ssl, int component)
feb11 0:85fceccc1a7c 2363 {
feb11 0:85fceccc1a7c 2364 printf(unsupported_str);
feb11 0:85fceccc1a7c 2365 return NULL;
feb11 0:85fceccc1a7c 2366 }
feb11 0:85fceccc1a7c 2367
feb11 0:85fceccc1a7c 2368 EXP_FUNC const char * STDCALL ssl_get_cert_subject_alt_dnsname(const SSL *ssl, int index)
feb11 0:85fceccc1a7c 2369 {
feb11 0:85fceccc1a7c 2370 printf(unsupported_str);
feb11 0:85fceccc1a7c 2371 return NULL;
feb11 0:85fceccc1a7c 2372 }
feb11 0:85fceccc1a7c 2373
feb11 0:85fceccc1a7c 2374 #endif /* CONFIG_SSL_CERT_VERIFICATION */
feb11 0:85fceccc1a7c 2375
feb11 0:85fceccc1a7c 2376 #endif /* CONFIG_BINDINGS */
feb11 0:85fceccc1a7c 2377
feb11 0:85fceccc1a7c 2378
feb11 0:85fceccc1a7c 2379