@@ -709,6 +709,53 @@ apr_status_t md_pkey_fsave(md_pkey_t *pkey, apr_pool_t *p,
709709 return rv ;
710710}
711711
712+ apr_status_t md_pkey_read_http (md_pkey_t * * ppkey , apr_pool_t * pool ,
713+ const struct md_http_response_t * res )
714+ {
715+ apr_status_t rv ;
716+ apr_off_t data_len ;
717+ char * pem_data ;
718+ apr_size_t pem_len ;
719+ md_pkey_t * pkey ;
720+ BIO * bf ;
721+ passwd_ctx ctx ;
722+
723+ rv = apr_brigade_length (res -> body , 1 , & data_len );
724+ if (APR_SUCCESS != rv ) goto leave ;
725+ if (data_len > 1024 * 1024 ) { /* certs usually are <2k each */
726+ rv = APR_EINVAL ;
727+ goto leave ;
728+ }
729+ rv = apr_brigade_pflatten (res -> body , & pem_data , & pem_len , res -> req -> pool );
730+ if (APR_SUCCESS != rv ) goto leave ;
731+
732+ if (NULL == (bf = BIO_new_mem_buf (pem_data , (int )pem_len ))) {
733+ rv = APR_ENOMEM ;
734+ goto leave ;
735+ }
736+ pkey = make_pkey (pool );
737+ ctx .pass_phrase = NULL ;
738+ ctx .pass_len = 0 ;
739+ ERR_clear_error ();
740+ pkey -> pkey = PEM_read_bio_PrivateKey (bf , NULL , NULL , & ctx );
741+ BIO_free (bf );
742+
743+ if (pkey -> pkey == NULL ) {
744+ unsigned long err = ERR_get_error ();
745+ rv = APR_EINVAL ;
746+ md_log_perror (MD_LOG_MARK , MD_LOG_WARNING , rv , pool ,
747+ "error loading pkey from http response: %s" ,
748+ ERR_error_string (err , NULL ));
749+ goto leave ;
750+ }
751+ rv = APR_SUCCESS ;
752+ apr_pool_cleanup_register (pool , pkey , pkey_cleanup , apr_pool_cleanup_null );
753+
754+ leave :
755+ * ppkey = (APR_SUCCESS == rv )? pkey : NULL ;
756+ return rv ;
757+ }
758+
712759/* Determine the message digest used for signing with the given private key.
713760 */
714761static const EVP_MD * pkey_get_MD (md_pkey_t * pkey )
@@ -1137,6 +1184,11 @@ const char *md_cert_get_serial_number(const md_cert_t *cert, apr_pool_t *p)
11371184 return s ;
11381185}
11391186
1187+ int md_certs_are_equal (const md_cert_t * a , const md_cert_t * b )
1188+ {
1189+ return X509_cmp (a -> x509 , b -> x509 ) == 0 ;
1190+ }
1191+
11401192int md_cert_is_valid_now (const md_cert_t * cert )
11411193{
11421194 return ((X509_cmp_current_time (X509_get_notBefore (cert -> x509 )) < 0 )
0 commit comments