| 734 | } |
| 735 | |
| 736 | apr_status_t md_pkey_read_http(md_pkey_t **ppkey, apr_pool_t *pool, |
| 737 | const struct md_http_response_t *res) |
| 738 | { |
| 739 | apr_status_t rv; |
| 740 | apr_off_t data_len; |
| 741 | char *pem_data; |
| 742 | apr_size_t pem_len; |
| 743 | md_pkey_t *pkey; |
| 744 | BIO *bf; |
| 745 | passwd_ctx ctx; |
| 746 | |
| 747 | rv = apr_brigade_length(res->body, 1, &data_len); |
| 748 | if (APR_SUCCESS != rv) goto leave; |
| 749 | if (data_len > 1024*1024) { /* certs usually are <2k each */ |
| 750 | rv = APR_EINVAL; |
| 751 | goto leave; |
| 752 | } |
| 753 | rv = apr_brigade_pflatten(res->body, &pem_data, &pem_len, res->req->pool); |
| 754 | if (APR_SUCCESS != rv) goto leave; |
| 755 | |
| 756 | if (NULL == (bf = BIO_new_mem_buf(pem_data, (int)pem_len))) { |
| 757 | rv = APR_ENOMEM; |
| 758 | goto leave; |
| 759 | } |
| 760 | pkey = make_pkey(pool); |
| 761 | ctx.pass_phrase = NULL; |
| 762 | ctx.pass_len = 0; |
| 763 | ERR_clear_error(); |
| 764 | pkey->pkey = PEM_read_bio_PrivateKey(bf, NULL, NULL, &ctx); |
| 765 | BIO_free(bf); |
| 766 | |
| 767 | if (pkey->pkey == NULL) { |
| 768 | unsigned long err = ERR_get_error(); |
| 769 | rv = APR_EINVAL; |
| 770 | md_log_perror(MD_LOG_MARK, MD_LOG_WARNING, rv, pool, |
| 771 | "error loading pkey from http response: %s", |
| 772 | ERR_error_string(err, NULL)); |
| 773 | goto leave; |
| 774 | } |
| 775 | rv = APR_SUCCESS; |
| 776 | apr_pool_cleanup_register(pool, pkey, pkey_cleanup, apr_pool_cleanup_null); |
| 777 | |
| 778 | leave: |
| 779 | *ppkey = (APR_SUCCESS == rv)? pkey : NULL; |
| 780 | return rv; |
| 781 | } |
| 782 | |
| 783 | /* Determine the message digest used for signing with the given private key. |
| 784 | */ |
nothing calls this directly
no test coverage detected