Skip to content

Commit e2179a4

Browse files
committed
Add option --acme-force-renewal-period to simplify renewal tests
1 parent 1e1063b commit e2179a4

4 files changed

Lines changed: 46 additions & 3 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,8 @@ If you want to test certificate renewal, you can change the expirations by modif
293293
}
294294
```
295295

296+
You can also instruct BlogTech to renew certificates even though they are not expired using the option `--acme-force-renewal-period=<maximum duration in ms>`.
297+
296298
## Configuration Files
297299

298300
BlogTech allows you to move any number of command-line arguments to a configuration file.

src/acme.c

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,7 @@ void acme_config_init(ACME_Config *config,
468468
config->dont_verify_cert = false;
469469
config->trace_bytes = false;
470470
config->logger = NULL;
471+
config->force_renewal_period = -1;
471472

472473
config->email = email;
473474
config->country = country;
@@ -584,6 +585,7 @@ int acme_init(ACME *acme, ACME_Config *config)
584585
acme->dont_verify_cert = config->dont_verify_cert;
585586
acme->trace_bytes = config->trace_bytes;
586587
acme->logger = config->logger;
588+
acme->force_renewal_period = config->force_renewal_period;
587589

588590
acme->agree_tos = config->agree_tos;
589591

@@ -638,14 +640,29 @@ int acme_init(ACME *acme, ACME_Config *config)
638640
log(acme->logger, S("Certificate file '{}' not found. Continuing without a certificate.\n"), V(config->certificate_file));
639641
} else {
640642

643+
Time current_time = get_current_time();
644+
if (current_time == INVALID_TIME) {
645+
log(acme->logger, S("Couldn't read the time.\n"), V());
646+
acme_free(acme);
647+
return -1;
648+
}
649+
641650
Time certificate_expiry;
642651
ret = get_chain_expiry(certificate, &certificate_expiry);
643652
if (ret < 0) {
644653
log(acme->logger, S("Couldn't determine expiry of certificate file '{}'.\n"), V(config->certificate_file));
645654
acme_free(acme);
646655
return -1;
647656
}
648-
log(acme->logger, S("Certificate will expire at {} UNIX time\n"), V(certificate_expiry / 1000));
657+
log(acme->logger, S("Certificate will expire in {} seconds\n"), V((certificate_expiry - current_time) / 1000));
658+
659+
if (acme->force_renewal_period > -1) {
660+
Time expiry_limit = current_time + acme->force_renewal_period;
661+
if (expiry_limit < certificate_expiry) {
662+
certificate_expiry = expiry_limit;
663+
log(acme->logger, S("Forcing certificate renewal in {} seconds\n"), V(acme->force_renewal_period / 1000));
664+
}
665+
}
649666

650667
string certificate_key;
651668
ret = file_read_all(acme->certificate_key_file, &certificate_key);
@@ -937,7 +954,7 @@ static int complete_account_creation_request(ACME *acme, CHTTP_Response *respons
937954
log(acme->logger, S("ACME account was created. The account key was stored in '{}'\n"), V(acme->account_key_file));
938955
} else {
939956
ASSERT(response->status == 200);
940-
log(acme->logger, S("Existing ACME account found"), V());
957+
log(acme->logger, S("Existing ACME account found\n"), V());
941958
}
942959

943960
BIO_free(bio);
@@ -1464,13 +1481,27 @@ static int complete_certificate_download_request(ACME *acme, CHTTP_Response *res
14641481
ASSERT(certificate.ptr != NULL);
14651482
ASSERT(certificate.len > 0);
14661483

1484+
Time current_time = get_current_time();
1485+
if (current_time == INVALID_TIME) {
1486+
log(acme->logger, S("Couldn't read the time.\n"), V());
1487+
return -1;
1488+
}
1489+
14671490
Time certificate_expiry;
14681491
int ret = get_chain_expiry(certificate, &certificate_expiry);
14691492
if (ret < 0) {
14701493
log(acme->logger, S("Couldn't determine expiry of the newly issued certificate.\n"), V());
14711494
return -1;
14721495
}
1473-
log(acme->logger, S("Certificate will expire {} UNIX time\n"), V(certificate_expiry / 1000));
1496+
log(acme->logger, S("Certificate will expire in {} seconds\n"), V((certificate_expiry - current_time) / 1000));
1497+
1498+
if (acme->force_renewal_period > -1) {
1499+
Time expiry_limit = current_time + acme->force_renewal_period;
1500+
if (expiry_limit < certificate_expiry) {
1501+
certificate_expiry = expiry_limit;
1502+
log(acme->logger, S("Forcing certificate renewal in {} seconds\n"), V(acme->force_renewal_period / 1000));
1503+
}
1504+
}
14741505

14751506
acme->certificate.ptr = malloc(certificate.len); // TODO: allocstr
14761507
if (acme->certificate.ptr == NULL) {
@@ -1611,6 +1642,9 @@ void acme_process_timeout(ACME *acme, CHTTP_Client *client)
16111642
break;
16121643
case ACME_STATE_WAIT:
16131644
{
1645+
if (acme->certificate_expiry > current_time)
1646+
break;
1647+
16141648
// Free previous order data before starting a new certificate order
16151649
reset_order_data(acme);
16161650
if (send_order_creation_request(acme, acme->client) < 0) {

src/acme.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ typedef struct {
1919
b8 dont_verify_cert;
2020
b8 trace_bytes;
2121
Logger *logger;
22+
int force_renewal_period;
2223

2324
/////////////////////////////////////////////
2425
// Information
@@ -154,6 +155,7 @@ typedef struct {
154155
b8 dont_verify_cert;
155156
b8 trace_bytes;
156157
Logger *logger;
158+
int force_renewal_period;
157159

158160
string account_key_file;
159161
string certificate_file;

src/main_server.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ typedef struct {
4747
string acme_country;
4848
string acme_org;
4949
b8 acme_insecure; // TODO: document
50+
s32 acme_force_renewal_period; // TODO: document
5051
string acme_domains[ACME_DOMAIN_LIMIT];
5152
int num_acme_domains;
5253
} ServerConfig;
@@ -250,6 +251,7 @@ static int load_server_config(ConfigReader *reader, ServerConfig *config)
250251
config->acme_url = S("https://acme-v02.api.letsencrypt.org/directory");
251252
config->acme_insecure = false;
252253
config->num_acme_domains = 0;
254+
config->acme_force_renewal_period = -1;
253255

254256
b8 have_acme_email = false;
255257
b8 have_acme_country = false;
@@ -322,6 +324,8 @@ static int load_server_config(ConfigReader *reader, ServerConfig *config)
322324
}
323325
} else if (streq(name, S("acme-insecure"))) {
324326
parse_config_value_yn(name, value, &config->acme_insecure, &bad_config);
327+
} else if (streq(name, S("acme-force-renewal-period"))) {
328+
parse_config_value_time_ms(name, value, &config->acme_force_renewal_period, &bad_config);
325329
}
326330
}
327331

@@ -614,6 +618,7 @@ int main_server(int argc, char **argv)
614618
acme_config.certificate_key_file = server_config.cert_key_file;
615619
acme_config.dont_verify_cert = server_config.acme_insecure;
616620
acme_config.trace_bytes = server_config.trace_bytes;
621+
acme_config.force_renewal_period = server_config.acme_force_renewal_period;
617622

618623
if (acme_init(&acme, &acme_config) < 0) {
619624
fprintf(stderr, "Couldn't setup the ACME client\n");

0 commit comments

Comments
 (0)