Esempio n. 1
0
    void TCPStream_CFNetwork::secure() {
        if (state != Stream::State::Open) {
            return;
        }

        state = Stream::State::OpenAndSecuring;

        OSStatus status = noErr;

        secureLayerContext = SSLCreateContext(kCFAllocatorDefault, kSSLClientSide, kSSLStreamType);

        status = SSLSetConnection(secureLayerContext, reinterpret_cast<SSLConnectionRef>(this));
        if (status != noErr) {
            handleSecuringFailedEvent();
            return;
        }

        status = SSLSetIOFuncs(secureLayerContext,
                                        TCPStream_CFNetwork::secureTransportReadCallback,
                                        TCPStream_CFNetwork::secureTransportWriteCallback);
        if (status != noErr) {
            handleSecuringFailedEvent();
            return;
        }

        status = SSLSetPeerDomainName(secureLayerContext, domainName.c_str(), domainName.size());
        if (status != noErr) {
            handleSecuringFailedEvent();
            return;
        }

        do {
            status = SSLHandshake(secureLayerContext);
        } while (status == errSSLWouldBlock);

        switch (status) {
            default:
                //TODO: Log this!
                handleSecuringFailedEvent();
                return;
            case errSSLFatalAlert:
                handleSecuringFailedEvent();
                return;
            case errSSLUnknownRootCert:
            case errSSLNoRootCert:
            case errSSLCertExpired:
            case errSSLXCertChainInvalid:
                //TODO: The UI (if any) should probably ask what to do instead of simply failing.
                handleSecuringFailedEvent();
                return;
            case errSSLClientCertRequested:
                //TODO: The App should supply this.  Add an event handler.
                handleSecuringFailedEvent();
                return;
            case noErr:
                state = Stream::State::OpenAndSecured;
                handleSecuredEvent();
                return;
        }
    }
Esempio n. 2
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 void
test(void)
{
    SSLContextRef ssl = NULL;

    require(ssl=SSLCreateContext(kCFAllocatorDefault, kSSLClientSide, kSSLStreamType), out);
    ok(ssl, "SSLCreateContext failed");

    /* The order of this tests does matter, be careful when adding tests */
    ok(!test_GetSupportedCiphers(ssl), "GetSupportedCiphers test failed");
    ok(!test_GetEnabledCiphers(ssl), "GetEnabledCiphers test failed");

    CFRelease(ssl); ssl=NULL;

    require(ssl=SSLCreateContext(kCFAllocatorDefault, kSSLClientSide, kSSLStreamType), out);
    ok(ssl, "SSLCreateContext failed");
    
    ok(!test_SetEnabledCiphers(ssl), "SetEnabledCiphers test failed");

out:
    if(ssl) CFRelease(ssl);
}
static SSLContextRef make_ssl_ref(bool server, int sock, CFArrayRef certs)
{
    SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, server?kSSLServerSide:kSSLClientSide, kSSLStreamType);
    require(ctx, out);

    require_noerr(SSLSetIOFuncs(ctx, (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
    require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)sock), out);
    require_noerr(SSLSetCertificate(ctx, certs), out);

    return ctx;
