static int coap_security_handler_init(coap_security_t *sec){ const char *pers = "dtls_client"; mbedtls_ssl_init( &sec->_ssl ); mbedtls_ssl_config_init( &sec->_conf ); mbedtls_ctr_drbg_init( &sec->_ctr_drbg ); mbedtls_entropy_init( &sec->_entropy ); #if defined(MBEDTLS_X509_CRT_PARSE_C) mbedtls_x509_crt_init( &sec->_cacert ); mbedtls_x509_crt_init( &sec->_owncert ); #endif mbedtls_pk_init( &sec->_pkey ); memset(&sec->_cookie, 0, sizeof(simple_cookie_t)); memset(&sec->_keyblk, 0, sizeof(key_block_t)); sec->_is_started = false; //TODO: Must have at least 1 strong entropy source, otherwise DTLS will fail. //This is NOT strong even we say it is! if( mbedtls_entropy_add_source( &sec->_entropy, entropy_poll, NULL, 128, 1 ) < 0 ){ return -1; } if( ( mbedtls_ctr_drbg_seed( &sec->_ctr_drbg, mbedtls_entropy_func, &sec->_entropy, (const unsigned char *) pers, strlen( pers ) ) ) != 0 ) { return -1; } return 0; }
/* * Initialise the given ctr_drbg context, using a personalisation string and an * entropy gathering function. */ mbedtls_ctr_drbg_context * rand_ctx_get() { static mbedtls_entropy_context ec = {0}; static mbedtls_ctr_drbg_context cd_ctx = {0}; static bool rand_initialised = false; if (!rand_initialised) { struct gc_arena gc = gc_new(); struct buffer pers_string = alloc_buf_gc(100, &gc); /* * Personalisation string, should be as unique as possible (see NIST * 800-90 section 8.7.1). We have very little information at this stage. * Include Program Name, memory address of the context and PID. */ buf_printf(&pers_string, "OpenVPN %0u %p %s", platform_getpid(), &cd_ctx, time_string(0, 0, 0, &gc)); /* Initialise mbed TLS RNG, and built-in entropy sources */ mbedtls_entropy_init(&ec); mbedtls_ctr_drbg_init(&cd_ctx); if (!mbed_ok(mbedtls_ctr_drbg_seed(&cd_ctx, mbedtls_entropy_func, &ec, BPTR(&pers_string), BLEN(&pers_string)))) { msg(M_FATAL, "Failed to initialize random generator"); } gc_free(&gc); rand_initialised = true; } return &cd_ctx; }
void* ssl_socket_init(int fd, const char *domain) { struct ssl_state *state = (struct ssl_state*)calloc(1, sizeof(*state)); state->domain = domain; mbedtls_debug_set_threshold(DEBUG_LEVEL); mbedtls_net_init(&state->net_ctx); mbedtls_ssl_init(&state->ctx); mbedtls_ssl_config_init(&state->conf); #if defined(MBEDTLS_X509_CRT_PARSE_C) mbedtls_x509_crt_init(&state->ca); #endif mbedtls_ctr_drbg_init(&state->ctr_drbg); mbedtls_entropy_init(&state->entropy); state->net_ctx.fd = fd; if (mbedtls_ctr_drbg_seed(&state->ctr_drbg, mbedtls_entropy_func, &state->entropy, (const unsigned char*)pers, strlen(pers)) != 0) goto error; #if defined(MBEDTLS_X509_CRT_PARSE_C) if (mbedtls_x509_crt_parse(&state->ca, (const unsigned char*)cacert_pem, sizeof(cacert_pem) / sizeof(cacert_pem[0])) < 0) goto error; #endif return state; error: if (state) free(state); return NULL; }
int iot_tls_init(Network *pNetwork) { IoT_Error_t ret_val = NONE_ERROR; const char *pers = "aws_iot_tls_wrapper"; unsigned char buf[MBEDTLS_SSL_MAX_CONTENT_LEN + 1]; mbedtls_net_init(&server_fd); mbedtls_ssl_init(&ssl); mbedtls_ssl_config_init(&conf); mbedtls_ctr_drbg_init(&ctr_drbg); mbedtls_x509_crt_init(&cacert); mbedtls_x509_crt_init(&clicert); mbedtls_pk_init(&pkey); DEBUG("\n . Seeding the random number generator..."); mbedtls_entropy_init(&entropy); if ((ret_val = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) pers, strlen(pers))) != 0) { ERROR(" failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n", -ret); return ret; } DEBUG("ok\n"); pNetwork->my_socket = 0; pNetwork->connect = iot_tls_connect; pNetwork->mqttread = iot_tls_read; pNetwork->mqttwrite = iot_tls_write; pNetwork->disconnect = iot_tls_disconnect; pNetwork->isConnected = iot_tls_is_connected; pNetwork->destroy = iot_tls_destroy; return ret_val; }
int ssh_crypto_init(void) { size_t i; int rc; if (libmbedcrypto_initialized) { return SSH_OK; } mbedtls_entropy_init(&ssh_mbedtls_entropy); mbedtls_ctr_drbg_init(&ssh_mbedtls_ctr_drbg); rc = mbedtls_ctr_drbg_seed(&ssh_mbedtls_ctr_drbg, mbedtls_entropy_func, &ssh_mbedtls_entropy, NULL, 0); if (rc != 0) { mbedtls_ctr_drbg_free(&ssh_mbedtls_ctr_drbg); } for (i = 0; ssh_ciphertab[i].name != NULL; i++) { int cmp; cmp = strcmp(ssh_ciphertab[i].name, "*****@*****.**"); if (cmp == 0) { memcpy(&ssh_ciphertab[i], ssh_get_chacha20poly1305_cipher(), sizeof(struct ssh_cipher_struct)); break; } } libmbedcrypto_initialized = 1; return SSH_OK; }
/* Initialize TLS library */ int init_tls_module(mbedtls_x509_crt *ca_certificates) { char version[16]; if (mbedtls_version_get_number() < 0x02000000) { mbedtls_version_get_string(version); fprintf(stderr, "This Hiawatha installation requires at least mbed TLS v2.0.0 and you have v%s.", version); return -1; } if (mbedtls_version_check_feature("MBEDTLS_THREADING_PTHREAD") != 0) { fprintf(stderr, "mbed TLS was compiled without the required MBEDTLS_THREADING_PTHREAD compiler flag.\n"); return -1; } #ifdef ENABLE_DEBUG mbedtls_debug_set_threshold(TLS_DEBUG_LEVEL); #endif /* Entropy settings */ mbedtls_entropy_init(&entropy); mbedtls_ctr_drbg_init(&ctr_drbg); if (mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (unsigned char*)"Hiawatha_RND", 10) != 0) { return -1; } mbedtls_ctr_drbg_set_prediction_resistance(&ctr_drbg, MBEDTLS_CTR_DRBG_PR_OFF); /* Cache settings */ mbedtls_ssl_cache_init(&cache); mbedtls_ssl_cache_set_max_entries(&cache, 100); /* Client SSL configuratiomn */ mbedtls_ssl_config_init(&client_config); if (mbedtls_ssl_config_defaults(&client_config, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT) != 0) { return -1; } mbedtls_ssl_conf_min_version(&client_config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1); mbedtls_ssl_conf_renegotiation(&client_config, MBEDTLS_SSL_RENEGOTIATION_DISABLED); mbedtls_ssl_conf_rng(&client_config, tls_random, &ctr_drbg); #ifdef ENABLE_DEBUG mbedtls_ssl_conf_dbg(&client_config, tls_debug, &client_config); #endif if (ca_certificates == NULL) { mbedtls_ssl_conf_authmode(&client_config, MBEDTLS_SSL_VERIFY_NONE); } else { mbedtls_ssl_conf_authmode(&client_config, MBEDTLS_SSL_VERIFY_REQUIRED); mbedtls_ssl_conf_ca_chain(&client_config, ca_certificates, NULL); } if (pthread_mutex_init(&random_mutex, NULL) != 0) { return -1; } else if (pthread_mutex_init(&cache_mutex, NULL) != 0) { return -1; } return 0; }
struct flb_tls_context *flb_tls_context_new() { int ret; struct flb_tls_context *ctx; ctx = malloc(sizeof(struct flb_tls_context)); if (!ctx) { perror("malloc"); return NULL; } mbedtls_entropy_init(&ctx->entropy); mbedtls_ctr_drbg_init(&ctx->ctr_drbg); ret = mbedtls_ctr_drbg_seed(&ctx->ctr_drbg, mbedtls_entropy_func, &ctx->entropy, (const unsigned char *) FLB_TLS_CLIENT, sizeof(FLB_TLS_CLIENT) -1); if (ret == -1) { io_tls_error(ret); goto error; } return ctx; error: free(ctx); return NULL; }
// コンテキストを初期化します。 // mtls_alloc() に続いてコールしてください。 // 成功すれば 0、失敗すれば -1 を返します。 int mtls_init(mtlsctx_t* ctx) { int r; TRACE("start\n"); // グローバルコンテキストの初期化 if (gctx.initialized == 0) { mbedtls_ctr_drbg_init(&gctx.ctr_drbg); mbedtls_entropy_init(&gctx.entropy); // init RNG r = mbedtls_ctr_drbg_seed(&gctx.ctr_drbg, mbedtls_entropy_func, &gctx.entropy, "a", 1); if (r != 0) { ERROR("mbedtls_ctr_drbg_seed failed: %s\n", mtls_errmsg(r)); goto errexit; } gctx.initialized = 1; } ctx->usessl = 0; mbedtls_net_init(&ctx->net); mbedtls_ssl_init(&ctx->ssl); mbedtls_ssl_config_init(&ctx->conf); // TLS config r = mbedtls_ssl_config_defaults(&ctx->conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); if (r != 0) { ERROR("mbedtls_ssl_config_defaults failed: %s\n", mtls_errmsg(r)); goto errexit; } mbedtls_ssl_conf_authmode(&ctx->conf, MBEDTLS_SSL_VERIFY_NONE); mbedtls_ssl_conf_rng(&ctx->conf, mbedtls_ctr_drbg_random, &gctx.ctr_drbg); mbedtls_ssl_conf_dbg(&ctx->conf, debug_callback, stderr); r = mbedtls_ssl_setup(&ctx->ssl, &ctx->conf); if (r != 0) { ERROR("mbedtls_ssl_setup failed: %s\n", mtls_errmsg(r)); goto errexit; } mbedtls_ssl_set_bio(&ctx->ssl, &ctx->net, mbedtls_net_send, mbedtls_net_recv, NULL); ctx->initialized = 1; TRACE("done\n"); return 0; errexit: // cleanup TRACE("NG\n"); return -1; }
static int tls_server_listen(const char *host, const char *port) { int ret = mbedtls_ctr_drbg_seed( &stls.ctr_drbg, mbedtls_entropy_func, &stls.entropy, (uint8_t*)seed, strlen(seed)); if (ret) return -1; ret = mbedtls_x509_crt_parse(&stls.cacert, ca_cert, ca_cert_len); if (ret) { printf("cacert parse failed\n"); return -1; } ret = mbedtls_x509_crt_parse(&stls.srvcert, server_cert, server_cert_len); if (ret) { printf("servercert parse failed\n"); return -1; } ret = mbedtls_pk_parse_key(&stls.pkey, server_key, server_key_len, NULL, 0); if (ret) { printf("key parse failed\n"); return -1; } ret = mbedtls_ssl_config_defaults( &stls.conf, MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); if (ret) { printf("defaults failed\n"); return -1; } mbedtls_ssl_conf_rng(&stls.conf, mbedtls_ctr_drbg_random, &stls.ctr_drbg); mbedtls_ssl_conf_dbg(&stls.conf, tls_debug, NULL); mbedtls_debug_set_threshold(1); mbedtls_ssl_conf_ca_chain(&stls.conf, stls.cacert.next, NULL); ret = mbedtls_ssl_conf_own_cert(&stls.conf, &stls.srvcert, &stls.pkey); if (ret) { printf("setting own cert failed\n"); return -1; } ret = mbedtls_net_bind(&stls.fd, host, port, MBEDTLS_NET_PROTO_TCP); if (ret) { printf("bind failed\n"); return -1; } return stls.fd.fd; }
void ssl_main() { #if _MSC_VER mbedtls_threading_set_alt( threading_mutex_init_alt, threading_mutex_free_alt, threading_mutex_lock_alt, threading_mutex_unlock_alt ); #endif // Init RNG mbedtls_entropy_init( &entropy ); mbedtls_ctr_drbg_init( &ctr_drbg ); mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0 ); }
/** * @brief Initation the SSL client. * @param[in] ssl: mbedtls ssl struct. * @param[in] tcp_fd. The underlying file descriptor. * @param[in] custom_config: custome config. * @return The result. 0 is ok. */ static int nghttp2_ssl_client_init(mbedtls_ssl_context *ssl, mbedtls_net_context *tcp_fd, http2_ssl_custom_conf_t *custom_config) { int ret = -1; http2_verify_source_t *verify_source = &custom_config->verify_source; mbedtls_ssl_config *conf = &(custom_config->conf); /* * 0. Initialize the RNG and the session data */ #if defined(MBEDTLS_DEBUG_C) mbedtls_debug_set_threshold(DEBUG_LEVEL); #endif mbedtls_net_init( tcp_fd ); mbedtls_ssl_init( ssl ); mbedtls_ssl_config_init( conf ); mbedtls_x509_crt_init( &(verify_source->cacertl) ); mbedtls_ctr_drbg_init( &ctr_drbg ); NGHTTP2_DBG( "\n . Seeding the random number generator..." ); mbedtls_entropy_init( &entropy ); if ( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) pers, strlen( pers ) ) ) != 0 ) { NGHTTP2_DBG( " failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret ); return ret; } NGHTTP2_DBG( " ok\n" ); /* * 0. Initialize certificates */ NGHTTP2_DBG( " . Loading the CA root certificate ..." ); if (NULL != verify_source->trusted_ca_crt) { if (0 != (ret = mbedtls_x509_crt_parse(&verify_source->cacertl, (unsigned char *)verify_source->trusted_ca_crt, strlen(verify_source->trusted_ca_crt) + 1))) { NGHTTP2_DBG(" failed ! x509parse_crt returned -0x%04x", -ret); return ret; } } NGHTTP2_DBG( " ok (%d skipped)", ret ); return 0; }
static dukf_ssl_context_t *create_dukf_ssl_context(const char *hostname, int fd) { char errortext[256]; dukf_ssl_context_t *dukf_ssl_context; dukf_ssl_context = malloc(sizeof(dukf_ssl_context_t)); mbedtls_ssl_init(&dukf_ssl_context->ssl); mbedtls_ssl_config_init(&dukf_ssl_context->conf); mbedtls_x509_crt_init(&dukf_ssl_context->cacert); mbedtls_ctr_drbg_init(&dukf_ssl_context->ctr_drbg); mbedtls_entropy_init(&dukf_ssl_context->entropy); mbedtls_ssl_conf_dbg(&dukf_ssl_context->conf, debug_log, NULL); dukf_ssl_context->fd = fd; int rc = mbedtls_ctr_drbg_seed( &dukf_ssl_context->ctr_drbg, mbedtls_entropy_func, &dukf_ssl_context->entropy, (const unsigned char *) pers, strlen(pers)); if (rc != 0) { LOGE(" failed\n ! mbedtls_ctr_drbg_seed returned %d", rc); return NULL; } rc = mbedtls_ssl_config_defaults( &dukf_ssl_context->conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); if (rc != 0) { LOGE("mbedtls_ssl_config_defaults returned %d", rc); return NULL; } mbedtls_ssl_conf_authmode(&dukf_ssl_context->conf, MBEDTLS_SSL_VERIFY_NONE); mbedtls_ssl_conf_rng(&dukf_ssl_context->conf, mbedtls_ctr_drbg_random, &dukf_ssl_context->ctr_drbg); rc = mbedtls_ssl_setup(&dukf_ssl_context->ssl, &dukf_ssl_context->conf); if (rc != 0) { mbedtls_strerror(rc, errortext, sizeof(errortext)); LOGE("error from mbedtls_ssl_setup: %d - %x - %s\n", rc, rc, errortext); return NULL; } rc = mbedtls_ssl_set_hostname(&dukf_ssl_context->ssl, hostname); if (rc) { mbedtls_strerror(rc, errortext, sizeof(errortext)); LOGE("error from mbedtls_ssl_set_hostname: %s %d - %x - %s", hostname, rc, rc, errortext); return NULL; } mbedtls_ssl_set_bio(&dukf_ssl_context->ssl, dukf_ssl_context, ssl_send, ssl_recv, NULL); return dukf_ssl_context; } // create_ssl_socket
static CURLcode Curl_mbedtls_random(struct Curl_easy *data, unsigned char *entropy, size_t length) { #if defined(MBEDTLS_CTR_DRBG_C) int ret = -1; char errorbuf[128]; mbedtls_entropy_context ctr_entropy; mbedtls_ctr_drbg_context ctr_drbg; mbedtls_entropy_init(&ctr_entropy); mbedtls_ctr_drbg_init(&ctr_drbg); errorbuf[0]=0; ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &ctr_entropy, NULL, 0); if(ret) { #ifdef MBEDTLS_ERROR_C mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); #endif /* MBEDTLS_ERROR_C */ failf(data, "Failed - mbedTLS: ctr_drbg_seed returned (-0x%04X) %s\n", -ret, errorbuf); } else { ret = mbedtls_ctr_drbg_random(&ctr_drbg, entropy, length); if(ret) { #ifdef MBEDTLS_ERROR_C mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); #endif /* MBEDTLS_ERROR_C */ failf(data, "mbedTLS: ctr_drbg_init returned (-0x%04X) %s\n", -ret, errorbuf); } } mbedtls_ctr_drbg_free(&ctr_drbg); mbedtls_entropy_free(&ctr_entropy); return ret == 0 ? CURLE_OK : CURLE_FAILED_INIT; #elif defined(MBEDTLS_HAVEGE_C) mbedtls_havege_state hs; mbedtls_havege_init(&hs); mbedtls_havege_random(&hs, entropy, length); mbedtls_havege_free(&hs); return CURLE_OK; #else return CURLE_NOT_BUILT_IN; #endif }
static int dslink_socket_connect_secure(SslSocket *sock, const char *address, unsigned short port) { if ((errno = mbedtls_ctr_drbg_seed(sock->drbg, mbedtls_entropy_func, sock->entropy, NULL, 0)) != 0) { return DSLINK_CRYPT_ENTROPY_SEED_ERR; } char num[6]; snprintf(num, sizeof(num), "%d", port); if ((errno = mbedtls_net_connect(sock->socket_fd, address, num, MBEDTLS_NET_PROTO_TCP)) != 0) { return DSLINK_SOCK_CONNECT_ERR; } if ((errno = mbedtls_ssl_config_defaults(sock->conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0) { return DSLINK_SOCK_SSL_CONFIG_ERR; } mbedtls_ssl_conf_authmode(sock->conf, MBEDTLS_SSL_VERIFY_NONE); mbedtls_ssl_conf_rng(sock->conf, mbedtls_ctr_drbg_random, sock->drbg); if ((errno = mbedtls_ssl_setup(sock->ssl, sock->conf)) != 0) { return DSLINK_SOCK_SSL_SETUP_ERR; } if ((errno = mbedtls_ssl_set_hostname(sock->ssl, "_")) != 0) { return DSLINK_SOCK_SSL_HOSTNAME_SET_ERR; } mbedtls_ssl_set_bio(sock->ssl, sock->socket_fd, mbedtls_net_send, mbedtls_net_recv, NULL); int stat; while ((stat = mbedtls_ssl_handshake(sock->ssl)) != 0) { if (stat != MBEDTLS_ERR_SSL_WANT_READ && stat != MBEDTLS_ERR_SSL_WANT_WRITE) { errno = stat; return DSLINK_SOCK_SSL_HANDSHAKE_ERR; } } return 0; }
Error StreamPeerMbedTLS::connect_to_stream(Ref<StreamPeer> p_base, bool p_validate_certs, const String &p_for_hostname) { base = p_base; int ret = 0; int authmode = p_validate_certs ? MBEDTLS_SSL_VERIFY_REQUIRED : MBEDTLS_SSL_VERIFY_NONE; mbedtls_ssl_init(&ssl); mbedtls_ssl_config_init(&conf); mbedtls_ctr_drbg_init(&ctr_drbg); mbedtls_entropy_init(&entropy); ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0); if (ret != 0) { ERR_PRINTS(" failed\n ! mbedtls_ctr_drbg_seed returned an error" + itos(ret)); return FAILED; } mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); mbedtls_ssl_conf_authmode(&conf, authmode); mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL); mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg); mbedtls_ssl_conf_dbg(&conf, my_debug, stdout); mbedtls_ssl_setup(&ssl, &conf); mbedtls_ssl_set_hostname(&ssl, p_for_hostname.utf8().get_data()); mbedtls_ssl_set_bio(&ssl, this, bio_send, bio_recv, NULL); while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) { if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { ERR_PRINTS("TLS handshake error: " + itos(ret)); _print_error(ret); status = STATUS_ERROR_HOSTNAME_MISMATCH; return FAILED; } } connected = true; status = STATUS_CONNECTED; return OK; }
int rb_init_ssl(void) { int ret; mbedtls_entropy_init(&entropy); mbedtls_ctr_drbg_init(&ctr_drbg); if((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0)) != 0) { rb_lib_log("rb_init_prng: unable to initialize PRNG, mbedtls_ctr_drbg_seed() returned -0x%x", -ret); return 0; } #if 0 mbedtls_ssl_config_init(&serv_config); if ((ret = mbedtls_ssl_config_defaults(&serv_config, MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0) { rb_lib_log("rb_init_ssl: unable to initialize default SSL parameters for server context: -0x%x", -ret); return 0; } #endif // mbedtls_ssl_conf_rng(&serv_config, mbedtls_ctr_drbg_random, &ctr_drbg); /***************************************************************************************************************/ #if 0 mbedtls_ssl_config_init(&client_config); if ((ret = mbedtls_ssl_config_defaults(&client_config, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0) { rb_lib_log("rb_init_ssl: unable to initialize default SSL parameters for client context: -0x%x", -ret); return 0; } mbedtls_ssl_conf_rng(&client_config, mbedtls_ctr_drbg_random, &ctr_drbg); #endif return 1; }
int init_aes_key(unsigned char *key, size_t bytes) { mbedtls_ctr_drbg_context ctr_drbg; mbedtls_entropy_context entropy; const uint8_t pers[] = "aes_generate_key"; int ret; mbedtls_entropy_init(&entropy); mbedtls_ctr_drbg_init(&ctr_drbg); if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, pers, sizeof(pers) - 1)) == 0) { ret = mbedtls_ctr_drbg_random(&ctr_drbg, key, bytes); } mbedtls_ctr_drbg_free(&ctr_drbg); mbedtls_entropy_free(&entropy); return ret; }
kaa_error_t rsa_encrypt(const uint8_t *key, size_t key_size, const uint8_t *input, size_t input_len, uint8_t *output) { if (key == NULL || key_size == 0) { return KAA_ERR_BADPARAM; } mbedtls_pk_context pk; mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; const uint8_t pers[] = "key_gen"; mbedtls_pk_init(&pk); if (mbedtls_pk_parse_public_key(&pk, key, key_size) != 0) { return KAA_ERR_INVALID_PUB_KEY; } mbedtls_ctr_drbg_init(&ctr_drbg); mbedtls_entropy_init(&entropy); int ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, pers, sizeof(pers) - 1); if (!ret) { ret = mbedtls_rsa_rsaes_pkcs1_v15_encrypt(mbedtls_pk_rsa(pk), mbedtls_ctr_drbg_random, &ctr_drbg, MBEDTLS_RSA_PUBLIC, input_len, input, output); } mbedtls_ctr_drbg_free(&ctr_drbg); mbedtls_entropy_free(&entropy); mbedtls_pk_free(&pk); if (ret) { return KAA_ERR_GENERIC; } return KAA_ERR_NONE; }
static int coap_security_handler_init(coap_security_t *sec){ const char *pers = "dtls_client"; #ifdef COAP_SERVICE_PROVIDE_STRONG_ENTROPY_SOURCE const int entropy_source_type = MBEDTLS_ENTROPY_SOURCE_STRONG; #else const int entropy_source_type = MBEDTLS_ENTROPY_SOURCE_WEAK; #endif mbedtls_ssl_init( &sec->_ssl ); mbedtls_ssl_config_init( &sec->_conf ); mbedtls_ctr_drbg_init( &sec->_ctr_drbg ); mbedtls_entropy_init( &sec->_entropy ); #if defined(MBEDTLS_X509_CRT_PARSE_C) mbedtls_x509_crt_init( &sec->_cacert ); mbedtls_x509_crt_init( &sec->_owncert ); #endif mbedtls_pk_init( &sec->_pkey ); memset(&sec->_cookie, 0, sizeof(simple_cookie_t)); memset(&sec->_keyblk, 0, sizeof(key_block_t)); sec->_is_started = false; if( mbedtls_entropy_add_source( &sec->_entropy, entropy_poll, NULL, 128, entropy_source_type ) < 0 ){ return -1; } if( ( mbedtls_ctr_drbg_seed( &sec->_ctr_drbg, mbedtls_entropy_func, &sec->_entropy, (const unsigned char *) pers, strlen( pers ) ) ) != 0 ) { return -1; } return 0; }
int Server_init_rng(Server *srv) { int rc; unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; void *ctx = NULL; mbedtls_entropy_init( &srv->entropy ); // test the entropy source rc = mbedtls_entropy_func(&srv->entropy, buf, MBEDTLS_ENTROPY_BLOCK_SIZE); if(rc == 0) { ctx = calloc(sizeof(mbedtls_ctr_drbg_context), 1); mbedtls_ctr_drbg_init((mbedtls_ctr_drbg_context *)ctx); rc = mbedtls_ctr_drbg_seed((mbedtls_ctr_drbg_context *)ctx, mbedtls_entropy_func, &srv->entropy, NULL, 0); check(rc == 0, "Init rng failed: ctr_drbg_init returned %d\n", rc); srv->rng_func = mbedtls_ctr_drbg_random; srv->rng_ctx = ctx; } else { log_warn("entropy source unavailable. falling back to havege rng"); ctx = calloc(sizeof(mbedtls_havege_state), 1); mbedtls_havege_init((mbedtls_havege_state *)ctx); srv->rng_func = mbedtls_havege_random; srv->rng_ctx = ctx; } return 0; error: if(ctx != NULL) free(ctx); return -1; }
int rsa_sign(mbedtls_pk_context *pk, const uint8_t *input, size_t input_size, uint8_t *output, size_t *output_size) { // TODO(KAA-982): Use asserts if (!input || !input_size || !output || !output_size) { return KAA_ERR_BADPARAM; } int ret = 0; uint8_t hash[32]; mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; const uint8_t pers[] = "mbedtls_pk_sign"; mbedtls_entropy_init(&entropy); mbedtls_ctr_drbg_init(&ctr_drbg); if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, pers,sizeof(pers) - 1)) != 0) { goto exit; } const mbedtls_md_info_t *info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); if ((ret = mbedtls_md(info, input, input_size, hash)) != 0) { goto exit; } ret = mbedtls_pk_sign(pk, MBEDTLS_MD_SHA1, hash, 0, output, output_size, mbedtls_ctr_drbg_random, &ctr_drbg); exit: mbedtls_ctr_drbg_free(&ctr_drbg); mbedtls_entropy_free(&entropy); return ret ? KAA_ERR_BADDATA : KAA_ERR_NONE; }
int main( void ) { int ret, len; mbedtls_net_context listen_fd, client_fd; unsigned char buf[1024]; const char *pers = "dtls_server"; unsigned char client_ip[16] = { 0 }; size_t cliip_len; mbedtls_ssl_cookie_ctx cookie_ctx; mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; mbedtls_ssl_context ssl; mbedtls_ssl_config conf; mbedtls_x509_crt srvcert; mbedtls_pk_context pkey; mbedtls_timing_delay_context timer; #if defined(MBEDTLS_SSL_CACHE_C) mbedtls_ssl_cache_context cache; #endif mbedtls_net_init( &listen_fd ); mbedtls_net_init( &client_fd ); mbedtls_ssl_init( &ssl ); mbedtls_ssl_config_init( &conf ); mbedtls_ssl_cookie_init( &cookie_ctx ); #if defined(MBEDTLS_SSL_CACHE_C) mbedtls_ssl_cache_init( &cache ); #endif mbedtls_x509_crt_init( &srvcert ); mbedtls_pk_init( &pkey ); mbedtls_entropy_init( &entropy ); mbedtls_ctr_drbg_init( &ctr_drbg ); #if defined(MBEDTLS_DEBUG_C) mbedtls_debug_set_threshold( DEBUG_LEVEL ); #endif /* * 1. Load the certificates and private RSA key */ printf( "\n . Loading the server cert. and key..." ); fflush( stdout ); /* * This demonstration program uses embedded test certificates. * Instead, you may want to use mbedtls_x509_crt_parse_file() to read the * server and CA certificates, as well as mbedtls_pk_parse_keyfile(). */ ret = mbedtls_x509_crt_parse( &srvcert, (const unsigned char *) mbedtls_test_srv_crt, mbedtls_test_srv_crt_len ); if( ret != 0 ) { printf( " failed\n ! mbedtls_x509_crt_parse returned %d\n\n", ret ); goto exit; } ret = mbedtls_x509_crt_parse( &srvcert, (const unsigned char *) mbedtls_test_cas_pem, mbedtls_test_cas_pem_len ); if( ret != 0 ) { printf( " failed\n ! mbedtls_x509_crt_parse returned %d\n\n", ret ); goto exit; } ret = mbedtls_pk_parse_key( &pkey, (const unsigned char *) mbedtls_test_srv_key, mbedtls_test_srv_key_len, NULL, 0 ); if( ret != 0 ) { printf( " failed\n ! mbedtls_pk_parse_key returned %d\n\n", ret ); goto exit; } printf( " ok\n" ); /* * 2. Setup the "listening" UDP socket */ printf( " . Bind on udp/*/4433 ..." ); fflush( stdout ); if( ( ret = mbedtls_net_bind( &listen_fd, NULL, "4433", MBEDTLS_NET_PROTO_UDP ) ) != 0 ) { printf( " failed\n ! mbedtls_net_bind returned %d\n\n", ret ); goto exit; } printf( " ok\n" ); /* * 3. Seed the RNG */ printf( " . Seeding the random number generator..." ); fflush( stdout ); if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) pers, strlen( pers ) ) ) != 0 ) { printf( " failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret ); goto exit; } printf( " ok\n" ); /* * 4. Setup stuff */ printf( " . Setting up the DTLS data..." ); fflush( stdout ); if( ( ret = mbedtls_ssl_config_defaults( &conf, MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_DATAGRAM, MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ssl_config_defaults returned %d\n\n", ret ); goto exit; } mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg ); mbedtls_ssl_conf_dbg( &conf, my_debug, stdout ); #if defined(MBEDTLS_SSL_CACHE_C) mbedtls_ssl_conf_session_cache( &conf, &cache, mbedtls_ssl_cache_get, mbedtls_ssl_cache_set ); #endif mbedtls_ssl_conf_ca_chain( &conf, srvcert.next, NULL ); if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &srvcert, &pkey ) ) != 0 ) { printf( " failed\n ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret ); goto exit; } if( ( ret = mbedtls_ssl_cookie_setup( &cookie_ctx, mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 ) { printf( " failed\n ! mbedtls_ssl_cookie_setup returned %d\n\n", ret ); goto exit; } mbedtls_ssl_conf_dtls_cookies( &conf, mbedtls_ssl_cookie_write, mbedtls_ssl_cookie_check, &cookie_ctx ); if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 ) { printf( " failed\n ! mbedtls_ssl_setup returned %d\n\n", ret ); goto exit; } mbedtls_ssl_set_timer_cb( &ssl, &timer, mbedtls_timing_set_delay, mbedtls_timing_get_delay ); printf( " ok\n" ); reset: #ifdef MBEDTLS_ERROR_C if( ret != 0 ) { char error_buf[100]; mbedtls_strerror( ret, error_buf, 100 ); printf("Last error was: %d - %s\n\n", ret, error_buf ); } #endif mbedtls_net_free( &client_fd ); mbedtls_ssl_session_reset( &ssl ); /* * 3. Wait until a client connects */ printf( " . Waiting for a remote connection ..." ); fflush( stdout ); if( ( ret = mbedtls_net_accept( &listen_fd, &client_fd, client_ip, sizeof( client_ip ), &cliip_len ) ) != 0 ) { printf( " failed\n ! mbedtls_net_accept returned %d\n\n", ret ); goto exit; } /* For HelloVerifyRequest cookies */ if( ( ret = mbedtls_ssl_set_client_transport_id( &ssl, client_ip, cliip_len ) ) != 0 ) { printf( " failed\n ! " "mbedtls_ssl_set_client_transport_id() returned -0x%x\n\n", -ret ); goto exit; } mbedtls_ssl_set_bio( &ssl, &client_fd, mbedtls_net_send, mbedtls_net_recv, mbedtls_net_recv_timeout ); printf( " ok\n" ); /* * 5. Handshake */ printf( " . Performing the DTLS handshake..." ); fflush( stdout ); do ret = mbedtls_ssl_handshake( &ssl ); while( ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE ); if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ) { printf( " hello verification requested\n" ); ret = 0; goto reset; } else if( ret != 0 ) { printf( " failed\n ! mbedtls_ssl_handshake returned -0x%x\n\n", -ret ); goto reset; } printf( " ok\n" ); /* * 6. Read the echo Request */ printf( " < Read from client:" ); fflush( stdout ); len = sizeof( buf ) - 1; memset( buf, 0, sizeof( buf ) ); do ret = mbedtls_ssl_read( &ssl, buf, len ); while( ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE ); if( ret <= 0 ) { switch( ret ) { case MBEDTLS_ERR_SSL_TIMEOUT: printf( " timeout\n\n" ); goto reset; case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: printf( " connection was closed gracefully\n" ); ret = 0; goto close_notify; default: printf( " mbedtls_ssl_read returned -0x%x\n\n", -ret ); goto reset; } } len = ret; printf( " %d bytes read\n\n%s\n\n", len, buf ); /* * 7. Write the 200 Response */ printf( " > Write to client:" ); fflush( stdout ); do ret = mbedtls_ssl_write( &ssl, buf, len ); while( ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE ); if( ret < 0 ) { printf( " failed\n ! mbedtls_ssl_write returned %d\n\n", ret ); goto exit; } len = ret; printf( " %d bytes written\n\n%s\n\n", len, buf ); /* * 8. Done, cleanly close the connection */ close_notify: printf( " . Closing the connection..." ); /* No error checking, the connection might be closed already */ do ret = mbedtls_ssl_close_notify( &ssl ); while( ret == MBEDTLS_ERR_SSL_WANT_WRITE ); ret = 0; printf( " done\n" ); goto reset; /* * Final clean-ups and exit */ exit: #ifdef MBEDTLS_ERROR_C if( ret != 0 ) { char error_buf[100]; mbedtls_strerror( ret, error_buf, 100 ); printf( "Last error was: %d - %s\n\n", ret, error_buf ); } #endif mbedtls_net_free( &client_fd ); mbedtls_net_free( &listen_fd ); mbedtls_x509_crt_free( &srvcert ); mbedtls_pk_free( &pkey ); mbedtls_ssl_free( &ssl ); mbedtls_ssl_config_free( &conf ); mbedtls_ssl_cookie_free( &cookie_ctx ); #if defined(MBEDTLS_SSL_CACHE_C) mbedtls_ssl_cache_free( &cache ); #endif mbedtls_ctr_drbg_free( &ctr_drbg ); mbedtls_entropy_free( &entropy ); #if defined(_WIN32) printf( " Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif /* Shell can not handle large exit numbers -> 1 for errors */ if( ret < 0 ) ret = 1; return( ret ); }
int _ssl_init(nsp_state *N, TCP_SOCKET *sock, short srvmode, char *certfile, char *keyfile) { #define __FN__ __FILE__ ":_ssl_init()" #if defined HAVE_OPENSSL SSL_load_error_strings(); SSLeay_add_ssl_algorithms(); if (srvmode) { sock->ssl_meth = (SSL_METHOD *)SSLv23_server_method(); } else { sock->ssl_meth = (SSL_METHOD *)SSLv23_client_method(); } sock->ssl_ctx = SSL_CTX_new(sock->ssl_meth); if (!sock->ssl_ctx) { n_warn(N, __FN__, "SSL Error"); return -1; } if ((certfile == NULL) || (keyfile == NULL)) return 0; if (SSL_CTX_use_certificate_file(sock->ssl_ctx, certfile, SSL_FILETYPE_PEM) <= 0) { n_warn(N, __FN__, "SSL Error loading certificate '%s'", certfile); return -1; } if (SSL_CTX_use_PrivateKey_file(sock->ssl_ctx, keyfile, SSL_FILETYPE_PEM) <= 0) { n_warn(N, __FN__, "SSL Error loading private key '%s'", keyfile); return -1; } if (!SSL_CTX_check_private_key(sock->ssl_ctx)) { n_warn(N, __FN__, "Private key does not match the public certificate"); return -1; } return 0; #elif defined HAVE_MBEDTLS const char *pers = "ssl_server"; int rc; mbedtls_ssl_config_init(&sock->conf); if ((rc = mbedtls_ssl_config_defaults(&sock->conf, srvmode ? MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0) { n_warn(N, __FN__, "mbedtls_ssl_config_defaults failed. error %d", rc); return -1; } mbedtls_ssl_conf_authmode(&sock->conf, MBEDTLS_SSL_VERIFY_NONE); mbedtls_entropy_init(&sock->entropy); mbedtls_ctr_drbg_init(&sock->ctr_drbg); if ((rc = mbedtls_ctr_drbg_seed(&sock->ctr_drbg, mbedtls_entropy_func, &sock->entropy, (const unsigned char *)pers, nc_strlen(pers))) != 0) { print_mbedtls_error(N, __FN__, rc); return -1; } mbedtls_ssl_conf_rng(&sock->conf, mbedtls_ctr_drbg_random, &sock->ctr_drbg); if ((certfile == NULL) || (keyfile == NULL)) { return 0; //if ((rc = mbedtls_x509_crt_parse(&sock->srvcert, (unsigned char *)mbedtls_test_srv_crt, nc_strlen(mbedtls_test_srv_crt))) != 0) { // print_mbedtls_error(N, __FN__, rc); // return -1; //} //if ((rc = mbedtls_x509_crt_parse(&sock->srvcert, (unsigned char *)mbedtls_test_ca_crt, nc_strlen(mbedtls_test_ca_crt))) != 0) { // print_mbedtls_error(N, __FN__, rc); // return -1; //} //if ((rc = mbedtls_pk_parse_key(&sock->pubkey, (unsigned char *)mbedtls_test_srv_key, nc_strlen(mbedtls_test_srv_key), NULL, 0)) != 0) { // print_mbedtls_error(N, __FN__, rc); // return -1; //} } else { if ((rc = mbedtls_x509_crt_parse_file(&sock->srvcert, certfile)) != 0) { //n_warn(N, __FN__, "x509_read_crtfile returned %08x", rc); print_mbedtls_error(N, __FN__, rc); return -1; } if ((rc = mbedtls_pk_parse_keyfile(&sock->pubkey, keyfile, NULL)) != 0) { //n_warn(N, __FN__, "x509_read_keyfile returned %08x", rc); print_mbedtls_error(N, __FN__, rc); return -1; } } mbedtls_ssl_conf_ca_chain(&sock->conf, sock->srvcert.next, NULL); if ((rc = mbedtls_ssl_conf_own_cert(&sock->conf, &sock->srvcert, &sock->pubkey)) != 0) { n_warn(N, __FN__, "mbedtls_ssl_conf_own_cert returned %08x", rc); return -1; } return 0; #endif #undef __FN__ }
/** * @brief create SSL low-level object */ int ssl_pm_new(SSL *ssl) { struct ssl_pm *ssl_pm; int ret; const unsigned char pers[] = "OpenSSL PM"; size_t pers_len = sizeof(pers); int endpoint; int version; const SSL_METHOD *method = ssl->method; ssl_pm = ssl_mem_zalloc(sizeof(struct ssl_pm)); if (!ssl_pm) { SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "no enough memory > (ssl_pm)"); goto no_mem; } if (!ssl->ctx->read_buffer_len) ssl->ctx->read_buffer_len = 2048; max_content_len = ssl->ctx->read_buffer_len; // printf("ssl->ctx->read_buffer_len = %d ++++++++++++++++++++\n", ssl->ctx->read_buffer_len); mbedtls_net_init(&ssl_pm->fd); mbedtls_net_init(&ssl_pm->cl_fd); mbedtls_ssl_config_init(&ssl_pm->conf); mbedtls_ctr_drbg_init(&ssl_pm->ctr_drbg); mbedtls_entropy_init(&ssl_pm->entropy); mbedtls_ssl_init(&ssl_pm->ssl); ret = mbedtls_ctr_drbg_seed(&ssl_pm->ctr_drbg, mbedtls_entropy_func, &ssl_pm->entropy, pers, pers_len); if (ret) { SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ctr_drbg_seed() return -0x%x", -ret); goto mbedtls_err1; } if (method->endpoint) { endpoint = MBEDTLS_SSL_IS_SERVER; } else { endpoint = MBEDTLS_SSL_IS_CLIENT; } ret = mbedtls_ssl_config_defaults(&ssl_pm->conf, endpoint, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); if (ret) { SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_config_defaults() return -0x%x", -ret); goto mbedtls_err2; } if (TLS_ANY_VERSION != ssl->version) { if (TLS1_2_VERSION == ssl->version) version = MBEDTLS_SSL_MINOR_VERSION_3; else if (TLS1_1_VERSION == ssl->version) version = MBEDTLS_SSL_MINOR_VERSION_2; else if (TLS1_VERSION == ssl->version) version = MBEDTLS_SSL_MINOR_VERSION_1; else version = MBEDTLS_SSL_MINOR_VERSION_0; mbedtls_ssl_conf_max_version(&ssl_pm->conf, MBEDTLS_SSL_MAJOR_VERSION_3, version); mbedtls_ssl_conf_min_version(&ssl_pm->conf, MBEDTLS_SSL_MAJOR_VERSION_3, version); } else { mbedtls_ssl_conf_max_version(&ssl_pm->conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3); mbedtls_ssl_conf_min_version(&ssl_pm->conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0); } mbedtls_ssl_conf_rng(&ssl_pm->conf, mbedtls_ctr_drbg_random, &ssl_pm->ctr_drbg); #ifdef CONFIG_OPENSSL_LOWLEVEL_DEBUG mbedtls_debug_set_threshold(MBEDTLS_DEBUG_LEVEL); mbedtls_ssl_conf_dbg(&ssl_pm->conf, ssl_platform_debug, NULL); #else mbedtls_ssl_conf_dbg(&ssl_pm->conf, NULL, NULL); #endif ret = mbedtls_ssl_setup(&ssl_pm->ssl, &ssl_pm->conf); if (ret) { SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_setup() return -0x%x", -ret); goto mbedtls_err2; } mbedtls_ssl_set_bio(&ssl_pm->ssl, &ssl_pm->fd, mbedtls_net_send, mbedtls_net_recv, NULL); ssl->ssl_pm = ssl_pm; return 0; mbedtls_err2: mbedtls_ssl_config_free(&ssl_pm->conf); mbedtls_ctr_drbg_free(&ssl_pm->ctr_drbg); mbedtls_err1: mbedtls_entropy_free(&ssl_pm->entropy); ssl_mem_free(ssl_pm); no_mem: return -1; }
int main( int argc, char *argv[] ) { int ret = 0; mbedtls_x509_crt issuer_crt; mbedtls_pk_context loaded_issuer_key, loaded_subject_key; mbedtls_pk_context *issuer_key = &loaded_issuer_key, *subject_key = &loaded_subject_key; char buf[1024]; char issuer_name[128]; int i; char *p, *q, *r; #if defined(MBEDTLS_X509_CSR_PARSE_C) char subject_name[128]; mbedtls_x509_csr csr; #endif mbedtls_x509write_cert crt; mbedtls_mpi serial; mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; const char *pers = "crt example app"; /* * Set to sane values */ mbedtls_x509write_crt_init( &crt ); mbedtls_x509write_crt_set_md_alg( &crt, MBEDTLS_MD_SHA256 ); mbedtls_pk_init( &loaded_issuer_key ); mbedtls_pk_init( &loaded_subject_key ); mbedtls_mpi_init( &serial ); mbedtls_ctr_drbg_init( &ctr_drbg ); #if defined(MBEDTLS_X509_CSR_PARSE_C) mbedtls_x509_csr_init( &csr ); #endif mbedtls_x509_crt_init( &issuer_crt ); memset( buf, 0, 1024 ); if( argc == 0 ) { usage: mbedtls_printf( USAGE ); ret = 1; goto exit; } opt.issuer_crt = DFL_ISSUER_CRT; opt.request_file = DFL_REQUEST_FILE; opt.subject_key = DFL_SUBJECT_KEY; opt.issuer_key = DFL_ISSUER_KEY; opt.subject_pwd = DFL_SUBJECT_PWD; opt.issuer_pwd = DFL_ISSUER_PWD; opt.output_file = DFL_OUTPUT_FILENAME; opt.subject_name = DFL_SUBJECT_NAME; opt.issuer_name = DFL_ISSUER_NAME; opt.not_before = DFL_NOT_BEFORE; opt.not_after = DFL_NOT_AFTER; opt.serial = DFL_SERIAL; opt.selfsign = DFL_SELFSIGN; opt.is_ca = DFL_IS_CA; opt.max_pathlen = DFL_MAX_PATHLEN; opt.key_usage = DFL_KEY_USAGE; opt.ns_cert_type = DFL_NS_CERT_TYPE; for( i = 1; i < argc; i++ ) { p = argv[i]; if( ( q = strchr( p, '=' ) ) == NULL ) goto usage; *q++ = '\0'; if( strcmp( p, "request_file" ) == 0 ) opt.request_file = q; else if( strcmp( p, "subject_key" ) == 0 ) opt.subject_key = q; else if( strcmp( p, "issuer_key" ) == 0 ) opt.issuer_key = q; else if( strcmp( p, "subject_pwd" ) == 0 ) opt.subject_pwd = q; else if( strcmp( p, "issuer_pwd" ) == 0 ) opt.issuer_pwd = q; else if( strcmp( p, "issuer_crt" ) == 0 ) opt.issuer_crt = q; else if( strcmp( p, "output_file" ) == 0 ) opt.output_file = q; else if( strcmp( p, "subject_name" ) == 0 ) { opt.subject_name = q; } else if( strcmp( p, "issuer_name" ) == 0 ) { opt.issuer_name = q; } else if( strcmp( p, "not_before" ) == 0 ) { opt.not_before = q; } else if( strcmp( p, "not_after" ) == 0 ) { opt.not_after = q; } else if( strcmp( p, "serial" ) == 0 ) { opt.serial = q; } else if( strcmp( p, "selfsign" ) == 0 ) { opt.selfsign = atoi( q ); if( opt.selfsign < 0 || opt.selfsign > 1 ) goto usage; } else if( strcmp( p, "is_ca" ) == 0 ) { opt.is_ca = atoi( q ); if( opt.is_ca < 0 || opt.is_ca > 1 ) goto usage; } else if( strcmp( p, "max_pathlen" ) == 0 ) { opt.max_pathlen = atoi( q ); if( opt.max_pathlen < -1 || opt.max_pathlen > 127 ) goto usage; } else if( strcmp( p, "key_usage" ) == 0 ) { while( q != NULL ) { if( ( r = strchr( q, ',' ) ) != NULL ) *r++ = '\0'; if( strcmp( q, "digital_signature" ) == 0 ) opt.key_usage |= MBEDTLS_X509_KU_DIGITAL_SIGNATURE; else if( strcmp( q, "non_repudiation" ) == 0 ) opt.key_usage |= MBEDTLS_X509_KU_NON_REPUDIATION; else if( strcmp( q, "key_encipherment" ) == 0 ) opt.key_usage |= MBEDTLS_X509_KU_KEY_ENCIPHERMENT; else if( strcmp( q, "data_encipherment" ) == 0 ) opt.key_usage |= MBEDTLS_X509_KU_DATA_ENCIPHERMENT; else if( strcmp( q, "key_agreement" ) == 0 ) opt.key_usage |= MBEDTLS_X509_KU_KEY_AGREEMENT; else if( strcmp( q, "key_cert_sign" ) == 0 ) opt.key_usage |= MBEDTLS_X509_KU_KEY_CERT_SIGN; else if( strcmp( q, "crl_sign" ) == 0 ) opt.key_usage |= MBEDTLS_X509_KU_CRL_SIGN; else goto usage; q = r; } } else if( strcmp( p, "ns_cert_type" ) == 0 ) { while( q != NULL ) { if( ( r = strchr( q, ',' ) ) != NULL ) *r++ = '\0'; if( strcmp( q, "ssl_client" ) == 0 ) opt.ns_cert_type |= MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT; else if( strcmp( q, "ssl_server" ) == 0 ) opt.ns_cert_type |= MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER; else if( strcmp( q, "email" ) == 0 ) opt.ns_cert_type |= MBEDTLS_X509_NS_CERT_TYPE_EMAIL; else if( strcmp( q, "object_signing" ) == 0 ) opt.ns_cert_type |= MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING; else if( strcmp( q, "ssl_ca" ) == 0 ) opt.ns_cert_type |= MBEDTLS_X509_NS_CERT_TYPE_SSL_CA; else if( strcmp( q, "email_ca" ) == 0 ) opt.ns_cert_type |= MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA; else if( strcmp( q, "object_signing_ca" ) == 0 ) opt.ns_cert_type |= MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA; else goto usage; q = r; } } else goto usage; } mbedtls_printf("\n"); /* * 0. Seed the PRNG */ mbedtls_printf( " . Seeding the random number generator..." ); fflush( stdout ); mbedtls_entropy_init( &entropy ); if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) pers, strlen( pers ) ) ) != 0 ) { mbedtls_strerror( ret, buf, 1024 ); mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned %d - %s\n", ret, buf ); goto exit; } mbedtls_printf( " ok\n" ); // Parse serial to MPI // mbedtls_printf( " . Reading serial number..." ); fflush( stdout ); if( ( ret = mbedtls_mpi_read_string( &serial, 10, opt.serial ) ) != 0 ) { mbedtls_strerror( ret, buf, 1024 ); mbedtls_printf( " failed\n ! mbedtls_mpi_read_string returned -0x%02x - %s\n\n", -ret, buf ); goto exit; } mbedtls_printf( " ok\n" ); // Parse issuer certificate if present // if( !opt.selfsign && strlen( opt.issuer_crt ) ) { /* * 1.0.a. Load the certificates */ mbedtls_printf( " . Loading the issuer certificate ..." ); fflush( stdout ); if( ( ret = mbedtls_x509_crt_parse_file( &issuer_crt, opt.issuer_crt ) ) != 0 ) { mbedtls_strerror( ret, buf, 1024 ); mbedtls_printf( " failed\n ! mbedtls_x509_crt_parse_file returned -0x%02x - %s\n\n", -ret, buf ); goto exit; } ret = mbedtls_x509_dn_gets( issuer_name, sizeof(issuer_name), &issuer_crt.subject ); if( ret < 0 ) { mbedtls_strerror( ret, buf, 1024 ); mbedtls_printf( " failed\n ! mbedtls_x509_dn_gets returned -0x%02x - %s\n\n", -ret, buf ); goto exit; } opt.issuer_name = issuer_name; mbedtls_printf( " ok\n" ); } #if defined(MBEDTLS_X509_CSR_PARSE_C) // Parse certificate request if present // if( !opt.selfsign && strlen( opt.request_file ) ) { /* * 1.0.b. Load the CSR */ mbedtls_printf( " . Loading the certificate request ..." ); fflush( stdout ); if( ( ret = mbedtls_x509_csr_parse_file( &csr, opt.request_file ) ) != 0 ) { mbedtls_strerror( ret, buf, 1024 ); mbedtls_printf( " failed\n ! mbedtls_x509_csr_parse_file returned -0x%02x - %s\n\n", -ret, buf ); goto exit; } ret = mbedtls_x509_dn_gets( subject_name, sizeof(subject_name), &csr.subject ); if( ret < 0 ) { mbedtls_strerror( ret, buf, 1024 ); mbedtls_printf( " failed\n ! mbedtls_x509_dn_gets returned -0x%02x - %s\n\n", -ret, buf ); goto exit; } opt.subject_name = subject_name; subject_key = &csr.pk; mbedtls_printf( " ok\n" ); } #endif /* MBEDTLS_X509_CSR_PARSE_C */ /* * 1.1. Load the keys */ if( !opt.selfsign && !strlen( opt.request_file ) ) { mbedtls_printf( " . Loading the subject key ..." ); fflush( stdout ); ret = mbedtls_pk_parse_keyfile( &loaded_subject_key, opt.subject_key, opt.subject_pwd ); if( ret != 0 ) { mbedtls_strerror( ret, buf, 1024 ); mbedtls_printf( " failed\n ! mbedtls_pk_parse_keyfile returned -0x%02x - %s\n\n", -ret, buf ); goto exit; } mbedtls_printf( " ok\n" ); } mbedtls_printf( " . Loading the issuer key ..." ); fflush( stdout ); ret = mbedtls_pk_parse_keyfile( &loaded_issuer_key, opt.issuer_key, opt.issuer_pwd ); if( ret != 0 ) { mbedtls_strerror( ret, buf, 1024 ); mbedtls_printf( " failed\n ! mbedtls_pk_parse_keyfile returned -x%02x - %s\n\n", -ret, buf ); goto exit; } // Check if key and issuer certificate match // if( strlen( opt.issuer_crt ) ) { if( !mbedtls_pk_can_do( &issuer_crt.pk, MBEDTLS_PK_RSA ) || mbedtls_mpi_cmp_mpi( &mbedtls_pk_rsa( issuer_crt.pk )->N, &mbedtls_pk_rsa( *issuer_key )->N ) != 0 || mbedtls_mpi_cmp_mpi( &mbedtls_pk_rsa( issuer_crt.pk )->E, &mbedtls_pk_rsa( *issuer_key )->E ) != 0 ) { mbedtls_printf( " failed\n ! issuer_key does not match issuer certificate\n\n" ); ret = -1; goto exit; } } mbedtls_printf( " ok\n" ); if( opt.selfsign ) { opt.subject_name = opt.issuer_name; subject_key = issuer_key; } mbedtls_x509write_crt_set_subject_key( &crt, subject_key ); mbedtls_x509write_crt_set_issuer_key( &crt, issuer_key ); /* * 1.0. Check the names for validity */ if( ( ret = mbedtls_x509write_crt_set_subject_name( &crt, opt.subject_name ) ) != 0 ) { mbedtls_strerror( ret, buf, 1024 ); mbedtls_printf( " failed\n ! mbedtls_x509write_crt_set_subject_name returned -0x%02x - %s\n\n", -ret, buf ); goto exit; } if( ( ret = mbedtls_x509write_crt_set_issuer_name( &crt, opt.issuer_name ) ) != 0 ) { mbedtls_strerror( ret, buf, 1024 ); mbedtls_printf( " failed\n ! mbedtls_x509write_crt_set_issuer_name returned -0x%02x - %s\n\n", -ret, buf ); goto exit; } mbedtls_printf( " . Setting certificate values ..." ); fflush( stdout ); ret = mbedtls_x509write_crt_set_serial( &crt, &serial ); if( ret != 0 ) { mbedtls_strerror( ret, buf, 1024 ); mbedtls_printf( " failed\n ! mbedtls_x509write_crt_set_serial returned -0x%02x - %s\n\n", -ret, buf ); goto exit; } ret = mbedtls_x509write_crt_set_validity( &crt, opt.not_before, opt.not_after ); if( ret != 0 ) { mbedtls_strerror( ret, buf, 1024 ); mbedtls_printf( " failed\n ! mbedtls_x509write_crt_set_validity returned -0x%02x - %s\n\n", -ret, buf ); goto exit; } mbedtls_printf( " ok\n" ); mbedtls_printf( " . Adding the Basic Constraints extension ..." ); fflush( stdout ); ret = mbedtls_x509write_crt_set_basic_constraints( &crt, opt.is_ca, opt.max_pathlen ); if( ret != 0 ) { mbedtls_strerror( ret, buf, 1024 ); mbedtls_printf( " failed\n ! x509write_crt_set_basic_contraints returned -0x%02x - %s\n\n", -ret, buf ); goto exit; } mbedtls_printf( " ok\n" ); #if defined(MBEDTLS_SHA1_C) mbedtls_printf( " . Adding the Subject Key Identifier ..." ); fflush( stdout ); ret = mbedtls_x509write_crt_set_subject_key_identifier( &crt ); if( ret != 0 ) { mbedtls_strerror( ret, buf, 1024 ); mbedtls_printf( " failed\n ! mbedtls_x509write_crt_set_subject_key_identifier returned -0x%02x - %s\n\n", -ret, buf ); goto exit; } mbedtls_printf( " ok\n" ); mbedtls_printf( " . Adding the Authority Key Identifier ..." ); fflush( stdout ); ret = mbedtls_x509write_crt_set_authority_key_identifier( &crt ); if( ret != 0 ) { mbedtls_strerror( ret, buf, 1024 ); mbedtls_printf( " failed\n ! mbedtls_x509write_crt_set_authority_key_identifier returned -0x%02x - %s\n\n", -ret, buf ); goto exit; } mbedtls_printf( " ok\n" ); #endif /* MBEDTLS_SHA1_C */ if( opt.key_usage ) { mbedtls_printf( " . Adding the Key Usage extension ..." ); fflush( stdout ); ret = mbedtls_x509write_crt_set_key_usage( &crt, opt.key_usage ); if( ret != 0 ) { mbedtls_strerror( ret, buf, 1024 ); mbedtls_printf( " failed\n ! mbedtls_x509write_crt_set_key_usage returned -0x%02x - %s\n\n", -ret, buf ); goto exit; } mbedtls_printf( " ok\n" ); } if( opt.ns_cert_type ) { mbedtls_printf( " . Adding the NS Cert Type extension ..." ); fflush( stdout ); ret = mbedtls_x509write_crt_set_ns_cert_type( &crt, opt.ns_cert_type ); if( ret != 0 ) { mbedtls_strerror( ret, buf, 1024 ); mbedtls_printf( " failed\n ! mbedtls_x509write_crt_set_ns_cert_type returned -0x%02x - %s\n\n", -ret, buf ); goto exit; } mbedtls_printf( " ok\n" ); } /* * 1.2. Writing the request */ mbedtls_printf( " . Writing the certificate..." ); fflush( stdout ); if( ( ret = write_certificate( &crt, opt.output_file, mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 ) { mbedtls_strerror( ret, buf, 1024 ); mbedtls_printf( " failed\n ! write_certifcate -0x%02x - %s\n\n", -ret, buf ); goto exit; } mbedtls_printf( " ok\n" ); exit: mbedtls_x509write_crt_free( &crt ); mbedtls_pk_free( &loaded_subject_key ); mbedtls_pk_free( &loaded_issuer_key ); mbedtls_mpi_free( &serial ); mbedtls_ctr_drbg_free( &ctr_drbg ); mbedtls_entropy_free( &entropy ); #if defined(_WIN32) mbedtls_printf( " + Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif return( ret ); }
int main( int argc, char *argv[] ) { int i; unsigned char tmp[200]; char title[TITLE_LEN]; todo_list todo; #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) unsigned char alloc_buf[HEAP_SIZE] = { 0 }; #endif if( argc <= 1 ) { memset( &todo, 1, sizeof( todo ) ); } else { memset( &todo, 0, sizeof( todo ) ); for( i = 1; i < argc; i++ ) { if( strcmp( argv[i], "md4" ) == 0 ) todo.md4 = 1; else if( strcmp( argv[i], "md5" ) == 0 ) todo.md5 = 1; else if( strcmp( argv[i], "ripemd160" ) == 0 ) todo.ripemd160 = 1; else if( strcmp( argv[i], "sha1" ) == 0 ) todo.sha1 = 1; else if( strcmp( argv[i], "sha256" ) == 0 ) todo.sha256 = 1; else if( strcmp( argv[i], "sha512" ) == 0 ) todo.sha512 = 1; else if( strcmp( argv[i], "arc4" ) == 0 ) todo.arc4 = 1; else if( strcmp( argv[i], "des3" ) == 0 ) todo.des3 = 1; else if( strcmp( argv[i], "des" ) == 0 ) todo.des = 1; else if( strcmp( argv[i], "aes_cbc" ) == 0 ) todo.aes_cbc = 1; else if( strcmp( argv[i], "aes_gcm" ) == 0 ) todo.aes_gcm = 1; else if( strcmp( argv[i], "aes_ccm" ) == 0 ) todo.aes_ccm = 1; else if( strcmp( argv[i], "aes_cmac" ) == 0 ) todo.aes_cmac = 1; else if( strcmp( argv[i], "des3_cmac" ) == 0 ) todo.des3_cmac = 1; else if( strcmp( argv[i], "camellia" ) == 0 ) todo.camellia = 1; else if( strcmp( argv[i], "blowfish" ) == 0 ) todo.blowfish = 1; else if( strcmp( argv[i], "havege" ) == 0 ) todo.havege = 1; else if( strcmp( argv[i], "ctr_drbg" ) == 0 ) todo.ctr_drbg = 1; else if( strcmp( argv[i], "hmac_drbg" ) == 0 ) todo.hmac_drbg = 1; else if( strcmp( argv[i], "rsa" ) == 0 ) todo.rsa = 1; else if( strcmp( argv[i], "dhm" ) == 0 ) todo.dhm = 1; else if( strcmp( argv[i], "ecdsa" ) == 0 ) todo.ecdsa = 1; else if( strcmp( argv[i], "ecdh" ) == 0 ) todo.ecdh = 1; else { mbedtls_printf( "Unrecognized option: %s\n", argv[i] ); mbedtls_printf( "Available options: " OPTIONS ); } } } mbedtls_printf( "\n" ); #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof( alloc_buf ) ); #endif memset( buf, 0xAA, sizeof( buf ) ); memset( tmp, 0xBB, sizeof( tmp ) ); #if defined(MBEDTLS_MD4_C) if( todo.md4 ) TIME_AND_TSC( "MD4", mbedtls_md4_ret( buf, BUFSIZE, tmp ) ); #endif #if defined(MBEDTLS_MD5_C) if( todo.md5 ) TIME_AND_TSC( "MD5", mbedtls_md5_ret( buf, BUFSIZE, tmp ) ); #endif #if defined(MBEDTLS_RIPEMD160_C) if( todo.ripemd160 ) TIME_AND_TSC( "RIPEMD160", mbedtls_ripemd160_ret( buf, BUFSIZE, tmp ) ); #endif #if defined(MBEDTLS_SHA1_C) if( todo.sha1 ) TIME_AND_TSC( "SHA-1", mbedtls_sha1_ret( buf, BUFSIZE, tmp ) ); #endif #if defined(MBEDTLS_SHA256_C) if( todo.sha256 ) TIME_AND_TSC( "SHA-256", mbedtls_sha256_ret( buf, BUFSIZE, tmp, 0 ) ); #endif #if defined(MBEDTLS_SHA512_C) if( todo.sha512 ) TIME_AND_TSC( "SHA-512", mbedtls_sha512_ret( buf, BUFSIZE, tmp, 0 ) ); #endif #if defined(MBEDTLS_ARC4_C) if( todo.arc4 ) { mbedtls_arc4_context arc4; mbedtls_arc4_init( &arc4 ); mbedtls_arc4_setup( &arc4, tmp, 32 ); TIME_AND_TSC( "ARC4", mbedtls_arc4_crypt( &arc4, BUFSIZE, buf, buf ) ); mbedtls_arc4_free( &arc4 ); } #endif #if defined(MBEDTLS_DES_C) #if defined(MBEDTLS_CIPHER_MODE_CBC) if( todo.des3 ) { mbedtls_des3_context des3; mbedtls_des3_init( &des3 ); mbedtls_des3_set3key_enc( &des3, tmp ); TIME_AND_TSC( "3DES", mbedtls_des3_crypt_cbc( &des3, MBEDTLS_DES_ENCRYPT, BUFSIZE, tmp, buf, buf ) ); mbedtls_des3_free( &des3 ); } if( todo.des ) { mbedtls_des_context des; mbedtls_des_init( &des ); mbedtls_des_setkey_enc( &des, tmp ); TIME_AND_TSC( "DES", mbedtls_des_crypt_cbc( &des, MBEDTLS_DES_ENCRYPT, BUFSIZE, tmp, buf, buf ) ); mbedtls_des_free( &des ); } #endif /* MBEDTLS_CIPHER_MODE_CBC */ #if defined(MBEDTLS_CMAC_C) if( todo.des3_cmac ) { unsigned char output[8]; const mbedtls_cipher_info_t *cipher_info; memset( buf, 0, sizeof( buf ) ); memset( tmp, 0, sizeof( tmp ) ); cipher_info = mbedtls_cipher_info_from_type( MBEDTLS_CIPHER_DES_EDE3_ECB ); TIME_AND_TSC( "3DES-CMAC", mbedtls_cipher_cmac( cipher_info, tmp, 192, buf, BUFSIZE, output ) ); } #endif /* MBEDTLS_CMAC_C */ #endif /* MBEDTLS_DES_C */ #if defined(MBEDTLS_AES_C) #if defined(MBEDTLS_CIPHER_MODE_CBC) if( todo.aes_cbc ) { int keysize; mbedtls_aes_context aes; mbedtls_aes_init( &aes ); for( keysize = 128; keysize <= 256; keysize += 64 ) { mbedtls_snprintf( title, sizeof( title ), "AES-CBC-%d", keysize ); memset( buf, 0, sizeof( buf ) ); memset( tmp, 0, sizeof( tmp ) ); mbedtls_aes_setkey_enc( &aes, tmp, keysize ); TIME_AND_TSC( title, mbedtls_aes_crypt_cbc( &aes, MBEDTLS_AES_ENCRYPT, BUFSIZE, tmp, buf, buf ) ); } mbedtls_aes_free( &aes ); } #endif #if defined(MBEDTLS_GCM_C) if( todo.aes_gcm ) { int keysize; mbedtls_gcm_context gcm; mbedtls_gcm_init( &gcm ); for( keysize = 128; keysize <= 256; keysize += 64 ) { mbedtls_snprintf( title, sizeof( title ), "AES-GCM-%d", keysize ); memset( buf, 0, sizeof( buf ) ); memset( tmp, 0, sizeof( tmp ) ); mbedtls_gcm_setkey( &gcm, MBEDTLS_CIPHER_ID_AES, tmp, keysize ); TIME_AND_TSC( title, mbedtls_gcm_crypt_and_tag( &gcm, MBEDTLS_GCM_ENCRYPT, BUFSIZE, tmp, 12, NULL, 0, buf, buf, 16, tmp ) ); mbedtls_gcm_free( &gcm ); } } #endif #if defined(MBEDTLS_CCM_C) if( todo.aes_ccm ) { int keysize; mbedtls_ccm_context ccm; mbedtls_ccm_init( &ccm ); for( keysize = 128; keysize <= 256; keysize += 64 ) { mbedtls_snprintf( title, sizeof( title ), "AES-CCM-%d", keysize ); memset( buf, 0, sizeof( buf ) ); memset( tmp, 0, sizeof( tmp ) ); mbedtls_ccm_setkey( &ccm, MBEDTLS_CIPHER_ID_AES, tmp, keysize ); TIME_AND_TSC( title, mbedtls_ccm_encrypt_and_tag( &ccm, BUFSIZE, tmp, 12, NULL, 0, buf, buf, tmp, 16 ) ); mbedtls_ccm_free( &ccm ); } } #endif #if defined(MBEDTLS_CMAC_C) if( todo.aes_cmac ) { unsigned char output[16]; const mbedtls_cipher_info_t *cipher_info; mbedtls_cipher_type_t cipher_type; int keysize; for( keysize = 128, cipher_type = MBEDTLS_CIPHER_AES_128_ECB; keysize <= 256; keysize += 64, cipher_type++ ) { mbedtls_snprintf( title, sizeof( title ), "AES-CMAC-%d", keysize ); memset( buf, 0, sizeof( buf ) ); memset( tmp, 0, sizeof( tmp ) ); cipher_info = mbedtls_cipher_info_from_type( cipher_type ); TIME_AND_TSC( title, mbedtls_cipher_cmac( cipher_info, tmp, keysize, buf, BUFSIZE, output ) ); } memset( buf, 0, sizeof( buf ) ); memset( tmp, 0, sizeof( tmp ) ); TIME_AND_TSC( "AES-CMAC-PRF-128", mbedtls_aes_cmac_prf_128( tmp, 16, buf, BUFSIZE, output ) ); } #endif /* MBEDTLS_CMAC_C */ #endif /* MBEDTLS_AES_C */ #if defined(MBEDTLS_CAMELLIA_C) && defined(MBEDTLS_CIPHER_MODE_CBC) if( todo.camellia ) { int keysize; mbedtls_camellia_context camellia; mbedtls_camellia_init( &camellia ); for( keysize = 128; keysize <= 256; keysize += 64 ) { mbedtls_snprintf( title, sizeof( title ), "CAMELLIA-CBC-%d", keysize ); memset( buf, 0, sizeof( buf ) ); memset( tmp, 0, sizeof( tmp ) ); mbedtls_camellia_setkey_enc( &camellia, tmp, keysize ); TIME_AND_TSC( title, mbedtls_camellia_crypt_cbc( &camellia, MBEDTLS_CAMELLIA_ENCRYPT, BUFSIZE, tmp, buf, buf ) ); } mbedtls_camellia_free( &camellia ); } #endif #if defined(MBEDTLS_BLOWFISH_C) && defined(MBEDTLS_CIPHER_MODE_CBC) if( todo.blowfish ) { int keysize; mbedtls_blowfish_context blowfish; mbedtls_blowfish_init( &blowfish ); for( keysize = 128; keysize <= 256; keysize += 64 ) { mbedtls_snprintf( title, sizeof( title ), "BLOWFISH-CBC-%d", keysize ); memset( buf, 0, sizeof( buf ) ); memset( tmp, 0, sizeof( tmp ) ); mbedtls_blowfish_setkey( &blowfish, tmp, keysize ); TIME_AND_TSC( title, mbedtls_blowfish_crypt_cbc( &blowfish, MBEDTLS_BLOWFISH_ENCRYPT, BUFSIZE, tmp, buf, buf ) ); } mbedtls_blowfish_free( &blowfish ); } #endif #if defined(MBEDTLS_HAVEGE_C) if( todo.havege ) { mbedtls_havege_state hs; mbedtls_havege_init( &hs ); TIME_AND_TSC( "HAVEGE", mbedtls_havege_random( &hs, buf, BUFSIZE ) ); mbedtls_havege_free( &hs ); } #endif #if defined(MBEDTLS_CTR_DRBG_C) if( todo.ctr_drbg ) { mbedtls_ctr_drbg_context ctr_drbg; mbedtls_ctr_drbg_init( &ctr_drbg ); if( mbedtls_ctr_drbg_seed( &ctr_drbg, myrand, NULL, NULL, 0 ) != 0 ) mbedtls_exit(1); TIME_AND_TSC( "CTR_DRBG (NOPR)", if( mbedtls_ctr_drbg_random( &ctr_drbg, buf, BUFSIZE ) != 0 ) mbedtls_exit(1) ); if( mbedtls_ctr_drbg_seed( &ctr_drbg, myrand, NULL, NULL, 0 ) != 0 ) mbedtls_exit(1); mbedtls_ctr_drbg_set_prediction_resistance( &ctr_drbg, MBEDTLS_CTR_DRBG_PR_ON ); TIME_AND_TSC( "CTR_DRBG (PR)", if( mbedtls_ctr_drbg_random( &ctr_drbg, buf, BUFSIZE ) != 0 ) mbedtls_exit(1) ); mbedtls_ctr_drbg_free( &ctr_drbg ); }
int main( void ) { int ret, len, written; mbedtls_net_context server_fd; unsigned char buf[1024]; const char *pers = "pinning_client"; /* XXX create some state for our verify callback */ struct vrfy_state vrfy_state = { .pins = pins, }; mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; mbedtls_ssl_context ssl; mbedtls_ssl_config conf; mbedtls_x509_crt cacert; /* Ensure valid memory references */ mbedtls_net_init( &server_fd ); mbedtls_ssl_init( &ssl ); mbedtls_ssl_config_init( &conf ); mbedtls_x509_crt_init( &cacert ); mbedtls_ctr_drbg_init( &ctr_drbg ); mbedtls_entropy_init( &entropy ); /* * 0. Initialize the RNG and the session data */ mbedtls_printf( "\n . Seeding the random number generator..." ); fflush( stdout ); if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) pers, strlen( pers ) ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret ); goto exit; } mbedtls_printf( " ok\n" ); /* * 1. Load certificates */ mbedtls_printf( " . Loading the CA root certificate ..." ); fflush( stdout ); ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_cas_pem, mbedtls_test_cas_pem_len ); if( ret < 0 ) { mbedtls_printf( " failed\n ! mbedtls_x509_crt_parse returned -0x%x\n\n", -ret ); goto exit; } mbedtls_printf( " ok (%d skipped)\n", ret ); /* * 2. Start the TCP connection */ mbedtls_printf( " . Connecting to tcp/%s/%s...", SERVER_NAME, SERVER_PORT ); fflush( stdout ); if( ( ret = mbedtls_net_connect( &server_fd, SERVER_NAME, SERVER_PORT, MBEDTLS_NET_PROTO_TCP ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_net_connect returned %d\n\n", ret ); goto exit; } mbedtls_printf( " ok\n" ); /* * 3. Setup SSL/TSL stuff */ mbedtls_printf( " . Setting up the SSL/TLS structure..." ); fflush( stdout ); if( ( ret = mbedtls_ssl_config_defaults( &conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ssl_config_defaults returned %d\n\n", ret ); goto exit; } #if defined(MBEDTLS_DEBUG_C) mbedtls_debug_set_threshold( DEBUG_LEVEL ); #endif mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL ); mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg ); mbedtls_ssl_conf_dbg( &conf, my_debug, stdout ); /* XXX: register our certificate verification callback */ mbedtls_ssl_conf_verify( &conf, my_verify, &vrfy_state ); if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ssl_setup returned %d\n\n", ret ); goto exit; } if( ( ret = mbedtls_ssl_set_hostname( &ssl, SERVER_NAME ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", ret ); goto exit; } mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL ); mbedtls_printf( " ok\n" ); /* * 4. Handshake */ mbedtls_printf( " . Performing the SSL/TLS handshake..." ); fflush( stdout ); while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 ) { if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE ) { mbedtls_printf( " failed\n ! mbedtls_ssl_handshake returned -0x%x\n\n", -ret ); goto exit; } } mbedtls_printf( " ok\n" ); /* * 5. Write request */ mbedtls_printf( " > Write to server:" ); fflush( stdout ); len = snprintf( (char *) buf, sizeof( buf ), GET_REQUEST ); if( len < 0 || (size_t) len > sizeof( buf ) ) { mbedtls_printf( " failed\n ! buffer too small for request\n\n" ); goto exit; } for( written = 0; written < len; written += ret ) { while( ( ret = mbedtls_ssl_write( &ssl, buf + written, len - written ) ) <= 0 ) { if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE ) { mbedtls_printf( " failed\n ! mbedtls_ssl_write returned -0x%x\n\n", -ret ); goto exit; } } } mbedtls_printf( " %d bytes written\n\n%s", written, (char *) buf ); /* * 6. Read the HTTP response */ mbedtls_printf( " < Read from server:" ); fflush( stdout ); do { len = sizeof( buf ) - 1; memset( buf, 0, sizeof( buf ) ); ret = mbedtls_ssl_read( &ssl, buf, len ); if( ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE ) continue; if( ret <= 0 ) { switch( ret ) { case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: mbedtls_printf( " connection was closed gracefully\n" ); ret = 0; goto close_notify; case 0: case MBEDTLS_ERR_NET_CONN_RESET: mbedtls_printf( " connection was reset by peer\n" ); ret = 0; goto exit; default: mbedtls_printf( " mbedtls_ssl_read returned -0x%x\n", -ret ); goto exit; } } len = ret; buf[len] = '\0'; mbedtls_printf( " %d bytes read\n\n%s", len, (char *) buf ); /* End of message should be detected according to the syntax of the * application protocol (eg HTTP), just use a dummy test here. */ if( ret > 0 && buf[len-1] == '\n' ) { ret = 0; break; } } while( 1 ); /* * 8. Done, cleanly close the connection */ close_notify: mbedtls_printf( " . Closing the connection..." ); fflush( stdout ); /* No error checking, the connection might be closed already */ do ret = mbedtls_ssl_close_notify( &ssl ); while( ret == MBEDTLS_ERR_SSL_WANT_WRITE ); ret = 0; mbedtls_printf( " done\n" ); exit: #ifdef MBEDTLS_ERROR_C if( ret != 0 ) { char error_buf[100]; mbedtls_strerror( ret, error_buf, 100 ); mbedtls_printf("Last error was: %d - %s\n\n", ret, error_buf ); } #endif mbedtls_net_free( &server_fd ); mbedtls_x509_crt_free( &cacert ); mbedtls_ssl_free( &ssl ); mbedtls_ssl_config_free( &conf ); mbedtls_ctr_drbg_free( &ctr_drbg ); mbedtls_entropy_free( &entropy ); #if defined(_WIN32) mbedtls_printf( " + Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif return( ret != 0 ); }
int main( int argc, char *argv[] ) { int ret = 0, len; mbedtls_net_context server_fd; unsigned char buf[1024]; #if defined(MBEDTLS_BASE64_C) unsigned char base[1024]; #endif char hostname[32]; const char *pers = "ssl_mail_client"; mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; mbedtls_ssl_context ssl; mbedtls_ssl_config conf; mbedtls_x509_crt cacert; mbedtls_x509_crt clicert; mbedtls_pk_context pkey; int i; size_t n; char *p, *q; const int *list; /* * Make sure memory references are valid in case we exit early. */ mbedtls_net_init( &server_fd ); mbedtls_ssl_init( &ssl ); mbedtls_ssl_config_init( &conf ); memset( &buf, 0, sizeof( buf ) ); mbedtls_x509_crt_init( &cacert ); mbedtls_x509_crt_init( &clicert ); mbedtls_pk_init( &pkey ); mbedtls_ctr_drbg_init( &ctr_drbg ); if( argc == 0 ) { usage: mbedtls_printf( USAGE ); list = mbedtls_ssl_list_ciphersuites(); while( *list ) { mbedtls_printf(" %s\n", mbedtls_ssl_get_ciphersuite_name( *list ) ); list++; } mbedtls_printf("\n"); goto exit; } opt.server_name = DFL_SERVER_NAME; opt.server_port = DFL_SERVER_PORT; opt.debug_level = DFL_DEBUG_LEVEL; opt.authentication = DFL_AUTHENTICATION; opt.mode = DFL_MODE; opt.user_name = DFL_USER_NAME; opt.user_pwd = DFL_USER_PWD; opt.mail_from = DFL_MAIL_FROM; opt.mail_to = DFL_MAIL_TO; opt.ca_file = DFL_CA_FILE; opt.crt_file = DFL_CRT_FILE; opt.key_file = DFL_KEY_FILE; opt.force_ciphersuite[0]= DFL_FORCE_CIPHER; for( i = 1; i < argc; i++ ) { p = argv[i]; if( ( q = strchr( p, '=' ) ) == NULL ) goto usage; *q++ = '\0'; if( strcmp( p, "server_name" ) == 0 ) opt.server_name = q; else if( strcmp( p, "server_port" ) == 0 ) opt.server_port = q; else if( strcmp( p, "debug_level" ) == 0 ) { opt.debug_level = atoi( q ); if( opt.debug_level < 0 || opt.debug_level > 65535 ) goto usage; } else if( strcmp( p, "authentication" ) == 0 ) { opt.authentication = atoi( q ); if( opt.authentication < 0 || opt.authentication > 1 ) goto usage; } else if( strcmp( p, "mode" ) == 0 ) { opt.mode = atoi( q ); if( opt.mode < 0 || opt.mode > 1 ) goto usage; } else if( strcmp( p, "user_name" ) == 0 ) opt.user_name = q; else if( strcmp( p, "user_pwd" ) == 0 ) opt.user_pwd = q; else if( strcmp( p, "mail_from" ) == 0 ) opt.mail_from = q; else if( strcmp( p, "mail_to" ) == 0 ) opt.mail_to = q; else if( strcmp( p, "ca_file" ) == 0 ) opt.ca_file = q; else if( strcmp( p, "crt_file" ) == 0 ) opt.crt_file = q; else if( strcmp( p, "key_file" ) == 0 ) opt.key_file = q; else if( strcmp( p, "force_ciphersuite" ) == 0 ) { opt.force_ciphersuite[0] = -1; opt.force_ciphersuite[0] = mbedtls_ssl_get_ciphersuite_id( q ); if( opt.force_ciphersuite[0] <= 0 ) goto usage; opt.force_ciphersuite[1] = 0; } else goto usage; } /* * 0. Initialize the RNG and the session data */ mbedtls_printf( "\n . Seeding the random number generator..." ); fflush( stdout ); mbedtls_entropy_init( &entropy ); if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) pers, strlen( pers ) ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret ); goto exit; } mbedtls_printf( " ok\n" ); /* * 1.1. Load the trusted CA */ mbedtls_printf( " . Loading the CA root certificate ..." ); fflush( stdout ); #if defined(MBEDTLS_FS_IO) if( strlen( opt.ca_file ) ) ret = mbedtls_x509_crt_parse_file( &cacert, opt.ca_file ); else #endif #if defined(MBEDTLS_CERTS_C) ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_cas_pem, mbedtls_test_cas_pem_len ); #else { ret = 1; mbedtls_printf("MBEDTLS_CERTS_C not defined."); } #endif if( ret < 0 ) { mbedtls_printf( " failed\n ! mbedtls_x509_crt_parse returned %d\n\n", ret ); goto exit; } mbedtls_printf( " ok (%d skipped)\n", ret ); /* * 1.2. Load own certificate and private key * * (can be skipped if client authentication is not required) */ mbedtls_printf( " . Loading the client cert. and key..." ); fflush( stdout ); #if defined(MBEDTLS_FS_IO) if( strlen( opt.crt_file ) ) ret = mbedtls_x509_crt_parse_file( &clicert, opt.crt_file ); else #endif #if defined(MBEDTLS_CERTS_C) ret = mbedtls_x509_crt_parse( &clicert, (const unsigned char *) mbedtls_test_cli_crt, mbedtls_test_cli_crt_len ); #else { ret = -1; mbedtls_printf("MBEDTLS_CERTS_C not defined."); } #endif if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_x509_crt_parse returned %d\n\n", ret ); goto exit; } #if defined(MBEDTLS_FS_IO) if( strlen( opt.key_file ) ) ret = mbedtls_pk_parse_keyfile( &pkey, opt.key_file, "" ); else #endif #if defined(MBEDTLS_CERTS_C) && defined(MBEDTLS_PEM_PARSE_C) ret = mbedtls_pk_parse_key( &pkey, (const unsigned char *) mbedtls_test_cli_key, mbedtls_test_cli_key_len, NULL, 0 ); #else { ret = -1; mbedtls_printf("MBEDTLS_CERTS_C or MBEDTLS_PEM_PARSE_C not defined."); } #endif if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_pk_parse_key returned %d\n\n", ret ); goto exit; } mbedtls_printf( " ok\n" ); /* * 2. Start the connection */ mbedtls_printf( " . Connecting to tcp/%s/%s...", opt.server_name, opt.server_port ); fflush( stdout ); if( ( ret = mbedtls_net_connect( &server_fd, opt.server_name, opt.server_port, MBEDTLS_NET_PROTO_TCP ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_net_connect returned %d\n\n", ret ); goto exit; } mbedtls_printf( " ok\n" ); /* * 3. Setup stuff */ mbedtls_printf( " . Setting up the SSL/TLS structure..." ); fflush( stdout ); if( ( ret = mbedtls_ssl_config_defaults( &conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ssl_config_defaults returned %d\n\n", ret ); goto exit; } /* OPTIONAL is not optimal for security, * but makes interop easier in this simplified example */ mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_OPTIONAL ); mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg ); mbedtls_ssl_conf_dbg( &conf, my_debug, stdout ); if( opt.force_ciphersuite[0] != DFL_FORCE_CIPHER ) mbedtls_ssl_conf_ciphersuites( &conf, opt.force_ciphersuite ); mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL ); if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &clicert, &pkey ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret ); goto exit; } if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ssl_setup returned %d\n\n", ret ); goto exit; } if( ( ret = mbedtls_ssl_set_hostname( &ssl, opt.server_name ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", ret ); goto exit; } mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL ); mbedtls_printf( " ok\n" ); if( opt.mode == MODE_SSL_TLS ) { if( do_handshake( &ssl ) != 0 ) goto exit; mbedtls_printf( " > Get header from server:" ); fflush( stdout ); ret = write_ssl_and_get_response( &ssl, buf, 0 ); if( ret < 200 || ret > 299 ) { mbedtls_printf( " failed\n ! server responded with %d\n\n", ret ); goto exit; } mbedtls_printf(" ok\n" ); mbedtls_printf( " > Write EHLO to server:" ); fflush( stdout ); gethostname( hostname, 32 ); len = sprintf( (char *) buf, "EHLO %s\r\n", hostname ); ret = write_ssl_and_get_response( &ssl, buf, len ); if( ret < 200 || ret > 299 ) { mbedtls_printf( " failed\n ! server responded with %d\n\n", ret ); goto exit; } } else { mbedtls_printf( " > Get header from server:" ); fflush( stdout ); ret = write_and_get_response( &server_fd, buf, 0 ); if( ret < 200 || ret > 299 ) { mbedtls_printf( " failed\n ! server responded with %d\n\n", ret ); goto exit; } mbedtls_printf(" ok\n" ); mbedtls_printf( " > Write EHLO to server:" ); fflush( stdout ); gethostname( hostname, 32 ); len = sprintf( (char *) buf, "EHLO %s\r\n", hostname ); ret = write_and_get_response( &server_fd, buf, len ); if( ret < 200 || ret > 299 ) { mbedtls_printf( " failed\n ! server responded with %d\n\n", ret ); goto exit; } mbedtls_printf(" ok\n" ); mbedtls_printf( " > Write STARTTLS to server:" ); fflush( stdout ); gethostname( hostname, 32 ); len = sprintf( (char *) buf, "STARTTLS\r\n" ); ret = write_and_get_response( &server_fd, buf, len ); if( ret < 200 || ret > 299 ) { mbedtls_printf( " failed\n ! server responded with %d\n\n", ret ); goto exit; } mbedtls_printf(" ok\n" ); if( do_handshake( &ssl ) != 0 ) goto exit; } #if defined(MBEDTLS_BASE64_C) if( opt.authentication ) { mbedtls_printf( " > Write AUTH LOGIN to server:" ); fflush( stdout ); len = sprintf( (char *) buf, "AUTH LOGIN\r\n" ); ret = write_ssl_and_get_response( &ssl, buf, len ); if( ret < 200 || ret > 399 ) { mbedtls_printf( " failed\n ! server responded with %d\n\n", ret ); goto exit; } mbedtls_printf(" ok\n" ); mbedtls_printf( " > Write username to server: %s", opt.user_name ); fflush( stdout ); ret = mbedtls_base64_encode( base, sizeof( base ), &n, (const unsigned char *) opt.user_name, strlen( opt.user_name ) ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_base64_encode returned %d\n\n", ret ); goto exit; } len = sprintf( (char *) buf, "%s\r\n", base ); ret = write_ssl_and_get_response( &ssl, buf, len ); if( ret < 300 || ret > 399 ) { mbedtls_printf( " failed\n ! server responded with %d\n\n", ret ); goto exit; } mbedtls_printf(" ok\n" ); mbedtls_printf( " > Write password to server: %s", opt.user_pwd ); fflush( stdout ); ret = mbedtls_base64_encode( base, sizeof( base ), &n, (const unsigned char *) opt.user_pwd, strlen( opt.user_pwd ) ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_base64_encode returned %d\n\n", ret ); goto exit; } len = sprintf( (char *) buf, "%s\r\n", base ); ret = write_ssl_and_get_response( &ssl, buf, len ); if( ret < 200 || ret > 399 ) { mbedtls_printf( " failed\n ! server responded with %d\n\n", ret ); goto exit; } mbedtls_printf(" ok\n" ); } #endif mbedtls_printf( " > Write MAIL FROM to server:" ); fflush( stdout ); len = sprintf( (char *) buf, "MAIL FROM:<%s>\r\n", opt.mail_from ); ret = write_ssl_and_get_response( &ssl, buf, len ); if( ret < 200 || ret > 299 ) { mbedtls_printf( " failed\n ! server responded with %d\n\n", ret ); goto exit; } mbedtls_printf(" ok\n" ); mbedtls_printf( " > Write RCPT TO to server:" ); fflush( stdout ); len = sprintf( (char *) buf, "RCPT TO:<%s>\r\n", opt.mail_to ); ret = write_ssl_and_get_response( &ssl, buf, len ); if( ret < 200 || ret > 299 ) { mbedtls_printf( " failed\n ! server responded with %d\n\n", ret ); goto exit; } mbedtls_printf(" ok\n" ); mbedtls_printf( " > Write DATA to server:" ); fflush( stdout ); len = sprintf( (char *) buf, "DATA\r\n" ); ret = write_ssl_and_get_response( &ssl, buf, len ); if( ret < 300 || ret > 399 ) { mbedtls_printf( " failed\n ! server responded with %d\n\n", ret ); goto exit; } mbedtls_printf(" ok\n" ); mbedtls_printf( " > Write content to server:" ); fflush( stdout ); len = sprintf( (char *) buf, "From: %s\r\nSubject: mbed TLS Test mail\r\n\r\n" "This is a simple test mail from the " "mbed TLS mail client example.\r\n" "\r\n" "Enjoy!", opt.mail_from ); ret = write_ssl_data( &ssl, buf, len ); len = sprintf( (char *) buf, "\r\n.\r\n"); ret = write_ssl_and_get_response( &ssl, buf, len ); if( ret < 200 || ret > 299 ) { mbedtls_printf( " failed\n ! server responded with %d\n\n", ret ); goto exit; } mbedtls_printf(" ok\n" ); mbedtls_ssl_close_notify( &ssl ); exit: mbedtls_net_free( &server_fd ); mbedtls_x509_crt_free( &clicert ); mbedtls_x509_crt_free( &cacert ); mbedtls_pk_free( &pkey ); mbedtls_ssl_free( &ssl ); mbedtls_ssl_config_free( &conf ); mbedtls_ctr_drbg_free( &ctr_drbg ); mbedtls_entropy_free( &entropy ); #if defined(_WIN32) mbedtls_printf( " + Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif return( ret ); }
static CURLcode mbed_connect_step1(struct connectdata *conn, int sockindex) { struct SessionHandle *data = conn->data; struct ssl_connect_data* connssl = &conn->ssl[sockindex]; bool sni = TRUE; /* default is SNI enabled */ int ret = -1; #ifdef ENABLE_IPV6 struct in6_addr addr; #else struct in_addr addr; #endif void *old_session = NULL; char errorbuf[128]; errorbuf[0]=0; /* mbedTLS only supports SSLv3 and TLSv1 */ if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) { failf(data, "mbedTLS does not support SSLv2"); return CURLE_SSL_CONNECT_ERROR; } else if(data->set.ssl.version == CURL_SSLVERSION_SSLv3) sni = FALSE; /* SSLv3 has no SNI */ #ifdef THREADING_SUPPORT entropy_init_mutex(&entropy); mbedtls_ctr_drbg_init(&connssl->ctr_drbg); ret = mbedtls_ctr_drbg_seed(&connssl->ctr_drbg, entropy_func_mutex, &entropy, NULL, 0); if(ret) { #ifdef MBEDTLS_ERROR_C mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); #endif /* MBEDTLS_ERROR_C */ failf(data, "Failed - mbedTLS: ctr_drbg_init returned (-0x%04X) %s\n", -ret, errorbuf); } #else mbedtls_entropy_init(&connssl->entropy); mbedtls_ctr_drbg_init(&connssl->ctr_drbg); ret = mbedtls_ctr_drbg_seed(&connssl->ctr_drbg, mbedtls_entropy_func, &connssl->entropy, NULL, 0); if(ret) { #ifdef MBEDTLS_ERROR_C mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); #endif /* MBEDTLS_ERROR_C */ failf(data, "Failed - mbedTLS: ctr_drbg_init returned (-0x%04X) %s\n", -ret, errorbuf); } #endif /* THREADING_SUPPORT */ /* Load the trusted CA */ mbedtls_x509_crt_init(&connssl->cacert); if(data->set.str[STRING_SSL_CAFILE]) { ret = mbedtls_x509_crt_parse_file(&connssl->cacert, data->set.str[STRING_SSL_CAFILE]); if(ret<0) { #ifdef MBEDTLS_ERROR_C mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); #endif /* MBEDTLS_ERROR_C */ failf(data, "Error reading ca cert file %s - mbedTLS: (-0x%04X) %s", data->set.str[STRING_SSL_CAFILE], -ret, errorbuf); if(data->set.ssl.verifypeer) return CURLE_SSL_CACERT_BADFILE; } } if(data->set.str[STRING_SSL_CAPATH]) { ret = mbedtls_x509_crt_parse_path(&connssl->cacert, data->set.str[STRING_SSL_CAPATH]); if(ret<0) { #ifdef MBEDTLS_ERROR_C mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); #endif /* MBEDTLS_ERROR_C */ failf(data, "Error reading ca cert path %s - mbedTLS: (-0x%04X) %s", data->set.str[STRING_SSL_CAPATH], -ret, errorbuf); if(data->set.ssl.verifypeer) return CURLE_SSL_CACERT_BADFILE; } } /* Load the client certificate */ mbedtls_x509_crt_init(&connssl->clicert); if(data->set.str[STRING_CERT]) { ret = mbedtls_x509_crt_parse_file(&connssl->clicert, data->set.str[STRING_CERT]); if(ret) { #ifdef MBEDTLS_ERROR_C mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); #endif /* MBEDTLS_ERROR_C */ failf(data, "Error reading client cert file %s - mbedTLS: (-0x%04X) %s", data->set.str[STRING_CERT], -ret, errorbuf); return CURLE_SSL_CERTPROBLEM; } } /* Load the client private key */ mbedtls_pk_init(&connssl->pk); if(data->set.str[STRING_KEY]) { ret = mbedtls_pk_parse_keyfile(&connssl->pk, data->set.str[STRING_KEY], data->set.str[STRING_KEY_PASSWD]); if(ret == 0 && !mbedtls_pk_can_do(&connssl->pk, MBEDTLS_PK_RSA)) ret = MBEDTLS_ERR_PK_TYPE_MISMATCH; if(ret) { #ifdef MBEDTLS_ERROR_C mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); #endif /* MBEDTLS_ERROR_C */ failf(data, "Error reading private key %s - mbedTLS: (-0x%04X) %s", data->set.str[STRING_KEY], -ret, errorbuf); return CURLE_SSL_CERTPROBLEM; } } /* Load the CRL */ mbedtls_x509_crl_init(&connssl->crl); if(data->set.str[STRING_SSL_CRLFILE]) { ret = mbedtls_x509_crl_parse_file(&connssl->crl, data->set.str[STRING_SSL_CRLFILE]); if(ret) { #ifdef MBEDTLS_ERROR_C mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); #endif /* MBEDTLS_ERROR_C */ failf(data, "Error reading CRL file %s - mbedTLS: (-0x%04X) %s", data->set.str[STRING_SSL_CRLFILE], -ret, errorbuf); return CURLE_SSL_CRL_BADFILE; } } infof(data, "mbedTLS: Connecting to %s:%d\n", conn->host.name, conn->remote_port); mbedtls_ssl_config_init(&connssl->config); mbedtls_ssl_init(&connssl->ssl); if(mbedtls_ssl_setup(&connssl->ssl, &connssl->config)) { failf(data, "mbedTLS: ssl_init failed"); return CURLE_SSL_CONNECT_ERROR; } ret = mbedtls_ssl_config_defaults(&connssl->config, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); if(ret) { failf(data, "mbedTLS: ssl_config failed"); return CURLE_SSL_CONNECT_ERROR; } /* new profile with RSA min key len = 1024 ... */ mbedtls_ssl_conf_cert_profile(&connssl->config, &mbedtls_x509_crt_profile_fr); switch(data->set.ssl.version) { case CURL_SSLVERSION_DEFAULT: case CURL_SSLVERSION_TLSv1: mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1); infof(data, "mbedTLS: Set min SSL version to TLS 1.0\n"); break; case CURL_SSLVERSION_SSLv3: mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0); mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0); infof(data, "mbedTLS: Set SSL version to SSLv3\n"); break; case CURL_SSLVERSION_TLSv1_0: mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1); mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1); infof(data, "mbedTLS: Set SSL version to TLS 1.0\n"); break; case CURL_SSLVERSION_TLSv1_1: mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_2); mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_2); infof(data, "mbedTLS: Set SSL version to TLS 1.1\n"); break; case CURL_SSLVERSION_TLSv1_2: mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3); mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3); infof(data, "mbedTLS: Set SSL version to TLS 1.2\n"); break; default: failf(data, "mbedTLS: Unsupported SSL protocol version"); return CURLE_SSL_CONNECT_ERROR; } mbedtls_ssl_conf_authmode(&connssl->config, MBEDTLS_SSL_VERIFY_OPTIONAL); mbedtls_ssl_conf_rng(&connssl->config, mbedtls_ctr_drbg_random, &connssl->ctr_drbg); mbedtls_ssl_set_bio(&connssl->ssl, &conn->sock[sockindex], mbedtls_net_send, mbedtls_net_recv, NULL /* rev_timeout() */); mbedtls_ssl_conf_ciphersuites(&connssl->config, mbedtls_ssl_list_ciphersuites()); if(!Curl_ssl_getsessionid(conn, &old_session, NULL)) { ret = mbedtls_ssl_set_session(&connssl->ssl, old_session); if(ret) { failf(data, "mbedtls_ssl_set_session returned -0x%x", -ret); return CURLE_SSL_CONNECT_ERROR; } infof(data, "mbedTLS re-using session\n"); } mbedtls_ssl_conf_ca_chain(&connssl->config, &connssl->cacert, &connssl->crl); if(data->set.str[STRING_KEY]) { mbedtls_ssl_conf_own_cert(&connssl->config, &connssl->clicert, &connssl->pk); } if(mbedtls_ssl_set_hostname(&connssl->ssl, conn->host.name)) { /* mbedtls_ssl_set_hostname() sets the name to use in CN/SAN checks *and* the name to set in the SNI extension. So even if curl connects to a host specified as an IP address, this function must be used. */ failf(data, "couldn't set hostname in mbedTLS"); return CURLE_SSL_CONNECT_ERROR; } #ifdef HAS_ALPN if(conn->bits.tls_enable_alpn) { const char **p = &connssl->protocols[0]; #ifdef USE_NGHTTP2 if(data->set.httpversion >= CURL_HTTP_VERSION_2) *p++ = NGHTTP2_PROTO_VERSION_ID; #endif *p++ = ALPN_HTTP_1_1; *p = NULL; /* this function doesn't clone the protocols array, which is why we need to keep it around */ if(mbedtls_ssl_conf_alpn_protocols(&connssl->config, &connssl->protocols[0])) { failf(data, "Failed setting ALPN protocols"); return CURLE_SSL_CONNECT_ERROR; } for(p = &connssl->protocols[0]; *p; ++p) infof(data, "ALPN, offering %s\n", *p); } #endif #ifdef MBEDTLS_DEBUG mbedtls_ssl_conf_dbg(&connssl->config, mbedtls_debug, data); #endif connssl->connecting_state = ssl_connect_2; return CURLE_OK; }
int rand_bytes(uint8_t *output, int len) { #if defined(USE_CRYPTO_OPENSSL) return RAND_bytes(output, len); #elif defined(USE_CRYPTO_POLARSSL) static entropy_context ec = {}; static ctr_drbg_context cd_ctx = {}; static unsigned char rand_initialised = 0; const size_t blen = min(len, CTR_DRBG_MAX_REQUEST); if (!rand_initialised) { #ifdef _WIN32 HCRYPTPROV hProvider; union { unsigned __int64 seed; BYTE buffer[8]; } rand_buffer; hProvider = 0; if (CryptAcquireContext(&hProvider, 0, 0, PROV_RSA_FULL, \ CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { CryptGenRandom(hProvider, 8, rand_buffer.buffer); CryptReleaseContext(hProvider, 0); } else { rand_buffer.seed = (unsigned __int64)clock(); } #else FILE *urand; union { uint64_t seed; uint8_t buffer[8]; } rand_buffer; urand = fopen("/dev/urandom", "r"); if (urand) { int read = fread(&rand_buffer.seed, sizeof(rand_buffer.seed), 1, urand); fclose(urand); if (read <= 0) { rand_buffer.seed = (uint64_t)clock(); } } else { rand_buffer.seed = (uint64_t)clock(); } #endif entropy_init(&ec); if (ctr_drbg_init(&cd_ctx, entropy_func, &ec, (const unsigned char *)rand_buffer.buffer, 8) != 0) { #if POLARSSL_VERSION_NUMBER >= 0x01030000 entropy_free(&ec); #endif FATAL("Failed to initialize random generator"); } rand_initialised = 1; } while (len > 0) { if (ctr_drbg_random(&cd_ctx, output, blen) != 0) { return 0; } output += blen; len -= blen; } return 1; #elif defined(USE_CRYPTO_MBEDTLS) static mbedtls_entropy_context ec = {}; // XXX: ctr_drbg_context changed, [if defined(MBEDTLS_THREADING_C) mbedtls_threading_mutex_t mutex;] static mbedtls_ctr_drbg_context cd_ctx = {}; static unsigned char rand_initialised = 0; const size_t blen = min(len, MBEDTLS_CTR_DRBG_MAX_REQUEST); if (!rand_initialised) { #ifdef _WIN32 HCRYPTPROV hProvider; union { unsigned __int64 seed; BYTE buffer[8]; } rand_buffer; hProvider = 0; if (CryptAcquireContext(&hProvider, 0, 0, PROV_RSA_FULL, \ CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { CryptGenRandom(hProvider, 8, rand_buffer.buffer); CryptReleaseContext(hProvider, 0); } else { rand_buffer.seed = (unsigned __int64)clock(); } #else FILE *urand; union { uint64_t seed; uint8_t buffer[8]; } rand_buffer; urand = fopen("/dev/urandom", "r"); if (urand) { int read = fread(&rand_buffer.seed, sizeof(rand_buffer.seed), 1, urand); fclose(urand); if (read <= 0) { rand_buffer.seed = (uint64_t)clock(); } } else { rand_buffer.seed = (uint64_t)clock(); } #endif mbedtls_entropy_init(&ec); // XXX: ctr_drbg_init changed, seems we should initialize it before calling mbedtls_ctr_drbg_seed() mbedtls_ctr_drbg_init(&cd_ctx); if (mbedtls_ctr_drbg_seed(&cd_ctx, mbedtls_entropy_func, &ec, (const unsigned char *)rand_buffer.buffer, 8) != 0) { mbedtls_entropy_free(&ec); FATAL("mbed TLS: Failed to initialize random generator"); } rand_initialised = 1; } while (len > 0) { if (mbedtls_ctr_drbg_random(&cd_ctx, output, blen) != 0) { return 0; } output += blen; len -= blen; } return 1; #endif }