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>