int git_stransport_stream_new(git_stream **out, const char *host, const char *port) { stransport_stream *st; int error; OSStatus ret; assert(out && host); st = git__calloc(1, sizeof(stransport_stream)); GITERR_CHECK_ALLOC(st); #ifdef GIT_CURL error = git_curl_stream_new(&st->io, host, port); #else error = git_socket_stream_new(&st->io, host, port); #endif if (error < 0){ git__free(st); return error; } st->ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType); if (!st->ctx) { giterr_set(GITERR_NET, "failed to create SSL context"); git__free(st); return -1; } if ((ret = SSLSetIOFuncs(st->ctx, read_cb, write_cb)) != noErr || (ret = SSLSetConnection(st->ctx, st->io)) != noErr || (ret = SSLSetSessionOption(st->ctx, kSSLSessionOptionBreakOnServerAuth, true)) != noErr || (ret = SSLSetProtocolVersionMin(st->ctx, kTLSProtocol1)) != noErr || (ret = SSLSetProtocolVersionMax(st->ctx, kTLSProtocol12)) != noErr || (ret = SSLSetPeerDomainName(st->ctx, host, strlen(host))) != noErr) { CFRelease(st->ctx); git__free(st); return stransport_error(ret); } st->parent.version = GIT_STREAM_VERSION; st->parent.encrypted = 1; st->parent.proxy_support = git_stream_supports_proxy(st->io); st->parent.connect = stransport_connect; st->parent.certificate = stransport_certificate; st->parent.set_proxy = stransport_set_proxy; st->parent.read = stransport_read; st->parent.write = stransport_write; st->parent.close = stransport_close; st->parent.free = stransport_free; *out = (git_stream *) st; return 0; }
static SSLContextRef make_ssl_ref(int sock, SSLProtocol maxprot, Boolean false_start) { SSLContextRef ctx = NULL; require_noerr(SSLNewContext(false, &ctx), out); require_noerr(SSLSetIOFuncs(ctx, (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out); require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)sock), out); require_noerr(SSLSetSessionOption(ctx, kSSLSessionOptionBreakOnServerAuth, true), out); require_noerr(SSLSetSessionOption(ctx, kSSLSessionOptionFalseStart, false_start), out); require_noerr(SSLSetProtocolVersionMax(ctx, maxprot), out); return ctx; out: if (ctx) SSLDisposeContext(ctx); return NULL; }
static CURLcode darwinssl_connect_step1(struct connectdata *conn, int sockindex) { struct SessionHandle *data = conn->data; curl_socket_t sockfd = conn->sock[sockindex]; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; bool sni = true; #ifdef ENABLE_IPV6 struct in6_addr addr; #else struct in_addr addr; #endif /*SSLConnectionRef ssl_connection;*/ OSStatus err = noErr; #if defined(__MAC_10_8) || defined(__IPHONE_5_0) if(SSLCreateContext != NULL) { /* use the newer API if avaialble */ if(connssl->ssl_ctx) CFRelease(connssl->ssl_ctx); connssl->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType); if(!connssl->ssl_ctx) { failf(data, "SSL: couldn't create a context!"); return CURLE_OUT_OF_MEMORY; } } else { #elif TARGET_OS_EMBEDDED == 0 if(connssl->ssl_ctx) (void)SSLDisposeContext(connssl->ssl_ctx); err = SSLNewContext(false, &(connssl->ssl_ctx)); if(err != noErr) { failf(data, "SSL: couldn't create a context: OSStatus %d", err); return CURLE_OUT_OF_MEMORY; } #endif /* defined(__MAC_10_8) || defined(__IPHONE_5_0) */ #if defined(__MAC_10_8) || defined(__IPHONE_5_0) } #endif /* defined(__MAC_10_8) || defined(__IPHONE_5_0) */ /* check to see if we've been told to use an explicit SSL/TLS version */ #if defined(__MAC_10_8) || defined(__IPHONE_5_0) if(SSLSetProtocolVersionMax != NULL) { switch(data->set.ssl.version) { case CURL_SSLVERSION_DEFAULT: default: (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3); (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12); break; case CURL_SSLVERSION_TLSv1: (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1); (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12); break; case CURL_SSLVERSION_SSLv3: (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3); (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3); break; case CURL_SSLVERSION_SSLv2: (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol2); (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol2); } } else { #if TARGET_OS_EMBEDDED == 0 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false); switch (data->set.ssl.version) { case CURL_SSLVERSION_DEFAULT: default: (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocol3, true); (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kTLSProtocol1, true); (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kTLSProtocol11, true); (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kTLSProtocol12, true); break; case CURL_SSLVERSION_TLSv1: (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kTLSProtocol1, true); (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kTLSProtocol11, true); (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kTLSProtocol12, true); break; case CURL_SSLVERSION_SSLv3: (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocol3, true); break; case CURL_SSLVERSION_SSLv2: (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocol2, true); break; } #endif /* TARGET_OS_EMBEDDED == 0 */ } #else (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false); switch(data->set.ssl.version) { default: case CURL_SSLVERSION_DEFAULT: (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocol3, true); (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kTLSProtocol1, true); break; case CURL_SSLVERSION_TLSv1: (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kTLSProtocol1, true); break; case CURL_SSLVERSION_SSLv2: (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocol2, true); break; case CURL_SSLVERSION_SSLv3: (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocol3, true); break; } #endif /* defined(__MAC_10_8) || defined(__IPHONE_5_0) */ /* No need to load certificates here. SecureTransport uses the Keychain * (which is also part of the Security framework) to evaluate trust. */ /* SSL always tries to verify the peer, this only says whether it should * fail to connect if the verification fails, or if it should continue * anyway. In the latter case the result of the verification is checked with * SSL_get_verify_result() below. */ #if defined(__MAC_10_6) || defined(__IPHONE_5_0) if(SSLSetSessionOption != NULL) { err = SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionBreakOnServerAuth, data->set.ssl.verifypeer?false:true); if(err != noErr) { failf(data, "SSL: SSLSetSessionOption() failed: OSStatus %d", err); return CURLE_SSL_CONNECT_ERROR; } } else { #elif TARGET_OS_EMBEDDED == 0 err = SSLSetEnableCertVerify(connssl->ssl_ctx, data->set.ssl.verifypeer?true:false); if(err != noErr) { failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err); return CURLE_SSL_CONNECT_ERROR; } #endif /* defined(__MAC_10_6) || defined(__IPHONE_5_0) */ #if defined(__MAC_10_6) || defined(__IPHONE_5_0) } #endif /* defined(__MAC_10_6) || defined(__IPHONE_5_0) */ /* If this is a domain name and not an IP address, then configure SNI: */ if((0 == Curl_inet_pton(AF_INET, conn->host.name, &addr)) && #ifdef ENABLE_IPV6 (0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr)) && #endif sni) { err = SSLSetPeerDomainName(connssl->ssl_ctx, conn->host.name, strlen(conn->host.name)); if(err != noErr) { infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d", err); } } err = SSLSetIOFuncs(connssl->ssl_ctx, SocketRead, SocketWrite); if(err != noErr) { failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err); return CURLE_SSL_CONNECT_ERROR; } /* pass the raw socket into the SSL layers */ /* We need to store the FD in a constant memory address, because * SSLSetConnection() will not copy that address. I've found that * conn->sock[sockindex] may change on its own. */ connssl->ssl_sockfd = sockfd; /*ssl_connection = &(connssl->ssl_sockfd); err = SSLSetConnection(connssl->ssl_ctx, ssl_connection);*/ err = SSLSetConnection(connssl->ssl_ctx, connssl); if(err != noErr) { failf(data, "SSL: SSLSetConnection() failed: %d", err); return CURLE_SSL_CONNECT_ERROR; } connssl->connecting_state = ssl_connect_2; return CURLE_OK; }