qcrypto_tls_session_check_certificate(QCryptoTLSSession *session,

                                      Error **errp)

{

    int ret;

    unsigned int status;

    const gnutls_datum_t *certs;

    unsigned int nCerts, i;

    time_t now;

    gnutls_x509_crt_t cert = NULL;



    now = time(NULL);

    if (now == ((time_t)-1)) {

        error_setg_errno(errp, errno, "Cannot get current time");

        return -1;

    }



    ret = gnutls_certificate_verify_peers2(session->handle, &status);

    if (ret < 0) {

        error_setg(errp, "Verify failed: %s", gnutls_strerror(ret));

        return -1;

    }



    if (status != 0) {

        const char *reason = "Invalid certificate";



        if (status & GNUTLS_CERT_INVALID) {

            reason = "The certificate is not trusted";

        }



        if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) {

            reason = "The certificate hasn't got a known issuer";

        }



        if (status & GNUTLS_CERT_REVOKED) {

            reason = "The certificate has been revoked";

        }



        if (status & GNUTLS_CERT_INSECURE_ALGORITHM) {

            reason = "The certificate uses an insecure algorithm";

        }



        error_setg(errp, "%s", reason);

        return -1;

    }



    certs = gnutls_certificate_get_peers(session->handle, &nCerts);

    if (!certs) {

        error_setg(errp, "No certificate peers");

        return -1;

    }



    for (i = 0; i < nCerts; i++) {

        ret = gnutls_x509_crt_init(&cert);

        if (ret < 0) {

            error_setg(errp, "Cannot initialize certificate: %s",

                       gnutls_strerror(ret));

            return -1;

        }



        ret = gnutls_x509_crt_import(cert, &certs[i], GNUTLS_X509_FMT_DER);

        if (ret < 0) {

            error_setg(errp, "Cannot import certificate: %s",

                       gnutls_strerror(ret));

            goto error;

        }



        if (gnutls_x509_crt_get_expiration_time(cert) < now) {

            error_setg(errp, "The certificate has expired");

            goto error;

        }



        if (gnutls_x509_crt_get_activation_time(cert) > now) {

            error_setg(errp, "The certificate is not yet activated");

            goto error;

        }



        if (gnutls_x509_crt_get_activation_time(cert) > now) {

            error_setg(errp, "The certificate is not yet activated");

            goto error;

        }



        if (i == 0) {

            size_t dnameSize = 1024;

            session->peername = g_malloc(dnameSize);

        requery:

            ret = gnutls_x509_crt_get_dn(cert, session->peername, &dnameSize);

            if (ret < 0) {

                if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {

                    session->peername = g_realloc(session->peername,

                                                  dnameSize);

                    goto requery;

                }

                error_setg(errp, "Cannot get client distinguished name: %s",

                           gnutls_strerror(ret));

                goto error;

            }

            if (session->aclname) {

                qemu_acl *acl = qemu_acl_find(session->aclname);

                int allow;

                if (!acl) {

                    error_setg(errp, "Cannot find ACL %s",

                               session->aclname);

                    goto error;

                }



                allow = qemu_acl_party_is_allowed(acl, session->peername);



                error_setg(errp, "TLS x509 ACL check for %s is %s",

                           session->peername, allow ? "allowed" : "denied");

                if (!allow) {

                    goto error;

                }

            }

            if (session->hostname) {

                if (!gnutls_x509_crt_check_hostname(cert, session->hostname)) {

                    error_setg(errp,

                               "Certificate does not match the hostname %s",

                               session->hostname);

                    goto error;

                }

            }

        }



        gnutls_x509_crt_deinit(cert);

    }



    return 0;



 error:

    gnutls_x509_crt_deinit(cert);

    return -1;

}

qcrypto_tls_session_check_certificate(QCryptoTLSSession *session,

                                      Error **errp)

