--- /dev/null
+ * mod_md: Certificate/keys pairs are verified as matching before a renewal is accepted
+ as successful or a staged renewal is replacing the existing certificates.
+ This avoid potential mess ups in the md store file system to render the active
+ certificates non-working. [@mkauf]
}
if (!md_array_is_empty(ad->cred->chain)) {
+
+ if (!ad->cred->pkey) {
+ rv = md_pkey_load(d->store, MD_SG_STAGING, d->md->name, ad->cred->spec, &ad->cred->pkey, d->p);
+ if (APR_SUCCESS != rv) {
+ md_result_printf(result, rv, "Loading the private key.");
+ goto out;
+ }
+ }
+
+ if (ad->cred->pkey) {
+ rv = md_check_cert_and_pkey(ad->cred->chain, ad->cred->pkey);
+ if (APR_SUCCESS != rv) {
+ md_result_printf(result, rv, "Certificate and private key do not match.");
+
+ /* Delete the order */
+ md_acme_order_purge(d->store, d->p, MD_SG_STAGING, d->md->name, d->env);
+
+ goto out;
+ }
+ }
+
rv = md_pubcert_save(d->store, d->p, MD_SG_STAGING, d->md->name,
ad->cred->spec, ad->cred->chain, 0);
if (APR_SUCCESS != rv) {
md_result_printf(result, rv, "no certificate in staged credentials #%d", i);
goto leave;
}
+ if (APR_SUCCESS != (rv = md_check_cert_and_pkey(creds->chain, creds->pkey))) {
+ md_result_printf(result, rv, "certificate and private key do not match in staged credentials #%d", i);
+ goto leave;
+ }
APR_ARRAY_PUSH(all_creds, md_credentials_t*) = creds;
}
return rv;
}
+apr_status_t md_check_cert_and_pkey(struct apr_array_header_t *certs, md_pkey_t *pkey)
+{
+ const md_cert_t *cert;
+
+ if (certs->nelts == 0) {
+ return APR_ENOENT;
+ }
+
+ cert = APR_ARRAY_IDX(certs, 0, const md_cert_t*);
+
+ if (1 != X509_check_private_key(cert->x509, pkey->pkey)) {
+ return APR_EGENERAL;
+ }
+
+ return APR_SUCCESS;
+}
apr_status_t md_cert_get_ocsp_responder_url(const char **purl, apr_pool_t *p, const md_cert_t *cert);
+apr_status_t md_check_cert_and_pkey(struct apr_array_header_t *certs, md_pkey_t *pkey);
+
+
/**************************************************************************************************/
/* X509 certificate transparency */