X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=lib%2Fvtls%2Fgtls.c;h=5d4e48a258a4cd36b643a59c63c1f6db801b84f5;hb=7b6dca47a42828c0ae87eab0d8b68f97d1495b67;hp=c54dfc1d2e158be915d4e926c9cc9bf2319ec05d;hpb=8a08705db260779441360e959b97b6c172f8acb0;p=platform%2Fupstream%2Fcurl.git diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c index c54dfc1..5d4e48a 100644 --- a/lib/vtls/gtls.c +++ b/lib/vtls/gtls.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -39,7 +39,6 @@ #ifdef USE_GNUTLS_NETTLE #include #include -#include #else #include #endif @@ -54,8 +53,9 @@ #include "select.h" #include "rawstr.h" #include "warnless.h" -#include "x509asn1.h" -#include "curl_printf.h" + +#define _MPRINTF_REPLACE /* use our functions only */ +#include #include "curl_memory.h" /* The last #include file should be: */ #include "memdebug.h" @@ -92,23 +92,14 @@ static bool gtls_inited = FALSE; # define GNUTLS_MAPS_WINSOCK_ERRORS 1 # endif -# if (GNUTLS_VERSION_NUMBER >= 0x030200) -# define HAS_ALPN -# endif - -# if (GNUTLS_VERSION_NUMBER >= 0x03020d) -# define HAS_OCSP -# endif - -# if (GNUTLS_VERSION_NUMBER >= 0x030306) -# define HAS_CAPATH +# ifdef USE_NGHTTP2 +# undef HAS_ALPN +# if (GNUTLS_VERSION_NUMBER >= 0x030200) +# define HAS_ALPN +# endif # endif #endif -#ifdef HAS_OCSP -# include -#endif - /* * Custom push and pull callback functions used by GNU TLS to read and write * to the socket. These functions are simple wrappers to send() and recv() @@ -213,7 +204,7 @@ static void showtime(struct SessionHandle *data, snprintf(data->state.buffer, BUFSIZE, - "\t %s: %s, %02d %s %4d %02d:%02d:%02d GMT", + "\t %s: %s, %02d %s %4d %02d:%02d:%02d GMT\n", text, Curl_wkday[tm->tm_wday?tm->tm_wday-1:6], tm->tm_mday, @@ -232,7 +223,7 @@ static gnutls_datum_t load_file (const char *file) long filelen; void *ptr; - if(!(f = fopen(file, "rb"))) + if(!(f = fopen(file, "r"))) return loaded_file; if(fseek(f, 0, SEEK_END) != 0 || (filelen = ftell(f)) < 0 @@ -328,8 +319,7 @@ static CURLcode handshake(struct connectdata *conn, if(strerr == NULL) strerr = gnutls_strerror(rc); - infof(data, "gnutls_handshake() warning: %s\n", strerr); - continue; + failf(data, "gnutls_handshake() warning: %s", strerr); } else if(rc < 0) { const char *strerr = NULL; @@ -402,6 +392,10 @@ gtls_connect_step1(struct connectdata *conn, const char* prioritylist; const char *err = NULL; #endif +#ifdef HAS_ALPN + int protocols_size = 2; + gnutls_datum_t protocols[2]; +#endif if(conn->ssl[sockindex].state == ssl_connection_complete) /* to make us tolerant against being called more than once for the @@ -469,24 +463,6 @@ gtls_connect_step1(struct connectdata *conn, rc, data->set.ssl.CAfile); } -#ifdef HAS_CAPATH - if(data->set.ssl.CApath) { - /* set the trusted CA cert directory */ - rc = gnutls_certificate_set_x509_trust_dir(conn->ssl[sockindex].cred, - data->set.ssl.CApath, - GNUTLS_X509_FMT_PEM); - if(rc < 0) { - infof(data, "error reading ca cert file %s (%s)\n", - data->set.ssl.CAfile, gnutls_strerror(rc)); - if(data->set.ssl.verifypeer) - return CURLE_SSL_CACERT_BADFILE; - } - else - infof(data, "found %d certificates in %s\n", - rc, data->set.ssl.CApath); - } -#endif - if(data->set.ssl.CRLfile) { /* set the CRL list file */ rc = gnutls_certificate_set_x509_crl_file(conn->ssl[sockindex].cred, @@ -633,25 +609,20 @@ gtls_connect_step1(struct connectdata *conn, #endif #ifdef HAS_ALPN - if(data->set.ssl_enable_alpn) { - int cur = 0; - gnutls_datum_t protocols[2]; - -#ifdef USE_NGHTTP2 - if(data->set.httpversion == CURL_HTTP_VERSION_2_0) { - protocols[cur].data = (unsigned char *)NGHTTP2_PROTO_VERSION_ID; - protocols[cur].size = NGHTTP2_PROTO_VERSION_ID_LEN; - cur++; - infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); + if(data->set.httpversion == CURL_HTTP_VERSION_2_0) { + if(data->set.ssl_enable_alpn) { + protocols[0].data = NGHTTP2_PROTO_VERSION_ID; + protocols[0].size = NGHTTP2_PROTO_VERSION_ID_LEN; + protocols[1].data = ALPN_HTTP_1_1; + protocols[1].size = ALPN_HTTP_1_1_LENGTH; + gnutls_alpn_set_protocols(session, protocols, protocols_size, 0); + infof(data, "ALPN, offering %s, %s\n", NGHTTP2_PROTO_VERSION_ID, + ALPN_HTTP_1_1); + connssl->asked_for_h2 = TRUE; + } + else { + infof(data, "SSL, can't negotiate HTTP/2.0 without ALPN\n"); } -#endif - - protocols[cur].data = (unsigned char *)ALPN_HTTP_1_1; - protocols[cur].size = ALPN_HTTP_1_1_LENGTH; - cur++; - infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1); - - gnutls_alpn_set_protocols(session, protocols, cur, 0); } #endif @@ -673,21 +644,13 @@ gtls_connect_step1(struct connectdata *conn, 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) { + if(rc != GNUTLS_E_SUCCESS) failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc)); - return CURLE_SSL_CONNECT_ERROR; - } } else #endif - { rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, conn->ssl[sockindex].cred); - if(rc != GNUTLS_E_SUCCESS) { - failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc)); - return CURLE_SSL_CONNECT_ERROR; - } - } /* set the connection handle (file descriptor for the socket) */ gnutls_transport_set_ptr(session, @@ -700,16 +663,6 @@ gtls_connect_step1(struct connectdata *conn, /* lowat must be set to zero when using custom push and pull functions. */ gnutls_transport_set_lowat(session, 0); -#ifdef HAS_OCSP - if(data->set.ssl.verifystatus) { - rc = gnutls_ocsp_status_request_enable_client(session, NULL, 0, NULL); - if(rc != GNUTLS_E_SUCCESS) { - failf(data, "gnutls_ocsp_status_request_enable_client() failed: %d", rc); - return CURLE_SSL_CONNECT_ERROR; - } - } -#endif - /* This might be a reconnect, so we check for a session ID in the cache to speed up things */ @@ -789,8 +742,8 @@ gtls_connect_step3(struct connectdata *conn, { unsigned int cert_list_size; const gnutls_datum_t *chainp; - unsigned int verify_status = 0; - gnutls_x509_crt_t x509_cert, x509_issuer; + unsigned int verify_status; + gnutls_x509_crt_t x509_cert,x509_issuer; gnutls_datum_t issuerp; char certbuf[256] = ""; /* big enough? */ size_t size; @@ -808,16 +761,6 @@ gtls_connect_step3(struct connectdata *conn, #endif CURLcode result = CURLE_OK; - gnutls_protocol_t version = gnutls_protocol_get_version(session); - - /* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */ - ptr = gnutls_cipher_suite_get_name(gnutls_kx_get(session), - gnutls_cipher_get(session), - gnutls_mac_get(session)); - - infof(data, "SSL connection using %s / %s\n", - gnutls_protocol_get_name(version), ptr); - /* This function will return the peer's raw certificate (chain) as sent by the peer. These certificates are in raw format (DER encoded for X.509). In case of a X.509 then a certificate list may be present. The @@ -848,23 +791,6 @@ gtls_connect_step3(struct connectdata *conn, infof(data, "\t common name: WARNING couldn't obtain\n"); } - if(data->set.ssl.certinfo && chainp) { - unsigned int i; - - result = Curl_ssl_init_certinfo(data, cert_list_size); - if(result) - return result; - - for(i = 0; i < cert_list_size; i++) { - const char *beg = (const char *) chainp[i].data; - const char *end = beg + chainp[i].size; - - result = Curl_extract_certinfo(conn, i, beg, end); - if(result) - return result; - } - } - if(data->set.ssl.verifypeer) { /* This function will try to verify the peer's certificate and return its status (trusted, invalid etc.). The value of status should be one or @@ -896,111 +822,6 @@ gtls_connect_step3(struct connectdata *conn, else infof(data, "\t server certificate verification SKIPPED\n"); -#ifdef HAS_OCSP - if(data->set.ssl.verifystatus) { - if(gnutls_ocsp_status_request_is_checked(session, 0) == 0) { - gnutls_datum_t status_request; - gnutls_ocsp_resp_t ocsp_resp; - - gnutls_ocsp_cert_status_t status; - gnutls_x509_crl_reason_t reason; - - rc = gnutls_ocsp_status_request_get(session, &status_request); - - infof(data, "\t server certificate status verification FAILED\n"); - - if(rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { - failf(data, "No OCSP response received"); - return CURLE_SSL_INVALIDCERTSTATUS; - } - - if(rc < 0) { - failf(data, "Invalid OCSP response received"); - return CURLE_SSL_INVALIDCERTSTATUS; - } - - gnutls_ocsp_resp_init(&ocsp_resp); - - rc = gnutls_ocsp_resp_import(ocsp_resp, &status_request); - if(rc < 0) { - failf(data, "Invalid OCSP response received"); - return CURLE_SSL_INVALIDCERTSTATUS; - } - - rc = gnutls_ocsp_resp_get_single(ocsp_resp, 0, NULL, NULL, NULL, NULL, - &status, NULL, NULL, NULL, &reason); - - switch(status) { - case GNUTLS_OCSP_CERT_GOOD: - break; - - case GNUTLS_OCSP_CERT_REVOKED: { - const char *crl_reason; - - switch(reason) { - default: - case GNUTLS_X509_CRLREASON_UNSPECIFIED: - crl_reason = "unspecified reason"; - break; - - case GNUTLS_X509_CRLREASON_KEYCOMPROMISE: - crl_reason = "private key compromised"; - break; - - case GNUTLS_X509_CRLREASON_CACOMPROMISE: - crl_reason = "CA compromised"; - break; - - case GNUTLS_X509_CRLREASON_AFFILIATIONCHANGED: - crl_reason = "affiliation has changed"; - break; - - case GNUTLS_X509_CRLREASON_SUPERSEDED: - crl_reason = "certificate superseded"; - break; - - case GNUTLS_X509_CRLREASON_CESSATIONOFOPERATION: - crl_reason = "operation has ceased"; - break; - - case GNUTLS_X509_CRLREASON_CERTIFICATEHOLD: - crl_reason = "certificate is on hold"; - break; - - case GNUTLS_X509_CRLREASON_REMOVEFROMCRL: - crl_reason = "will be removed from delta CRL"; - break; - - case GNUTLS_X509_CRLREASON_PRIVILEGEWITHDRAWN: - crl_reason = "privilege withdrawn"; - break; - - case GNUTLS_X509_CRLREASON_AACOMPROMISE: - crl_reason = "AA compromised"; - break; - } - - failf(data, "Server certificate was revoked: %s", crl_reason); - break; - } - - default: - case GNUTLS_OCSP_CERT_UNKNOWN: - failf(data, "Server certificate status is unknown"); - break; - } - - gnutls_ocsp_resp_deinit(ocsp_resp); - - return CURLE_SSL_INVALIDCERTSTATUS; - } - else - infof(data, "\t server certificate status verification OK\n"); - } - else - infof(data, "\t server certificate status verification SKIPPED\n"); -#endif - /* initialize an X.509 certificate structure. */ gnutls_x509_crt_init(&x509_cert); @@ -1013,7 +834,7 @@ gtls_connect_step3(struct connectdata *conn, gnutls_x509_crt_init(&x509_issuer); issuerp = load_file(data->set.ssl.issuercert); gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM); - rc = gnutls_x509_crt_check_issuer(x509_cert, x509_issuer); + rc = gnutls_x509_crt_check_issuer(x509_cert,x509_issuer); gnutls_x509_crt_deinit(x509_issuer); unload_file(issuerp); if(rc <= 0) { @@ -1022,7 +843,7 @@ gtls_connect_step3(struct connectdata *conn, gnutls_x509_crt_deinit(x509_cert); return CURLE_SSL_ISSUER_ERROR; } - infof(data, "\t server certificate issuer check OK (Issuer Cert: %s)\n", + infof(data,"\t server certificate issuer check OK (Issuer Cert: %s)\n", data->set.ssl.issuercert?data->set.ssl.issuercert:"none"); } @@ -1162,6 +983,7 @@ gtls_connect_step3(struct connectdata *conn, /* Show: + - ciphers used - subject - start date - expire date @@ -1201,6 +1023,14 @@ gtls_connect_step3(struct connectdata *conn, /* the *_get_name() says "NULL" if GNUTLS_COMP_NULL is returned */ infof(data, "\t compression: %s\n", ptr); + /* the name of the cipher used. ie 3DES. */ + ptr = gnutls_cipher_get_name(gnutls_cipher_get(session)); + infof(data, "\t cipher: %s\n", ptr); + + /* the MAC algorithms name. ie SHA1 */ + ptr = gnutls_mac_get_name(gnutls_mac_get(session)); + infof(data, "\t MAC: %s\n", ptr); + #ifdef HAS_ALPN if(data->set.ssl_enable_alpn) { rc = gnutls_alpn_get_selected_protocol(session, &proto); @@ -1208,21 +1038,19 @@ gtls_connect_step3(struct connectdata *conn, infof(data, "ALPN, server accepted to use %.*s\n", proto.size, proto.data); -#ifdef USE_NGHTTP2 if(proto.size == NGHTTP2_PROTO_VERSION_ID_LEN && - !memcmp(NGHTTP2_PROTO_VERSION_ID, proto.data, - NGHTTP2_PROTO_VERSION_ID_LEN)) { - conn->negnpn = CURL_HTTP_VERSION_2_0; + memcmp(NGHTTP2_PROTO_VERSION_ID, proto.data, + NGHTTP2_PROTO_VERSION_ID_LEN) == 0) { + conn->negnpn = NPN_HTTP2; } - else -#endif - if(proto.size == ALPN_HTTP_1_1_LENGTH && - !memcmp(ALPN_HTTP_1_1, proto.data, ALPN_HTTP_1_1_LENGTH)) { - conn->negnpn = CURL_HTTP_VERSION_1_1; + else if(proto.size == ALPN_HTTP_1_1_LENGTH && memcmp(ALPN_HTTP_1_1, + proto.data, ALPN_HTTP_1_1_LENGTH) == 0) { + conn->negnpn = NPN_HTTP1_1; } } - else + else if(connssl->asked_for_h2) { infof(data, "ALPN, server did not agree to a protocol\n"); + } } #endif @@ -1354,6 +1182,12 @@ static ssize_t gtls_send(struct connectdata *conn, return rc; } +void Curl_gtls_close_all(struct SessionHandle *data) +{ + /* FIX: make the OpenSSL code more generic and use parts of it here */ + (void)data; +} + static void close_one(struct connectdata *conn, int idx) { @@ -1558,32 +1392,4 @@ void Curl_gtls_md5sum(unsigned char *tmp, /* input */ #endif } -void Curl_gtls_sha256sum(const unsigned char *tmp, /* input */ - size_t tmplen, - unsigned char *sha256sum, /* output */ - size_t sha256len) -{ -#if defined(USE_GNUTLS_NETTLE) - struct sha256_ctx SHA256pw; - sha256_init(&SHA256pw); - sha256_update(&SHA256pw, (unsigned int)tmplen, tmp); - sha256_digest(&SHA256pw, (unsigned int)sha256len, sha256sum); -#elif defined(USE_GNUTLS) - gcry_md_hd_t SHA256pw; - gcry_md_open(&SHA256pw, GCRY_MD_SHA256, 0); - gcry_md_write(SHA256pw, tmp, tmplen); - memcpy(sha256sum, gcry_md_read (SHA256pw, 0), sha256len); - gcry_md_close(SHA256pw); -#endif -} - -bool Curl_gtls_cert_status_request(void) -{ -#ifdef HAS_OCSP - return TRUE; -#else - return FALSE; -#endif -} - #endif /* USE_GNUTLS */