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