in src/vtok_srv/src/worker.rs [168:224]
fn refresh_token(label: String, pin: String, envelope_key: schema::EnvelopeKey) -> ApiResponse {
let mut config = config::Config::load_rw().map_err(|_| ApiError::InternalError)?;
let slot = config
.slots_mut()
.iter_mut()
.find(|s| match s {
None => false,
Some(tok) => tok.label == label,
})
.ok_or(ApiError::TokenNotFound)?;
// It's safe to unwrap here, since the above find() ensures slot != None
let mut token = slot.as_mut().unwrap();
if token.pin != pin {
return Err(ApiError::AccessDenied);
}
// Since all the keys in one token are encrypted via the same envelope, we only need to
// successfully decrypt one key, in order to achieve attestation.
token
.private_keys
.iter()
.next()
.ok_or(ApiError::EmptyToken)
.and_then(|key| {
match envelope_key {
schema::EnvelopeKey::Kms {
ref region,
ref access_key_id,
ref secret_access_key,
ref session_token,
} => {
aws_ne::kms_decrypt(
region.as_bytes(),
access_key_id.as_bytes(),
secret_access_key.as_bytes(),
session_token.as_bytes(),
&base64::decode(key.encrypted_pem_b64.as_str())
.map_err(|_| ApiError::TokenKeyDecodingFailed)?,
)
.map_err(|_| ApiError::KmsDecryptFailed)
.and_then(|v| {
String::from_utf8(v).map_err(|_| ApiError::TokenRefreshFailed)
})
.ok()
.filter(|pem| pem == &key.pem)
.ok_or(ApiError::TokenRefreshFailed)?;
}
};
Ok(())
})?;
token.expiry_ts = util::time::monotonic_secs() + defs::TOKEN_EXPIRY_SECS;
config.save().map_err(|_| ApiError::InternalError)?;
Ok(ApiOk::None)
}