diff options
author | Quinn Slack <sqs@cs.stanford.edu> | 2011-01-19 20:35:02 +0100 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2011-01-19 20:35:02 +0100 |
commit | 59cf93ccdbaa5e866f9de6b2d9b1ae5cee84863f (patch) | |
tree | b0a40c875954b842a9bf50f409d571de04507044 /lib | |
parent | 4f13340ab8be7baa0fe6210bb3a19b8994875fd8 (diff) | |
download | curl-59cf93ccdbaa5e866f9de6b2d9b1ae5cee84863f.tar.gz |
TLS-SRP: support added when using GnuTLS
Diffstat (limited to 'lib')
-rw-r--r-- | lib/gtls.c | 71 | ||||
-rw-r--r-- | lib/strerror.c | 5 | ||||
-rw-r--r-- | lib/url.c | 27 | ||||
-rw-r--r-- | lib/urldata.h | 14 | ||||
-rw-r--r-- | lib/version.c | 3 |
5 files changed, 114 insertions, 6 deletions
diff --git a/lib/gtls.c b/lib/gtls.c index 9a87c39a8..b5ef8fb99 100644 --- a/lib/gtls.c +++ b/lib/gtls.c @@ -346,6 +346,29 @@ gtls_connect_step1(struct connectdata *conn, return CURLE_SSL_CONNECT_ERROR; } +#ifdef USE_TLS_SRP + if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) { + infof(data, "Using TLS-SRP username: %s\n", data->set.ssl.username); + + rc = gnutls_srp_allocate_client_credentials( + &conn->ssl[sockindex].srp_client_cred); + if(rc != GNUTLS_E_SUCCESS) { + failf(data, "gnutls_srp_allocate_client_cred() failed: %s", + gnutls_strerror(rc)); + return CURLE_TLSAUTH_FAILED; + } + + rc = gnutls_srp_set_client_credentials(conn->ssl[sockindex].srp_client_cred, + data->set.ssl.username, + data->set.ssl.password); + if(rc != GNUTLS_E_SUCCESS) { + failf(data, "gnutls_srp_set_client_cred() failed: %s", + gnutls_strerror(rc)); + return CURLE_TLSAUTH_FAILED; + } + } +#endif + if(data->set.ssl.CAfile) { /* set the trusted CA cert bundle file */ gnutls_certificate_set_verify_flags(conn->ssl[sockindex].cred, @@ -431,9 +454,18 @@ gtls_connect_step1(struct connectdata *conn, } } +#ifdef USE_TLS_SRP /* put the credentials to the current session */ - rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, - conn->ssl[sockindex].cred); + if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) { + rc = gnutls_credentials_set(session, GNUTLS_CRD_SRP, + conn->ssl[sockindex].srp_client_cred); + if (rc != GNUTLS_E_SUCCESS) { + failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc)); + } + } else +#endif + rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, + conn->ssl[sockindex].cred); /* set the connection handle (file descriptor for the socket) */ gnutls_transport_set_ptr(session, @@ -496,8 +528,21 @@ gtls_connect_step3(struct connectdata *conn, if(data->set.ssl.verifypeer || data->set.ssl.verifyhost || data->set.ssl.issuercert) { - failf(data, "failed to get server cert"); - return CURLE_PEER_FAILED_VERIFICATION; +#ifdef USE_TLS_SRP + if(data->set.ssl.authtype == CURL_TLSAUTH_SRP + && data->set.ssl.username != NULL + && !data->set.ssl.verifypeer + && gnutls_cipher_get(session)) { + /* no peer cert, but auth is ok if we have SRP user and cipher and no + peer verify */ + } + else { +#endif + failf(data, "failed to get server cert"); + return CURLE_PEER_FAILED_VERIFICATION; +#ifdef USE_TLS_SRP + } +#endif } infof(data, "\t common name: WARNING couldn't obtain\n"); } @@ -530,8 +575,10 @@ gtls_connect_step3(struct connectdata *conn, else infof(data, "\t server certificate verification OK\n"); } - else + else { infof(data, "\t server certificate verification SKIPPED\n"); + goto after_server_cert_verification; + } /* initialize an X.509 certificate structure. */ gnutls_x509_crt_init(&x509_cert); @@ -661,6 +708,8 @@ gtls_connect_step3(struct connectdata *conn, gnutls_x509_crt_deinit(x509_cert); +after_server_cert_verification: + /* compression algorithm (if any) */ ptr = gnutls_compression_get_name(gnutls_compression_get(session)); /* the *_get_name() says "NULL" if GNUTLS_COMP_NULL is returned */ @@ -820,6 +869,12 @@ static void close_one(struct connectdata *conn, gnutls_certificate_free_credentials(conn->ssl[idx].cred); conn->ssl[idx].cred = NULL; } +#ifdef USE_TLS_SRP + if (conn->ssl[idx].srp_client_cred) { + gnutls_srp_free_client_credentials(conn->ssl[idx].srp_client_cred); + conn->ssl[idx].srp_client_cred = NULL; + } +#endif } void Curl_gtls_close(struct connectdata *conn, int sockindex) @@ -889,6 +944,12 @@ int Curl_gtls_shutdown(struct connectdata *conn, int sockindex) } gnutls_certificate_free_credentials(conn->ssl[sockindex].cred); +#ifdef USE_TLS_SRP + if(data->set.ssl.authtype == CURL_TLSAUTH_SRP + && data->set.ssl.username != NULL) + gnutls_srp_free_client_credentials(conn->ssl[sockindex].srp_client_cred); +#endif + conn->ssl[sockindex].cred = NULL; conn->ssl[sockindex].session = NULL; diff --git a/lib/strerror.c b/lib/strerror.c index e8ecea59f..6b67a8777 100644 --- a/lib/strerror.c +++ b/lib/strerror.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2004 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2004 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -281,6 +281,9 @@ curl_easy_strerror(CURLcode error) case CURLE_CHUNK_FAILED: return "Chunk callback failed"; + case CURLE_TLSAUTH_FAILED: + return "TLS Authentication failed"; + /* error codes not used by current libcurl */ case CURLE_OBSOLETE4: case CURLE_OBSOLETE10: @@ -751,6 +751,9 @@ CURLcode Curl_init_userdefined(struct UserDefined *set) */ set->ssl.verifypeer = TRUE; set->ssl.verifyhost = 2; +#ifdef USE_TLS_SRP + set->ssl.authtype = CURL_TLSAUTH_NONE; +#endif set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth type */ set->ssl.sessionid = TRUE; /* session ID caching enabled by default */ @@ -2526,6 +2529,26 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, case CURLOPT_FNMATCH_DATA: data->set.fnmatch_data = va_arg(param, void *); break; +#ifdef USE_TLS_SRP + case CURLOPT_TLSAUTH_USERNAME: + result = setstropt(&data->set.str[STRING_TLSAUTH_USERNAME], + va_arg(param, char *)); + if (data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype) + data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */ + break; + case CURLOPT_TLSAUTH_PASSWORD: + result = setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD], + va_arg(param, char *)); + if (data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype) + data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */ + break; + case CURLOPT_TLSAUTH_TYPE: + if (strncmp((char *)va_arg(param, char *), "SRP", strlen("SRP")) == 0) + data->set.ssl.authtype = CURL_TLSAUTH_SRP; + else + data->set.ssl.authtype = CURL_TLSAUTH_NONE; + break; +#endif default: /* unknown tag and its companion, just ignore: */ result = CURLE_FAILED_INIT; /* correct this */ @@ -4929,6 +4952,10 @@ static CURLcode create_conn(struct SessionHandle *data, data->set.ssl.random_file = data->set.str[STRING_SSL_RANDOM_FILE]; data->set.ssl.egdsocket = data->set.str[STRING_SSL_EGDSOCKET]; data->set.ssl.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST]; +#ifdef USE_TLS_SRP + data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME]; + data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD]; +#endif if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config)) return CURLE_OUT_OF_MEMORY; diff --git a/lib/urldata.h b/lib/urldata.h index 55167fbc3..a86f7f156 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -251,6 +251,9 @@ struct ssl_connect_data { #ifdef USE_GNUTLS gnutls_session session; gnutls_certificate_credentials cred; +#ifdef USE_TLS_SRP + gnutls_srp_client_credentials srp_client_cred; +#endif ssl_connect_state connecting_state; #endif /* USE_GNUTLS */ #ifdef USE_POLARSSL @@ -300,6 +303,12 @@ struct ssl_config_data { void *fsslctxp; /* parameter for call back */ bool sessionid; /* cache session IDs or not */ bool certinfo; /* gather lots of certificate info */ + +#ifdef USE_TLS_SRP + char *username; /* TLS username (for, e.g., SRP) */ + char *password; /* TLS password (for, e.g., SRP) */ + enum CURL_TLSAUTH authtype; /* TLS authentication type (default SRP) */ +#endif }; /* information stored about one single SSL session */ @@ -1315,6 +1324,11 @@ enum dupstring { #endif STRING_MAIL_FROM, +#ifdef USE_TLS_SRP + STRING_TLSAUTH_USERNAME, /* TLS auth <username> */ + STRING_TLSAUTH_PASSWORD, /* TLS auth <password> */ +#endif + /* -- end of strings -- */ STRING_LAST /* not used, just an end-of-list marker */ }; diff --git a/lib/version.c b/lib/version.c index 5931e7180..52989cdc6 100644 --- a/lib/version.c +++ b/lib/version.c @@ -265,6 +265,9 @@ static curl_version_info_data version_info = { #if defined(CURL_DOES_CONVERSIONS) | CURL_VERSION_CONV #endif +#if defined(USE_TLS_SRP) + | CURL_VERSION_TLSAUTH_SRP +#endif , NULL, /* ssl_version */ 0, /* ssl_version_num, this is kept at zero */ |