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; }
/** * Initializes a client-side TLS session. */ static int st_ClientSessionOpen (vlc_tls_creds_t *crd, vlc_tls_t *session, int fd, const char *hostname) { msg_Dbg(session, "open TLS session for %s", hostname); vlc_tls_sys_t *sys = malloc (sizeof (*session->sys)); if (unlikely(sys == NULL)) return VLC_ENOMEM; sys->p_cred = crd->sys; sys->i_fd = fd; sys->b_handshaked = false; sys->b_blocking_send = false; sys->i_send_buffered_bytes = 0; session->sys = sys; session->sock.p_sys = session; session->sock.pf_send = st_Send; session->sock.pf_recv = st_Recv; session->handshake = st_Handshake; SSLContextRef p_context = NULL; #if TARGET_OS_IPHONE p_context = SSLCreateContext (NULL, kSSLClientSide, kSSLStreamType); if(p_context == NULL) { msg_Err(session, "cannot create ssl context"); goto error; } #else if (SSLNewContext (false, &p_context) != noErr) { msg_Err(session, "error calling SSLNewContext"); goto error; } #endif sys->p_context = p_context; OSStatus ret = SSLSetIOFuncs (p_context, st_SocketReadFunc, st_SocketWriteFunc); if(ret != noErr) { msg_Err(session, "cannot set io functions"); goto error; } ret = SSLSetConnection (p_context, session); if(ret != noErr) { msg_Err(session, "cannot set connection"); goto error; } ret = SSLSetPeerDomainName (p_context, hostname, strlen(hostname)); if(ret != noErr) { msg_Err(session, "cannot set peer domain name"); goto error; } /* disable automatic validation. We do so manually to also handle invalid certificates */ /* this has effect only on iOS 5 and OSX 10.8 or later ... */ SSLSetSessionOption (sys->p_context, kSSLSessionOptionBreakOnServerAuth, true); #if !TARGET_OS_IPHONE /* ... thus calling this for earlier osx versions, which is not available on iOS in turn */ SSLSetEnableCertVerify (sys->p_context, false); #endif return VLC_SUCCESS; error: st_ClientSessionClose(crd, session); return VLC_EGENERIC; }
Connection::Connection(Context& ctx, std::ios& ios, OpenMode omode) : _ctx(&ctx) , _context(0) , _ios(&ios) , _iocount(0) , _connected(false) , _wantRead(false) , _isReading(false) , _isWriting(false) , _receivedShutdown(false) , _sentShutdown(false) { Boolean isServer = (omode == Accept); SSLNewContext(isServer, &_context); SSLSetConnection(_context, (SSLConnectionRef) this); SSLSetIOFuncs(_context, &Connection::sslReadCallback, &Connection::sslWriteCallback); SSLSetProtocolVersionEnabled(_context, kSSLProtocolAll, false); switch(_ctx->protocol()) { case SSLv2: SSLSetProtocolVersionEnabled(_context, kSSLProtocol2, true); break; case SSLv3or2: SSLSetProtocolVersionEnabled(_context, kSSLProtocol2, true); SSLSetProtocolVersionEnabled(_context, kSSLProtocol3, true); break; default: case SSLv3: SSLSetProtocolVersionEnabled(_context, kSSLProtocol3, true); break; case TLSv1: SSLSetProtocolVersionEnabled(_context, kTLSProtocol1, true); break; } if(isServer) { #ifdef PT_IOS SSLSetEnableCertVerify(_context, false); SSLSetSessionOption(_context, kSSLSessionOptionBreakOnClientAuth, true); #else if(_ctx->verifyMode() == NoVerify) { SSLSetClientSideAuthenticate(_context, kNeverAuthenticate); } else if(_ctx->verifyMode() == TryVerify) { SSLSetClientSideAuthenticate(_context, kTryAuthenticate); } else if(_ctx->verifyMode() == AlwaysVerify) { SSLSetClientSideAuthenticate(_context, kAlwaysAuthenticate); } CFArrayRef caArr = _ctx->impl()->caCertificates(); SSLSetCertificateAuthorities(_context, caArr, true); SSLSetTrustedRoots(_context, caArr, true); #endif } else { SSLSetEnableCertVerify(_context, false); SSLSetSessionOption(_context, kSSLSessionOptionBreakOnServerAuth, true); } // certificates to present to peer CFArrayRef certs = _ctx->impl()->certificates(); if(certs) { log_debug("using " << CFArrayGetCount(certs) << " certificates"); SSLSetCertificate(_context, certs); } }
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); }