{

    int ret;

    unsigned int status;

    const gnutls_datum_t *certs;

    unsigned int nCerts, i;

    time_t now;

    gnutls_x509_crt_t cert = NULL;



    now = time(NULL);

    if (now == ((time_t)-1)) {

        error_setg_errno(errp, errno, "Cannot get current time");

        return -1;

    }



    ret = gnutls_certificate_verify_peers2(session->handle, &status);

    if (ret < 0) {

        error_setg(errp, "Verify failed: %s", gnutls_strerror(ret));

        return -1;

    }



    if (status != 0) {

        const char *reason = "Invalid certificate";



        if (status & GNUTLS_CERT_INVALID) {

            reason = "The certificate is not trusted";

        }



        if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) {

            reason = "The certificate hasn't got a known issuer";

        }



        if (status & GNUTLS_CERT_REVOKED) {

            reason = "The certificate has been revoked";

        }



        if (status & GNUTLS_CERT_INSECURE_ALGORITHM) {

            reason = "The certificate uses an insecure algorithm";

        }



        error_setg(errp, "%s", reason);

        return -1;

    }



    certs = gnutls_certificate_get_peers(session->handle, &nCerts);

    if (!certs) {

        error_setg(errp, "No certificate peers");

        return -1;

    }



    for (i = 0; i < nCerts; i++) {

        ret = gnutls_x509_crt_init(&cert);

        if (ret < 0) {

            error_setg(errp, "Cannot initialize certificate: %s",

                       gnutls_strerror(ret));

            return -1;

        }



        ret = gnutls_x509_crt_import(cert, &certs[i], GNUTLS_X509_FMT_DER);

        if (ret < 0) {

            error_setg(errp, "Cannot import certificate: %s",

                       gnutls_strerror(ret));

            goto error;

        }



        if (gnutls_x509_crt_get_expiration_time(cert) < now) {

            error_setg(errp, "The certificate has expired");

            goto error;

        }



        if (gnutls_x509_crt_get_activation_time(cert) > now) {

            error_setg(errp, "The certificate is not yet activated");

            goto error;

        }



        if (gnutls_x509_crt_get_activation_time(cert) > now) {

            error_setg(errp, "The certificate is not yet activated");

            goto error;

        }



        if (i == 0) {

            size_t dnameSize = 1024;

            session->peername = g_malloc(dnameSize);

        requery:

            ret = gnutls_x509_crt_get_dn(cert, session->peername, &dnameSize);

            if (ret < 0) {

                if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {

                    session->peername = g_realloc(session->peername,

                                                  dnameSize);

                    goto requery;

                }

                error_setg(errp, "Cannot get client distinguished name: %s",

                           gnutls_strerror(ret));

                goto error;

            }

            if (session->aclname) {

                qemu_acl *acl = qemu_acl_find(session->aclname);

                int allow;

                if (!acl) {

                    error_setg(errp, "Cannot find ACL %s",

                               session->aclname);

                    goto error;

                }



                allow = qemu_acl_party_is_allowed(acl, session->peername);



                error_setg(errp, "TLS x509 ACL check for %s is %s",

                           session->peername, allow ? "allowed" : "denied");

                if (!allow) {

                    goto error;

                }

            }

            if (session->hostname) {

                if (!gnutls_x509_crt_check_hostname(cert, session->hostname)) {

                    error_setg(errp,

                               "Certificate does not match the hostname %s",

                               session->hostname);

                    goto error;

                }

            }

        }



        gnutls_x509_crt_deinit(cert);

    }



    return 0;



 error:

    gnutls_x509_crt_deinit(cert);

    return -1;

}

                error_setg(errp, "TLS x509 ACL check for %s is %s",                            session->peername, allow ? "allowed" : "denied");
FUNC_0(QCryptoTLSSession *VAR_0,

                                      Error **VAR_1)

