diff options
Diffstat (limited to 'Utilities/cmcurl/lib/vtls/sectransp.c')
-rw-r--r-- | Utilities/cmcurl/lib/vtls/sectransp.c | 107 |
1 files changed, 39 insertions, 68 deletions
diff --git a/Utilities/cmcurl/lib/vtls/sectransp.c b/Utilities/cmcurl/lib/vtls/sectransp.c index 2e98169e26..7f55fb5be7 100644 --- a/Utilities/cmcurl/lib/vtls/sectransp.c +++ b/Utilities/cmcurl/lib/vtls/sectransp.c @@ -2150,50 +2150,39 @@ static long pem_to_der(const char *in, unsigned char **out, size_t *outlen) return sep_end - in; } +#define MAX_CERTS_SIZE (50*1024*1024) /* arbitrary - to catch mistakes */ + static int read_cert(const char *file, unsigned char **out, size_t *outlen) { int fd; - ssize_t n, len = 0, cap = 512; - unsigned char buf[512], *data; + ssize_t n; + unsigned char buf[512]; + struct dynbuf certs; + + Curl_dyn_init(&certs, MAX_CERTS_SIZE); fd = open(file, 0); if(fd < 0) return -1; - data = malloc(cap); - if(!data) { - close(fd); - return -1; - } - for(;;) { n = read(fd, buf, sizeof(buf)); + if(!n) + break; if(n < 0) { close(fd); - free(data); + Curl_dyn_free(&certs); return -1; } - else if(n == 0) { + if(Curl_dyn_addn(&certs, buf, n)) { close(fd); - break; - } - - if(len + n >= cap) { - cap *= 2; - data = Curl_saferealloc(data, cap); - if(!data) { - close(fd); - return -1; - } + return -1; } - - memcpy(data + len, buf, n); - len += n; } - data[len] = '\0'; + close(fd); - *out = data; - *outlen = len; + *out = Curl_dyn_uptr(&certs); + *outlen = Curl_dyn_len(&certs); return 0; } @@ -2202,16 +2191,18 @@ static int append_cert_to_array(struct Curl_easy *data, const unsigned char *buf, size_t buflen, CFMutableArrayRef array) { - CFDataRef certdata = CFDataCreate(kCFAllocatorDefault, buf, buflen); char *certp; CURLcode result; + SecCertificateRef cacert; + CFDataRef certdata; + + certdata = CFDataCreate(kCFAllocatorDefault, buf, buflen); if(!certdata) { failf(data, "SSL: failed to allocate array for CA certificate"); return CURLE_OUT_OF_MEMORY; } - SecCertificateRef cacert = - SecCertificateCreateWithData(kCFAllocatorDefault, certdata); + cacert = SecCertificateCreateWithData(kCFAllocatorDefault, certdata); CFRelease(certdata); if(!cacert) { failf(data, "SSL: failed to create SecCertificate from CA certificate"); @@ -2425,11 +2416,15 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, do { SecTrustRef trust; - OSStatus ret = SSLCopyPeerTrust(ctx, &trust); + OSStatus ret; + SecKeyRef keyRef; + OSStatus success; + + ret = SSLCopyPeerTrust(ctx, &trust); if(ret != noErr || !trust) break; - SecKeyRef keyRef = SecTrustCopyPublicKey(trust); + keyRef = SecTrustCopyPublicKey(trust); CFRelease(trust); if(!keyRef) break; @@ -2443,8 +2438,8 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, #elif SECTRANSP_PINNEDPUBKEY_V2 - OSStatus success = SecItemExport(keyRef, kSecFormatOpenSSL, 0, NULL, - &publicKeyBits); + success = SecItemExport(keyRef, kSecFormatOpenSSL, 0, NULL, + &publicKeyBits); CFRelease(keyRef); if(success != errSecSuccess || !publicKeyBits) break; @@ -2987,12 +2982,13 @@ static CURLcode sectransp_connect_step3(struct Curl_cfilter *cf, struct Curl_easy *data) { struct ssl_connect_data *connssl = cf->ctx; + CURLcode result; DEBUGF(LOG_CF(data, cf, "connect_step3")); /* There is no step 3! * Well, okay, let's collect server certificates, and if verbose mode is on, * let's print the details of the server certificates. */ - const CURLcode result = collect_server_cert(cf, data); + result = collect_server_cert(cf, data); if(result) return result; @@ -3237,35 +3233,6 @@ static size_t sectransp_version(char *buffer, size_t size) return msnprintf(buffer, size, "SecureTransport"); } -/* - * This function uses SSLGetSessionState to determine connection status. - * - * Return codes: - * 1 means the connection is still in place - * 0 means the connection has been closed - * -1 means the connection status is unknown - */ -static int sectransp_check_cxn(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct ssl_backend_data *backend = connssl->backend; - OSStatus err; - SSLSessionState state; - - (void)data; - DEBUGASSERT(backend); - - if(backend->ssl_ctx) { - DEBUGF(LOG_CF(data, cf, "check connection")); - err = SSLGetSessionState(backend->ssl_ctx, &state); - if(err == noErr) - return state == kSSLConnected || state == kSSLHandshake; - return -1; - } - return 0; -} - static bool sectransp_data_pending(struct Curl_cfilter *cf, const struct Curl_easy *data) { @@ -3410,13 +3377,15 @@ static ssize_t sectransp_recv(struct Curl_cfilter *cf, DEBUGASSERT(backend); again: + *curlcode = CURLE_OK; err = SSLRead(backend->ssl_ctx, buf, buffersize, &processed); if(err != noErr) { switch(err) { case errSSLWouldBlock: /* return how much we read (if anything) */ - if(processed) + if(processed) { return (ssize_t)processed; + } *curlcode = CURLE_AGAIN; return -1L; break; @@ -3428,7 +3397,7 @@ static ssize_t sectransp_recv(struct Curl_cfilter *cf, case errSSLClosedGraceful: case errSSLClosedNoNotify: *curlcode = CURLE_OK; - return -1L; + return 0; break; /* The below is errSSLPeerAuthCompleted; it's not defined in @@ -3439,8 +3408,10 @@ static ssize_t sectransp_recv(struct Curl_cfilter *cf, CURLcode result = verify_cert(cf, data, conn_config->CAfile, conn_config->ca_info_blob, backend->ssl_ctx); - if(result) - return result; + if(result) { + *curlcode = result; + return -1; + } } goto again; default: @@ -3477,7 +3448,7 @@ const struct Curl_ssl Curl_ssl_sectransp = { Curl_none_init, /* init */ Curl_none_cleanup, /* cleanup */ sectransp_version, /* version */ - sectransp_check_cxn, /* check_cxn */ + Curl_none_check_cxn, /* check_cxn */ sectransp_shutdown, /* shutdown */ sectransp_data_pending, /* data_pending */ sectransp_random, /* random */ |