/*!
  Adds the authority key identifier extension to the certificate. The key
  is extracted the specified certificate which must be the one later used
  to sign the certificate.
 */
bool CertificateBuilder::addAuthorityKeyIdentifier(const QSslCertificate &qcacert)
{
    gnutls_x509_crt_t cacrt = qsslcert_to_crt(qcacert, &d->errnumber);
    if (GNUTLS_E_SUCCESS != d->errnumber)
        return false;

    QByteArray ba(128, 0); // Normally 20 bytes (SHA1)
    size_t size = ba.size();

    // Try using the subject keyid
    d->errnumber = gnutls_x509_crt_get_subject_key_id(cacrt, reinterpret_cast<unsigned char *>(ba.data()), &size, NULL);

    // Or fallback to creating it
    if (GNUTLS_E_SUCCESS != d->errnumber) {
        d->errnumber = gnutls_x509_crt_get_key_id(cacrt, 0, reinterpret_cast<unsigned char *>(ba.data()), &size);

        if (GNUTLS_E_SUCCESS != d->errnumber) {
            gnutls_x509_crt_deinit(cacrt);
            return false;
        }
    }

    gnutls_x509_crt_deinit(cacrt);
    d->errnumber = gnutls_x509_crt_set_authority_key_id(d->crt, reinterpret_cast<const unsigned char *>(ba.constData()), size);

    return GNUTLS_E_SUCCESS == d->errnumber;
}
static gnutls_x509_crt generate_signed_certificate(requiem_client_profile_t *cp,
                                                   uint64_t analyzerid,
                                                   gnutls_x509_crt ca_crt,
                                                   gnutls_x509_privkey ca_key,
                                                   gnutls_x509_crq crq)
{
        int ret;
        gnutls_x509_crt crt;
        unsigned char buf[65535];
        size_t size = sizeof(buf);

        crt = generate_certificate(cp, NULL, generated_certificate_lifetime);
        if ( ! crt )
                return NULL;

        ret = gnutls_x509_crt_set_crq(crt, crq);
        if ( ret < 0 ) {
                fprintf(stderr, "error associating certificate with CRQ: %s.\n", gnutls_strerror(ret));
                goto err;
        }

        ret = gnutls_x509_crt_set_serial(crt, &analyzerid, sizeof(analyzerid));
        if ( ret < 0 ) {
                fprintf(stderr, "error setting certificate serial: %s.\n", gnutls_strerror(ret));
                goto err;
        }

        ret = gnutls_x509_crt_get_key_id(ca_crt, 0, buf, &size);
        if ( ret < 0 ) {
                fprintf(stderr, "error getting CA key ID: %s.\n", gnutls_strerror(ret));
                goto err;
        }

        ret = gnutls_x509_crt_set_authority_key_id(crt, buf, size);
        if ( ret < 0 ) {
                fprintf(stderr, "error setting authority key ID: %s?\n", gnutls_strerror(ret));
                goto err;
        }

        ret = gnutls_x509_crt_sign(crt, ca_crt, ca_key);
        if ( ret < 0 ) {
                fprintf(stderr, "error signing certificate: %s.\n", gnutls_strerror(ret));
                goto err;
        }

        return crt;

 err:
        gnutls_x509_crt_deinit(crt);
        return NULL;
}