{

    int VAR_2;

    unsigned int VAR_3;

    const gnutls_datum_t *VAR_4;

    unsigned int VAR_5, VAR_6;

    time_t now;

    gnutls_x509_crt_t cert = NULL;



    now = time(NULL);

    if (now == ((time_t)-1)) {

        error_setg_errno(VAR_1, errno, "Cannot get current time");

        return -1;

    }



    VAR_2 = gnutls_certificate_verify_peers2(VAR_0->handle, &VAR_3);

    if (VAR_2 < 0) {

        error_setg(VAR_1, "Verify failed: %s", gnutls_strerror(VAR_2));

        return -1;

    }



    if (VAR_3 != 0) {

        const char *VAR_7 = "Invalid certificate";



        if (VAR_3 & GNUTLS_CERT_INVALID) {

            VAR_7 = "The certificate is not trusted";

        }



        if (VAR_3 & GNUTLS_CERT_SIGNER_NOT_FOUND) {

            VAR_7 = "The certificate hasn't got a known issuer";

        }



        if (VAR_3 & GNUTLS_CERT_REVOKED) {

            VAR_7 = "The certificate has been revoked";

        }



        if (VAR_3 & GNUTLS_CERT_INSECURE_ALGORITHM) {

            VAR_7 = "The certificate uses an insecure algorithm";

        }



        error_setg(VAR_1, "%s", VAR_7);

        return -1;

    }



    VAR_4 = gnutls_certificate_get_peers(VAR_0->handle, &VAR_5);

    if (!VAR_4) {

        error_setg(VAR_1, "No certificate peers");

        return -1;

    }



    for (VAR_6 = 0; VAR_6 < VAR_5; VAR_6++) {

        VAR_2 = gnutls_x509_crt_init(&cert);

        if (VAR_2 < 0) {

            error_setg(VAR_1, "Cannot initialize certificate: %s",

                       gnutls_strerror(VAR_2));

            return -1;

        }



        VAR_2 = gnutls_x509_crt_import(cert, &VAR_4[VAR_6], GNUTLS_X509_FMT_DER);

        if (VAR_2 < 0) {

            error_setg(VAR_1, "Cannot import certificate: %s",

                       gnutls_strerror(VAR_2));

            goto error;

        }



        if (gnutls_x509_crt_get_expiration_time(cert) < now) {

            error_setg(VAR_1, "The certificate has expired");

            goto error;

        }



        if (gnutls_x509_crt_get_activation_time(cert) > now) {

            error_setg(VAR_1, "The certificate is not yet activated");

            goto error;

        }



        if (gnutls_x509_crt_get_activation_time(cert) > now) {

            error_setg(VAR_1, "The certificate is not yet activated");

            goto error;

        }



        if (VAR_6 == 0) {

            size_t dnameSize = 1024;

            VAR_0->peername = g_malloc(dnameSize);

        requery:

            VAR_2 = gnutls_x509_crt_get_dn(cert, VAR_0->peername, &dnameSize);

            if (VAR_2 < 0) {

                if (VAR_2 == GNUTLS_E_SHORT_MEMORY_BUFFER) {

                    VAR_0->peername = g_realloc(VAR_0->peername,

                                                  dnameSize);

                    goto requery;

                }

                error_setg(VAR_1, "Cannot get client distinguished name: %s",

                           gnutls_strerror(VAR_2));

                goto error;

            }

            if (VAR_0->aclname) {

                qemu_acl *acl = qemu_acl_find(VAR_0->aclname);

                int VAR_8;

                if (!acl) {

                    error_setg(VAR_1, "Cannot find ACL %s",

                               VAR_0->aclname);

                    goto error;

                }



                VAR_8 = qemu_acl_party_is_allowed(acl, VAR_0->peername);



                error_setg(VAR_1, "TLS x509 ACL check for %s is %s",

                           VAR_0->peername, VAR_8 ? "allowed" : "denied");

                if (!VAR_8) {

                    goto error;

                }

            }

            if (VAR_0->hostname) {

                if (!gnutls_x509_crt_check_hostname(cert, VAR_0->hostname)) {

                    error_setg(VAR_1,

                               "Certificate does not match the hostname %s",

                               VAR_0->hostname);

                    goto error;

                }

            }

        }



        gnutls_x509_crt_deinit(cert);

    }



    return 0;



 error:

    gnutls_x509_crt_deinit(cert);

    return -1;

}

