static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,
                        X509 *x, X509 *xca, EVP_PKEY *pkey,
                        STACK_OF(OPENSSL_STRING) *sigopts,
                        char *serialfile, int create,
                        int days, int clrext, CONF *conf, char *section,
                        ASN1_INTEGER *sno, int reqfile)
{
    int ret = 0;
    ASN1_INTEGER *bs = NULL;
    X509_STORE_CTX xsc;
    EVP_PKEY *upkey;
    upkey = X509_get0_pubkey(xca);
    EVP_PKEY_copy_parameters(upkey, pkey);
    if (!X509_STORE_CTX_init(&xsc, ctx, x, NULL)) {
        BIO_printf(bio_err, "Error initialising X509 store\n");
        goto end;
    }
    if (sno)
        bs = sno;
    else if ((bs = x509_load_serial(CAfile, serialfile, create)) == NULL)
        goto end;
    X509_STORE_CTX_set_cert(&xsc, x);
    X509_STORE_CTX_set_flags(&xsc, X509_V_FLAG_CHECK_SS_SIGNATURE);
    if (!reqfile && X509_verify_cert(&xsc) <= 0)
        goto end;
    if (!X509_check_private_key(xca, pkey)) {
        BIO_printf(bio_err,
                   "CA certificate and CA private key do not match\n");
        goto end;
    }
    if (!X509_set_issuer_name(x, X509_get_subject_name(xca)))
        goto end;
    if (!X509_set_serialNumber(x, bs))
        goto end;
    if (X509_gmtime_adj(X509_get_notBefore(x), 0L) == NULL)
        goto end;
    if (X509_time_adj_ex(X509_get_notAfter(x), days, 0, NULL) == NULL)
        goto end;
    if (clrext) {
        while (X509_get_ext_count(x) > 0)
            X509_delete_ext(x, 0);
    }
    if (conf) {
        X509V3_CTX ctx2;
        X509_set_version(x, 2);
        X509V3_set_ctx(&ctx2, xca, x, NULL, NULL, 0);
        X509V3_set_nconf(&ctx2, conf);
        if (!X509V3_EXT_add_nconf(conf, &ctx2, section, x))
            goto end;
    }
    if (!do_X509_sign(x, pkey, digest, sigopts))
        goto end;
    ret = 1;
 end:
    X509_STORE_CTX_cleanup(&xsc);
    if (!ret)
        ERR_print_errors(bio_err);
    if (!sno)
        ASN1_INTEGER_free(bs);
    return ret;
}
['static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,\n                        X509 *x, X509 *xca, EVP_PKEY *pkey,\n                        STACK_OF(OPENSSL_STRING) *sigopts,\n                        char *serialfile, int create,\n                        int days, int clrext, CONF *conf, char *section,\n                        ASN1_INTEGER *sno, int reqfile)\n{\n    int ret = 0;\n    ASN1_INTEGER *bs = NULL;\n    X509_STORE_CTX xsc;\n    EVP_PKEY *upkey;\n    upkey = X509_get0_pubkey(xca);\n    EVP_PKEY_copy_parameters(upkey, pkey);\n    if (!X509_STORE_CTX_init(&xsc, ctx, x, NULL)) {\n        BIO_printf(bio_err, "Error initialising X509 store\\n");\n        goto end;\n    }\n    if (sno)\n        bs = sno;\n    else if ((bs = x509_load_serial(CAfile, serialfile, create)) == NULL)\n        goto end;\n    X509_STORE_CTX_set_cert(&xsc, x);\n    X509_STORE_CTX_set_flags(&xsc, X509_V_FLAG_CHECK_SS_SIGNATURE);\n    if (!reqfile && X509_verify_cert(&xsc) <= 0)\n        goto end;\n    if (!X509_check_private_key(xca, pkey)) {\n        BIO_printf(bio_err,\n                   "CA certificate and CA private key do not match\\n");\n        goto end;\n    }\n    if (!X509_set_issuer_name(x, X509_get_subject_name(xca)))\n        goto end;\n    if (!X509_set_serialNumber(x, bs))\n        goto end;\n    if (X509_gmtime_adj(X509_get_notBefore(x), 0L) == NULL)\n        goto end;\n    if (X509_time_adj_ex(X509_get_notAfter(x), days, 0, NULL) == NULL)\n        goto end;\n    if (clrext) {\n        while (X509_get_ext_count(x) > 0)\n            X509_delete_ext(x, 0);\n    }\n    if (conf) {\n        X509V3_CTX ctx2;\n        X509_set_version(x, 2);\n        X509V3_set_ctx(&ctx2, xca, x, NULL, NULL, 0);\n        X509V3_set_nconf(&ctx2, conf);\n        if (!X509V3_EXT_add_nconf(conf, &ctx2, section, x))\n            goto end;\n    }\n    if (!do_X509_sign(x, pkey, digest, sigopts))\n        goto end;\n    ret = 1;\n end:\n    X509_STORE_CTX_cleanup(&xsc);\n    if (!ret)\n        ERR_print_errors(bio_err);\n    if (!sno)\n        ASN1_INTEGER_free(bs);\n    return ret;\n}', 'EVP_PKEY *X509_get0_pubkey(X509 *x)\n{\n    if (x == NULL)\n        return NULL;\n    return X509_PUBKEY_get0(x->cert_info.key);\n}']