X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=lib%2Fvtls%2Fgtls.c;h=550a0edcd232b6ca231d4c1ad27918542b1844cd;hb=7a9f915fa6be8c8955ff2c59169538a4d0349080;hp=c54dfc1d2e158be915d4e926c9cc9bf2319ec05d;hpb=2bc9d6bb53df44a0c5174767de734620c2cdfd9e;p=platform%2Fupstream%2Fcurl.git diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c index c54dfc1..550a0ed 100644 --- a/lib/vtls/gtls.c +++ b/lib/vtls/gtls.c @@ -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,17 +92,16 @@ static bool gtls_inited = FALSE; # define GNUTLS_MAPS_WINSOCK_ERRORS 1 # endif -# if (GNUTLS_VERSION_NUMBER >= 0x030200) -# define HAS_ALPN +# ifdef USE_NGHTTP2 +# undef HAS_ALPN +# if (GNUTLS_VERSION_NUMBER >= 0x030200) +# define HAS_ALPN +# endif # endif # if (GNUTLS_VERSION_NUMBER >= 0x03020d) # define HAS_OCSP # endif - -# if (GNUTLS_VERSION_NUMBER >= 0x030306) -# define HAS_CAPATH -# endif #endif #ifdef HAS_OCSP @@ -213,7 +212,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 +231,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 +327,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 +400,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 +471,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 +617,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 +652,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, @@ -789,8 +760,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 +779,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 +809,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 @@ -899,106 +843,18 @@ gtls_connect_step3(struct connectdata *conn, #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); + if(verify_status & GNUTLS_CERT_REVOKED) + failf(data, "SSL server certificate was REVOKED\n"); + else + failf(data, "SSL server certificate status verification FAILED"); return CURLE_SSL_INVALIDCERTSTATUS; } else - infof(data, "\t server certificate status verification OK\n"); + infof(data, "SSL server certificate status verification OK\n"); } else - infof(data, "\t server certificate status verification SKIPPED\n"); + infof(data, "SSL server certificate status verification SKIPPED\n"); #endif /* initialize an X.509 certificate structure. */ @@ -1013,7 +869,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 +878,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 +1018,7 @@ gtls_connect_step3(struct connectdata *conn, /* Show: + - ciphers used - subject - start date - expire date @@ -1201,6 +1058,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 +1073,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 +1217,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,25 +1427,6 @@ 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