| 415 | } |
| 416 | |
| 417 | static apr_status_t get_chain(void *baton, int attempt) |
| 418 | { |
| 419 | md_proto_driver_t *d = baton; |
| 420 | md_acme_driver_t *ad = d->baton; |
| 421 | const char *prev_link = NULL; |
| 422 | apr_status_t rv = APR_SUCCESS; |
| 423 | |
| 424 | while (APR_SUCCESS == rv && ad->cred->chain->nelts < 10) { |
| 425 | int nelts = ad->cred->chain->nelts; |
| 426 | |
| 427 | if (ad->chain_up_link && (!prev_link || strcmp(prev_link, ad->chain_up_link))) { |
| 428 | prev_link = ad->chain_up_link; |
| 429 | |
| 430 | md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, d->p, |
| 431 | "next chain cert at %s", ad->chain_up_link); |
| 432 | rv = md_acme_GET(ad->acme, ad->chain_up_link, NULL, NULL, on_add_chain, NULL, 1, d); |
| 433 | |
| 434 | if (APR_SUCCESS == rv && nelts == ad->cred->chain->nelts) { |
| 435 | break; |
| 436 | } |
| 437 | else if (APR_SUCCESS != rv) { |
| 438 | md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, d->p, |
| 439 | "error retrieving certificate from %s", ad->chain_up_link); |
| 440 | return rv; |
| 441 | } |
| 442 | } |
| 443 | else if (ad->cred->chain->nelts <= 1) { |
| 444 | /* This cannot be the complete chain (no one signs new web certs with their root) |
| 445 | * and we did not see a "Link: ...rel=up", so we do not know how to continue. */ |
| 446 | md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, d->p, |
| 447 | "no link header 'up' for new certificate, unable to retrieve chain"); |
| 448 | rv = APR_EINVAL; |
| 449 | break; |
| 450 | } |
| 451 | else { |
| 452 | rv = APR_SUCCESS; |
| 453 | break; |
| 454 | } |
| 455 | } |
| 456 | md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, rv, d->p, |
| 457 | "got chain with %d certs (%d. attempt)", ad->cred->chain->nelts, attempt); |
| 458 | return rv; |
| 459 | } |
| 460 | |
| 461 | static apr_status_t ad_chain_retrieve(md_proto_driver_t *d) |
| 462 | { |
nothing calls this directly
no test coverage detected