-static int x509_certify(X509_STORE *ctx, const char *CAfile, const EVP_MD *digest,
- X509 *x, X509 *xca, EVP_PKEY *pkey,
- STACK_OF(OPENSSL_STRING) *sigopts,
- const char *serialfile, int create,
- int days, int clrext, CONF *conf, const char *section,
- ASN1_INTEGER *sno, int reqfile, int preserve_dates)
-{
- int ret = 0;
- ASN1_INTEGER *bs = NULL;
- X509_STORE_CTX *xsc = NULL;
- EVP_PKEY *upkey;
-
- upkey = X509_get0_pubkey(xca);
- if (upkey == NULL) {
- BIO_printf(bio_err, "Error obtaining CA X509 public key\n");
- goto end;
- }
- EVP_PKEY_copy_parameters(upkey, pkey);
-
- xsc = X509_STORE_CTX_new();
- if (xsc == NULL || !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;
-
- /*
- * NOTE: this certificate can/should be self-signed, unless it was a
- * certificate request in which case it is not.
- */
- 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 (!preserve_dates && !set_cert_times(x, NULL, NULL, days))
- goto end;
-
- if (clrext) {
- while (X509_get_ext_count(x) > 0)
- X509_delete_ext(x, 0);
- }
-
- if (conf != NULL) {
- X509V3_CTX ctx2;
- X509_set_version(x, 2); /* version 3 certificate */
- 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_free(xsc);
- if (!ret)
- ERR_print_errors(bio_err);
- if (!sno)
- ASN1_INTEGER_free(bs);
- return ret;
-}
-