kaa_error_t kaa_init_rsa_keypair(void) { #ifdef KAA_RUNTIME_KEY_GENERATION /* Initialization should be performed only once */ static bool initialized = false; if (!initialized) { if (mbedtls_pk_parse_keyfile(&kaa_pk_context_, KAA_PRIVATE_KEY_STORAGE, NULL)) { if (rsa_genkey(&kaa_pk_context_)) { mbedtls_pk_free(&kaa_pk_context_); return KAA_ERR_BADDATA; } if (write_rsa_key(&kaa_pk_context_, KAA_PRIVATE_KEY_STORAGE, PRIVATE_KEY)) { mbedtls_pk_free(&kaa_pk_context_); return KAA_ERR_BADDATA; } if (write_rsa_key(&kaa_pk_context_, KAA_PUBLIC_KEY_STORAGE, PUBLIC_KEY)) { mbedtls_pk_free(&kaa_pk_context_); return KAA_ERR_BADDATA; } } if (mbedtls_pk_parse_public_keyfile(&pk_pub_context, KAA_PUBLIC_KEY_STORAGE)) { pk_pub_context = kaa_pk_context_; } initialized = true; } #else if (mbedtls_pk_parse_key(&kaa_pk_context_, KAA_RSA_PRIVATE_KEY, KAA_RSA_PRIVATE_KEY_LENGTH, NULL, 0)) { return KAA_ERR_BADDATA; } #endif /* KAA_RUNTIME_KEY_GENERATION */ return KAA_ERR_NONE; }
/* Load private key and certificate from file */ int tls_load_key_cert(char *file, mbedtls_pk_context **private_key, mbedtls_x509_crt **certificate) { int result; if (file == NULL) { return -1; } if ((*private_key = (mbedtls_pk_context*)malloc(sizeof(mbedtls_pk_context))) == NULL) { return -1; } mbedtls_pk_init(*private_key); if ((result = mbedtls_pk_parse_keyfile(*private_key, file, NULL)) != 0) { print_tls_error(result, "Error loading private key from %s", file); return -1; } if ((*certificate = (mbedtls_x509_crt*)malloc(sizeof(mbedtls_x509_crt))) == NULL) { return -1; } mbedtls_x509_crt_init(*certificate); if ((result = mbedtls_x509_crt_parse_file(*certificate, file)) != 0) { print_tls_error(result, "Error loading X.509 certificates from %s", file); return -1; } return 0; }
rb_ssl_ctx * rb_setup_ssl_client(const char *ssl_cipher_list, const char *cert, const char *keyfile) { int ret; rb_ssl_ctx *sctx; sctx = rb_malloc(sizeof(rb_ssl_ctx)); mbedtls_ssl_config_init(&sctx->config); if ((ret = mbedtls_ssl_config_defaults(&sctx->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(&sctx->config, mbedtls_ctr_drbg_random, &ctr_drbg); mbedtls_ssl_conf_authmode(&sctx->config, MBEDTLS_SSL_VERIFY_NONE); if(cert != NULL && keyfile != NULL) { mbedtls_x509_crt_init(&sctx->x509); ret = mbedtls_x509_crt_parse_file(&sctx->x509, cert); if (ret != 0) { rb_lib_log("rb_setup_ssl_client: failed to parse certificate '%s': -0x%x", cert, -ret); return 0; } mbedtls_pk_init(&sctx->serv_pk); ret = mbedtls_pk_parse_keyfile(&sctx->serv_pk, keyfile, NULL); if (ret != 0) { rb_lib_log("rb_setup_ssl_client: failed to parse private key '%s': -0x%x", keyfile, -ret); return 0; } if (&sctx->x509.next) mbedtls_ssl_conf_ca_chain(&sctx->config, sctx->x509.next, NULL); if ((ret = mbedtls_ssl_conf_own_cert(&sctx->config, &sctx->x509, &sctx->serv_pk)) != 0) { rb_lib_log("rb_setup_ssl_client: failed to set up own certificate: -0x%x", -ret); return 0; } } return sctx; }
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__ }
int main( void ) { int ret, i; mbedtls_x509_crt cacert; mbedtls_x509_crl crl; char buf[10240]; mbedtls_x509_crt_init( &cacert ); mbedtls_x509_crl_init( &crl ); /* * 1.1. Load the trusted CA */ mbedtls_printf( "\n . Loading the CA root certificate ..." ); fflush( stdout ); /* * Alternatively, you may load the CA certificates from a .pem or * .crt file by calling mbedtls_x509_crt_parse_file( &cacert, "myca.crt" ). */ ret = mbedtls_x509_crt_parse_file( &cacert, "ssl/test-ca/test-ca.crt" ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_x509_crt_parse_file returned %d\n\n", ret ); goto exit; } mbedtls_printf( " ok\n" ); mbedtls_x509_crt_info( buf, 1024, "CRT: ", &cacert ); mbedtls_printf("%s\n", buf ); /* * 1.2. Load the CRL */ mbedtls_printf( " . Loading the CRL ..." ); fflush( stdout ); ret = mbedtls_x509_crl_parse_file( &crl, "ssl/test-ca/crl.pem" ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_x509_crl_parse_file returned %d\n\n", ret ); goto exit; } mbedtls_printf( " ok\n" ); mbedtls_x509_crl_info( buf, 1024, "CRL: ", &crl ); mbedtls_printf("%s\n", buf ); for( i = 0; i < MAX_CLIENT_CERTS; i++ ) { /* * 1.3. Load own certificate */ char name[512]; uint32_t flags; mbedtls_x509_crt clicert; mbedtls_pk_context pk; mbedtls_x509_crt_init( &clicert ); mbedtls_pk_init( &pk ); mbedtls_snprintf(name, 512, "ssl/test-ca/%s", client_certificates[i]); mbedtls_printf( " . Loading the client certificate %s...", name ); fflush( stdout ); ret = mbedtls_x509_crt_parse_file( &clicert, name ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_x509_crt_parse_file returned %d\n\n", ret ); goto exit; } mbedtls_printf( " ok\n" ); /* * 1.4. Verify certificate validity with CA certificate */ mbedtls_printf( " . Verify the client certificate with CA certificate..." ); fflush( stdout ); ret = mbedtls_x509_crt_verify( &clicert, &cacert, &crl, NULL, &flags, NULL, NULL ); if( ret != 0 ) { if( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ) { char vrfy_buf[512]; mbedtls_printf( " failed\n" ); mbedtls_x509_crt_verify_info( vrfy_buf, sizeof( vrfy_buf ), " ! ", flags ); mbedtls_printf( "%s\n", vrfy_buf ); } else { mbedtls_printf( " failed\n ! mbedtls_x509_crt_verify returned %d\n\n", ret ); goto exit; } } mbedtls_printf( " ok\n" ); /* * 1.5. Load own private key */ mbedtls_snprintf(name, 512, "ssl/test-ca/%s", client_private_keys[i]); mbedtls_printf( " . Loading the client private key %s...", name ); fflush( stdout ); ret = mbedtls_pk_parse_keyfile( &pk, name, NULL ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_pk_parse_keyfile returned %d\n\n", ret ); goto exit; } mbedtls_printf( " ok\n" ); /* * 1.6. Verify certificate validity with private key */ mbedtls_printf( " . Verify the client certificate with private key..." ); fflush( stdout ); /* EC NOT IMPLEMENTED YET */ if( ! mbedtls_pk_can_do( &clicert.pk, MBEDTLS_PK_RSA ) ) { mbedtls_printf( " failed\n ! certificate's key is not RSA\n\n" ); ret = MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE; goto exit; } ret = mbedtls_mpi_cmp_mpi(&mbedtls_pk_rsa( pk )->N, &mbedtls_pk_rsa( clicert.pk )->N); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_mpi_cmp_mpi for N returned %d\n\n", ret ); goto exit; } ret = mbedtls_mpi_cmp_mpi(&mbedtls_pk_rsa( pk )->E, &mbedtls_pk_rsa( clicert.pk )->E); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_mpi_cmp_mpi for E returned %d\n\n", ret ); goto exit; } ret = mbedtls_rsa_check_privkey( mbedtls_pk_rsa( pk ) ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_rsa_check_privkey returned %d\n\n", ret ); goto exit; } mbedtls_printf( " ok\n" ); mbedtls_x509_crt_free( &clicert ); mbedtls_pk_free( &pk ); } exit: mbedtls_x509_crt_free( &cacert ); mbedtls_x509_crl_free( &crl ); #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 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 ); }
static CURLcode mbed_connect_step1(struct connectdata *conn, int sockindex) { struct Curl_easy *data = conn->data; struct ssl_connect_data* connssl = &conn->ssl[sockindex]; const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile); const bool verifypeer = SSL_CONN_CONFIG(verifypeer); const char * const ssl_capath = SSL_CONN_CONFIG(CApath); char * const ssl_cert = SSL_SET_OPTION(cert); const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile); const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name; const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port; int ret = -1; char errorbuf[128]; errorbuf[0]=0; /* mbedTLS only supports SSLv3 and TLSv1 */ if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) { failf(data, "mbedTLS does not support SSLv2"); return CURLE_SSL_CONNECT_ERROR; } #ifdef THREADING_SUPPORT entropy_init_mutex(&ts_entropy); mbedtls_ctr_drbg_init(&BACKEND->ctr_drbg); ret = mbedtls_ctr_drbg_seed(&BACKEND->ctr_drbg, entropy_func_mutex, &ts_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(&BACKEND->entropy); mbedtls_ctr_drbg_init(&BACKEND->ctr_drbg); ret = mbedtls_ctr_drbg_seed(&BACKEND->ctr_drbg, mbedtls_entropy_func, &BACKEND->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(&BACKEND->cacert); if(ssl_cafile) { ret = mbedtls_x509_crt_parse_file(&BACKEND->cacert, 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", ssl_cafile, -ret, errorbuf); if(verifypeer) return CURLE_SSL_CACERT_BADFILE; } } if(ssl_capath) { ret = mbedtls_x509_crt_parse_path(&BACKEND->cacert, 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", ssl_capath, -ret, errorbuf); if(verifypeer) return CURLE_SSL_CACERT_BADFILE; } } /* Load the client certificate */ mbedtls_x509_crt_init(&BACKEND->clicert); if(ssl_cert) { ret = mbedtls_x509_crt_parse_file(&BACKEND->clicert, ssl_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", ssl_cert, -ret, errorbuf); return CURLE_SSL_CERTPROBLEM; } } /* Load the client private key */ mbedtls_pk_init(&BACKEND->pk); if(SSL_SET_OPTION(key)) { ret = mbedtls_pk_parse_keyfile(&BACKEND->pk, SSL_SET_OPTION(key), SSL_SET_OPTION(key_passwd)); if(ret == 0 && !mbedtls_pk_can_do(&BACKEND->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", SSL_SET_OPTION(key), -ret, errorbuf); return CURLE_SSL_CERTPROBLEM; } } /* Load the CRL */ mbedtls_x509_crl_init(&BACKEND->crl); if(ssl_crlfile) { ret = mbedtls_x509_crl_parse_file(&BACKEND->crl, 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", ssl_crlfile, -ret, errorbuf); return CURLE_SSL_CRL_BADFILE; } } infof(data, "mbedTLS: Connecting to %s:%d\n", hostname, port); mbedtls_ssl_config_init(&BACKEND->config); mbedtls_ssl_init(&BACKEND->ssl); if(mbedtls_ssl_setup(&BACKEND->ssl, &BACKEND->config)) { failf(data, "mbedTLS: ssl_init failed"); return CURLE_SSL_CONNECT_ERROR; } ret = mbedtls_ssl_config_defaults(&BACKEND->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(&BACKEND->config, &mbedtls_x509_crt_profile_fr); switch(SSL_CONN_CONFIG(version)) { case CURL_SSLVERSION_DEFAULT: case CURL_SSLVERSION_TLSv1: mbedtls_ssl_conf_min_version(&BACKEND->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(&BACKEND->config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0); mbedtls_ssl_conf_max_version(&BACKEND->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: case CURL_SSLVERSION_TLSv1_1: case CURL_SSLVERSION_TLSv1_2: case CURL_SSLVERSION_TLSv1_3: { CURLcode result = set_ssl_version_min_max(conn, sockindex); if(result != CURLE_OK) return result; break; } default: failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); return CURLE_SSL_CONNECT_ERROR; } mbedtls_ssl_conf_authmode(&BACKEND->config, MBEDTLS_SSL_VERIFY_OPTIONAL); mbedtls_ssl_conf_rng(&BACKEND->config, mbedtls_ctr_drbg_random, &BACKEND->ctr_drbg); mbedtls_ssl_set_bio(&BACKEND->ssl, &conn->sock[sockindex], mbedtls_net_send, mbedtls_net_recv, NULL /* rev_timeout() */); mbedtls_ssl_conf_ciphersuites(&BACKEND->config, mbedtls_ssl_list_ciphersuites()); #if defined(MBEDTLS_SSL_RENEGOTIATION) mbedtls_ssl_conf_renegotiation(&BACKEND->config, MBEDTLS_SSL_RENEGOTIATION_ENABLED); #endif #if defined(MBEDTLS_SSL_SESSION_TICKETS) mbedtls_ssl_conf_session_tickets(&BACKEND->config, MBEDTLS_SSL_SESSION_TICKETS_DISABLED); #endif /* Check if there's a cached ID we can/should use here! */ if(SSL_SET_OPTION(primary.sessionid)) { void *old_session = NULL; Curl_ssl_sessionid_lock(conn); if(!Curl_ssl_getsessionid(conn, &old_session, NULL, sockindex)) { ret = mbedtls_ssl_set_session(&BACKEND->ssl, old_session); if(ret) { Curl_ssl_sessionid_unlock(conn); failf(data, "mbedtls_ssl_set_session returned -0x%x", -ret); return CURLE_SSL_CONNECT_ERROR; } infof(data, "mbedTLS re-using session\n"); } Curl_ssl_sessionid_unlock(conn); } mbedtls_ssl_conf_ca_chain(&BACKEND->config, &BACKEND->cacert, &BACKEND->crl); if(SSL_SET_OPTION(key)) { mbedtls_ssl_conf_own_cert(&BACKEND->config, &BACKEND->clicert, &BACKEND->pk); } if(mbedtls_ssl_set_hostname(&BACKEND->ssl, hostname)) { /* 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 = &BACKEND->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(&BACKEND->config, &BACKEND->protocols[0])) { failf(data, "Failed setting ALPN protocols"); return CURLE_SSL_CONNECT_ERROR; } for(p = &BACKEND->protocols[0]; *p; ++p) infof(data, "ALPN, offering %s\n", *p); } #endif #ifdef MBEDTLS_DEBUG /* In order to make that work in mbedtls MBEDTLS_DEBUG_C must be defined. */ mbedtls_ssl_conf_dbg(&BACKEND->config, mbed_debug, data); /* - 0 No debug * - 1 Error * - 2 State change * - 3 Informational * - 4 Verbose */ mbedtls_debug_set_threshold(4); #endif /* give application a chance to interfere with mbedTLS set up. */ if(data->set.ssl.fsslctx) { ret = (*data->set.ssl.fsslctx)(data, &BACKEND->config, data->set.ssl.fsslctxp); if(ret) { failf(data, "error signaled by ssl ctx callback"); return ret; } } connssl->connecting_state = ssl_connect_2; return CURLE_OK; }
IoT_Error_t iot_tls_connect(Network *pNetwork, TLSConnectParams *params) { if(NULL == pNetwork) { return NULL_VALUE_ERROR; } if(NULL != params) { _iot_tls_set_connect_params(pNetwork, params->pRootCALocation, params->pDeviceCertLocation, params->pDevicePrivateKeyLocation, params->pDestinationURL, params->DestinationPort, params->timeout_ms, params->ServerVerificationFlag); } int ret = 0; const char *pers = "aws_iot_tls_wrapper"; #ifdef IOT_DEBUG unsigned char buf[MBEDTLS_SSL_MAX_CONTENT_LEN + 1]; #endif TLSDataParams *tlsDataParams = &(pNetwork->tlsDataParams); mbedtls_net_init(&(tlsDataParams->server_fd)); mbedtls_ssl_init(&(tlsDataParams->ssl)); mbedtls_ssl_config_init(&(tlsDataParams->conf)); mbedtls_ctr_drbg_init(&(tlsDataParams->ctr_drbg)); mbedtls_x509_crt_init(&(tlsDataParams->cacert)); mbedtls_x509_crt_init(&(tlsDataParams->clicert)); mbedtls_pk_init(&(tlsDataParams->pkey)); DEBUG("\n . Seeding the random number generator..."); mbedtls_entropy_init(&(tlsDataParams->entropy)); if ((ret = mbedtls_ctr_drbg_seed(&(tlsDataParams->ctr_drbg), mbedtls_entropy_func, &(tlsDataParams->entropy), (const unsigned char *) pers, strlen(pers))) != 0) { ERROR(" failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n", -ret); return NETWORK_MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED; } DEBUG(" . Loading the CA root certificate ..."); ret = mbedtls_x509_crt_parse_file(&(tlsDataParams->cacert), pNetwork->tlsConnectParams.pRootCALocation); if (ret < 0) { ERROR(" failed\n ! mbedtls_x509_crt_parse returned -0x%x while parsing root cert\n\n", -ret); return NETWORK_X509_ROOT_CRT_PARSE_ERROR; } DEBUG(" ok (%d skipped)\n", ret); DEBUG(" . Loading the client cert. and key..."); ret = mbedtls_x509_crt_parse_file(&(tlsDataParams->clicert), pNetwork->tlsConnectParams.pDeviceCertLocation); if (ret != 0) { ERROR(" failed\n ! mbedtls_x509_crt_parse returned -0x%x while parsing device cert\n\n", -ret); return NETWORK_X509_DEVICE_CRT_PARSE_ERROR; } ret = mbedtls_pk_parse_keyfile(&(tlsDataParams->pkey), pNetwork->tlsConnectParams.pDevicePrivateKeyLocation, ""); if (ret != 0) { ERROR(" failed\n ! mbedtls_pk_parse_key returned -0x%x while parsing private key\n\n", -ret); DEBUG(" path : %s ", pNetwork->tlsConnectParams.pDevicePrivateKeyLocation); return NETWORK_PK_PRIVATE_KEY_PARSE_ERROR; } DEBUG(" ok\n"); char portBuffer[6]; snprintf(portBuffer, 6, "%d", pNetwork->tlsConnectParams.DestinationPort); DEBUG(" . Connecting to %s/%s...", pNetwork->tlsConnectParams.pDestinationURL, portBuffer); if ((ret = mbedtls_net_connect(&(tlsDataParams->server_fd), pNetwork->tlsConnectParams.pDestinationURL, portBuffer, MBEDTLS_NET_PROTO_TCP)) != 0) { ERROR(" failed\n ! mbedtls_net_connect returned -0x%x\n\n", -ret); switch(ret) { case MBEDTLS_ERR_NET_SOCKET_FAILED: return NETWORK_ERR_NET_SOCKET_FAILED; case MBEDTLS_ERR_NET_UNKNOWN_HOST: return NETWORK_ERR_NET_UNKNOWN_HOST; case MBEDTLS_ERR_NET_CONNECT_FAILED: default: return NETWORK_ERR_NET_CONNECT_FAILED; }; } ret = mbedtls_net_set_block(&(tlsDataParams->server_fd)); if (ret != 0) { ERROR(" failed\n ! net_set_(non)block() returned -0x%x\n\n", -ret); return SSL_CONNECTION_ERROR; } DEBUG(" ok\n"); DEBUG(" . Setting up the SSL/TLS structure..."); if ((ret = mbedtls_ssl_config_defaults(&(tlsDataParams->conf), MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0) { ERROR(" failed\n ! mbedtls_ssl_config_defaults returned -0x%x\n\n", -ret); return SSL_CONNECTION_ERROR; } mbedtls_ssl_conf_verify(&(tlsDataParams->conf), _iot_tls_verify_cert, NULL); if (pNetwork->tlsConnectParams.ServerVerificationFlag == true) { mbedtls_ssl_conf_authmode(&(tlsDataParams->conf), MBEDTLS_SSL_VERIFY_REQUIRED); } else { mbedtls_ssl_conf_authmode(&(tlsDataParams->conf), MBEDTLS_SSL_VERIFY_OPTIONAL); } mbedtls_ssl_conf_rng(&(tlsDataParams->conf), mbedtls_ctr_drbg_random, &(tlsDataParams->ctr_drbg)); mbedtls_ssl_conf_ca_chain(&(tlsDataParams->conf), &(tlsDataParams->cacert), NULL); if ((ret = mbedtls_ssl_conf_own_cert(&(tlsDataParams->conf), &(tlsDataParams->clicert), &(tlsDataParams->pkey))) != 0) { ERROR(" failed\n ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret); return SSL_CONNECTION_ERROR; } mbedtls_ssl_conf_read_timeout(&(tlsDataParams->conf), pNetwork->tlsConnectParams.timeout_ms); if ((ret = mbedtls_ssl_setup(&(tlsDataParams->ssl), &(tlsDataParams->conf))) != 0) { ERROR(" failed\n ! mbedtls_ssl_setup returned -0x%x\n\n", -ret); return SSL_CONNECTION_ERROR; } if ((ret = mbedtls_ssl_set_hostname(&(tlsDataParams->ssl), pNetwork->tlsConnectParams.pDestinationURL)) != 0) { ERROR(" failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", ret); return SSL_CONNECTION_ERROR; } DEBUG("\n\nSSL state connect : %d ", tlsDataParams->ssl.state); mbedtls_ssl_set_bio(&(tlsDataParams->ssl), &(tlsDataParams->server_fd), mbedtls_net_send, NULL, mbedtls_net_recv_timeout); DEBUG(" ok\n"); DEBUG("\n\nSSL state connect : %d ", tlsDataParams->ssl.state); DEBUG(" . Performing the SSL/TLS handshake..."); while ((ret = mbedtls_ssl_handshake(&(tlsDataParams->ssl))) != 0) { if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { ERROR(" failed\n ! mbedtls_ssl_handshake returned -0x%x\n", -ret); if (ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) { ERROR(" Unable to verify the server's certificate. " "Either it is invalid,\n" " or you didn't set ca_file or ca_path " "to an appropriate value.\n" " Alternatively, you may want to use " "auth_mode=optional for testing purposes.\n"); } return SSL_CONNECTION_ERROR; } } DEBUG(" ok\n [ Protocol is %s ]\n [ Ciphersuite is %s ]\n", mbedtls_ssl_get_version(&(tlsDataParams->ssl)), mbedtls_ssl_get_ciphersuite(&(tlsDataParams->ssl))); if ((ret = mbedtls_ssl_get_record_expansion(&(tlsDataParams->ssl))) >= 0) { DEBUG(" [ Record expansion is %d ]\n", ret); } else { DEBUG(" [ Record expansion is unknown (compression) ]\n"); } DEBUG(" . Verifying peer X.509 certificate..."); if(pNetwork->tlsConnectParams.ServerVerificationFlag == true) { if((tlsDataParams->flags = mbedtls_ssl_get_verify_result(&(tlsDataParams->ssl))) != 0) { char vrfy_buf[512]; ERROR(" failed\n"); mbedtls_x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), " ! ", tlsDataParams->flags); ERROR("%s\n", vrfy_buf); ret = SSL_CONNECTION_ERROR; } else { DEBUG(" ok\n"); ret = SUCCESS; } } else { DEBUG(" Server Verification skipped\n"); ret = SUCCESS; } #ifdef IOT_DEBUG if (mbedtls_ssl_get_peer_cert(&(tlsDataParams->ssl)) != NULL) { DEBUG(" . Peer certificate information ...\n"); mbedtls_x509_crt_info((char *) buf, sizeof(buf) - 1, " ", mbedtls_ssl_get_peer_cert(&(tlsDataParams->ssl))); DEBUG("%s\n", buf); } #endif mbedtls_ssl_conf_read_timeout(&(tlsDataParams->conf), IOT_SSL_READ_TIMEOUT); return ret; }
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 mbedtls_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; size_t old_session_size = 0; 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, connssl->ssn.id, connssl->ssn.id_len); 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, connssl->ssn.id, connssl->ssn.id_len); 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 */ memset(&connssl->cacert, 0, sizeof(mbedtls_x509_crt)); 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 */ memset(&connssl->clicert, 0, sizeof(mbedtls_x509_crt)); 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 */ if(data->set.str[STRING_KEY]) { mbedtls_pk_init(&connssl->pk); 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 */ memset(&connssl->crl, 0, sizeof(mbedtls_x509_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_SSLv3: mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0); infof(data, "mbedTLS: Forced min. SSL Version to be 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); infof(data, "mbedTLS: Forced min. SSL Version to be 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); infof(data, "mbedTLS: Forced min. SSL Version to be 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); infof(data, "mbedTLS: Forced min. SSL Version to be TLS 1.2\n"); break; } 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, &old_session_size)) { memcpy(&connssl->ssn, old_session, old_session_size); infof(data, "mbedTLS re-using session\n"); } mbedtls_ssl_set_session(&connssl->ssl, &connssl->ssn); 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(!Curl_inet_pton(AF_INET, conn->host.name, &addr) && #ifdef ENABLE_IPV6 !Curl_inet_pton(AF_INET6, conn->host.name, &addr) && #endif sni && mbedtls_ssl_set_hostname(&connssl->ssl, conn->host.name)) { infof(data, "WARNING: failed to configure " "server name indication (SNI) TLS extension\n"); } #ifdef HAS_ALPN if(data->set.ssl_enable_alpn) { const char *protocols[3]; const char **p = protocols; #ifdef USE_NGHTTP2 if(data->set.httpversion >= CURL_HTTP_VERSION_2) *p++ = NGHTTP2_PROTO_VERSION_ID; #endif *p++ = ALPN_HTTP_1_1; *p = NULL; if(mbedtls_ssl_conf_alpn_protocols(&connssl->config, protocols)) { failf(data, "Failed setting ALPN protocols"); return CURLE_SSL_CONNECT_ERROR; } for(p = protocols; *p; ++p) infof(data, "ALPN, offering %s\n", *p); } #endif #ifdef MBEDTLS_DEBUG mbedtls_ssl_conf_dbg(&connssl->ssl, mbedtls_debug, data); #endif connssl->connecting_state = ssl_connect_2; return CURLE_OK; }
int main( int argc, char *argv[] ) { FILE *f; int ret, c; size_t i, olen = 0; mbedtls_pk_context pk; mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; unsigned char result[1024]; unsigned char buf[512]; const char *pers = "mbedtls_pk_decrypt"; ((void) argv); mbedtls_ctr_drbg_init( &ctr_drbg ); memset(result, 0, sizeof( result ) ); ret = 1; if( argc != 2 ) { mbedtls_printf( "usage: mbedtls_pk_decrypt <key_file>\n" ); #if defined(_WIN32) mbedtls_printf( "\n" ); #endif goto exit; } 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( "\n . Reading private key from '%s'", argv[1] ); fflush( stdout ); mbedtls_pk_init( &pk ); if( ( ret = mbedtls_pk_parse_keyfile( &pk, argv[1], "" ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_pk_parse_keyfile returned -0x%04x\n", -ret ); goto exit; } /* * Extract the RSA encrypted value from the text file */ ret = 1; if( ( f = fopen( "result-enc.txt", "rb" ) ) == NULL ) { mbedtls_printf( "\n ! Could not open %s\n\n", "result-enc.txt" ); goto exit; } i = 0; while( fscanf( f, "%02X", &c ) > 0 && i < (int) sizeof( buf ) ) buf[i++] = (unsigned char) c; fclose( f ); /* * Decrypt the encrypted RSA data and print the result. */ mbedtls_printf( "\n . Decrypting the encrypted data" ); fflush( stdout ); if( ( ret = mbedtls_pk_decrypt( &pk, buf, i, result, &olen, sizeof(result), mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_pk_decrypt returned -0x%04x\n", -ret ); goto exit; } mbedtls_printf( "\n . OK\n\n" ); mbedtls_printf( "The decrypted result is: '%s'\n\n", result ); ret = 0; exit: mbedtls_ctr_drbg_free( &ctr_drbg ); mbedtls_entropy_free( &entropy ); #if defined(MBEDTLS_ERROR_C) if( ret != 0 ) { mbedtls_strerror( ret, (char *) buf, sizeof(buf) ); mbedtls_printf( " ! Last error was: %s\n", buf ); } #endif #if defined(_WIN32) mbedtls_printf( " + Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif return( ret ); }
IoT_Error_t iot_tls_connect(Network *pNetwork, TLSConnectParams *params) { int ret = SUCCESS; TLSDataParams *tlsDataParams = NULL; char portBuffer[6]; char info_buf[256]; if(NULL == pNetwork) { return NULL_VALUE_ERROR; } if(NULL != params) { _iot_tls_set_connect_params(pNetwork, params->pRootCALocation, params->pDeviceCertLocation, params->pDevicePrivateKeyLocation, params->pDestinationURL, params->DestinationPort, params->timeout_ms, params->ServerVerificationFlag); } tlsDataParams = &(pNetwork->tlsDataParams); mbedtls_net_init(&(tlsDataParams->server_fd)); mbedtls_ssl_init(&(tlsDataParams->ssl)); mbedtls_ssl_config_init(&(tlsDataParams->conf)); #ifdef CONFIG_MBEDTLS_DEBUG mbedtls_esp_enable_debug_log(&(tlsDataParams->conf), 4); #endif mbedtls_ctr_drbg_init(&(tlsDataParams->ctr_drbg)); mbedtls_x509_crt_init(&(tlsDataParams->cacert)); mbedtls_x509_crt_init(&(tlsDataParams->clicert)); mbedtls_pk_init(&(tlsDataParams->pkey)); ESP_LOGD(TAG, "Seeding the random number generator..."); mbedtls_entropy_init(&(tlsDataParams->entropy)); if((ret = mbedtls_ctr_drbg_seed(&(tlsDataParams->ctr_drbg), mbedtls_entropy_func, &(tlsDataParams->entropy), (const unsigned char *) TAG, strlen(TAG))) != 0) { ESP_LOGE(TAG, "failed! mbedtls_ctr_drbg_seed returned -0x%x", -ret); return NETWORK_MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED; } /* Load root CA... Certs/keys can be paths or they can be raw data. These use a very basic heuristic: if the cert starts with '/' then it's a path, if it's longer than this then it's raw cert data (PEM or DER, neither of which can start with a slash. */ if (pNetwork->tlsConnectParams.pRootCALocation[0] == '/') { ESP_LOGD(TAG, "Loading CA root certificate from file ..."); ret = mbedtls_x509_crt_parse_file(&(tlsDataParams->cacert), pNetwork->tlsConnectParams.pRootCALocation); } else { ESP_LOGD(TAG, "Loading embedded CA root certificate ..."); ret = mbedtls_x509_crt_parse(&(tlsDataParams->cacert), (const unsigned char *)pNetwork->tlsConnectParams.pRootCALocation, strlen(pNetwork->tlsConnectParams.pRootCALocation)+1); } if(ret < 0) { ESP_LOGE(TAG, "failed! mbedtls_x509_crt_parse returned -0x%x while parsing root cert", -ret); return NETWORK_X509_ROOT_CRT_PARSE_ERROR; } ESP_LOGD(TAG, "ok (%d skipped)", ret); /* Load client certificate... */ if (pNetwork->tlsConnectParams.pDeviceCertLocation[0] == '/') { ESP_LOGD(TAG, "Loading client cert from file..."); ret = mbedtls_x509_crt_parse_file(&(tlsDataParams->clicert), pNetwork->tlsConnectParams.pDeviceCertLocation); } else { ESP_LOGD(TAG, "Loading embedded client certificate..."); ret = mbedtls_x509_crt_parse(&(tlsDataParams->clicert), (const unsigned char *)pNetwork->tlsConnectParams.pDeviceCertLocation, strlen(pNetwork->tlsConnectParams.pDeviceCertLocation)+1); } if(ret != 0) { ESP_LOGE(TAG, "failed! mbedtls_x509_crt_parse returned -0x%x while parsing device cert", -ret); return NETWORK_X509_DEVICE_CRT_PARSE_ERROR; } /* Parse client private key... */ if (pNetwork->tlsConnectParams.pDevicePrivateKeyLocation[0] == '/') { ESP_LOGD(TAG, "Loading client private key from file..."); ret = mbedtls_pk_parse_keyfile(&(tlsDataParams->pkey), pNetwork->tlsConnectParams.pDevicePrivateKeyLocation, ""); } else { ESP_LOGD(TAG, "Loading embedded client private key..."); ret = mbedtls_pk_parse_key(&(tlsDataParams->pkey), (const unsigned char *)pNetwork->tlsConnectParams.pDevicePrivateKeyLocation, strlen(pNetwork->tlsConnectParams.pDevicePrivateKeyLocation)+1, (const unsigned char *)"", 0); } if(ret != 0) { ESP_LOGE(TAG, "failed! mbedtls_pk_parse_key returned -0x%x while parsing private key", -ret); return NETWORK_PK_PRIVATE_KEY_PARSE_ERROR; } /* Done parsing certs */ ESP_LOGD(TAG, "ok"); snprintf(portBuffer, 6, "%d", pNetwork->tlsConnectParams.DestinationPort); ESP_LOGD(TAG, "Connecting to %s/%s...", pNetwork->tlsConnectParams.pDestinationURL, portBuffer); if((ret = mbedtls_net_connect(&(tlsDataParams->server_fd), pNetwork->tlsConnectParams.pDestinationURL, portBuffer, MBEDTLS_NET_PROTO_TCP)) != 0) { ESP_LOGE(TAG, "failed! mbedtls_net_connect returned -0x%x", -ret); switch(ret) { case MBEDTLS_ERR_NET_SOCKET_FAILED: return NETWORK_ERR_NET_SOCKET_FAILED; case MBEDTLS_ERR_NET_UNKNOWN_HOST: return NETWORK_ERR_NET_UNKNOWN_HOST; case MBEDTLS_ERR_NET_CONNECT_FAILED: default: return NETWORK_ERR_NET_CONNECT_FAILED; }; } ret = mbedtls_net_set_block(&(tlsDataParams->server_fd)); if(ret != 0) { ESP_LOGE(TAG, "failed! net_set_(non)block() returned -0x%x", -ret); return SSL_CONNECTION_ERROR; } ESP_LOGD(TAG, "ok"); ESP_LOGD(TAG, "Setting up the SSL/TLS structure..."); if((ret = mbedtls_ssl_config_defaults(&(tlsDataParams->conf), MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0) { ESP_LOGE(TAG, "failed! mbedtls_ssl_config_defaults returned -0x%x", -ret); return SSL_CONNECTION_ERROR; } mbedtls_ssl_conf_verify(&(tlsDataParams->conf), _iot_tls_verify_cert, NULL); if(pNetwork->tlsConnectParams.ServerVerificationFlag == true) { mbedtls_ssl_conf_authmode(&(tlsDataParams->conf), MBEDTLS_SSL_VERIFY_REQUIRED); } else { mbedtls_ssl_conf_authmode(&(tlsDataParams->conf), MBEDTLS_SSL_VERIFY_OPTIONAL); } mbedtls_ssl_conf_rng(&(tlsDataParams->conf), mbedtls_ctr_drbg_random, &(tlsDataParams->ctr_drbg)); mbedtls_ssl_conf_ca_chain(&(tlsDataParams->conf), &(tlsDataParams->cacert), NULL); ret = mbedtls_ssl_conf_own_cert(&(tlsDataParams->conf), &(tlsDataParams->clicert), &(tlsDataParams->pkey)); if(ret != 0) { ESP_LOGE(TAG, "failed! mbedtls_ssl_conf_own_cert returned %d", ret); return SSL_CONNECTION_ERROR; } mbedtls_ssl_conf_read_timeout(&(tlsDataParams->conf), pNetwork->tlsConnectParams.timeout_ms); #ifdef CONFIG_MBEDTLS_SSL_ALPN /* Use the AWS IoT ALPN extension for MQTT, if port 443 is requested */ if (pNetwork->tlsConnectParams.DestinationPort == 443) { const char *alpnProtocols[] = { "x-amzn-mqtt-ca", NULL }; if ((ret = mbedtls_ssl_conf_alpn_protocols(&(tlsDataParams->conf), alpnProtocols)) != 0) { ESP_LOGE(TAG, "failed! mbedtls_ssl_conf_alpn_protocols returned -0x%x", -ret); return SSL_CONNECTION_ERROR; } } #endif if((ret = mbedtls_ssl_setup(&(tlsDataParams->ssl), &(tlsDataParams->conf))) != 0) { ESP_LOGE(TAG, "failed! mbedtls_ssl_setup returned -0x%x", -ret); return SSL_CONNECTION_ERROR; } if((ret = mbedtls_ssl_set_hostname(&(tlsDataParams->ssl), pNetwork->tlsConnectParams.pDestinationURL)) != 0) { ESP_LOGE(TAG, "failed! mbedtls_ssl_set_hostname returned %d", ret); return SSL_CONNECTION_ERROR; } ESP_LOGD(TAG, "SSL state connect : %d ", tlsDataParams->ssl.state); mbedtls_ssl_set_bio(&(tlsDataParams->ssl), &(tlsDataParams->server_fd), mbedtls_net_send, NULL, mbedtls_net_recv_timeout); ESP_LOGD(TAG, "ok"); ESP_LOGD(TAG, "SSL state connect : %d ", tlsDataParams->ssl.state); ESP_LOGD(TAG, "Performing the SSL/TLS handshake..."); while((ret = mbedtls_ssl_handshake(&(tlsDataParams->ssl))) != 0) { if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { ESP_LOGE(TAG, "failed! mbedtls_ssl_handshake returned -0x%x", -ret); if(ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) { ESP_LOGE(TAG, " Unable to verify the server's certificate. "); } return SSL_CONNECTION_ERROR; } } ESP_LOGD(TAG, "ok [ Protocol is %s ] [ Ciphersuite is %s ]", mbedtls_ssl_get_version(&(tlsDataParams->ssl)), mbedtls_ssl_get_ciphersuite(&(tlsDataParams->ssl))); if((ret = mbedtls_ssl_get_record_expansion(&(tlsDataParams->ssl))) >= 0) { ESP_LOGD(TAG, " [ Record expansion is %d ]", ret); } else { ESP_LOGD(TAG, " [ Record expansion is unknown (compression) ]"); } ESP_LOGD(TAG, "Verifying peer X.509 certificate..."); if(pNetwork->tlsConnectParams.ServerVerificationFlag == true) { if((tlsDataParams->flags = mbedtls_ssl_get_verify_result(&(tlsDataParams->ssl))) != 0) { ESP_LOGE(TAG, "failed"); mbedtls_x509_crt_verify_info(info_buf, sizeof(info_buf), " ! ", tlsDataParams->flags); ESP_LOGE(TAG, "%s", info_buf); ret = SSL_CONNECTION_ERROR; } else { ESP_LOGD(TAG, "ok"); ret = SUCCESS; } } else { ESP_LOGW(TAG, " Server Verification skipped"); ret = SUCCESS; } if(LOG_LOCAL_LEVEL >= ESP_LOG_DEBUG) { if (mbedtls_ssl_get_peer_cert(&(tlsDataParams->ssl)) != NULL) { ESP_LOGD(TAG, "Peer certificate information:"); mbedtls_x509_crt_info((char *) info_buf, sizeof(info_buf) - 1, " ", mbedtls_ssl_get_peer_cert(&(tlsDataParams->ssl))); ESP_LOGD(TAG, "%s", info_buf); } } return (IoT_Error_t) ret; }
int main( int argc, char *argv[] ) { int ret = 0; mbedtls_pk_context key; char buf[1024]; int i; char *p, *q; /* * Set to sane values */ mbedtls_pk_init( &key ); memset( buf, 0, sizeof( buf ) ); if( argc == 0 ) { usage: ret = 1; mbedtls_printf( USAGE ); goto exit; } opt.mode = DFL_MODE; opt.filename = DFL_FILENAME; opt.output_mode = DFL_OUTPUT_MODE; opt.output_file = DFL_OUTPUT_FILENAME; opt.output_format = DFL_OUTPUT_FORMAT; for( i = 1; i < argc; i++ ) { p = argv[i]; if( ( q = strchr( p, '=' ) ) == NULL ) goto usage; *q++ = '\0'; if( strcmp( p, "mode" ) == 0 ) { if( strcmp( q, "private" ) == 0 ) opt.mode = MODE_PRIVATE; else if( strcmp( q, "public" ) == 0 ) opt.mode = MODE_PUBLIC; else goto usage; } else if( strcmp( p, "output_mode" ) == 0 ) { if( strcmp( q, "private" ) == 0 ) opt.output_mode = OUTPUT_MODE_PRIVATE; else if( strcmp( q, "public" ) == 0 ) opt.output_mode = OUTPUT_MODE_PUBLIC; else goto usage; } else if( strcmp( p, "output_format" ) == 0 ) { #if defined(MBEDTLS_PEM_WRITE_C) if( strcmp( q, "pem" ) == 0 ) opt.output_format = OUTPUT_FORMAT_PEM; else #endif if( strcmp( q, "der" ) == 0 ) opt.output_format = OUTPUT_FORMAT_DER; else goto usage; } else if( strcmp( p, "filename" ) == 0 ) opt.filename = q; else if( strcmp( p, "output_file" ) == 0 ) opt.output_file = q; else goto usage; } if( opt.mode == MODE_NONE && opt.output_mode != OUTPUT_MODE_NONE ) { mbedtls_printf( "\nCannot output a key without reading one.\n"); goto exit; } if( opt.mode == MODE_PUBLIC && opt.output_mode == OUTPUT_MODE_PRIVATE ) { mbedtls_printf( "\nCannot output a private key from a public key.\n"); goto exit; } if( opt.mode == MODE_PRIVATE ) { /* * 1.1. Load the key */ mbedtls_printf( "\n . Loading the private key ..." ); fflush( stdout ); ret = mbedtls_pk_parse_keyfile( &key, opt.filename, NULL ); if( ret != 0 ) { mbedtls_strerror( ret, (char *) buf, sizeof(buf) ); mbedtls_printf( " failed\n ! mbedtls_pk_parse_keyfile returned -0x%04x - %s\n\n", -ret, buf ); goto exit; } mbedtls_printf( " ok\n" ); /* * 1.2 Print the key */ mbedtls_printf( " . Key information ...\n" ); #if defined(MBEDTLS_RSA_C) if( mbedtls_pk_get_type( &key ) == MBEDTLS_PK_RSA ) { mbedtls_rsa_context *rsa = mbedtls_pk_rsa( key ); mbedtls_mpi_write_file( "N: ", &rsa->N, 16, NULL ); mbedtls_mpi_write_file( "E: ", &rsa->E, 16, NULL ); mbedtls_mpi_write_file( "D: ", &rsa->D, 16, NULL ); mbedtls_mpi_write_file( "P: ", &rsa->P, 16, NULL ); mbedtls_mpi_write_file( "Q: ", &rsa->Q, 16, NULL ); mbedtls_mpi_write_file( "DP: ", &rsa->DP, 16, NULL ); mbedtls_mpi_write_file( "DQ: ", &rsa->DQ, 16, NULL ); mbedtls_mpi_write_file( "QP: ", &rsa->QP, 16, NULL ); } else #endif #if defined(MBEDTLS_ECP_C) if( mbedtls_pk_get_type( &key ) == MBEDTLS_PK_ECKEY ) { mbedtls_ecp_keypair *ecp = mbedtls_pk_ec( key ); mbedtls_mpi_write_file( "Q(X): ", &ecp->Q.X, 16, NULL ); mbedtls_mpi_write_file( "Q(Y): ", &ecp->Q.Y, 16, NULL ); mbedtls_mpi_write_file( "Q(Z): ", &ecp->Q.Z, 16, NULL ); mbedtls_mpi_write_file( "D : ", &ecp->d , 16, NULL ); } else #endif mbedtls_printf("key type not supported yet\n"); } else if( opt.mode == MODE_PUBLIC ) { /* * 1.1. Load the key */ mbedtls_printf( "\n . Loading the public key ..." ); fflush( stdout ); ret = mbedtls_pk_parse_public_keyfile( &key, opt.filename ); if( ret != 0 ) { mbedtls_strerror( ret, (char *) buf, sizeof(buf) ); mbedtls_printf( " failed\n ! mbedtls_pk_parse_public_key returned -0x%04x - %s\n\n", -ret, buf ); goto exit; } mbedtls_printf( " ok\n" ); /* * 1.2 Print the key */ mbedtls_printf( " . Key information ...\n" ); #if defined(MBEDTLS_RSA_C) if( mbedtls_pk_get_type( &key ) == MBEDTLS_PK_RSA ) { mbedtls_rsa_context *rsa = mbedtls_pk_rsa( key ); mbedtls_mpi_write_file( "N: ", &rsa->N, 16, NULL ); mbedtls_mpi_write_file( "E: ", &rsa->E, 16, NULL ); } else #endif #if defined(MBEDTLS_ECP_C) if( mbedtls_pk_get_type( &key ) == MBEDTLS_PK_ECKEY ) { mbedtls_ecp_keypair *ecp = mbedtls_pk_ec( key ); mbedtls_mpi_write_file( "Q(X): ", &ecp->Q.X, 16, NULL ); mbedtls_mpi_write_file( "Q(Y): ", &ecp->Q.Y, 16, NULL ); mbedtls_mpi_write_file( "Q(Z): ", &ecp->Q.Z, 16, NULL ); } else #endif mbedtls_printf("key type not supported yet\n"); } else goto usage; if( opt.output_mode == OUTPUT_MODE_PUBLIC ) { write_public_key( &key, opt.output_file ); } if( opt.output_mode == OUTPUT_MODE_PRIVATE ) { write_private_key( &key, opt.output_file ); } exit: if( ret != 0 && ret != 1) { #ifdef MBEDTLS_ERROR_C mbedtls_strerror( ret, buf, sizeof( buf ) ); mbedtls_printf( " - %s\n", buf ); #else mbedtls_printf("\n"); #endif } mbedtls_pk_free( &key ); #if defined(_WIN32) mbedtls_printf( " + Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif return( ret ); }
int iot_tls_connect(Network *pNetwork, TLSConnectParams params) { const char *pers = "aws_iot_tls_wrapper"; unsigned char buf[MBEDTLS_SSL_MAX_CONTENT_LEN + 1]; DEBUG(" . Loading the CA root certificate ..."); ret = mbedtls_x509_crt_parse_file(&cacert, params.pRootCALocation); if (ret < 0) { ERROR(" failed\n ! mbedtls_x509_crt_parse returned -0x%x\n\n", -ret); return ret; } DEBUG(" ok (%d skipped)\n", ret); DEBUG(" . Loading the client cert. and key..."); ret = mbedtls_x509_crt_parse_file(&clicert, params.pDeviceCertLocation); if (ret != 0) { ERROR(" failed\n ! mbedtls_x509_crt_parse returned -0x%x\n\n", -ret); return ret; } ret = mbedtls_pk_parse_keyfile(&pkey, params.pDevicePrivateKeyLocation, ""); if (ret != 0) { ERROR(" failed\n ! mbedtls_pk_parse_key returned -0x%x\n\n", -ret); return ret; } DEBUG(" ok\n"); char portBuffer[6]; sprintf(portBuffer, "%d", params.DestinationPort); DEBUG(" . Connecting to %s/%s...", params.pDestinationURL, portBuffer); if ((ret = mbedtls_net_connect(&server_fd, params.pDestinationURL, portBuffer, MBEDTLS_NET_PROTO_TCP)) != 0) { ERROR(" failed\n ! mbedtls_net_connect returned -0x%x\n\n", -ret); return ret; } ret = mbedtls_net_set_block(&server_fd); if (ret != 0) { ERROR(" failed\n ! net_set_(non)block() returned -0x%x\n\n", -ret); return ret; } DEBUG(" ok\n"); DEBUG(" . Setting up the SSL/TLS structure..."); if ((ret = mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0) { ERROR(" failed\n ! mbedtls_ssl_config_defaults returned -0x%x\n\n", -ret); return ret; } mbedtls_ssl_conf_verify(&conf, myCertVerify, NULL); if (params.ServerVerificationFlag == true) { mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_REQUIRED); } else { mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_OPTIONAL); } mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg); mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL); if ((ret = mbedtls_ssl_conf_own_cert(&conf, &clicert, &pkey)) != 0) { ERROR(" failed\n ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret); return ret; } mbedtls_ssl_conf_read_timeout(&conf, params.timeout_ms); if ((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) { ERROR(" failed\n ! mbedtls_ssl_setup returned -0x%x\n\n", -ret); return ret; } if ((ret = mbedtls_ssl_set_hostname(&ssl, params.pDestinationURL)) != 0) { ERROR(" failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", ret); return ret; } mbedtls_ssl_set_bio(&ssl, &server_fd, mbedtls_net_send, NULL, mbedtls_net_recv_timeout); DEBUG(" ok\n"); DEBUG(" . Performing the SSL/TLS handshake..."); while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) { if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { ERROR(" failed\n ! mbedtls_ssl_handshake returned -0x%x\n", -ret); if (ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) { ERROR(" Unable to verify the server's certificate. " "Either it is invalid,\n" " or you didn't set ca_file or ca_path " "to an appropriate value.\n" " Alternatively, you may want to use " "auth_mode=optional for testing purposes.\n"); } return ret; } } DEBUG(" ok\n [ Protocol is %s ]\n [ Ciphersuite is %s ]\n", mbedtls_ssl_get_version(&ssl), mbedtls_ssl_get_ciphersuite(&ssl)); if ((ret = mbedtls_ssl_get_record_expansion(&ssl)) >= 0) { DEBUG(" [ Record expansion is %d ]\n", ret); } else { DEBUG(" [ Record expansion is unknown (compression) ]\n"); } DEBUG(" . Verifying peer X.509 certificate..."); if (params.ServerVerificationFlag == true) { if ((flags = mbedtls_ssl_get_verify_result(&ssl)) != 0) { char vrfy_buf[512]; ERROR(" failed\n"); mbedtls_x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), " ! ", flags); ERROR("%s\n", vrfy_buf); } else { DEBUG(" ok\n"); ret = NONE_ERROR; } } else { DEBUG(" Server Verification skipped\n"); ret = NONE_ERROR; } if (mbedtls_ssl_get_peer_cert(&ssl) != NULL) { DEBUG(" . Peer certificate information ...\n"); mbedtls_x509_crt_info((char *) buf, sizeof(buf) - 1, " ", mbedtls_ssl_get_peer_cert(&ssl)); DEBUG("%s\n", buf); } mbedtls_ssl_conf_read_timeout(&conf, 10); return ret; }
static int Server_init_ssl(Server *srv) { int rc = 0; bstring certdir = NULL; bstring certpath = NULL; bstring keypath = NULL; bstring certdir_setting = Setting_get_str("certdir", NULL); check(certdir_setting != NULL, "to use ssl, you must specify a certdir"); if(srv->chroot != NULL && !Unixy_in_chroot()) { certdir = bformat("%s%s", bdata(srv->chroot), bdata(certdir_setting)); } else { certdir = bstrcpy(certdir_setting); } certpath = bformat("%s%s.crt", bdata(certdir), bdata(srv->uuid)); check_mem(certpath); keypath = bformat("%s%s.key", bdata(certdir), bdata(srv->uuid)); check_mem(keypath); rc = mbedtls_x509_crt_parse_file(&srv->own_cert, bdata(certpath)); check(rc == 0, "Failed to load cert from %s", bdata(certpath)); rc = mbedtls_pk_parse_keyfile(&srv->pk_key, bdata(keypath), NULL); check(rc == 0, "Failed to load key from %s", bdata(keypath)); bstring ssl_ciphers_val = Setting_get_str("ssl_ciphers", NULL); bstring ca_chain = Setting_get_str("ssl.ca_chain", NULL); if ( ca_chain != NULL ) { rc = mbedtls_x509_crt_parse_file(&srv->ca_chain, bdata(ca_chain)); check(rc == 0, "Failed to load cert from %s", bdata(ca_chain)); } else { //to indicate no ca_chain was loaded srv->ca_chain.version=-1; } if(ssl_ciphers_val != NULL) { rc = Server_load_ciphers(srv, ssl_ciphers_val); check(rc == 0, "Failed to load requested SSL ciphers."); } else { srv->ciphers = mbedtls_ssl_list_ciphersuites(); } srv->dhm_P = MBEDTLS_DHM_RFC5114_MODP_2048_P; srv->dhm_G = MBEDTLS_DHM_RFC5114_MODP_2048_G; bdestroy(certdir); bdestroy(certpath); bdestroy(keypath); return 0; error: // Do not free certdir_setting, as we're pulling it from Settings if(certdir != NULL) bdestroy(certdir); if(certpath != NULL) bdestroy(certpath); if(keypath != NULL) bdestroy(keypath); return -1; }
rb_ssl_ctx * rb_setup_ssl_server(const char *cacert, const char *cert, const char *keyfile, const char *dhfile, const char *ssl_cipher_list, const char *named_curve, rb_tls_ver_t tls_min_ver) { int ret; rb_ssl_ctx *sctx; sctx = rb_malloc(sizeof(rb_ssl_ctx)); mbedtls_ssl_config_init(&sctx->config); // mbedtls_entropy_init(&sctx->entropy); // mbedtls_ctr_drbg_init(&sctx->ctr_drbg); mbedtls_ssl_conf_rng(&sctx->config, mbedtls_ctr_drbg_random, &ctr_drbg); if ((ret = mbedtls_ssl_config_defaults(&sctx->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; } mbedtls_ssl_conf_rng(&sctx->config, mbedtls_ctr_drbg_random, &ctr_drbg); if(cacert != NULL) { mbedtls_x509_crt_init(&sctx->cacert); ret = mbedtls_x509_crt_parse_file(&sctx->cacert, cacert); if(ret != 0) { rb_lib_log("rb_setup_ssl_server: failed to parse CA certificate '%s': -0x%x", cert, -ret); return 0; } } mbedtls_x509_crt_init(&sctx->x509); ret = mbedtls_x509_crt_parse_file(&sctx->x509, cert); if (ret != 0) { rb_lib_log("rb_setup_ssl_server: failed to parse certificate '%s': -0x%x", cert, -ret); return 0; } mbedtls_pk_init(&sctx->serv_pk); ret = mbedtls_pk_parse_keyfile(&sctx->serv_pk, keyfile, NULL); if (ret != 0) { rb_lib_log("rb_setup_ssl_server: failed to parse private key '%s': -0x%x", keyfile, -ret); return 0; } mbedtls_dhm_init(&sctx->dh_params); ret = mbedtls_dhm_parse_dhmfile(&sctx->dh_params, dhfile); if (ret != 0) { rb_lib_log("rb_setup_ssl_server: failed to parse DH parameters '%s': -0x%x", dhfile, -ret); return 0; } ret = mbedtls_ssl_conf_dh_param_ctx(&sctx->config, &sctx->dh_params); if (ret != 0) { rb_lib_log("rb_setup_ssl_server: failed to set DH parameters on SSL config context: -0x%x", -ret); return 0; } if (&sctx->x509.next) mbedtls_ssl_conf_ca_chain(&sctx->config, sctx->x509.next, NULL); mbedtls_ssl_conf_ca_chain(&sctx->config, &sctx->cacert, NULL); if ((ret = mbedtls_ssl_conf_own_cert(&sctx->config, &sctx->x509, &sctx->serv_pk)) != 0) { rb_lib_log("rb_setup_ssl_server: failed to set up own certificate: -0x%x", -ret); return 0; } return sctx; }
int main( int argc, char *argv[] ) { FILE *f; int ret = 1; mbedtls_pk_context pk; mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; unsigned char hash[32]; unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; char filename[512]; const char *pers = "rsa_sign_pss"; size_t olen = 0; mbedtls_entropy_init( &entropy ); mbedtls_pk_init( &pk ); mbedtls_ctr_drbg_init( &ctr_drbg ); if( argc != 3 ) { mbedtls_printf( "usage: rsa_sign_pss <key_file> <filename>\n" ); #if defined(_WIN32) mbedtls_printf( "\n" ); #endif goto exit; } 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( "\n . Reading private key from '%s'", argv[1] ); fflush( stdout ); if( ( ret = mbedtls_pk_parse_keyfile( &pk, argv[1], "" ) ) != 0 ) { ret = 1; mbedtls_printf( " failed\n ! Could not read key from '%s'\n", argv[1] ); mbedtls_printf( " ! mbedtls_pk_parse_public_keyfile returned %d\n\n", ret ); goto exit; } if( !mbedtls_pk_can_do( &pk, MBEDTLS_PK_RSA ) ) { ret = 1; mbedtls_printf( " failed\n ! Key is not an RSA key\n" ); goto exit; } mbedtls_rsa_set_padding( mbedtls_pk_rsa( pk ), MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256 ); /* * Compute the SHA-256 hash of the input file, * then calculate the RSA signature of the hash. */ mbedtls_printf( "\n . Generating the RSA/SHA-256 signature" ); fflush( stdout ); if( ( ret = mbedtls_md_file( mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ), argv[2], hash ) ) != 0 ) { mbedtls_printf( " failed\n ! Could not open or read %s\n\n", argv[2] ); goto exit; } if( ( ret = mbedtls_pk_sign( &pk, MBEDTLS_MD_SHA256, hash, 0, buf, &olen, mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_pk_sign returned %d\n\n", ret ); goto exit; } /* * Write the signature into <filename>.sig */ mbedtls_snprintf( filename, 512, "%s.sig", argv[2] ); if( ( f = fopen( filename, "wb+" ) ) == NULL ) { ret = 1; mbedtls_printf( " failed\n ! Could not create %s\n\n", filename ); goto exit; } if( fwrite( buf, 1, olen, f ) != olen ) { mbedtls_printf( "failed\n ! fwrite failed\n\n" ); goto exit; } fclose( f ); mbedtls_printf( "\n . Done (created \"%s\")\n\n", filename ); exit: mbedtls_pk_free( &pk ); 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 main( int argc, char *argv[] ) { FILE *f; int ret = 1; int exit_code = MBEDTLS_EXIT_FAILURE; mbedtls_pk_context pk; mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; unsigned char hash[32]; unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; char filename[512]; const char *pers = "mbedtls_pk_sign"; size_t olen = 0; mbedtls_entropy_init( &entropy ); mbedtls_ctr_drbg_init( &ctr_drbg ); mbedtls_pk_init( &pk ); if( argc != 3 ) { mbedtls_printf( "usage: mbedtls_pk_sign <key_file> <filename>\n" ); #if defined(_WIN32) mbedtls_printf( "\n" ); #endif goto exit; } 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 -0x%04x\n", -ret ); goto exit; } mbedtls_printf( "\n . Reading private key from '%s'", argv[1] ); fflush( stdout ); if( ( ret = mbedtls_pk_parse_keyfile( &pk, argv[1], "" ) ) != 0 ) { mbedtls_printf( " failed\n ! Could not parse '%s'\n", argv[1] ); goto exit; } /* * Compute the SHA-256 hash of the input file, * then calculate the signature of the hash. */ mbedtls_printf( "\n . Generating the SHA-256 signature" ); fflush( stdout ); if( ( ret = mbedtls_md_file( mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ), argv[2], hash ) ) != 0 ) { mbedtls_printf( " failed\n ! Could not open or read %s\n\n", argv[2] ); goto exit; } if( ( ret = mbedtls_pk_sign( &pk, MBEDTLS_MD_SHA256, hash, 0, buf, &olen, mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_pk_sign returned -0x%04x\n", -ret ); goto exit; } /* * Write the signature into <filename>.sig */ mbedtls_snprintf( filename, sizeof(filename), "%s.sig", argv[2] ); if( ( f = fopen( filename, "wb+" ) ) == NULL ) { mbedtls_printf( " failed\n ! Could not create %s\n\n", filename ); goto exit; } if( fwrite( buf, 1, olen, f ) != olen ) { mbedtls_printf( "failed\n ! fwrite failed\n\n" ); fclose( f ); goto exit; } fclose( f ); mbedtls_printf( "\n . Done (created \"%s\")\n\n", filename ); exit_code = MBEDTLS_EXIT_SUCCESS; exit: mbedtls_pk_free( &pk ); mbedtls_ctr_drbg_free( &ctr_drbg ); mbedtls_entropy_free( &entropy ); #if defined(MBEDTLS_ERROR_C) if( exit_code != MBEDTLS_EXIT_SUCCESS ) { mbedtls_strerror( ret, (char *) buf, sizeof(buf) ); mbedtls_printf( " ! Last error was: %s\n", buf ); } #endif #if defined(_WIN32) mbedtls_printf( " + Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif return( exit_code ); }