Browse Source

Create account key pair at startup

If several certificates uses the same account and this account doesn't
exists yet, they will both try to create it, resulting in a race
condition. This commit solves the problem by creating the account key
pair at startup. Account creation on the endpoint is not subject to a
race condition since the request does not differ from the one used to
retrieve the account id.
Fix #3
pull/5/head
Rodolphe Breard 5 years ago
parent
commit
117a19f985
  1. 2
      acmed/src/acme_proto.rs
  2. 29
      acmed/src/acme_proto/account.rs
  3. 2
      acmed/src/main_event_loop.rs

2
acmed/src/acme_proto.rs

@ -10,7 +10,7 @@ use acme_common::error::Error;
use serde_json::json; use serde_json::json;
use std::fmt; use std::fmt;
mod account;
pub mod account;
mod certificate; mod certificate;
mod http; mod http;
pub mod structs; pub mod structs;

29
acmed/src/acme_proto/account.rs

@ -22,17 +22,7 @@ impl AccountManager {
root_certs: &[String], root_certs: &[String],
) -> Result<(Self, String), Error> { ) -> Result<(Self, String), Error> {
// TODO: store the key id (account url) // TODO: store the key id (account url)
let key_pair = if storage::account_files_exists(cert) {
// TODO: check if the keys are suitable for the specified signature algorithm
// and, if not, initiate a key rollover.
storage::get_account_keypair(cert)?
} else {
// TODO: allow to change the signature algo
let sign_alg = SignatureAlgorithm::from_str(crate::DEFAULT_JWS_SIGN_ALGO)?;
let key_pair = sign_alg.gen_key_pair()?;
storage::set_account_keypair(cert, &key_pair)?;
key_pair
};
let key_pair = storage::get_account_keypair(cert)?;
let account = Account::new(cert); let account = Account::new(cert);
let account = serde_json::to_string(&account)?; let account = serde_json::to_string(&account)?;
let data_builder = let data_builder =
@ -53,3 +43,20 @@ impl AccountManager {
Ok((ac, nonce)) Ok((ac, nonce))
} }
} }
pub fn init_account(cert: &Certificate) -> Result<(), Error> {
if !storage::account_files_exists(cert) {
// TODO: allow to change the signature algo
let sign_alg = SignatureAlgorithm::from_str(crate::DEFAULT_JWS_SIGN_ALGO)?;
let key_pair = sign_alg.gen_key_pair()?;
storage::set_account_keypair(cert, &key_pair)?;
let msg = format!("Account {} created.", &cert.account.name);
cert.info(&msg)
} else {
// TODO: check if the keys are suitable for the specified signature algorithm
// and, if not, initiate a key rollover.
let msg = format!("Account {} already exists.", &cert.account.name);
cert.debug(&msg)
}
Ok(())
}

2
acmed/src/main_event_loop.rs

@ -1,3 +1,4 @@
use crate::acme_proto::account::init_account;
use crate::acme_proto::request_certificate; use crate::acme_proto::request_certificate;
use crate::certificate::Certificate; use crate::certificate::Certificate;
use crate::config; use crate::config;
@ -67,6 +68,7 @@ impl MainEventLoop {
env: crt.env.to_owned(), env: crt.env.to_owned(),
id: i + 1, id: i + 1,
}; };
init_account(&cert)?;
certs.push(cert); certs.push(cert);
} }

Loading…
Cancel
Save