#if defined(HAVE_ACME)
+static EVP_PKEY *tmp_pkey = NULL;
+static X509 *tmp_x509 = NULL;
+
+
static void acme_trace(enum trace_level level, uint64_t mask, const struct trace_source *src,
const struct ist where, const struct ist func,
const void *a1, const void *a2, const void *a3, const void *a4);
return pkey;
}
+/*
+ * Generate a temporary expired X509 or reuse the one generated.
+ * Use tmp_pkey to generate
+ *
+ * Increment the refcount when returning the existing one
+ */
+X509 *acme_gen_tmp_x509()
+{
+ X509 *newcrt = NULL;
+ X509_NAME *name;
+ const EVP_MD *digest;
+ X509V3_CTX ctx;
+ unsigned int i;
+ CONF *ctmp = NULL;
+ int key_type;
+ EVP_PKEY *pkey = tmp_pkey;
+
+ if (tmp_x509) {
+ X509_up_ref(tmp_x509);
+ return tmp_x509;
+ }
+
+ if (!tmp_pkey)
+ goto mkcert_error;
+
+ /* Create the certificate */
+ if (!(newcrt = X509_new()))
+ goto mkcert_error;
+
+ /* Set version number for the certificate (X509v3) and the serial
+ * number */
+ if (X509_set_version(newcrt, 2L) != 1)
+ goto mkcert_error;
+
+ /* Generate an expired certificate */
+ if (!X509_gmtime_adj(X509_getm_notBefore(newcrt), (long)-60*60*48) ||
+ !X509_gmtime_adj(X509_getm_notAfter(newcrt),(long)-60*60*24))
+ goto mkcert_error;
+
+ /* set public key in the certificate */
+ if (X509_set_pubkey(newcrt, pkey) != 1)
+ goto mkcert_error;
+
+ if ((name = X509_NAME_new()) == NULL)
+ goto mkcert_error;
+
+ /* Set the subject name using the servername but the CN */
+ if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, "expired",
+ -1, -1, 0) != 1) {
+ X509_NAME_free(name);
+ goto mkcert_error;
+ }
+ if (X509_set_subject_name(newcrt, name) != 1) {
+ X509_NAME_free(name);
+ goto mkcert_error;
+ }
+ /* Set issuer name as itself */
+ if (X509_set_issuer_name(newcrt, name) != 1)
+ goto mkcert_error;
+ X509_NAME_free(name);
+
+ /* Autosign the certificate with the private key */
+ key_type = EVP_PKEY_base_id(pkey);
+
+ if (key_type == EVP_PKEY_RSA)
+ digest = EVP_sha256();
+ else if (key_type == EVP_PKEY_EC)
+ digest = EVP_sha256();
+
+ if (!(X509_sign(newcrt, pkey, digest)))
+ goto mkcert_error;
+
+ tmp_x509 = newcrt;
+
+ return newcrt;
+
+mkcert_error:
+ if (ctmp) NCONF_free(ctmp);
+ if (newcrt) X509_free(newcrt);
+ return NULL;
+
+}
+
+
+/*
+ * Generate a temporary RSA2048 pkey or reuse the one generated.
+ *
+ * Increment the refcount when returning the existing one
+ *
+ */
+EVP_PKEY *acme_gen_tmp_pkey()
+{
+ if (tmp_pkey) {
+ EVP_PKEY_up_ref(tmp_pkey);
+ return tmp_pkey;
+ }
+
+ tmp_pkey = acme_EVP_PKEY_gen(EVP_PKEY_RSA, 0, 2048, NULL);
+
+ return tmp_pkey;
+}
+
+
/* start an ACME task */
static int acme_start_task(struct ckch_store *store, char **errmsg)
{