Ejemplo n.º 1
0
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;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
/**
 * 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;
}
Ejemplo n.º 5
0
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);
}