コード例 #1
0
static int openssl_verify(int preverify_ok, X509_STORE_CTX *ctx)
{
    int depth;
    SpiceOpenSSLVerify *v;
    SSL *ssl;
    X509* cert;

    ssl = (SSL*)X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
    v = (SpiceOpenSSLVerify*)SSL_get_app_data(ssl);

    depth = X509_STORE_CTX_get_error_depth(ctx);
    if (depth > 0) {
        if (!preverify_ok) {
            SPICE_DEBUG("openssl verify failed at depth=%d", depth);
            v->all_preverify_ok = 0;
            return 0;
        } else
            return 1;
    }

    /* depth == 0 */
    cert = X509_STORE_CTX_get_current_cert(ctx);
    if (!cert) {
        SPICE_DEBUG("failed to get server certificate");
        return 0;
    }

    if (v->verifyop & SPICE_SSL_VERIFY_OP_PUBKEY &&
        verify_pubkey(cert, v->pubkey, v->pubkey_size))
        return 1;

    if (!v->all_preverify_ok || !preverify_ok)
        return 0;

    if (v->verifyop & SPICE_SSL_VERIFY_OP_HOSTNAME &&
        verify_hostname(cert, v->hostname))
        return 1;

    if (v->verifyop & SPICE_SSL_VERIFY_OP_SUBJECT &&
        verify_subject(cert, v))
        return 1;

    return 0;
}
コード例 #2
0
ファイル: imap-send.c プロジェクト: Fykec/git
static int ssl_socket_connect(struct imap_socket *sock, int use_tls_only, int verify)
{
#if (OPENSSL_VERSION_NUMBER >= 0x10000000L)
	const SSL_METHOD *meth;
#else
	SSL_METHOD *meth;
#endif
	SSL_CTX *ctx;
	int ret;
	X509 *cert;

	SSL_library_init();
	SSL_load_error_strings();

	meth = SSLv23_method();
	if (!meth) {
		ssl_socket_perror("SSLv23_method");
		return -1;
	}

	ctx = SSL_CTX_new(meth);
	if (!ctx) {
		ssl_socket_perror("SSL_CTX_new");
		return -1;
	}

	if (use_tls_only)
		SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);

	if (verify)
		SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);

	if (!SSL_CTX_set_default_verify_paths(ctx)) {
		ssl_socket_perror("SSL_CTX_set_default_verify_paths");
		return -1;
	}
	sock->ssl = SSL_new(ctx);
	if (!sock->ssl) {
		ssl_socket_perror("SSL_new");
		return -1;
	}
	if (!SSL_set_rfd(sock->ssl, sock->fd[0])) {
		ssl_socket_perror("SSL_set_rfd");
		return -1;
	}
	if (!SSL_set_wfd(sock->ssl, sock->fd[1])) {
		ssl_socket_perror("SSL_set_wfd");
		return -1;
	}

#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
	/*
	 * SNI (RFC4366)
	 * OpenSSL does not document this function, but the implementation
	 * returns 1 on success, 0 on failure after calling SSLerr().
	 */
	ret = SSL_set_tlsext_host_name(sock->ssl, server.host);
	if (ret != 1)
		warning("SSL_set_tlsext_host_name(%s) failed.", server.host);
#endif

	ret = SSL_connect(sock->ssl);
	if (ret <= 0) {
		socket_perror("SSL_connect", sock, ret);
		return -1;
	}

	if (verify) {
		/* make sure the hostname matches that of the certificate */
		cert = SSL_get_peer_certificate(sock->ssl);
		if (!cert)
			return error("unable to get peer certificate.");
		if (verify_hostname(cert, server.host) < 0)
			return -1;
	}

	return 0;
}
コード例 #3
0
ファイル: tcp.c プロジェクト: yfqian/libsvc
tcp_stream_t *
tcp_stream_create_ssl_from_fd(int fd, const char *hostname,
                              const tcp_ssl_info_t *tsi,
                              char *errbuf, size_t errlen)
{
  char errmsg[120];

  tcp_stream_t *ts = calloc(1, sizeof(tcp_stream_t));
  ts->ts_fd = fd;

  if((ts->ts_ssl = SSL_new(ssl_ctx)) == NULL)
    goto bad_ssl;


  if(SSL_set_fd(ts->ts_ssl, fd) == 0)
    goto bad_ssl;

  if(tsi->key != NULL) {
    BIO *cbio = BIO_new_mem_buf((char *)tsi->key, -1);
    EVP_PKEY *key = PEM_read_bio_PrivateKey(cbio, NULL, NULL, NULL);
    BIO_free(cbio);
    if(key == NULL) {
      snprintf(errbuf, errlen, "Unable to load private key");
      goto bad;
    }

    SSL_use_PrivateKey(ts->ts_ssl, key);
    EVP_PKEY_free(key);
  }

  if(tsi->cert != NULL) {
    BIO *cbio = BIO_new_mem_buf((char *)tsi->cert, -1);
    X509 *cert = PEM_read_bio_X509(cbio, NULL, 0, NULL);
    BIO_free(cbio);

    if(cert == NULL) {
      snprintf(errbuf, errlen, "Unable to load certificate");
      goto bad;
    }

    SSL_use_certificate(ts->ts_ssl, cert);
    X509_free(cert);
  }

  if(SSL_connect(ts->ts_ssl) <= 0) {
    goto bad_ssl;
  }

  SSL_set_mode(ts->ts_ssl, SSL_MODE_AUTO_RETRY);

  X509 *peer = SSL_get_peer_certificate(ts->ts_ssl);
  if(peer == NULL) {
    goto bad_ssl;
  }

  int err = SSL_get_verify_result(ts->ts_ssl);
  if(err != X509_V_OK) {
    snprintf(errbuf, errlen, "Certificate error: %s",
             X509_verify_cert_error_string(err));
    X509_free(peer);
    goto bad;
  }

  if(verify_hostname(hostname, peer, errbuf, errlen)) {
    X509_free(peer);
    goto bad;
  }

  X509_free(peer);

  ts->ts_fd = fd;
  htsbuf_queue_init(&ts->ts_spill, INT32_MAX);
  htsbuf_queue_init(&ts->ts_sendq, INT32_MAX);

  ts->ts_write = ssl_write;
  ts->ts_read  = ssl_read;
  return ts;

 bad_ssl:
  ERR_error_string(ERR_get_error(), errmsg);
  snprintf(errbuf, errlen, "SSL: %s", errmsg);
 bad:
  tcp_close(ts);
  return NULL;
}