out:
    if (ctx)
        CFRelease(ctx);
    return NULL;
}
static void
tests(void)
{
    SSLContextRef       ctx = NULL;
    SecIdentityRef	identity;
    CFArrayRef		list = NULL;
    CFArrayRef		trust_chain;

    AddIdentityToKeychain();
    EAPSecIdentityListCreate(&list);
    identity = (SecIdentityRef)CFArrayGetValueAtIndex(list, 0);
    is(CFGetRetainCount(identity), 1, "identity rc = 1");
    ok_status(EAPSecIdentityCreateIdentityTrustChain(identity, &trust_chain),
        "EAPSecIdentityCreateIdentityTrustChain");
    ok(ctx=SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType), "SSLNewContext");
    ok_status(SSLSetCertificate(ctx, trust_chain), "SSLSetCertificate");
    CFReleaseNull(ctx);
    DeleteIdentityFromKeychain();
    CFRelease(trust_chain);
    CFReleaseNull(list);
}
Esempio n. 6
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;
}
Esempio n. 7
0
int					/* O - 1 on success, 0 on error */
cupsdStartTLS(cupsd_client_t *con)	/* I - Client connection */
{
  OSStatus	error = 0;		/* Error code */
  SecTrustRef	peerTrust;		/* Peer certificates */


  cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] Encrypting connection.",
                  con->number);

  con->http->encryption = HTTP_ENCRYPTION_ALWAYS;

  con->http->tls_credentials = copy_cdsa_certificate(con);

  if (!con->http->tls_credentials)
  {
   /*
    * No keychain (yet), make a self-signed certificate...
    */

    if (make_certificate(con))
      con->http->tls_credentials = copy_cdsa_certificate(con);
  }

  if (!con->http->tls_credentials)
  {
    cupsdLogMessage(CUPSD_LOG_ERROR,
        	    "Could not find signing key in keychain \"%s\"",
		    ServerCertificate);
    error = errSSLBadConfiguration;
  }

  if (!error)
    con->http->tls = SSLCreateContext(kCFAllocatorDefault, kSSLServerSide,
                                     kSSLStreamType);

  if (!error)
    error = SSLSetIOFuncs(con->http->tls, _httpReadCDSA, _httpWriteCDSA);

  if (!error)
    error = SSLSetConnection(con->http->tls, HTTP(con));

  if (!error)
    error = SSLSetCertificate(con->http->tls, con->http->tls_credentials);

  if (!error)
  {
   /*
    * Perform SSL/TLS handshake
    */

    while ((error = SSLHandshake(con->http->tls)) == errSSLWouldBlock)
      usleep(1000);
  }

  if (error)
  {
    cupsdLogMessage(CUPSD_LOG_ERROR,
                    "Unable to encrypt connection from %s - %s (%d)",
                    con->http->hostname, cssmErrorString(error), (int)error);

    con->http->error  = error;
    con->http->status = HTTP_ERROR;

    if (con->http->tls)
    {
      CFRelease(con->http->tls);
      con->http->tls = NULL;
    }

    if (con->http->tls_credentials)
    {
      CFRelease(con->http->tls_credentials);
      con->http->tls_credentials = NULL;
    }

    return (0);
  }

  cupsdLogMessage(CUPSD_LOG_DEBUG, "Connection from %s now encrypted.",
                  con->http->hostname);

  if (!SSLCopyPeerTrust(con->http->tls, &peerTrust) && peerTrust)
  {
    cupsdLogMessage(CUPSD_LOG_DEBUG, "Received %d peer certificates.",
		    (int)SecTrustGetCertificateCount(peerTrust));
    CFRelease(peerTrust);
  }
  else
    cupsdLogMessage(CUPSD_LOG_DEBUG, "Received NO peer certificates.");

  return (1);
}
Esempio n. 8
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;
}
Esempio n. 9
0
static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
{
    TLSContext *c = h->priv_data;
    TLSShared *s = &c->tls_shared;
    int ret;

    if ((ret = ff_tls_open_underlying(s, h, uri, options)) < 0)
        goto fail;

    c->ssl_context = SSLCreateContext(NULL, s->listen ? kSSLServerSide : kSSLClientSide, kSSLStreamType);
    if (!c->ssl_context) {
        av_log(h, AV_LOG_ERROR, "Unable to create SSL context\n");
        ret = AVERROR(ENOMEM);
        goto fail;
    }
    if (s->ca_file) {
        if ((ret = load_ca(h)) < 0)
            goto fail;
    }
    if (s->ca_file || !s->verify)
        CHECK_ERROR(SSLSetSessionOption, c->ssl_context, kSSLSessionOptionBreakOnServerAuth, true);
    if (s->cert_file)
        if ((ret = load_cert(h)) < 0)
            goto fail;
    CHECK_ERROR(SSLSetPeerDomainName, c->ssl_context, s->host, strlen(s->host));
    CHECK_ERROR(SSLSetIOFuncs, c->ssl_context, tls_read_cb, tls_write_cb);
    CHECK_ERROR(SSLSetConnection, c->ssl_context, h);
    while (1) {
        OSStatus status = SSLHandshake(c->ssl_context);
        if (status == errSSLServerAuthCompleted) {
            SecTrustRef peerTrust;
            SecTrustResultType trustResult;
            if (!s->verify)
                continue;

            if (SSLCopyPeerTrust(c->ssl_context, &peerTrust) != noErr) {
                ret = AVERROR(ENOMEM);
                goto fail;
            }

            if (SecTrustSetAnchorCertificates(peerTrust, c->ca_array) != noErr) {
                ret = AVERROR_UNKNOWN;
                goto fail;
            }

            if (SecTrustEvaluate(peerTrust, &trustResult) != noErr) {
                ret = AVERROR_UNKNOWN;
                goto fail;
            }

            if (trustResult == kSecTrustResultProceed ||
                trustResult == kSecTrustResultUnspecified) {
                // certificate is trusted
                status = errSSLWouldBlock; // so we call SSLHandshake again
            } else if (trustResult == kSecTrustResultRecoverableTrustFailure) {
                // not trusted, for some reason other than being expired
                status = errSSLXCertChainInvalid;
            } else {
                // cannot use this certificate (fatal)
                status = errSSLBadCert;
            }

            if (peerTrust)
                CFRelease(peerTrust);
        }
        if (status == noErr)
            break;

        av_log(h, AV_LOG_ERROR, "Unable to negotiate TLS/SSL session: %i\n", (int)status);
        ret = AVERROR(EIO);
        goto fail;
    }

    return 0;
fail:
    tls_close(h);
    return ret;
}
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);
}
Esempio n. 11
0
int main_impl(const char *deviceName, const char *serverName, int port, const char *certFile, const char *keyFile, const char *caCertFile, const char *logFile)
{
	struct hostent *srv;
	int dev = -1;
	FILE* log = NULL;
	SOCKET sock = SOCKET_ERROR;
	struct sockaddr_in srvaddr;
	int keepalive = 1, hasCert, retCode;
	SSL_CTX *sslContext = NULL;
	SSL *sslSession = NULL;
	int sslRead;
	char b[100];

	// initial validation

	if (port < 1 || port > 65535)
	{
		printf("Port must be between 1 and 65535\n");
		return 3;
	}

	srv = gethostbyname(serverName);
	if (srv == NULL)
	{
		srv = gethostbyaddr(serverName, 4, AF_INET);
		if (srv == NULL)
		{
			printf("Cannot resolve server address: %s\n", serverName);
			return 3;
		}
	}

	hasCert = HAS_STR(certFile) + HAS_STR(keyFile) + HAS_STR(caCertFile);
	if (hasCert != 0 && hasCert != 3)
	{
		printf("Either all or none certificates must be specified\n");
		return 3;
	}

	// initial validation complete
	// connecting to server and opening device

	OpenLog(logFile);

	INFO("Opening device...\n");

	dev = open(deviceName, O_BINARY | O_RDWR | O_NOCTTY);
	if (dev == -1)
	{
		ERR("Failed to open device: %s\n", strerror(errno));
		RETURN(3);
	}

	DBG("Configuring device...\n");

	ConfigureDevice(dev);

	DBG("Creating a socket...\n");

	sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (sock == SOCKET_ERROR)
	{
		ERR("Cannot create a socket\n");
		RETURN(3);
	}

	DBG("Enabling keep-alives on the socket...\n");
	if (0 != setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive)))
	{
		WARN("Failed to enable keep-alives\n");
	}
	
	srvaddr.sin_family = AF_INET;
	srvaddr.sin_port = htons((u_short) port);
	memcpy(&srvaddr.sin_addr, srv->h_addr_list[0], 4);
	
	INFO("Connecting to server...\n");

	if (0 != connect(sock, (const struct sockaddr *) &srvaddr, sizeof(srvaddr)))
	{
		ERR("Cannot connect to %s:%d\n", serverName, port);
		RETURN(3);
	}

	if (0 != hasCert)
	{
		if (0 != SSLInit())
		{
			RETURN(3);
		}

		sslContext = SSLCreateContext(certFile, keyFile, caCertFile);
		if (sslContext == NULL)
		{
			RETURN(3);
		}

		sslSession = SSLHandshake(sock, sslContext);
		if (sslSession == NULL)
		{
			RETURN(3);
		}

		sslRead = SSL_read(sslSession, b, sizeof(b));
		switch (SSL_get_error(sslSession, sslRead))
		{
		case SSL_ERROR_NONE:
			break;

		case SSL_ERROR_ZERO_RETURN:
			DBG("Server has closed the SSL connection\n");

			SSLCloseSession(sslSession);

			sslSession = SSLHandshake(sock, sslContext);
			if (sslSession == NULL)
			{
				RETURN(3);
			}
			break;

		default:
			DEFAULT_HANDLER("Failed to receive server response", sslSession, sslRead);
			RETURN(3);
		}
	}
	
	
	IsTerminating = 0;

	signal(SIGTERM, sig_handler);
	signal(SIGINT, sig_handler);
#ifdef WIN32
	signal(SIGBREAK, sig_handler);
#endif

	retCode = worker(dev, sock, sslSession, certFile, keyFile, caCertFile);

	RETURN(retCode);
}