FUNC_0(QCryptoTLSSession *VAR_0,
Error **VAR_1)
{ int VAR_2; unsigned int VAR_3; const gnutls_datum_t *VAR_4; unsigned int VAR_5, VAR_6; time_t now; gnutls_x509_crt_t cert = NULL; now = time(NULL); if (now == ((time_t)-1)) { error_setg_errno(VAR_1, errno, "Cannot get current time"); return -1; } VAR_2 = gnutls_certificate_verify_peers2(VAR_0->handle, &VAR_3); if (VAR_2 < 0) { error_setg(VAR_1, "Verify failed: %s", gnutls_strerror(VAR_2)); return -1; } if (VAR_3 != 0) { const char *VAR_7 = "Invalid certificate"; if (VAR_3 & GNUTLS_CERT_INVALID) { VAR_7 = "The certificate is not trusted"; } if (VAR_3 & GNUTLS_CERT_SIGNER_NOT_FOUND) { VAR_7 = "The certificate hasn't got a known issuer"; } if (VAR_3 & GNUTLS_CERT_REVOKED) { VAR_7 = "The certificate has been revoked"; } if (VAR_3 & GNUTLS_CERT_INSECURE_ALGORITHM) { VAR_7 = "The certificate uses an insecure algorithm"; } error_setg(VAR_1, "%s", VAR_7); return -1; } VAR_4 = gnutls_certificate_get_peers(VAR_0->handle, &VAR_5); if (!VAR_4) { error_setg(VAR_1, "No certificate peers"); return -1; } for (VAR_6 = 0; VAR_6 < VAR_5; VAR_6++) { VAR_2 = gnutls_x509_crt_init(&cert); if (VAR_2 < 0) { error_setg(VAR_1, "Cannot initialize certificate: %s",
gnutls_strerror(VAR_2)); return -1; } VAR_2 = gnutls_x509_crt_import(cert, &VAR_4[VAR_6], GNUTLS_X509_FMT_DER); if (VAR_2 < 0) { error_setg(VAR_1, "Cannot import certificate: %s",
gnutls_strerror(VAR_2)); goto error; } if (gnutls_x509_crt_get_expiration_time(cert) < now) { error_setg(VAR_1, "The certificate has expired"); goto error; } if (gnutls_x509_crt_get_activation_time(cert) > now) { error_setg(VAR_1, "The certificate is not yet activated"); goto error; } if (gnutls_x509_crt_get_activation_time(cert) > now) { error_setg(VAR_1, "The certificate is not yet activated"); goto error; } if (VAR_6 == 0) { size_t dnameSize = 1024; VAR_0->peername = g_malloc(dnameSize); requery:
VAR_2 = gnutls_x509_crt_get_dn(cert, VAR_0->peername, &dnameSize); if (VAR_2 < 0) { if (VAR_2 == GNUTLS_E_SHORT_MEMORY_BUFFER) { VAR_0->peername = g_realloc(VAR_0->peername,
dnameSize); goto requery; } error_setg(VAR_1, "Cannot get client distinguished name: %s",
gnutls_strerror(VAR_2)); goto error; } if (VAR_0->aclname) { qemu_acl *acl = qemu_acl_find(VAR_0->aclname); int VAR_8; if (!acl) { error_setg(VAR_1, "Cannot find ACL %s",
VAR_0->aclname); goto error; } VAR_8 = qemu_acl_party_is_allowed(acl, VAR_0->peername); error_setg(VAR_1, "TLS x509 ACL check for %s is %s",
VAR_0->peername, VAR_8 ? "allowed" : "denied"); if (!VAR_8) { goto error; } } if (VAR_0->hostname) { if (!gnutls_x509_crt_check_hostname(cert, VAR_0->hostname)) { error_setg(VAR_1,
"Certificate does not match the hostname %s",
VAR_0->hostname); goto error; } } } gnutls_x509_crt_deinit(cert); } return 0; error:
gnutls_x509_crt_deinit(cert); return -1; }