static int belle_sip_certificate_fill(belle_sip_certificates_chain_t* certificate,const char* buff, size_t size,belle_sip_certificate_raw_format_t format) { #ifdef HAVE_POLARSSL int err; #if POLARSSL_VERSION_NUMBER < 0x01030000 if ((err=x509parse_crt(&certificate->cert,(const unsigned char *)buff,size)) <0) { #else if ((err=x509_crt_parse(&certificate->cert,(const unsigned char *)buff,size)) <0) { #endif char tmp[128]; error_strerror(err,tmp,sizeof(tmp)); belle_sip_error("cannot parse x509 cert because [%s]",tmp); return -1; } return 0; #else /*HAVE_POLARSSL*/ return -1; #endif } static int belle_sip_certificate_fill_from_file(belle_sip_certificates_chain_t* certificate,const char* path,belle_sip_certificate_raw_format_t format) { #ifdef HAVE_POLARSSL int err; #if POLARSSL_VERSION_NUMBER < 0x01030000 if ((err=x509parse_crtfile(&certificate->cert, path)) <0) { #else if ((err=x509_crt_parse_file(&certificate->cert, path)) <0) { #endif char tmp[128]; error_strerror(err,tmp,sizeof(tmp)); belle_sip_error("cannot parse x509 cert because [%s]",tmp); return -1; } return 0; #else /*HAVE_POLARSSL*/ return -1; #endif } /*belle_sip_certificate */ belle_sip_certificates_chain_t* belle_sip_certificates_chain_parse(const char* buff, size_t size,belle_sip_certificate_raw_format_t format) { belle_sip_certificates_chain_t* certificate = belle_sip_object_new(belle_sip_certificates_chain_t); if (belle_sip_certificate_fill(certificate,buff, size,format)) { belle_sip_object_unref(certificate); certificate=NULL; } return certificate; }
int rsa_get_public_key_fingerprint(rsa_context *rsa, uint64_t *fingerprint, char fingerprint_ascii[FLETCHER_SIZE_STR]) { int ret; if ((ret = rsa_check_pubkey(rsa)) != 0) { char err[128]; error_strerror(ret, err, sizeof err); dolog(D_ENC, "ERROR verifying public key: %s\n", err); return -ERR_NO_PUBKEY; } uint8_t pk[2048]; // public key is not bigger than this int pk_len = asn1_encode_public_key_der(pk, sizeof pk, rsa); if (pk_len <= 0) { return -ERR_UNKNOWN(901); } uint64_t fp; if (fingerprint == NULL ) { fingerprint = &fp; } *fingerprint = fletcher64(pk, pk_len); if (fingerprint_ascii) fletcher64_to_str(fingerprint_ascii, fingerprint); return 0; }
int main( int argc, char *argv[] ) { int ret; if( argc != 2 ) { printf( USAGE ); return( 0 ); } ret = atoi( argv[1] ); if( ret > 0 ) ret = - ret; if( ret != 0 ) { char error_buf[200]; error_strerror( ret, error_buf, 200 ); printf("Last error was: %d - %s\n\n", ret, error_buf ); } #if defined(_WIN32) printf( " + Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif return( ret ); }
int do_handshake( ssl_context *ssl, struct options *opt ) { int ret; unsigned char buf[1024]; memset(buf, 0, 1024); /* * 4. Handshake */ printf( " . Performing the SSL/TLS handshake..." ); fflush( stdout ); while( ( ret = ssl_handshake( ssl ) ) != 0 ) { if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE ) { #if defined(POLARSSL_ERROR_C) error_strerror( ret, (char *) buf, 1024 ); #endif printf( " failed\n ! ssl_handshake returned %d: %s\n\n", ret, buf ); return( -1 ); } } printf( " ok\n [ Ciphersuite is %s ]\n", ssl_get_ciphersuite( ssl ) ); /* * 5. Verify the server certificate */ printf( " . Verifying peer X.509 certificate..." ); if( ( ret = ssl_get_verify_result( ssl ) ) != 0 ) { printf( " failed\n" ); if( ( ret & BADCERT_EXPIRED ) != 0 ) printf( " ! server certificate has expired\n" ); if( ( ret & BADCERT_REVOKED ) != 0 ) printf( " ! server certificate has been revoked\n" ); if( ( ret & BADCERT_CN_MISMATCH ) != 0 ) printf( " ! CN mismatch (expected CN=%s)\n", opt->server_name ); if( ( ret & BADCERT_NOT_TRUSTED ) != 0 ) printf( " ! self-signed or not signed by a trusted CA\n" ); printf( "\n" ); } else printf( " ok\n" ); printf( " . Peer certificate information ...\n" ); x509parse_cert_info( (char *) buf, sizeof( buf ) - 1, " ", ssl_get_peer_cert( ssl ) ); printf( "%s\n", buf ); return( 0 ); }
static void print_ssl_error(char *message, int code) { char cause[1024]; error_strerror(code, cause, 1023); cause[1023] = '\0'; fprintf(stderr, "%s (-0x%X): %s\n", message, -code, cause); }
static int tls_channel_send(belle_sip_channel_t *obj, const void *buf, size_t buflen){ belle_sip_tls_channel_t* channel = (belle_sip_tls_channel_t*)obj; int err = ssl_write(&channel->sslctx,buf,buflen); if (err<0){ char tmp[256]={0}; error_strerror(err,tmp,sizeof(tmp)); belle_sip_error("Channel [%p]: ssl_write() error [%i]: %s",obj,err,tmp); } return err; }
int32_t bctbx_signing_key_parse(bctbx_signing_key_t *key, const char *buffer, size_t buffer_length, const unsigned char *password, size_t password_length) { int err; err=x509parse_key((rsa_context *)key, (const unsigned char *)buffer, buffer_length+1, password, password_length); if (err<0) { char tmp[128]; error_strerror(err,tmp,sizeof(tmp)); bctbx_error("cannot parse public key because [%s]",tmp); return BCTBX_ERROR_UNABLE_TO_PARSE_KEY; } return 0; }
int32_t bctbx_signing_key_parse_file(bctbx_signing_key_t *key, const char *path, const char *password) { int err; err=x509parse_keyfile((rsa_context *)key, path, password); if (err<0) { char tmp[128]; error_strerror(err,tmp,sizeof(tmp)); bctbx_error("cannot parse public key because [%s]",tmp); return BCTBX_ERROR_UNABLE_TO_PARSE_KEY; } return 0; }
static int tls_channel_recv(belle_sip_channel_t *obj, void *buf, size_t buflen){ belle_sip_tls_channel_t* channel = (belle_sip_tls_channel_t*)obj; int err = ssl_read(&channel->sslctx,buf,buflen); if (err==POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY) return 0; if (err<0){ char tmp[256]={0}; if (err==POLARSSL_ERR_NET_WANT_READ) return -BELLESIP_EWOULDBLOCK; error_strerror(err,tmp,sizeof(tmp)); belle_sip_error("Channel [%p]: ssl_read() error [%i]: %s",obj, err, tmp); } return err; }
int CTTLS::_send(const char *buf, int iLen) { ssl_context *ssl=&((T_SSL*)pSSL)->ssl; if(!iConnected)return -1001; if(iClosed)return -1002; if(iCertFailed) { Sleep(30); return -1003; } int ret=0; int iShouldDisconnect=0; while( ( ret = ssl_write( ssl, (const unsigned char *)buf, iLen ) ) <= 0 ) { if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE ) { iShouldDisconnect=1; Sleep(5); break; } if(!iConnected)break; if(ret == POLARSSL_ERR_NET_WANT_READ) { iWaitForRead=1; for(int i=0; i<5 && iWaitForRead; i++) Sleep(20); } } void tmp_log(const char *p); char d[64]; sprintf(d, "[ssl-send=%p %.*s l=%d ret=%d]",ssl, 7,buf, iLen, ret); tmp_log(d); if(ret<0) { if(ret==POLARSSL_ERR_NET_CONN_RESET || ret==POLARSSL_ERR_NET_SEND_FAILED) { iShouldDisconnect=1; } if(iShouldDisconnect) { addrConnected.clear(); iConnected=0; tmp_log("tls_send err clear connaddr"); } error_strerror(ret,&bufErr[0],sizeof(bufErr)-1); tivi_slog(" send[%s]%d",&bufErr[0],iShouldDisconnect); } else { //TODO msg("getCS",5,void *p, int iSize); // tivi_slog( " [ Ciphersuite is %s ]\n", ssl_get_ciphersuite( ssl ) ); } return ret; }
void bctbx_strerror(int32_t error_code, char *buffer, size_t buffer_length) { if (error_code>0) { snprintf(buffer, buffer_length, "%s", "Invalid Error code"); return ; } /* polarssl error code are all negatived and bas smaller than 0x0000F000 */ /* bctoolbox defined error codes are all in format -0x7XXXXXXX */ if (-error_code<0x00010000) { /* it's a polarssl error code */ error_strerror(error_code, buffer, buffer_length); return; } snprintf(buffer, buffer_length, "%s [-0x%x]", "bctoolbox defined error code", -error_code); return; }
static void log_polarssl_error(int error_code, char const* file, int line) { if (tr_logLevelIsActive(TR_LOG_ERROR)) { char error_message[256]; #if defined(POLARSSL_IS_MBEDTLS) mbedtls_strerror(error_code, error_message, sizeof(error_message)); #elif API_VERSION_NUMBER >= 0x01030000 polarssl_strerror(error_code, error_message, sizeof(error_message)); #else error_strerror(error_code, error_message, sizeof(error_message)); #endif tr_logAddMessage(file, line, TR_LOG_ERROR, MY_NAME, "PolarSSL error: %s", error_message); } }
/* * Returns: self | nil, string */ static int lssl_seterror (lua_State *L, int err) { if (!err) { lua_settop(L, 1); return 1; } lua_pushnil(L); { char buf[256]; error_strerror(err, buf, sizeof(buf)); lua_pushstring(L, buf); } lua_pushvalue(L, -1); lua_setglobal(L, LSSL_ERROR_MESSAGE); return 2; }
static int tls_process_handshake(belle_sip_channel_t *obj){ belle_sip_tls_channel_t* channel=(belle_sip_tls_channel_t*)obj; int err=tls_channel_handshake(channel); if (err==0){ belle_sip_message("Channel [%p]: SSL handshake finished.",obj); belle_sip_source_set_timeout((belle_sip_source_t*)obj,-1); belle_sip_message("Calling channel ready from the ssll "); belle_sip_channel_set_ready(obj,(struct sockaddr*)&channel->ss,channel->socklen); }else if (err==POLARSSL_ERR_NET_WANT_READ || err==POLARSSL_ERR_NET_WANT_WRITE){ belle_sip_message("Channel [%p]: SSL handshake in progress...",obj); }else{ char tmp[128]; error_strerror(err,tmp,sizeof(tmp)); belle_sip_error("Channel [%p]: SSL handshake failed : %s",obj,tmp); return -1; } return 0; }
BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_END static int tls_channel_handshake(belle_sip_tls_channel_t *channel) { int ret; while( channel->sslctx.state != SSL_HANDSHAKE_OVER ) { if ((ret = ssl_handshake_step( &channel->sslctx ))) { break; } if (channel->sslctx.state == SSL_CLIENT_CERTIFICATE && channel->sslctx.client_auth >0) { BELLE_SIP_INVOKE_LISTENERS_ARG1_ARG2( channel->base.base.listeners ,belle_sip_channel_listener_t ,on_auth_requested ,&channel->base.base ,NULL/*not set yet*/); if (channel->client_cert_chain && channel->client_cert_key) { #if POLARSSL_VERSION_NUMBER >= 0x01030000 int err; #endif char tmp[512]={0}; #if POLARSSL_VERSION_NUMBER < 0x01030000 x509parse_cert_info(tmp,sizeof(tmp)-1,"",&channel->client_cert_chain->cert); #else x509_crt_info(tmp,sizeof(tmp)-1,"",&channel->client_cert_chain->cert); #endif belle_sip_message("Channel [%p] found client certificate:\n%s",channel,tmp); #if POLARSSL_VERSION_NUMBER < 0x01030000 ssl_set_own_cert(&channel->sslctx,&channel->client_cert_chain->cert,&channel->client_cert_key->key); #else /* allows public keys other than RSA */ if ((err=ssl_set_own_cert(&channel->sslctx,&channel->client_cert_chain->cert,&channel->client_cert_key->key))) { error_strerror(err,tmp,sizeof(tmp)-1); belle_sip_error("Channel [%p] cannot ssl_set_own_cert [%s]",channel,tmp); } /*update own cert see ssl_handshake frompolarssl*/ channel->sslctx.handshake->key_cert = channel->sslctx.key_cert; #endif } } } return ret; }
static void ngx_cdecl ngx_mbedtls_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, int sslerr, char *fmt, ...) { va_list args; u_char *p, *last; u_char errstr[NGX_MAX_CONF_ERRSTR]; last = errstr + NGX_MAX_CONF_ERRSTR; va_start(args, fmt); p = ngx_vslprintf(errstr, last - 1, fmt, args); va_end(args); p = ngx_cpystrn(p, (u_char *) " (SSL:", last - p); error_strerror(sslerr, (char *) p, last - p); ngx_log_error(level, log, err, "%s", errstr); }
static CURLcode polarssl_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]; memset(errorbuf, 0, sizeof(errorbuf)); /* PolarSSL only supports SSLv3 and TLSv1 */ if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) { failf(data, "PolarSSL does not support SSLv2"); return CURLE_SSL_CONNECT_ERROR; } else if(data->set.ssl.version == CURL_SSLVERSION_SSLv3) sni = FALSE; /* SSLv3 has no SNI */ #if POLARSSL_VERSION_NUMBER<0x01010000 havege_init(&connssl->hs); #else #ifdef THREADING_SUPPORT entropy_init_mutex(&entropy); if((ret = ctr_drbg_init(&connssl->ctr_drbg, entropy_func_mutex, &entropy, connssl->ssn.id, connssl->ssn.length)) != 0) { #ifdef POLARSSL_ERROR_C error_strerror(ret, errorbuf, sizeof(errorbuf)); #endif /* POLARSSL_ERROR_C */ failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n", -ret, errorbuf); } #else entropy_init(&connssl->entropy); if((ret = ctr_drbg_init(&connssl->ctr_drbg, entropy_func, &connssl->entropy, connssl->ssn.id, connssl->ssn.length)) != 0) { #ifdef POLARSSL_ERROR_C error_strerror(ret, errorbuf, sizeof(errorbuf)); #endif /* POLARSSL_ERROR_C */ failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n", -ret, errorbuf); } #endif /* THREADING_SUPPORT */ #endif /* POLARSSL_VERSION_NUMBER<0x01010000 */ /* Load the trusted CA */ memset(&connssl->cacert, 0, sizeof(x509_cert)); if(data->set.str[STRING_SSL_CAFILE]) { ret = x509parse_crtfile(&connssl->cacert, data->set.str[STRING_SSL_CAFILE]); if(ret<0) { #ifdef POLARSSL_ERROR_C error_strerror(ret, errorbuf, sizeof(errorbuf)); #endif /* POLARSSL_ERROR_C */ failf(data, "Error reading ca cert file %s - PolarSSL: (-0x%04X) %s", data->set.str[STRING_SSL_CAFILE], -ret, errorbuf); if(data->set.ssl.verifypeer) return CURLE_SSL_CACERT_BADFILE; } } /* Load the client certificate */ memset(&connssl->clicert, 0, sizeof(x509_cert)); if(data->set.str[STRING_CERT]) { ret = x509parse_crtfile(&connssl->clicert, data->set.str[STRING_CERT]); if(ret) { #ifdef POLARSSL_ERROR_C error_strerror(ret, errorbuf, sizeof(errorbuf)); #endif /* POLARSSL_ERROR_C */ failf(data, "Error reading client cert file %s - PolarSSL: (-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]) { ret = x509parse_keyfile(&connssl->rsa, data->set.str[STRING_KEY], data->set.str[STRING_KEY_PASSWD]); if(ret) { #ifdef POLARSSL_ERROR_C error_strerror(ret, errorbuf, sizeof(errorbuf)); #endif /* POLARSSL_ERROR_C */ failf(data, "Error reading private key %s - PolarSSL: (-0x%04X) %s", data->set.str[STRING_KEY], -ret, errorbuf); return CURLE_SSL_CERTPROBLEM; } } /* Load the CRL */ memset(&connssl->crl, 0, sizeof(x509_crl)); if(data->set.str[STRING_SSL_CRLFILE]) { ret = x509parse_crlfile(&connssl->crl, data->set.str[STRING_SSL_CRLFILE]); if(ret) { #ifdef POLARSSL_ERROR_C error_strerror(ret, errorbuf, sizeof(errorbuf)); #endif /* POLARSSL_ERROR_C */ failf(data, "Error reading CRL file %s - PolarSSL: (-0x%04X) %s", data->set.str[STRING_SSL_CRLFILE], -ret, errorbuf); return CURLE_SSL_CRL_BADFILE; } } infof(data, "PolarSSL: Connecting to %s:%d\n", conn->host.name, conn->remote_port); if(ssl_init(&connssl->ssl)) { failf(data, "PolarSSL: ssl_init failed"); return CURLE_SSL_CONNECT_ERROR; } ssl_set_endpoint(&connssl->ssl, SSL_IS_CLIENT); ssl_set_authmode(&connssl->ssl, SSL_VERIFY_OPTIONAL); #if POLARSSL_VERSION_NUMBER<0x01010000 ssl_set_rng(&connssl->ssl, havege_rand, &connssl->hs); #else ssl_set_rng(&connssl->ssl, ctr_drbg_random, &connssl->ctr_drbg); #endif /* POLARSSL_VERSION_NUMBER<0x01010000 */ ssl_set_bio(&connssl->ssl, net_recv, &conn->sock[sockindex], net_send, &conn->sock[sockindex]); #if POLARSSL_VERSION_NUMBER<0x01000000 ssl_set_ciphers(&connssl->ssl, ssl_default_ciphers); #else ssl_set_ciphersuites(&connssl->ssl, ssl_default_ciphersuites); #endif if(!Curl_ssl_getsessionid(conn, &old_session, &old_session_size)) { memcpy(&connssl->ssn, old_session, old_session_size); infof(data, "PolarSSL re-using session\n"); } /* PolarSSL SVN revision r1316 to r1317, matching <1.2.0 is to cover Ubuntu's 1.1.4 version and the like */ #if POLARSSL_VERSION_NUMBER<0x01020000 ssl_set_session(&connssl->ssl, 1, 600, &connssl->ssn); #else ssl_set_session(&connssl->ssl, &connssl->ssn); #endif ssl_set_ca_chain(&connssl->ssl, &connssl->cacert, &connssl->crl, conn->host.name); ssl_set_own_cert(&connssl->ssl, &connssl->clicert, &connssl->rsa); if(!Curl_inet_pton(AF_INET, conn->host.name, &addr) && #ifdef ENABLE_IPV6 !Curl_inet_pton(AF_INET6, conn->host.name, &addr) && #endif sni && ssl_set_hostname(&connssl->ssl, conn->host.name)) { infof(data, "WARNING: failed to configure " "server name indication (SNI) TLS extension\n"); } #ifdef POLARSSL_DEBUG ssl_set_dbg(&connssl->ssl, polarssl_debug, data); #endif connssl->connecting_state = ssl_connect_2; return CURLE_OK; }
/** * @brief SSL Server task. * @param pvParameters not used * @retval None */ void ssl_server(void const * argument) { int ret, len; int listen_fd; int client_fd = -1; unsigned char buf[1524]; ssl_context ssl; x509_cert srvcert; rsa_context rsa; #if defined(POLARSSL_SSL_CACHE_C) ssl_cache_context cache; ssl_cache_init( &cache ); #endif /* * Load the certificates and private RSA key */ printf( "\n . Loading the server cert. and key..." ); memset( &srvcert, 0, sizeof( x509_cert ) ); /* * This demonstration program uses embedded test certificates. * Instead, you may want to use x509parse_crtfile() to read the * server and CA certificates, as well as x509parse_keyfile(). */ ret = x509parse_crt( &srvcert, (const unsigned char *) test_srv_crt, strlen( test_srv_crt ) ); if( ret != 0 ) { printf( " failed\n ! x509parse_crt returned %d\n\n", ret ); goto exit; } ret = x509parse_crt( &srvcert, (const unsigned char *) test_ca_crt, strlen( test_ca_crt ) ); if( ret != 0 ) { printf( " failed\n ! x509parse_crt returned %d\n\n", ret ); goto exit; } rsa_init( &rsa, RSA_PKCS_V15, 0 ); ret = x509parse_key( &rsa, (const unsigned char *) test_srv_key, strlen( test_srv_key ), NULL, 0 ); if( ret != 0 ) { printf( " failed\n ! x509parse_key returned %d\n\n", ret ); goto exit; } printf( " ok\n\r" ); /* * Setup the listening TCP socket */ printf( " . Bind on https://localhost:443/ ..." ); if( ( ret = net_bind( &listen_fd, NULL, 443) ) != 0 ) { printf( " failed\n ! net_bind returned %d\n\n", ret ); goto exit; } printf( " ok\n\r" ); /* * Setup stuff */ printf( " . Setting up the SSL data...." ); if( ( ret = ssl_init( &ssl ) ) != 0 ) { printf( " failed\n ! ssl_init returned %d\n\n", ret ); goto reset; } ssl_set_endpoint( &ssl, SSL_IS_SERVER ); ssl_set_authmode( &ssl, SSL_VERIFY_NONE ); ssl_set_rng( &ssl, RandVal , NULL ); ssl_set_dbg( &ssl, my_debug, stdout ); #if defined(POLARSSL_SSL_CACHE_C) ssl_set_session_cache( &ssl, ssl_cache_get, &cache, ssl_cache_set, &cache ); #endif ssl_set_ca_chain( &ssl, srvcert.next, NULL, NULL ); ssl_set_own_cert( &ssl, &srvcert, &rsa ); ssl_set_bio( &ssl, net_recv, &client_fd, net_send, &client_fd ); printf( " ok\n\r" ); for(;;) { /* * Wait until a client connects */ client_fd = -1; printf( " . Waiting for a remote connection ..." ); if( ( ret = net_accept( listen_fd, &client_fd, NULL ) ) != 0 ) { printf( " failed\n ! net_accept returned %d\n\n", ret ); goto exit; } printf( " ok\n\r" ); /* * Handshake */ printf( " . Performing the SSL/TLS handshake..." ); while( ( ret = ssl_handshake( &ssl ) ) != 0 ) { if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE ) { printf( " failed\n ! ssl_handshake returned -0x%x\n\n", -ret ); goto reset; } } printf( " ok\n\r" ); /* * Read the HTTP Request */ printf( " < Read from client:" ); memset( buf, 0, sizeof( buf ) ); len = 0; do { ret = ssl_read( &ssl, buf + len, 1523 - len); if( ret == POLARSSL_ERR_NET_WANT_READ || ret == POLARSSL_ERR_NET_WANT_WRITE ) continue; if( ret <= 0 ) { switch( ret ) { case POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY: printf( " connection was closed gracefully\n" ); break; case POLARSSL_ERR_NET_CONN_RESET: printf( " connection was reset by peer\n" ); break; default: printf( " ssl_read returned -0x%x\n", -ret ); break; } break; } len += ret; if( ret > 1 ) break; } while( 1 ); printf( " %d bytes read\n\r", len); /* * Write the 200 Response */ printf( " > Write to client: " ); /* Send the dynamic html page */ ssl_DynPage(&ssl); goto reset; exit: #ifdef POLARSSL_ERROR_C if( ret != 0 ) { char error_buf[100]; error_strerror( ret, error_buf, 100 ); printf("Last error was: %d - %s\n\n", ret, error_buf ); } #endif x509_free( &srvcert ); rsa_free( &rsa ); ssl_free( &ssl ); #if defined(POLARSSL_SSL_CACHE_C) ssl_cache_free( &cache ); #endif reset: if (client_fd != -1) net_close(client_fd); ssl_session_reset( &ssl ); } }
/** * @brief SSL client task. * @param pvParameters not used * @retval None */ void ssl_client(void const * argument) { int ret, len, server_fd; unsigned char buf[1024]; ssl_context ssl; x509_cert cacert; memset( &ssl, 0, sizeof( ssl_context ) ); memset( &cacert, 0, sizeof( x509_cert ) ); /* * Initialize certificates */ printf( " . Loading the CA root certificate ..." ); #if defined(POLARSSL_CERTS_C) ret = x509parse_crt( &cacert, (const unsigned char *) test_ca_crt, strlen( test_ca_crt ) ); #else ret = 1; printf("POLARSSL_CERTS_C not defined."); #endif if( ret < 0 ) { printf( " failed\n ! x509parse_crt returned -0x%x\n\n", -ret ); goto exit; } printf( " ok (%d skipped)\n", ret ); /* Start the connection */ do { printf(( "\n\rSSL : Start the connection \n\r")); printf("\n\rConnecting to tcp/%s/ Port:%4d...", SSL_SERVER_NAME, SSL_SERVER_PORT); /* Bint the connection to SSL server port */ ret = net_connect(&server_fd, SSL_SERVER_NAME, SSL_SERVER_PORT); if(ret != 0) { /* Connection to SSL server failed */ printf(" failed \n\r ! net_connect returned %d\n\r", -ret); /* Wait 500 ms until next retry */ vTaskDelay(500); } }while(ret!=0); printf( " ok\n\r" ); /* * 2. Setup stuff */ printf( " . Setting up the SSL/TLS structure..." ); if( ( ret = ssl_init( &ssl ) ) != 0 ) { printf( " failed\n ! ssl_init returned %d\n\n\r", ret ); goto exit; } printf( " ok\n\r" ); ssl_set_endpoint( &ssl, SSL_IS_CLIENT ); ssl_set_authmode( &ssl, SSL_VERIFY_OPTIONAL ); ssl_set_ca_chain( &ssl, &cacert, NULL, "PolarSSL Server 1" ); ssl_set_rng( &ssl, RandVal , NULL ); ssl_set_dbg( &ssl, my_debug, NULL); ssl_set_bio( &ssl, net_recv, &server_fd, net_send, &server_fd ); /* Set max ssl version to TLS v1.1 because TLS v1.2 needs SHA-256 for HASH which is not supported by STM32F417xx Hardware*/ ssl_set_max_version( &ssl, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_2); /* * Handshake */ printf( " . Performing the SSL/TLS handshake..." ); while( ( ret = ssl_handshake( &ssl ) ) != 0 ) { if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE ) { printf( " failed\n ! ssl_handshake returned -0x%x\n\n\r", -ret ); goto exit; } } printf( " ok\n\r" ); /* * Verify the server certificate */ printf( "\n\r . Verifying peer X.509 certificate..." ); if( ( ret = ssl_get_verify_result( &ssl ) ) != 0 ) { printf( " failed\n\r" ); if( ( ret & BADCERT_EXPIRED ) != 0 ) printf( " ! server certificate has expired\n" ); if( ( ret & BADCERT_REVOKED ) != 0 ) printf( " ! server certificate has been revoked\n" ); if( ( ret & BADCERT_CN_MISMATCH ) != 0 ) printf( " ! CN mismatch (expected CN=%s)\n", "PolarSSL Server 1" ); if( ( ret & BADCERT_NOT_TRUSTED ) != 0 ) printf( " ! self-signed or not signed by a trusted CA\n" ); printf( "\n\r" ); } else printf( " ok\n\r" ); /* * Write the GET request */ printf( " > Write to server:" ); len = sprintf( (char *) buf, GET_REQUEST ); while( ( ret = ssl_write( &ssl, buf, len ) ) <= 0 ) { if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE ) { printf( " failed\n ! ssl_write returned %d\n\n\r", ret ); goto exit; } } len = ret; printf( " %d bytes written\n\n\r%s", len, (char *) buf ); /* * Read the HTTP response */ printf( " < Read from server:" ); do { len = sizeof( buf ) - 1; memset( buf, 0, sizeof( buf ) ); ret = ssl_read( &ssl, buf, len ); if( ret == POLARSSL_ERR_NET_WANT_READ || ret == POLARSSL_ERR_NET_WANT_WRITE ) continue; if( ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY ) break; if( ret < 0 ) { printf( "failed\n\r ! ssl_read returned %d\n\n\r", ret ); break; } if( ret == 0 ) { printf( "\n\nEOF\n\n\r" ); break; } len = ret; printf( " %d bytes read\n\n\r%s", len, (char *) buf ); } while( 1 ); exit: #ifdef POLARSSL_ERROR_C if( ret != 0 ) { char error_buf[100]; error_strerror( ret, error_buf, 100 ); printf("Last error was: %d - %s\n\n\r", ret, error_buf ); } #endif x509_free( &cacert ); net_close( server_fd ); ssl_free( &ssl ); memset( &ssl, 0, sizeof( ssl ) ); /* Infinite loop */ for( ;; ) { /* Toggle LED1 */ BSP_LED_Toggle(LED1); /* Insert 400 ms delay */ osDelay(400); } }
int main( int argc, char *argv[] ) { int ret, len, server_fd; unsigned char buf[1024]; char *pers = "ssl_client1"; entropy_context entropy; ctr_drbg_context ctr_drbg; ssl_context ssl; x509_cert cacert; ((void) argc); ((void) argv); /* * 0. Initialize the RNG and the session data */ memset( &ssl, 0, sizeof( ssl_context ) ); memset( &cacert, 0, sizeof( x509_cert ) ); printf( "\n . Seeding the random number generator..." ); fflush( stdout ); entropy_init( &entropy ); if( ( ret = ctr_drbg_init( &ctr_drbg, entropy_func, &entropy, (unsigned char *) pers, strlen( pers ) ) ) != 0 ) { printf( " failed\n ! ctr_drbg_init returned %d\n", ret ); goto exit; } printf( " ok\n" ); /* * 0. Initialize certificates */ printf( " . Loading the CA root certificate ..." ); fflush( stdout ); #if defined(POLARSSL_CERTS_C) ret = x509parse_crt( &cacert, (unsigned char *) test_ca_crt, strlen( test_ca_crt ) ); #else ret = 1; printf("POLARSSL_CERTS_C not defined."); #endif if( ret < 0 ) { printf( " failed\n ! x509parse_crt returned -0x%x\n\n", -ret ); goto exit; } printf( " ok (%d skipped)\n", ret ); /* * 1. Start the connection */ printf( " . Connecting to tcp/%s/%4d...", SERVER_NAME, SERVER_PORT ); fflush( stdout ); if( ( ret = net_connect( &server_fd, SERVER_NAME, SERVER_PORT ) ) != 0 ) { printf( " failed\n ! net_connect returned %d\n\n", ret ); goto exit; } printf( " ok\n" ); /* * 2. Setup stuff */ printf( " . Setting up the SSL/TLS structure..." ); fflush( stdout ); if( ( ret = ssl_init( &ssl ) ) != 0 ) { printf( " failed\n ! ssl_init returned %d\n\n", ret ); goto exit; } printf( " ok\n" ); ssl_set_endpoint( &ssl, SSL_IS_CLIENT ); ssl_set_authmode( &ssl, SSL_VERIFY_OPTIONAL ); ssl_set_ca_chain( &ssl, &cacert, NULL, "PolarSSL Server 1" ); ssl_set_rng( &ssl, ctr_drbg_random, &ctr_drbg ); ssl_set_dbg( &ssl, my_debug, stdout ); ssl_set_bio( &ssl, net_recv, &server_fd, net_send, &server_fd ); /* * 4. Handshake */ printf( " . Performing the SSL/TLS handshake..." ); fflush( stdout ); while( ( ret = ssl_handshake( &ssl ) ) != 0 ) { if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE ) { printf( " failed\n ! ssl_handshake returned -0x%x\n\n", -ret ); goto exit; } } printf( " ok\n" ); /* * 5. Verify the server certificate */ printf( " . Verifying peer X.509 certificate..." ); if( ( ret = ssl_get_verify_result( &ssl ) ) != 0 ) { printf( " failed\n" ); if( ( ret & BADCERT_EXPIRED ) != 0 ) printf( " ! server certificate has expired\n" ); if( ( ret & BADCERT_REVOKED ) != 0 ) printf( " ! server certificate has been revoked\n" ); if( ( ret & BADCERT_CN_MISMATCH ) != 0 ) printf( " ! CN mismatch (expected CN=%s)\n", "PolarSSL Server 1" ); if( ( ret & BADCERT_NOT_TRUSTED ) != 0 ) printf( " ! self-signed or not signed by a trusted CA\n" ); printf( "\n" ); } else printf( " ok\n" ); /* * 3. Write the GET request */ printf( " > Write to server:" ); fflush( stdout ); len = sprintf( (char *) buf, GET_REQUEST ); while( ( ret = ssl_write( &ssl, buf, len ) ) <= 0 ) { if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE ) { printf( " failed\n ! ssl_write returned %d\n\n", ret ); goto exit; } } len = ret; printf( " %d bytes written\n\n%s", len, (char *) buf ); /* * 7. Read the HTTP response */ printf( " < Read from server:" ); fflush( stdout ); do { len = sizeof( buf ) - 1; memset( buf, 0, sizeof( buf ) ); ret = ssl_read( &ssl, buf, len ); if( ret == POLARSSL_ERR_NET_WANT_READ || ret == POLARSSL_ERR_NET_WANT_WRITE ) continue; if( ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY ) break; if( ret < 0 ) { printf( "failed\n ! ssl_read returned %d\n\n", ret ); break; } if( ret == 0 ) { printf( "\n\nEOF\n\n" ); break; } len = ret; printf( " %d bytes read\n\n%s", len, (char *) buf ); } while( 1 ); ssl_close_notify( &ssl ); exit: #ifdef POLARSSL_ERROR_C if( ret != 0 ) { char error_buf[100]; error_strerror( ret, error_buf, 100 ); printf("Last error was: %d - %s\n\n", ret, error_buf ); } #endif x509_free( &cacert ); net_close( server_fd ); ssl_free( &ssl ); memset( &ssl, 0, sizeof( ssl ) ); #if defined(_WIN32) printf( " + Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif return( ret ); }
static CURLcode polarssl_connect_step2(struct connectdata *conn, int sockindex) { int ret; struct SessionHandle *data = conn->data; struct ssl_connect_data* connssl = &conn->ssl[sockindex]; char buffer[1024]; #ifdef HAS_ALPN const char* next_protocol; #endif char errorbuf[128]; errorbuf[0] = 0; conn->recv[sockindex] = polarssl_recv; conn->send[sockindex] = polarssl_send; for(;;) { if(!(ret = ssl_handshake(&connssl->ssl))) break; else if(ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE) { #ifdef POLARSSL_ERROR_C error_strerror(ret, errorbuf, sizeof(errorbuf)); #endif /* POLARSSL_ERROR_C */ failf(data, "ssl_handshake returned - PolarSSL: (-0x%04X) %s", -ret, errorbuf); return CURLE_SSL_CONNECT_ERROR; } else { if(ret == POLARSSL_ERR_NET_WANT_READ) { connssl->connecting_state = ssl_connect_2_reading; return CURLE_OK; } if(ret == POLARSSL_ERR_NET_WANT_WRITE) { connssl->connecting_state = ssl_connect_2_writing; return CURLE_OK; } failf(data, "SSL_connect failed with error %d.", ret); return CURLE_SSL_CONNECT_ERROR; } } infof(data, "PolarSSL: Handshake complete, cipher is %s\n", ssl_get_ciphersuite(&conn->ssl[sockindex].ssl) ); ret = ssl_get_verify_result(&conn->ssl[sockindex].ssl); if(ret && data->set.ssl.verifypeer) { if(ret & BADCERT_EXPIRED) failf(data, "Cert verify failed: BADCERT_EXPIRED"); if(ret & BADCERT_REVOKED) { failf(data, "Cert verify failed: BADCERT_REVOKED"); return CURLE_SSL_CACERT; } if(ret & BADCERT_CN_MISMATCH) failf(data, "Cert verify failed: BADCERT_CN_MISMATCH"); if(ret & BADCERT_NOT_TRUSTED) failf(data, "Cert verify failed: BADCERT_NOT_TRUSTED"); return CURLE_PEER_FAILED_VERIFICATION; } if(ssl_get_peer_cert(&(connssl->ssl))) { /* If the session was resumed, there will be no peer certs */ memset(buffer, 0, sizeof(buffer)); if(x509_crt_info(buffer, sizeof(buffer), (char *)"* ", ssl_get_peer_cert(&(connssl->ssl))) != -1) infof(data, "Dumping cert info:\n%s\n", buffer); } #ifdef HAS_ALPN if(data->set.ssl_enable_alpn) { next_protocol = ssl_get_alpn_protocol(&connssl->ssl); if(next_protocol != NULL) { infof(data, "ALPN, server accepted to use %s\n", next_protocol); if(strncmp(next_protocol, NGHTTP2_PROTO_VERSION_ID, NGHTTP2_PROTO_VERSION_ID_LEN)) { conn->negnpn = NPN_HTTP2; } else if(strncmp(next_protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH)) { conn->negnpn = NPN_HTTP1_1; } } else { infof(data, "ALPN, server did not agree to a protocol\n"); } } #endif connssl->connecting_state = ssl_connect_3; infof(data, "SSL connected\n"); return CURLE_OK; }
static CURLcode polarssl_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; /* PolarSSL only supports SSLv3 and TLSv1 */ if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) { failf(data, "PolarSSL 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); if((ret = ctr_drbg_init(&connssl->ctr_drbg, entropy_func_mutex, &entropy, connssl->ssn.id, connssl->ssn.length)) != 0) { #ifdef POLARSSL_ERROR_C error_strerror(ret, errorbuf, sizeof(errorbuf)); #endif /* POLARSSL_ERROR_C */ failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n", -ret, errorbuf); } #else entropy_init(&connssl->entropy); if((ret = ctr_drbg_init(&connssl->ctr_drbg, entropy_func, &connssl->entropy, connssl->ssn.id, connssl->ssn.length)) != 0) { #ifdef POLARSSL_ERROR_C error_strerror(ret, errorbuf, sizeof(errorbuf)); #endif /* POLARSSL_ERROR_C */ failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n", -ret, errorbuf); } #endif /* THREADING_SUPPORT */ /* Load the trusted CA */ memset(&connssl->cacert, 0, sizeof(x509_crt)); if(data->set.str[STRING_SSL_CAFILE]) { ret = x509_crt_parse_file(&connssl->cacert, data->set.str[STRING_SSL_CAFILE]); if(ret<0) { #ifdef POLARSSL_ERROR_C error_strerror(ret, errorbuf, sizeof(errorbuf)); #endif /* POLARSSL_ERROR_C */ failf(data, "Error reading ca cert file %s - PolarSSL: (-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 = x509_crt_parse_path(&connssl->cacert, data->set.str[STRING_SSL_CAPATH]); if(ret<0) { #ifdef POLARSSL_ERROR_C error_strerror(ret, errorbuf, sizeof(errorbuf)); #endif /* POLARSSL_ERROR_C */ failf(data, "Error reading ca cert path %s - PolarSSL: (-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(x509_crt)); if(data->set.str[STRING_CERT]) { ret = x509_crt_parse_file(&connssl->clicert, data->set.str[STRING_CERT]); if(ret) { #ifdef POLARSSL_ERROR_C error_strerror(ret, errorbuf, sizeof(errorbuf)); #endif /* POLARSSL_ERROR_C */ failf(data, "Error reading client cert file %s - PolarSSL: (-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]) { pk_context pk; pk_init(&pk); ret = pk_parse_keyfile(&pk, data->set.str[STRING_KEY], data->set.str[STRING_KEY_PASSWD]); if(ret == 0 && !pk_can_do(&pk, POLARSSL_PK_RSA)) ret = POLARSSL_ERR_PK_TYPE_MISMATCH; if(ret == 0) rsa_copy(&connssl->rsa, pk_rsa(pk)); else rsa_free(&connssl->rsa); pk_free(&pk); if(ret) { #ifdef POLARSSL_ERROR_C error_strerror(ret, errorbuf, sizeof(errorbuf)); #endif /* POLARSSL_ERROR_C */ failf(data, "Error reading private key %s - PolarSSL: (-0x%04X) %s", data->set.str[STRING_KEY], -ret, errorbuf); return CURLE_SSL_CERTPROBLEM; } } /* Load the CRL */ memset(&connssl->crl, 0, sizeof(x509_crl)); if(data->set.str[STRING_SSL_CRLFILE]) { ret = x509_crl_parse_file(&connssl->crl, data->set.str[STRING_SSL_CRLFILE]); if(ret) { #ifdef POLARSSL_ERROR_C error_strerror(ret, errorbuf, sizeof(errorbuf)); #endif /* POLARSSL_ERROR_C */ failf(data, "Error reading CRL file %s - PolarSSL: (-0x%04X) %s", data->set.str[STRING_SSL_CRLFILE], -ret, errorbuf); return CURLE_SSL_CRL_BADFILE; } } infof(data, "PolarSSL: Connecting to %s:%d\n", conn->host.name, conn->remote_port); if(ssl_init(&connssl->ssl)) { failf(data, "PolarSSL: ssl_init failed"); return CURLE_SSL_CONNECT_ERROR; } switch(data->set.ssl.version) { default: case CURL_SSLVERSION_DEFAULT: ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1); break; case CURL_SSLVERSION_SSLv3: ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0); infof(data, "PolarSSL: Forced min. SSL Version to be SSLv3\n"); break; case CURL_SSLVERSION_TLSv1_0: ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1); infof(data, "PolarSSL: Forced min. SSL Version to be TLS 1.0\n"); break; case CURL_SSLVERSION_TLSv1_1: ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_2); infof(data, "PolarSSL: Forced min. SSL Version to be TLS 1.1\n"); break; case CURL_SSLVERSION_TLSv1_2: ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3); infof(data, "PolarSSL: Forced min. SSL Version to be TLS 1.2\n"); break; } ssl_set_endpoint(&connssl->ssl, SSL_IS_CLIENT); ssl_set_authmode(&connssl->ssl, SSL_VERIFY_OPTIONAL); ssl_set_rng(&connssl->ssl, ctr_drbg_random, &connssl->ctr_drbg); ssl_set_bio(&connssl->ssl, net_recv, &conn->sock[sockindex], net_send, &conn->sock[sockindex]); ssl_set_ciphersuites(&connssl->ssl, ssl_list_ciphersuites()); if(!Curl_ssl_getsessionid(conn, &old_session, &old_session_size)) { memcpy(&connssl->ssn, old_session, old_session_size); infof(data, "PolarSSL re-using session\n"); } ssl_set_session(&connssl->ssl, &connssl->ssn); ssl_set_ca_chain(&connssl->ssl, &connssl->cacert, &connssl->crl, conn->host.name); ssl_set_own_cert_rsa(&connssl->ssl, &connssl->clicert, &connssl->rsa); if(!Curl_inet_pton(AF_INET, conn->host.name, &addr) && #ifdef ENABLE_IPV6 !Curl_inet_pton(AF_INET6, conn->host.name, &addr) && #endif sni && 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.httpversion == CURL_HTTP_VERSION_2_0) { if(data->set.ssl_enable_alpn) { static const char* protocols[] = { NGHTTP2_PROTO_VERSION_ID, ALPN_HTTP_1_1, NULL }; ssl_set_alpn_protocols(&connssl->ssl, protocols); infof(data, "ALPN, offering %s, %s\n", protocols[0], protocols[1]); } } #endif #ifdef POLARSSL_DEBUG ssl_set_dbg(&connssl->ssl, polarssl_debug, data); #endif connssl->connecting_state = ssl_connect_2; return CURLE_OK; }
static CURLcode polarssl_connect_step2(struct connectdata *conn, int sockindex) { int ret; struct SessionHandle *data = conn->data; struct ssl_connect_data* connssl = &conn->ssl[sockindex]; char buffer[1024]; char errorbuf[128]; memset(errorbuf, 0, sizeof(errorbuf)); conn->recv[sockindex] = polarssl_recv; conn->send[sockindex] = polarssl_send; for(;;) { if(!(ret = ssl_handshake(&connssl->ssl))) break; else if(ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE) { #ifdef POLARSSL_ERROR_C error_strerror(ret, errorbuf, sizeof(errorbuf)); #endif /* POLARSSL_ERROR_C */ failf(data, "ssl_handshake returned - PolarSSL: (-0x%04X) %s", -ret, errorbuf); return CURLE_SSL_CONNECT_ERROR; } else { if(ret == POLARSSL_ERR_NET_WANT_READ) { connssl->connecting_state = ssl_connect_2_reading; return CURLE_OK; } if(ret == POLARSSL_ERR_NET_WANT_WRITE) { connssl->connecting_state = ssl_connect_2_writing; return CURLE_OK; } failf(data, "SSL_connect failed with error %d.", ret); return CURLE_SSL_CONNECT_ERROR; } } infof(data, "PolarSSL: Handshake complete, cipher is %s\n", ssl_get_ciphersuite(&conn->ssl[sockindex].ssl) ); ret = ssl_get_verify_result(&conn->ssl[sockindex].ssl); if(ret && data->set.ssl.verifypeer) { if(ret & BADCERT_EXPIRED) failf(data, "Cert verify failed: BADCERT_EXPIRED"); if(ret & BADCERT_REVOKED) { failf(data, "Cert verify failed: BADCERT_REVOKED"); return CURLE_SSL_CACERT; } if(ret & BADCERT_CN_MISMATCH) failf(data, "Cert verify failed: BADCERT_CN_MISMATCH"); if(ret & BADCERT_NOT_TRUSTED) failf(data, "Cert verify failed: BADCERT_NOT_TRUSTED"); return CURLE_PEER_FAILED_VERIFICATION; } if(ssl_get_peer_cert(&(connssl->ssl))) { /* If the session was resumed, there will be no peer certs */ memset(buffer, 0, sizeof(buffer)); if(x509_crt_info(buffer, sizeof(buffer), (char *)"* ", ssl_get_peer_cert(&(connssl->ssl))) != -1) infof(data, "Dumping cert info:\n%s\n", buffer); } connssl->connecting_state = ssl_connect_3; infof(data, "SSL connected\n"); return CURLE_OK; }
int main( int argc, char *argv[] ) { int ret = 0, len; int listen_fd; int client_fd = -1; unsigned char buf[1024]; const char *pers = "ssl_server2"; entropy_context entropy; ctr_drbg_context ctr_drbg; ssl_context ssl; x509_cert cacert; x509_cert srvcert; rsa_context rsa; #if defined(POLARSSL_SSL_CACHE_C) ssl_cache_context cache; #endif int i; char *p, *q; const int *list; /* * Make sure memory references are valid. */ listen_fd = 0; memset( &cacert, 0, sizeof( x509_cert ) ); memset( &srvcert, 0, sizeof( x509_cert ) ); memset( &rsa, 0, sizeof( rsa_context ) ); #if defined(POLARSSL_SSL_CACHE_C) ssl_cache_init( &cache ); #endif if( argc == 0 ) { usage: if( ret == 0 ) ret = 1; printf( USAGE ); list = ssl_list_ciphersuites(); while( *list ) { printf(" %s\n", ssl_get_ciphersuite_name( *list ) ); list++; } printf("\n"); goto exit; } opt.server_port = DFL_SERVER_PORT; opt.debug_level = DFL_DEBUG_LEVEL; opt.ca_file = DFL_CA_FILE; opt.ca_path = DFL_CA_PATH; opt.crt_file = DFL_CRT_FILE; opt.key_file = DFL_KEY_FILE; opt.force_ciphersuite[0]= DFL_FORCE_CIPHER; opt.renegotiation = DFL_RENEGOTIATION; opt.allow_legacy = DFL_ALLOW_LEGACY; opt.min_version = DFL_MIN_VERSION; opt.auth_mode = DFL_AUTH_MODE; for( i = 1; i < argc; i++ ) { p = argv[i]; if( ( q = strchr( p, '=' ) ) == NULL ) goto usage; *q++ = '\0'; if( strcmp( p, "server_port" ) == 0 ) { opt.server_port = atoi( q ); if( opt.server_port < 1 || opt.server_port > 65535 ) goto usage; } 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, "ca_file" ) == 0 ) opt.ca_file = q; else if( strcmp( p, "ca_path" ) == 0 ) opt.ca_path = 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] = ssl_get_ciphersuite_id( q ); if( opt.force_ciphersuite[0] <= 0 ) { ret = 2; goto usage; } opt.force_ciphersuite[1] = 0; } else if( strcmp( p, "renegotiation" ) == 0 ) { opt.renegotiation = (atoi( q )) ? SSL_RENEGOTIATION_ENABLED : SSL_RENEGOTIATION_DISABLED; } else if( strcmp( p, "allow_legacy" ) == 0 ) { opt.allow_legacy = atoi( q ); if( opt.allow_legacy < 0 || opt.allow_legacy > 1 ) goto usage; } else if( strcmp( p, "min_version" ) == 0 ) { if( strcmp( q, "ssl3" ) == 0 ) opt.min_version = SSL_MINOR_VERSION_0; else if( strcmp( q, "tls1" ) == 0 ) opt.min_version = SSL_MINOR_VERSION_1; else if( strcmp( q, "tls1_1" ) == 0 ) opt.min_version = SSL_MINOR_VERSION_2; else if( strcmp( q, "tls1_2" ) == 0 ) opt.min_version = SSL_MINOR_VERSION_3; else goto usage; } else if( strcmp( p, "auth_mode" ) == 0 ) { if( strcmp( q, "none" ) == 0 ) opt.auth_mode = SSL_VERIFY_NONE; else if( strcmp( q, "optional" ) == 0 ) opt.auth_mode = SSL_VERIFY_OPTIONAL; else if( strcmp( q, "required" ) == 0 ) opt.auth_mode = SSL_VERIFY_REQUIRED; else goto usage; } else goto usage; } /* * 0. Initialize the RNG and the session data */ printf( "\n . Seeding the random number generator..." ); fflush( stdout ); entropy_init( &entropy ); if( ( ret = ctr_drbg_init( &ctr_drbg, entropy_func, &entropy, (const unsigned char *) pers, strlen( pers ) ) ) != 0 ) { printf( " failed\n ! ctr_drbg_init returned -0x%x\n", -ret ); goto exit; } printf( " ok\n" ); /* * 1.1. Load the trusted CA */ printf( " . Loading the CA root certificate ..." ); fflush( stdout ); #if defined(POLARSSL_FS_IO) if( strlen( opt.ca_path ) ) ret = x509parse_crtpath( &cacert, opt.ca_path ); else if( strlen( opt.ca_file ) ) ret = x509parse_crtfile( &cacert, opt.ca_file ); else #endif #if defined(POLARSSL_CERTS_C) ret = x509parse_crt( &cacert, (const unsigned char *) test_ca_crt, strlen( test_ca_crt ) ); #else { ret = 1; printf("POLARSSL_CERTS_C not defined."); } #endif if( ret < 0 ) { printf( " failed\n ! x509parse_crt returned -0x%x\n\n", -ret ); goto exit; } printf( " ok (%d skipped)\n", ret ); /* * 1.2. Load own certificate and private key */ printf( " . Loading the server cert. and key..." ); fflush( stdout ); #if defined(POLARSSL_FS_IO) if( strlen( opt.crt_file ) ) ret = x509parse_crtfile( &srvcert, opt.crt_file ); else #endif #if defined(POLARSSL_CERTS_C) ret = x509parse_crt( &srvcert, (const unsigned char *) test_srv_crt, strlen( test_srv_crt ) ); #else { ret = 1; printf("POLARSSL_CERTS_C not defined."); } #endif if( ret != 0 ) { printf( " failed\n ! x509parse_crt returned -0x%x\n\n", -ret ); goto exit; } #if defined(POLARSSL_FS_IO) if( strlen( opt.key_file ) ) ret = x509parse_keyfile( &rsa, opt.key_file, "" ); else #endif #if defined(POLARSSL_CERTS_C) ret = x509parse_key( &rsa, (const unsigned char *) test_srv_key, strlen( test_srv_key ), NULL, 0 ); #else { ret = 1; printf("POLARSSL_CERTS_C not defined."); } #endif if( ret != 0 ) { printf( " failed\n ! x509parse_key returned -0x%x\n\n", -ret ); goto exit; } printf( " ok\n" ); /* * 2. Setup the listening TCP socket */ printf( " . Bind on tcp://localhost:%-4d/ ...", opt.server_port ); fflush( stdout ); if( ( ret = net_bind( &listen_fd, NULL, opt.server_port ) ) != 0 ) { printf( " failed\n ! net_bind returned -0x%x\n\n", -ret ); goto exit; } printf( " ok\n" ); /* * 3. Setup stuff */ printf( " . Setting up the SSL/TLS structure..." ); fflush( stdout ); if( ( ret = ssl_init( &ssl ) ) != 0 ) { printf( " failed\n ! ssl_init returned -0x%x\n\n", -ret ); goto exit; } ssl_set_endpoint( &ssl, SSL_IS_SERVER ); ssl_set_authmode( &ssl, opt.auth_mode ); ssl_set_rng( &ssl, ctr_drbg_random, &ctr_drbg ); ssl_set_dbg( &ssl, my_debug, stdout ); #if defined(POLARSSL_SSL_CACHE_C) ssl_set_session_cache( &ssl, ssl_cache_get, &cache, ssl_cache_set, &cache ); #endif if( opt.force_ciphersuite[0] == DFL_FORCE_CIPHER ) ssl_set_ciphersuites( &ssl, my_ciphersuites ); else ssl_set_ciphersuites( &ssl, opt.force_ciphersuite ); ssl_set_renegotiation( &ssl, opt.renegotiation ); ssl_legacy_renegotiation( &ssl, opt.allow_legacy ); ssl_set_ca_chain( &ssl, &cacert, NULL, NULL ); ssl_set_own_cert( &ssl, &srvcert, &rsa ); #if defined(POLARSSL_DHM_C) /* * Use different group than default DHM group */ ssl_set_dh_param( &ssl, POLARSSL_DHM_RFC5114_MODP_2048_P, POLARSSL_DHM_RFC5114_MODP_2048_G ); #endif if( opt.min_version != -1 ) ssl_set_min_version( &ssl, SSL_MAJOR_VERSION_3, opt.min_version ); printf( " ok\n" ); reset: #ifdef POLARSSL_ERROR_C if( ret != 0 ) { char error_buf[100]; error_strerror( ret, error_buf, 100 ); printf("Last error was: %d - %s\n\n", ret, error_buf ); } #endif if( client_fd != -1 ) net_close( client_fd ); ssl_session_reset( &ssl ); /* * 3. Wait until a client connects */ #if defined(_WIN32_WCE) { SHELLEXECUTEINFO sei; ZeroMemory( &sei, sizeof( SHELLEXECUTEINFO ) ); sei.cbSize = sizeof( SHELLEXECUTEINFO ); sei.fMask = 0; sei.hwnd = 0; sei.lpVerb = _T( "open" ); sei.lpFile = _T( "https://localhost:4433/" ); sei.lpParameters = NULL; sei.lpDirectory = NULL; sei.nShow = SW_SHOWNORMAL; ShellExecuteEx( &sei ); } #elif defined(_WIN32) ShellExecute( NULL, "open", "https://localhost:4433/", NULL, NULL, SW_SHOWNORMAL ); #endif client_fd = -1; printf( " . Waiting for a remote connection ..." ); fflush( stdout ); if( ( ret = net_accept( listen_fd, &client_fd, NULL ) ) != 0 ) { printf( " failed\n ! net_accept returned -0x%x\n\n", -ret ); goto exit; } ssl_set_bio( &ssl, net_recv, &client_fd, net_send, &client_fd ); printf( " ok\n" ); /* * 4. Handshake */ printf( " . Performing the SSL/TLS handshake..." ); fflush( stdout ); while( ( ret = ssl_handshake( &ssl ) ) != 0 ) { if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE ) { printf( " failed\n ! ssl_handshake returned -0x%x\n\n", -ret ); goto reset; } } printf( " ok\n [ Ciphersuite is %s ]\n", ssl_get_ciphersuite( &ssl ) ); /* * 5. Verify the server certificate */ printf( " . Verifying peer X.509 certificate..." ); if( ( ret = ssl_get_verify_result( &ssl ) ) != 0 ) { printf( " failed\n" ); if( !ssl_get_peer_cert( &ssl ) ) printf( " ! no client certificate sent\n" ); if( ( ret & BADCERT_EXPIRED ) != 0 ) printf( " ! client certificate has expired\n" ); if( ( ret & BADCERT_REVOKED ) != 0 ) printf( " ! client certificate has been revoked\n" ); if( ( ret & BADCERT_NOT_TRUSTED ) != 0 ) printf( " ! self-signed or not signed by a trusted CA\n" ); printf( "\n" ); } else printf( " ok\n" ); if( ssl_get_peer_cert( &ssl ) ) { printf( " . Peer certificate information ...\n" ); x509parse_cert_info( (char *) buf, sizeof( buf ) - 1, " ", ssl_get_peer_cert( &ssl ) ); printf( "%s\n", buf ); } /* * 6. Read the HTTP Request */ printf( " < Read from client:" ); fflush( stdout ); do { len = sizeof( buf ) - 1; memset( buf, 0, sizeof( buf ) ); ret = ssl_read( &ssl, buf, len ); if( ret == POLARSSL_ERR_NET_WANT_READ || ret == POLARSSL_ERR_NET_WANT_WRITE ) continue; if( ret <= 0 ) { switch( ret ) { case POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY: printf( " connection was closed gracefully\n" ); break; case POLARSSL_ERR_NET_CONN_RESET: printf( " connection was reset by peer\n" ); break; default: printf( " ssl_read returned -0x%x\n", -ret ); break; } break; } len = ret; printf( " %d bytes read\n\n%s", len, (char *) buf ); if( ret > 0 ) break; } while( 1 ); /* * 7. Write the 200 Response */ printf( " > Write to client:" ); fflush( stdout ); len = sprintf( (char *) buf, HTTP_RESPONSE, ssl_get_ciphersuite( &ssl ) ); while( ( ret = ssl_write( &ssl, buf, len ) ) <= 0 ) { if( ret == POLARSSL_ERR_NET_CONN_RESET ) { printf( " failed\n ! peer closed the connection\n\n" ); goto reset; } if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE ) { printf( " failed\n ! ssl_write returned %d\n\n", ret ); goto exit; } } len = ret; printf( " %d bytes written\n\n%s\n", len, (char *) buf ); ret = 0; goto reset; exit: #ifdef POLARSSL_ERROR_C if( ret != 0 ) { char error_buf[100]; error_strerror( ret, error_buf, 100 ); printf("Last error was: -0x%X - %s\n\n", -ret, error_buf ); } #endif net_close( client_fd ); x509_free( &srvcert ); x509_free( &cacert ); rsa_free( &rsa ); ssl_free( &ssl ); #if defined(POLARSSL_SSL_CACHE_C) ssl_cache_free( &cache ); #endif #if defined(_WIN32) printf( " + Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif return( ret ); }
static CURLcode polarssl_connect_step2(struct connectdata *conn, int sockindex) { int ret; struct SessionHandle *data = conn->data; struct ssl_connect_data* connssl = &conn->ssl[sockindex]; char buffer[1024]; char errorbuf[128]; memset(errorbuf, 0, sizeof(errorbuf)); conn->recv[sockindex] = polarssl_recv; conn->send[sockindex] = polarssl_send; for(;;) { if(!(ret = ssl_handshake(&connssl->ssl))) break; else if(ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE) { #ifdef POLARSSL_ERROR_C error_strerror(ret, errorbuf, sizeof(errorbuf)); #endif /* POLARSSL_ERROR_C */ failf(data, "ssl_handshake returned - PolarSSL: (-0x%04X) %s", -ret, errorbuf); return CURLE_SSL_CONNECT_ERROR; } else { if(ret == POLARSSL_ERR_NET_WANT_READ) { connssl->connecting_state = ssl_connect_2_reading; return CURLE_OK; } if(ret == POLARSSL_ERR_NET_WANT_WRITE) { connssl->connecting_state = ssl_connect_2_writing; return CURLE_OK; } failf(data, "SSL_connect failed with error %d.", ret); return CURLE_SSL_CONNECT_ERROR; } } infof(data, "PolarSSL: Handshake complete, cipher is %s\n", #if POLARSSL_VERSION_NUMBER<0x01000000 ssl_get_cipher(&conn->ssl[sockindex].ssl) #elif POLARSSL_VERSION_NUMBER >= 0x01010000 ssl_get_ciphersuite(&conn->ssl[sockindex].ssl) #else ssl_get_ciphersuite_name(&conn->ssl[sockindex].ssl) #endif ); ret = ssl_get_verify_result(&conn->ssl[sockindex].ssl); if(ret && data->set.ssl.verifypeer) { if(ret & BADCERT_EXPIRED) failf(data, "Cert verify failed: BADCERT_EXPIRED"); if(ret & BADCERT_REVOKED) { failf(data, "Cert verify failed: BADCERT_REVOKED"); return CURLE_SSL_CACERT; } if(ret & BADCERT_CN_MISMATCH) failf(data, "Cert verify failed: BADCERT_CN_MISMATCH"); if(ret & BADCERT_NOT_TRUSTED) failf(data, "Cert verify failed: BADCERT_NOT_TRUSTED"); return CURLE_PEER_FAILED_VERIFICATION; } /* PolarSSL SVN revision r1316 to r1317, matching <1.2.0 is to cover Ubuntu's 1.1.4 version and the like */ #if POLARSSL_VERSION_NUMBER<0x01020000 if(conn->ssl[sockindex].ssl.peer_cert) { #else if(ssl_get_peer_cert(&(connssl->ssl))) { #endif /* If the session was resumed, there will be no peer certs */ memset(buffer, 0, sizeof(buffer)); /* PolarSSL SVN revision r1316 to r1317, matching <1.2.0 is to cover Ubuntu's 1.1.4 version and the like */ #if POLARSSL_VERSION_NUMBER<0x01020000 if(x509parse_cert_info(buffer, sizeof(buffer), (char *)"* ", conn->ssl[sockindex].ssl.peer_cert) != -1) #else if(x509parse_cert_info(buffer, sizeof(buffer), (char *)"* ", ssl_get_peer_cert(&(connssl->ssl))) != -1) #endif infof(data, "Dumping cert info:\n%s\n", buffer); } connssl->connecting_state = ssl_connect_3; infof(data, "SSL connected\n"); return CURLE_OK; } static CURLcode polarssl_connect_step3(struct connectdata *conn, int sockindex) { CURLcode retcode = CURLE_OK; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct SessionHandle *data = conn->data; void *old_ssl_sessionid = NULL; ssl_session *our_ssl_sessionid = &conn->ssl[sockindex].ssn ; int incache; DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); /* Save the current session data for possible re-use */ incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL)); if(incache) { if(old_ssl_sessionid != our_ssl_sessionid) { infof(data, "old SSL session ID is stale, removing\n"); Curl_ssl_delsessionid(conn, old_ssl_sessionid); incache = FALSE; } } if(!incache) { void *new_session = malloc(sizeof(ssl_session)); if(new_session) { memcpy(new_session, our_ssl_sessionid, sizeof(ssl_session)); retcode = Curl_ssl_addsessionid(conn, new_session, sizeof(ssl_session)); } else { retcode = CURLE_OUT_OF_MEMORY; } if(retcode) { failf(data, "failed to store ssl session"); return retcode; } } connssl->connecting_state = ssl_connect_done; return CURLE_OK; }
static CURLcode polarssl_connect_step1(struct connectdata *conn, int sockindex) { struct Curl_easy *data = conn->data; struct ssl_connect_data* connssl = &conn->ssl[sockindex]; const char *capath = SSL_CONN_CONFIG(CApath); 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; /* PolarSSL only supports SSLv3 and TLSv1 */ if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) { failf(data, "PolarSSL does not support SSLv2"); return CURLE_SSL_CONNECT_ERROR; } #ifdef THREADING_SUPPORT entropy_init_mutex(&entropy); if((ret = ctr_drbg_init(&BACKEND->ctr_drbg, entropy_func_mutex, &entropy, NULL, 0)) != 0) { error_strerror(ret, errorbuf, sizeof(errorbuf)); failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n", -ret, errorbuf); } #else entropy_init(&BACKEND->entropy); if((ret = ctr_drbg_init(&BACKEND->ctr_drbg, entropy_func, &BACKEND->entropy, NULL, 0)) != 0) { error_strerror(ret, errorbuf, sizeof(errorbuf)); failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n", -ret, errorbuf); } #endif /* THREADING_SUPPORT */ /* Load the trusted CA */ memset(&BACKEND->cacert, 0, sizeof(x509_crt)); if(SSL_CONN_CONFIG(CAfile)) { ret = x509_crt_parse_file(&BACKEND->cacert, SSL_CONN_CONFIG(CAfile)); if(ret<0) { error_strerror(ret, errorbuf, sizeof(errorbuf)); failf(data, "Error reading ca cert file %s - PolarSSL: (-0x%04X) %s", SSL_CONN_CONFIG(CAfile), -ret, errorbuf); if(SSL_CONN_CONFIG(verifypeer)) return CURLE_SSL_CACERT_BADFILE; } } if(capath) { ret = x509_crt_parse_path(&BACKEND->cacert, capath); if(ret<0) { error_strerror(ret, errorbuf, sizeof(errorbuf)); failf(data, "Error reading ca cert path %s - PolarSSL: (-0x%04X) %s", capath, -ret, errorbuf); if(SSL_CONN_CONFIG(verifypeer)) return CURLE_SSL_CACERT_BADFILE; } } /* Load the client certificate */ memset(&BACKEND->clicert, 0, sizeof(x509_crt)); if(SSL_SET_OPTION(cert)) { ret = x509_crt_parse_file(&BACKEND->clicert, SSL_SET_OPTION(cert)); if(ret) { error_strerror(ret, errorbuf, sizeof(errorbuf)); failf(data, "Error reading client cert file %s - PolarSSL: (-0x%04X) %s", SSL_SET_OPTION(cert), -ret, errorbuf); return CURLE_SSL_CERTPROBLEM; } } /* Load the client private key */ if(SSL_SET_OPTION(key)) { pk_context pk; pk_init(&pk); ret = pk_parse_keyfile(&pk, SSL_SET_OPTION(key), SSL_SET_OPTION(key_passwd)); if(ret == 0 && !pk_can_do(&pk, POLARSSL_PK_RSA)) ret = POLARSSL_ERR_PK_TYPE_MISMATCH; if(ret == 0) rsa_copy(&BACKEND->rsa, pk_rsa(pk)); else rsa_free(&BACKEND->rsa); pk_free(&pk); if(ret) { error_strerror(ret, errorbuf, sizeof(errorbuf)); failf(data, "Error reading private key %s - PolarSSL: (-0x%04X) %s", SSL_SET_OPTION(key), -ret, errorbuf); return CURLE_SSL_CERTPROBLEM; } } /* Load the CRL */ memset(&BACKEND->crl, 0, sizeof(x509_crl)); if(SSL_SET_OPTION(CRLfile)) { ret = x509_crl_parse_file(&BACKEND->crl, SSL_SET_OPTION(CRLfile)); if(ret) { error_strerror(ret, errorbuf, sizeof(errorbuf)); failf(data, "Error reading CRL file %s - PolarSSL: (-0x%04X) %s", SSL_SET_OPTION(CRLfile), -ret, errorbuf); return CURLE_SSL_CRL_BADFILE; } } infof(data, "PolarSSL: Connecting to %s:%d\n", hostname, port); if(ssl_init(&BACKEND->ssl)) { failf(data, "PolarSSL: ssl_init failed"); return CURLE_SSL_CONNECT_ERROR; } switch(SSL_CONN_CONFIG(version)) { case CURL_SSLVERSION_DEFAULT: case CURL_SSLVERSION_TLSv1: ssl_set_min_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1); break; case CURL_SSLVERSION_SSLv3: ssl_set_min_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0); ssl_set_max_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0); infof(data, "PolarSSL: Forced min. SSL Version to be 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; } ssl_set_endpoint(&BACKEND->ssl, SSL_IS_CLIENT); ssl_set_authmode(&BACKEND->ssl, SSL_VERIFY_OPTIONAL); ssl_set_rng(&BACKEND->ssl, ctr_drbg_random, &BACKEND->ctr_drbg); ssl_set_bio(&BACKEND->ssl, net_recv, &conn->sock[sockindex], net_send, &conn->sock[sockindex]); ssl_set_ciphersuites(&BACKEND->ssl, ssl_list_ciphersuites()); /* 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 = ssl_set_session(&BACKEND->ssl, old_session); if(ret) { Curl_ssl_sessionid_unlock(conn); failf(data, "ssl_set_session returned -0x%x", -ret); return CURLE_SSL_CONNECT_ERROR; } infof(data, "PolarSSL re-using session\n"); } Curl_ssl_sessionid_unlock(conn); } ssl_set_ca_chain(&BACKEND->ssl, &BACKEND->cacert, &BACKEND->crl, hostname); ssl_set_own_cert_rsa(&BACKEND->ssl, &BACKEND->clicert, &BACKEND->rsa); if(ssl_set_hostname(&BACKEND->ssl, hostname)) { /* 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 PolarSSL"); return CURLE_SSL_CONNECT_ERROR; } #ifdef HAS_ALPN if(conn->bits.tls_enable_alpn) { static const char *protocols[3]; int cur = 0; #ifdef USE_NGHTTP2 if(data->set.httpversion >= CURL_HTTP_VERSION_2) { protocols[cur++] = NGHTTP2_PROTO_VERSION_ID; infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); } #endif protocols[cur++] = ALPN_HTTP_1_1; infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1); protocols[cur] = NULL; ssl_set_alpn_protocols(&BACKEND->ssl, protocols); } #endif #ifdef POLARSSL_DEBUG ssl_set_dbg(&BACKEND->ssl, polarssl_debug, data); #endif connssl->connecting_state = ssl_connect_2; return CURLE_OK; }
int main( int argc, char *argv[] ) { int ret = 0; rsa_context rsa; char buf[1024]; int i, j, n; char *p, *q; /* * Set to sane values */ memset( &rsa, 0, sizeof( rsa_context ) ); memset( buf, 0, 1024 ); if( argc == 0 ) { usage: printf( USAGE ); goto exit; } opt.mode = DFL_MODE; opt.filename = DFL_FILENAME; opt.debug_level = DFL_DEBUG_LEVEL; for( i = 1; i < argc; i++ ) { n = strlen( argv[i] ); for( j = 0; j < n; j++ ) { if( argv[i][j] >= 'A' && argv[i][j] <= 'Z' ) argv[i][j] |= 0x20; } 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, "filename" ) == 0 ) opt.filename = 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 goto usage; } if( opt.mode == MODE_PRIVATE ) { /* * 1.1. Load the key */ printf( "\n . Loading the private key ..." ); fflush( stdout ); ret = x509parse_keyfile( &rsa, opt.filename, NULL ); if( ret != 0 ) { #ifdef POLARSSL_ERROR_C error_strerror( ret, buf, 1024 ); #endif printf( " failed\n ! x509parse_key returned %d - %s\n\n", ret, buf ); rsa_free( &rsa ); goto exit; } printf( " ok\n" ); /* * 1.2 Print the key */ printf( " . Key information ...\n" ); mpi_write_file( "N: ", &rsa.N, 16, NULL ); mpi_write_file( "E: ", &rsa.E, 16, NULL ); mpi_write_file( "D: ", &rsa.D, 16, NULL ); mpi_write_file( "P: ", &rsa.P, 16, NULL ); mpi_write_file( "Q: ", &rsa.Q, 16, NULL ); mpi_write_file( "DP: ", &rsa.DP, 16, NULL ); mpi_write_file( "DQ: ", &rsa.DQ, 16, NULL ); mpi_write_file( "QP: ", &rsa.QP, 16, NULL ); } else if( opt.mode == MODE_PUBLIC ) { /* * 1.1. Load the key */ printf( "\n . Loading the public key ..." ); fflush( stdout ); ret = x509parse_public_keyfile( &rsa, opt.filename ); if( ret != 0 ) { #ifdef POLARSSL_ERROR_C error_strerror( ret, buf, 1024 ); #endif printf( " failed\n ! x509parse_public_key returned %d - %s\n\n", ret, buf ); rsa_free( &rsa ); goto exit; } printf( " ok\n" ); /* * 1.2 Print the key */ printf( " . Key information ...\n" ); mpi_write_file( "N: ", &rsa.N, 16, NULL ); mpi_write_file( "E: ", &rsa.E, 16, NULL ); } else goto usage; exit: rsa_free( &rsa ); #ifdef WIN32 printf( " + Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif return( ret ); }
int main( int argc, char *argv[] ) { int ret = 0, len, server_fd; unsigned char buf[1024]; char *pers = "ssl_client2"; entropy_context entropy; ctr_drbg_context ctr_drbg; ssl_context ssl; x509_cert cacert; x509_cert clicert; rsa_context rsa; int i; char *p, *q; const int *list; /* * Make sure memory references are valid. */ server_fd = 0; memset( &ssl, 0, sizeof( ssl_context ) ); memset( &cacert, 0, sizeof( x509_cert ) ); memset( &clicert, 0, sizeof( x509_cert ) ); memset( &rsa, 0, sizeof( rsa_context ) ); if( argc == 0 ) { usage: if( ret == 0 ) ret = 1; printf( USAGE ); list = ssl_list_ciphersuites(); while( *list ) { printf(" %s\n", ssl_get_ciphersuite_name( *list ) ); list++; } printf("\n"); goto exit; } opt.server_name = DFL_SERVER_NAME; opt.server_port = DFL_SERVER_PORT; opt.debug_level = DFL_DEBUG_LEVEL; opt.request_page = DFL_REQUEST_PAGE; opt.ca_file = DFL_CA_FILE; opt.ca_path = DFL_CA_PATH; opt.crt_file = DFL_CRT_FILE; opt.key_file = DFL_KEY_FILE; opt.force_ciphersuite[0]= DFL_FORCE_CIPHER; opt.renegotiation = DFL_RENEGOTIATION; opt.allow_legacy = DFL_ALLOW_LEGACY; opt.min_version = DFL_MIN_VERSION; opt.max_version = DFL_MAX_VERSION; opt.auth_mode = DFL_AUTH_MODE; 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 = atoi( q ); if( opt.server_port < 1 || opt.server_port > 65535 ) goto usage; } 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, "request_page" ) == 0 ) opt.request_page = q; else if( strcmp( p, "ca_file" ) == 0 ) opt.ca_file = q; else if( strcmp( p, "ca_path" ) == 0 ) opt.ca_path = 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] = ssl_get_ciphersuite_id( q ); if( opt.force_ciphersuite[0] <= 0 ) { ret = 2; goto usage; } opt.force_ciphersuite[1] = 0; } else if( strcmp( p, "renegotiation" ) == 0 ) { opt.renegotiation = (atoi( q )) ? SSL_RENEGOTIATION_ENABLED : SSL_RENEGOTIATION_DISABLED; } else if( strcmp( p, "allow_legacy" ) == 0 ) { opt.allow_legacy = atoi( q ); if( opt.allow_legacy < 0 || opt.allow_legacy > 1 ) goto usage; } else if( strcmp( p, "min_version" ) == 0 ) { if( strcmp( q, "ssl3" ) == 0 ) opt.min_version = SSL_MINOR_VERSION_0; else if( strcmp( q, "tls1" ) == 0 ) opt.min_version = SSL_MINOR_VERSION_1; else if( strcmp( q, "tls1_1" ) == 0 ) opt.min_version = SSL_MINOR_VERSION_2; else if( strcmp( q, "tls1_2" ) == 0 ) opt.min_version = SSL_MINOR_VERSION_3; else goto usage; } else if( strcmp( p, "max_version" ) == 0 ) { if( strcmp( q, "ssl3" ) == 0 ) opt.max_version = SSL_MINOR_VERSION_0; else if( strcmp( q, "tls1" ) == 0 ) opt.max_version = SSL_MINOR_VERSION_1; else if( strcmp( q, "tls1_1" ) == 0 ) opt.max_version = SSL_MINOR_VERSION_2; else if( strcmp( q, "tls1_2" ) == 0 ) opt.max_version = SSL_MINOR_VERSION_3; else goto usage; } else if( strcmp( p, "force_version" ) == 0 ) { if( strcmp( q, "ssl3" ) == 0 ) { opt.min_version = SSL_MINOR_VERSION_0; opt.max_version = SSL_MINOR_VERSION_0; } else if( strcmp( q, "tls1" ) == 0 ) { opt.min_version = SSL_MINOR_VERSION_1; opt.max_version = SSL_MINOR_VERSION_1; } else if( strcmp( q, "tls1_1" ) == 0 ) { opt.min_version = SSL_MINOR_VERSION_2; opt.max_version = SSL_MINOR_VERSION_2; } else if( strcmp( q, "tls1_2" ) == 0 ) { opt.min_version = SSL_MINOR_VERSION_3; opt.max_version = SSL_MINOR_VERSION_3; } else goto usage; } else if( strcmp( p, "auth_mode" ) == 0 ) { if( strcmp( q, "none" ) == 0 ) opt.auth_mode = SSL_VERIFY_NONE; else if( strcmp( q, "optional" ) == 0 ) opt.auth_mode = SSL_VERIFY_OPTIONAL; else if( strcmp( q, "required" ) == 0 ) opt.auth_mode = SSL_VERIFY_REQUIRED; else goto usage; } else goto usage; } /* * 0. Initialize the RNG and the session data */ printf( "\n . Seeding the random number generator..." ); fflush( stdout ); entropy_init( &entropy ); if( ( ret = ctr_drbg_init( &ctr_drbg, entropy_func, &entropy, (unsigned char *) pers, strlen( pers ) ) ) != 0 ) { printf( " failed\n ! ctr_drbg_init returned -0x%x\n", -ret ); goto exit; } printf( " ok\n" ); /* * 1.1. Load the trusted CA */ printf( " . Loading the CA root certificate ..." ); fflush( stdout ); #if defined(POLARSSL_FS_IO) if( strlen( opt.ca_path ) ) ret = x509parse_crtpath( &cacert, opt.ca_path ); else if( strlen( opt.ca_file ) ) ret = x509parse_crtfile( &cacert, opt.ca_file ); else #endif #if defined(POLARSSL_CERTS_C) ret = x509parse_crt( &cacert, (unsigned char *) test_ca_crt, strlen( test_ca_crt ) ); #else { ret = 1; printf("POLARSSL_CERTS_C not defined."); } #endif if( ret < 0 ) { printf( " failed\n ! x509parse_crt returned -0x%x\n\n", -ret ); goto exit; } printf( " ok (%d skipped)\n", ret ); /* * 1.2. Load own certificate and private key * * (can be skipped if client authentication is not required) */ printf( " . Loading the client cert. and key..." ); fflush( stdout ); #if defined(POLARSSL_FS_IO) if( strlen( opt.crt_file ) ) ret = x509parse_crtfile( &clicert, opt.crt_file ); else #endif #if defined(POLARSSL_CERTS_C) ret = x509parse_crt( &clicert, (unsigned char *) test_cli_crt, strlen( test_cli_crt ) ); #else { ret = 1; printf("POLARSSL_CERTS_C not defined."); } #endif if( ret != 0 ) { printf( " failed\n ! x509parse_crt returned -0x%x\n\n", -ret ); goto exit; } #if defined(POLARSSL_FS_IO) if( strlen( opt.key_file ) ) ret = x509parse_keyfile( &rsa, opt.key_file, "" ); else #endif #if defined(POLARSSL_CERTS_C) ret = x509parse_key( &rsa, (unsigned char *) test_cli_key, strlen( test_cli_key ), NULL, 0 ); #else { ret = 1; printf("POLARSSL_CERTS_C not defined."); } #endif if( ret != 0 ) { printf( " failed\n ! x509parse_key returned -0x%x\n\n", -ret ); goto exit; } printf( " ok\n" ); /* * 2. Start the connection */ printf( " . Connecting to tcp/%s/%-4d...", opt.server_name, opt.server_port ); fflush( stdout ); if( ( ret = net_connect( &server_fd, opt.server_name, opt.server_port ) ) != 0 ) { printf( " failed\n ! net_connect returned -0x%x\n\n", -ret ); goto exit; } printf( " ok\n" ); /* * 3. Setup stuff */ printf( " . Setting up the SSL/TLS structure..." ); fflush( stdout ); if( ( ret = ssl_init( &ssl ) ) != 0 ) { printf( " failed\n ! ssl_init returned -0x%x\n\n", -ret ); goto exit; } printf( " ok\n" ); if( opt.debug_level > 0 ) ssl_set_verify( &ssl, my_verify, NULL ); ssl_set_endpoint( &ssl, SSL_IS_CLIENT ); ssl_set_authmode( &ssl, opt.auth_mode ); ssl_set_rng( &ssl, ctr_drbg_random, &ctr_drbg ); ssl_set_dbg( &ssl, my_debug, stdout ); ssl_set_bio( &ssl, net_recv, &server_fd, net_send, &server_fd ); if( opt.force_ciphersuite[0] != DFL_FORCE_CIPHER ) ssl_set_ciphersuites( &ssl, opt.force_ciphersuite ); ssl_set_renegotiation( &ssl, opt.renegotiation ); ssl_legacy_renegotiation( &ssl, opt.allow_legacy ); ssl_set_ca_chain( &ssl, &cacert, NULL, opt.server_name ); ssl_set_own_cert( &ssl, &clicert, &rsa ); ssl_set_hostname( &ssl, opt.server_name ); if( opt.min_version != -1 ) ssl_set_min_version( &ssl, SSL_MAJOR_VERSION_3, opt.min_version ); if( opt.max_version != -1 ) ssl_set_max_version( &ssl, SSL_MAJOR_VERSION_3, opt.max_version ); /* * 4. Handshake */ printf( " . Performing the SSL/TLS handshake..." ); fflush( stdout ); while( ( ret = ssl_handshake( &ssl ) ) != 0 ) { if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE ) { printf( " failed\n ! ssl_handshake returned -0x%x\n\n", -ret ); goto exit; } } printf( " ok\n [ Ciphersuite is %s ]\n", ssl_get_ciphersuite( &ssl ) ); /* * 5. Verify the server certificate */ printf( " . Verifying peer X.509 certificate..." ); if( ( ret = ssl_get_verify_result( &ssl ) ) != 0 ) { printf( " failed\n" ); if( ( ret & BADCERT_EXPIRED ) != 0 ) printf( " ! server certificate has expired\n" ); if( ( ret & BADCERT_REVOKED ) != 0 ) printf( " ! server certificate has been revoked\n" ); if( ( ret & BADCERT_CN_MISMATCH ) != 0 ) printf( " ! CN mismatch (expected CN=%s)\n", opt.server_name ); if( ( ret & BADCERT_NOT_TRUSTED ) != 0 ) printf( " ! self-signed or not signed by a trusted CA\n" ); printf( "\n" ); } else printf( " ok\n" ); printf( " . Peer certificate information ...\n" ); x509parse_cert_info( (char *) buf, sizeof( buf ) - 1, " ", ssl_get_peer_cert( &ssl ) ); printf( "%s\n", buf ); /* * 6. Write the GET request */ printf( " > Write to server:" ); fflush( stdout ); len = sprintf( (char *) buf, GET_REQUEST, opt.request_page ); while( ( ret = ssl_write( &ssl, buf, len ) ) <= 0 ) { if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE ) { printf( " failed\n ! ssl_write returned -0x%x\n\n", -ret ); goto exit; } } len = ret; printf( " %d bytes written\n\n%s", len, (char *) buf ); /* * 7. Read the HTTP response */ printf( " < Read from server:" ); fflush( stdout ); do { len = sizeof( buf ) - 1; memset( buf, 0, sizeof( buf ) ); ret = ssl_read( &ssl, buf, len ); if( ret == POLARSSL_ERR_NET_WANT_READ || ret == POLARSSL_ERR_NET_WANT_WRITE ) continue; if( ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY ) break; if( ret < 0 ) { printf( "failed\n ! ssl_read returned -0x%x\n\n", -ret ); break; } if( ret == 0 ) { printf("\n\nEOF\n\n"); break; } len = ret; printf( " %d bytes read\n\n%s", len, (char *) buf ); } while( 1 ); ssl_close_notify( &ssl ); exit: #ifdef POLARSSL_ERROR_C if( ret != 0 ) { char error_buf[100]; error_strerror( ret, error_buf, 100 ); printf("Last error was: -0x%X - %s\n\n", -ret, error_buf ); } #endif if( server_fd ) net_close( server_fd ); x509_free( &clicert ); x509_free( &cacert ); rsa_free( &rsa ); ssl_free( &ssl ); memset( &ssl, 0, sizeof( ssl ) ); #if defined(_WIN32) printf( " + Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif return( ret ); }
static CURLcode polarssl_connect_step2(struct connectdata *conn, int sockindex) { int ret; struct Curl_easy *data = conn->data; struct ssl_connect_data* connssl = &conn->ssl[sockindex]; char buffer[1024]; const char * const pinnedpubkey = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; char errorbuf[128]; errorbuf[0] = 0; conn->recv[sockindex] = polarssl_recv; conn->send[sockindex] = polarssl_send; ret = ssl_handshake(&BACKEND->ssl); switch(ret) { case 0: break; case POLARSSL_ERR_NET_WANT_READ: connssl->connecting_state = ssl_connect_2_reading; return CURLE_OK; case POLARSSL_ERR_NET_WANT_WRITE: connssl->connecting_state = ssl_connect_2_writing; return CURLE_OK; default: error_strerror(ret, errorbuf, sizeof(errorbuf)); failf(data, "ssl_handshake returned - PolarSSL: (-0x%04X) %s", -ret, errorbuf); return CURLE_SSL_CONNECT_ERROR; } infof(data, "PolarSSL: Handshake complete, cipher is %s\n", ssl_get_ciphersuite(&BACKEND->ssl) ); ret = ssl_get_verify_result(&BACKEND->ssl); if(ret && SSL_CONN_CONFIG(verifypeer)) { if(ret & BADCERT_EXPIRED) failf(data, "Cert verify failed: BADCERT_EXPIRED"); if(ret & BADCERT_REVOKED) { failf(data, "Cert verify failed: BADCERT_REVOKED"); return CURLE_SSL_CACERT; } if(ret & BADCERT_CN_MISMATCH) failf(data, "Cert verify failed: BADCERT_CN_MISMATCH"); if(ret & BADCERT_NOT_TRUSTED) failf(data, "Cert verify failed: BADCERT_NOT_TRUSTED"); return CURLE_PEER_FAILED_VERIFICATION; } if(ssl_get_peer_cert(&(BACKEND->ssl))) { /* If the session was resumed, there will be no peer certs */ memset(buffer, 0, sizeof(buffer)); if(x509_crt_info(buffer, sizeof(buffer), (char *)"* ", ssl_get_peer_cert(&(BACKEND->ssl))) != -1) infof(data, "Dumping cert info:\n%s\n", buffer); } /* adapted from mbedtls.c */ if(pinnedpubkey) { int size; CURLcode result; x509_crt *p; unsigned char pubkey[PUB_DER_MAX_BYTES]; const x509_crt *peercert; peercert = ssl_get_peer_cert(&BACKEND->ssl); if(!peercert || !peercert->raw.p || !peercert->raw.len) { failf(data, "Failed due to missing peer certificate"); return CURLE_SSL_PINNEDPUBKEYNOTMATCH; } p = calloc(1, sizeof(*p)); if(!p) return CURLE_OUT_OF_MEMORY; x509_crt_init(p); /* Make a copy of our const peercert because pk_write_pubkey_der needs a non-const key, for now. https://github.com/ARMmbed/mbedtls/issues/396 */ if(x509_crt_parse_der(p, peercert->raw.p, peercert->raw.len)) { failf(data, "Failed copying peer certificate"); x509_crt_free(p); free(p); return CURLE_SSL_PINNEDPUBKEYNOTMATCH; } size = pk_write_pubkey_der(&p->pk, pubkey, PUB_DER_MAX_BYTES); if(size <= 0) { failf(data, "Failed copying public key from peer certificate"); x509_crt_free(p); free(p); return CURLE_SSL_PINNEDPUBKEYNOTMATCH; } /* pk_write_pubkey_der writes data at the end of the buffer. */ result = Curl_pin_peer_pubkey(data, pinnedpubkey, &pubkey[PUB_DER_MAX_BYTES - size], size); if(result) { x509_crt_free(p); free(p); return result; } x509_crt_free(p); free(p); } #ifdef HAS_ALPN if(conn->bits.tls_enable_alpn) { const char *next_protocol = ssl_get_alpn_protocol(&BACKEND->ssl); if(next_protocol != NULL) { infof(data, "ALPN, server accepted to use %s\n", next_protocol); #ifdef USE_NGHTTP2 if(!strncmp(next_protocol, NGHTTP2_PROTO_VERSION_ID, NGHTTP2_PROTO_VERSION_ID_LEN)) { conn->negnpn = CURL_HTTP_VERSION_2; } else #endif if(!strncmp(next_protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH)) { conn->negnpn = CURL_HTTP_VERSION_1_1; } } else infof(data, "ALPN, server did not agree to a protocol\n"); } #endif connssl->connecting_state = ssl_connect_3; infof(data, "SSL connected\n"); return CURLE_OK; }
int main( int argc, char *argv[] ) { int ret = 0; rsa_context rsa; char buf[1024]; int i; char *p, *q; /* * Set to sane values */ memset( &rsa, 0, sizeof( rsa_context ) ); memset( buf, 0, 1024 ); if( argc == 0 ) { usage: printf( USAGE ); goto exit; } opt.mode = DFL_MODE; opt.filename = DFL_FILENAME; opt.password = DFL_PASSWORD; opt.password_file = DFL_PASSWORD_FILE; opt.debug_level = DFL_DEBUG_LEVEL; 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, "filename" ) == 0 ) opt.filename = q; else if( strcmp( p, "password" ) == 0 ) opt.password = q; else if( strcmp( p, "password_file" ) == 0 ) opt.password_file = 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 goto usage; } if( opt.mode == MODE_PRIVATE ) { if( strlen( opt.password ) && strlen( opt.password_file ) ) { printf( "Error: cannot have both password and password_file\n" ); goto usage; } if( strlen( opt.password_file ) ) { FILE *f; printf( "\n . Loading the password file ..." ); if( ( f = fopen( opt.password_file, "rb" ) ) == NULL ) { printf( " failed\n ! fopen returned NULL\n" ); goto exit; } fgets( buf, 1024, f ); fclose( f ); i = strlen( buf ); if( buf[i - 1] == '\n' ) buf[i - 1] = '\0'; if( buf[i - 2] == '\r' ) buf[i - 2] = '\0'; opt.password = buf; } /* * 1.1. Load the key */ printf( "\n . Loading the private key ..." ); fflush( stdout ); ret = x509parse_keyfile( &rsa, opt.filename, opt.password ); if( ret != 0 ) { #ifdef POLARSSL_ERROR_C error_strerror( ret, buf, 1024 ); #endif printf( " failed\n ! x509parse_key returned %d - %s\n\n", ret, buf ); rsa_free( &rsa ); goto exit; } printf( " ok\n" ); /* * 1.2 Print the key */ printf( " . Key information ...\n" ); mpi_write_file( "N: ", &rsa.N, 16, NULL ); mpi_write_file( "E: ", &rsa.E, 16, NULL ); mpi_write_file( "D: ", &rsa.D, 16, NULL ); mpi_write_file( "P: ", &rsa.P, 16, NULL ); mpi_write_file( "Q: ", &rsa.Q, 16, NULL ); mpi_write_file( "DP: ", &rsa.DP, 16, NULL ); mpi_write_file( "DQ: ", &rsa.DQ, 16, NULL ); mpi_write_file( "QP: ", &rsa.QP, 16, NULL ); } else if( opt.mode == MODE_PUBLIC ) { /* * 1.1. Load the key */ printf( "\n . Loading the public key ..." ); fflush( stdout ); ret = x509parse_public_keyfile( &rsa, opt.filename ); if( ret != 0 ) { #ifdef POLARSSL_ERROR_C error_strerror( ret, buf, 1024 ); #endif printf( " failed\n ! x509parse_public_key returned %d - %s\n\n", ret, buf ); rsa_free( &rsa ); goto exit; } printf( " ok\n" ); /* * 1.2 Print the key */ printf( " . Key information ...\n" ); mpi_write_file( "N: ", &rsa.N, 16, NULL ); mpi_write_file( "E: ", &rsa.E, 16, NULL ); } else goto usage; exit: rsa_free( &rsa ); #if defined(_WIN32) printf( " + Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif return( ret ); }