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 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; }
mongoc_stream_t * mongoc_stream_tls_secure_transport_new (mongoc_stream_t *base_stream, const char *host, mongoc_ssl_opt_t *opt, int client) { mongoc_stream_tls_t *tls; mongoc_stream_tls_secure_transport_t *secure_transport; ENTRY; BSON_ASSERT (base_stream); BSON_ASSERT (opt); if (opt->ca_dir) { MONGOC_ERROR ("Setting mongoc_ssl_opt_t.ca_dir has no effect when built " "against Secure Transport"); RETURN (NULL); } if (opt->crl_file) { MONGOC_ERROR ( "Setting mongoc_ssl_opt_t.crl_file has no effect when built " "against Secure Transport"); RETURN (NULL); } secure_transport = (mongoc_stream_tls_secure_transport_t *) bson_malloc0 ( sizeof *secure_transport); tls = (mongoc_stream_tls_t *) bson_malloc0 (sizeof *tls); tls->parent.type = MONGOC_STREAM_TLS; tls->parent.destroy = _mongoc_stream_tls_secure_transport_destroy; tls->parent.failed = _mongoc_stream_tls_secure_transport_failed; tls->parent.close = _mongoc_stream_tls_secure_transport_close; tls->parent.flush = _mongoc_stream_tls_secure_transport_flush; tls->parent.writev = _mongoc_stream_tls_secure_transport_writev; tls->parent.readv = _mongoc_stream_tls_secure_transport_readv; tls->parent.setsockopt = _mongoc_stream_tls_secure_transport_setsockopt; tls->parent.get_base_stream = _mongoc_stream_tls_secure_transport_get_base_stream; tls->parent.check_closed = _mongoc_stream_tls_secure_transport_check_closed; tls->parent.timed_out = _mongoc_stream_tls_secure_channel_timed_out; memcpy (&tls->ssl_opts, opt, sizeof tls->ssl_opts); tls->handshake = mongoc_stream_tls_secure_transport_handshake; tls->ctx = (void *) secure_transport; tls->timeout_msec = -1; secure_transport->ssl_ctx_ref = SSLCreateContext (kCFAllocatorDefault, client ? kSSLClientSide : kSSLServerSide, kSSLStreamType); SSLSetIOFuncs (secure_transport->ssl_ctx_ref, mongoc_secure_transport_read, mongoc_secure_transport_write); SSLSetProtocolVersionMin (secure_transport->ssl_ctx_ref, kTLSProtocol1); if (opt->pem_file && !mongoc_secure_transport_setup_certificate (secure_transport, opt)) { mongoc_stream_destroy ((mongoc_stream_t *) tls); RETURN (NULL); } if (opt->ca_file && !mongoc_secure_transport_setup_ca (secure_transport, opt)) { mongoc_stream_destroy ((mongoc_stream_t *) tls); RETURN (NULL); } /* don't link base_stream to tls until we're sure we won't destroy tls */ tls->base_stream = base_stream; if (client) { SSLSetSessionOption (secure_transport->ssl_ctx_ref, kSSLSessionOptionBreakOnServerAuth, opt->weak_cert_validation); } else if (!opt->allow_invalid_hostname) { /* used only in mock_server_t tests */ SSLSetClientSideAuthenticate (secure_transport->ssl_ctx_ref, kAlwaysAuthenticate); } if (!opt->allow_invalid_hostname) { SSLSetPeerDomainName (secure_transport->ssl_ctx_ref, host, strlen (host)); } SSLSetConnection (secure_transport->ssl_ctx_ref, tls); mongoc_counter_streams_active_inc (); RETURN ((mongoc_stream_t *) tls); }