3

我使用 libmesode(fork libstrophe)开发了一个 xmpp 客户端。我想通过认证来确保身份验证。服务器端有一个证书 server.pem 客户端有它的证书 client.pem

在 lidmesode 中用于检查证书的函数:

tls_t *tls_new(xmpp_ctx_t *ctx, sock_t sock, xmpp_certfail_handler certfail_handler, char *tls_cert_path)
{
    _xmppctx = ctx;
    _certfail_handler = certfail_handler;
    _cert_handled = 0;
    _last_cb_res = 0;
    tls_t *tls = xmpp_alloc(ctx, sizeof(*tls));

    if (tls) {
        int ret;
        memset(tls, 0, sizeof(*tls));

        tls->ctx = ctx;
        tls->sock = sock;
        tls->ssl_ctx = SSL_CTX_new(SSLv23_client_method());
        if (tls->ssl_ctx == NULL)
            goto err;

        SSL_CTX_set_client_cert_cb(tls->ssl_ctx, NULL);
        SSL_CTX_set_mode(tls->ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
        SSL_CTX_set_verify(tls->ssl_ctx, SSL_VERIFY_PEER, verify_callback);
        if (tls_cert_path) {
            SSL_CTX_load_verify_locations(tls->ssl_ctx, NULL, tls_cert_path);
            //SSL_CTX_use_certificate_file(tls->ssl_ctx, certif, SSL_FILETYPE_PEM);
        }
        tls->ssl = SSL_new(tls->ssl_ctx);
        if (tls->ssl == NULL)
            goto err_free_ctx;

        ret = SSL_set_fd(tls->ssl, sock);
        if (ret <= 0)
            goto err_free_ssl;
    }

    return tls;

err_free_ssl:
    SSL_free(tls->ssl);
err_free_ctx:
    SSL_CTX_free(tls->ssl_ctx);
err:
    xmpp_free(ctx, tls);
    _tls_log_error(ctx);
    return NULL;
} 

static int
verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)
{
    const STACK_OF(X509) *sk = X509_STORE_CTX_get1_chain(x509_ctx);
    int slen = sk_X509_num(sk);
    unsigned i;
    X509 *certsk;
    xmpp_debug(_xmppctx, "TLS", "STACK");
    for(i=0; i<slen; i++) {
        certsk = sk_X509_value(sk, i);
        _print_certificate(certsk);
    }
    xmpp_debug(_xmppctx, "TLS", "ENDSTACK");

    if (preverify_ok) {
        sk_X509_pop_free(sk, X509_free);
        printf("=========> 1\n");
        return 1;
    } else if (_cert_handled) {
        if (_last_cb_res == 0) {
            X509_STORE_CTX_set_error(x509_ctx, X509_V_ERR_APPLICATION_VERIFICATION);
        }
        sk_X509_pop_free(sk, X509_free);
        return _last_cb_res;
    } else {
        int err = X509_STORE_CTX_get_error(x509_ctx);
        const char *errstr = X509_verify_cert_error_string(err);
        xmpp_debug(_xmppctx, "TLS", "ERROR: %s", errstr);

        X509 *user_cert = sk_X509_value(sk, 0);
        struct _tlscert_t *tlscert = _x509_to_tlscert(_xmppctx, user_cert);
        int cb_res = 0;
        if (_certfail_handler) {
            cb_res = _certfail_handler(tlscert, errstr);
        }
        xmpp_conn_free_tlscert(_xmppctx, tlscert);

        _cert_handled = 1;
        _last_cb_res = cb_res;

        if (cb_res == 0) {
            X509_STORE_CTX_set_error(x509_ctx, X509_V_ERR_APPLICATION_VERIFICATION);
        }

        sk_X509_pop_free(sk, X509_free);
        return cb_res;
    }
}

当 xmpp 客户端使用 TLS 连接到 ejabbed xmpp 服务器时,openssl 检查自签名但继续连接的服务器证书!!。第二件事是:openssl 不使用客户端证书检查服务器证书以检查服务器证书是否受信任。

openssl 做这些检查吗?

1)如果自签名证书断开连接

2)检查证书是否可信。

以下捕获显示服务器发送证书,然后客户端发送密钥。

就是这个key应该取自客户端认证!

在此处输入图像描述

4

0 回答 0