Browse Source

Create a new account if the external account has changed

pull/39/head
Rodolphe Breard 4 years ago
parent
commit
3c173bcf13
  1. 30
      acmed/src/account.rs
  2. 21
      acmed/src/account/storage.rs
  3. 1
      acmed/src/acme_proto/account.rs

30
acmed/src/account.rs

@ -70,6 +70,7 @@ pub struct AccountEndpoint {
pub order_url: String,
pub key_hash: Vec<u8>,
pub contacts_hash: Vec<u8>,
pub external_account_hash: Vec<u8>,
}
impl AccountEndpoint {
@ -80,6 +81,7 @@ impl AccountEndpoint {
order_url: String::new(),
key_hash: Vec::new(),
contacts_hash: Vec::new(),
external_account_hash: Vec::new(),
}
}
}
@ -176,6 +178,7 @@ impl Account {
Some(mut a) => {
a.update_keys(key_type, signature_algorithm)?;
a.contacts = contacts;
a.external_account = external_account.to_owned();
a
}
None => {
@ -208,6 +211,18 @@ impl Account {
) -> Result<(), Error> {
let acc_ep = self.get_endpoint(&endpoint.name)?;
if !acc_ep.account_url.is_empty() {
if let Some(ec) = &self.external_account {
let external_account_hash = hash_external_account(&ec);
if external_account_hash != acc_ep.external_account_hash {
let msg = format!(
"external account changed on endpoint \"{}\"",
&endpoint.name
);
self.info(&msg);
register_account(endpoint, root_certs, self)?;
return Ok(());
}
}
let ct_hash = hash_contacts(&self.contacts);
let key_hash = hash_key(&self.current_key)?;
let contacts_changed = ct_hash != acc_ep.contacts_hash;
@ -257,6 +272,15 @@ impl Account {
Ok(())
}
pub fn update_external_account_hash(&mut self, endpoint_name: &str) -> Result<(), Error> {
if let Some(ec) = &self.external_account {
let ec = ec.clone();
let mut ep = self.get_endpoint_mut(endpoint_name)?;
ep.external_account_hash = hash_external_account(&ec);
}
Ok(())
}
fn update_keys(
&mut self,
key_type: KeyType,
@ -295,3 +319,9 @@ fn hash_key(key: &AccountKey) -> Result<Vec<u8>, Error> {
let pem = key.key.public_key_to_pem()?;
Ok(HashFunction::Sha256.hash(&pem))
}
fn hash_external_account(ec: &ExternalAccount) -> Vec<u8> {
let mut msg = ec.key.clone();
msg.extend(ec.identifier.as_bytes());
HashFunction::Sha256.hash(&msg)
}

21
acmed/src/account/storage.rs

@ -64,6 +64,7 @@ struct AccountEndpointStorage {
order_url: String,
key_hash: Vec<u8>,
contacts_hash: Vec<u8>,
external_account_hash: Vec<u8>,
}
impl AccountEndpointStorage {
@ -74,6 +75,7 @@ impl AccountEndpointStorage {
order_url: account_endpoint.order_url.clone(),
key_hash: account_endpoint.key_hash.clone(),
contacts_hash: account_endpoint.contacts_hash.clone(),
external_account_hash: account_endpoint.external_account_hash.clone(),
}
}
@ -84,6 +86,7 @@ impl AccountEndpointStorage {
order_url: self.order_url.clone(),
key_hash: self.key_hash.clone(),
contacts_hash: self.contacts_hash.clone(),
external_account_hash: self.external_account_hash.clone(),
}
}
}
@ -98,7 +101,7 @@ struct AccountStorage {
external_account: Option<ExternalAccountStorage>,
}
pub fn fetch(file_manager: &FileManager, name: &str) -> Result<Option<Account>, Error> {
fn do_fetch(file_manager: &FileManager, name: &str) -> Result<Option<Account>, Error> {
if account_files_exists(file_manager) {
let data = get_account_data(file_manager)?;
let obj: AccountStorage = bincode::deserialize(&data[..])
@ -137,7 +140,7 @@ pub fn fetch(file_manager: &FileManager, name: &str) -> Result<Option<Account>,
}
}
pub fn save(file_manager: &FileManager, account: &Account) -> Result<(), Error> {
fn do_save(file_manager: &FileManager, account: &Account) -> Result<(), Error> {
let endpoints: HashMap<String, AccountEndpointStorage> = account
.endpoints
.iter()
@ -169,3 +172,17 @@ pub fn save(file_manager: &FileManager, account: &Account) -> Result<(), Error>
.map_err(|e| Error::from(&e.to_string()).prefix(&account.name))?;
set_account_data(file_manager, &encoded)
}
pub fn fetch(file_manager: &FileManager, name: &str) -> Result<Option<Account>, Error> {
do_fetch(file_manager, name).map_err(|_| {
format!(
"account \"{}\": unable to load account file: file may be corrupted",
name
)
.into()
})
}
pub fn save(file_manager: &FileManager, account: &Account) -> Result<(), Error> {
do_save(file_manager, account).map_err(|e| format!("unable to save account file: {}", e).into())
}

1
acmed/src/acme_proto/account.rs

@ -57,6 +57,7 @@ pub fn register_account(
account.set_order_url(&endpoint.name, &order_url)?;
account.update_key_hash(&endpoint.name)?;
account.update_contacts_hash(&endpoint.name)?;
account.update_external_account_hash(&endpoint.name)?;
account.save()?;
account.info(&format!(
"account created on endpoint \"{}\"",

Loading…
Cancel
Save