Browse Source

Move common items to a dedicated lib

In a near future, ACMEd will be composed of several binaries which will
use some common functions and structures.
pull/5/head
Rodolphe Breard 6 years ago
parent
commit
a0d8944682
  1. 25
      acme_common/Cargo.toml
  2. 87
      acme_common/src/error.rs
  3. 0
      acme_common/src/gen.rs
  4. 6
      acme_common/src/lib.rs
  5. 2
      acmed/Cargo.toml
  6. 6
      acmed/src/acme_proto.rs
  7. 2
      acmed/src/acme_proto/account.rs
  8. 15
      acmed/src/acme_proto/certificate.rs
  9. 4
      acmed/src/acme_proto/http.rs
  10. 10
      acmed/src/acme_proto/jws.rs
  11. 7
      acmed/src/acme_proto/jws/algorithms.rs
  12. 2
      acmed/src/acme_proto/structs.rs
  13. 2
      acmed/src/acme_proto/structs/account.rs
  14. 4
      acmed/src/acme_proto/structs/authorization.rs
  15. 2
      acmed/src/acme_proto/structs/directory.rs
  16. 99
      acmed/src/acme_proto/structs/error.rs
  17. 2
      acmed/src/acme_proto/structs/order.rs
  18. 2
      acmed/src/certificate.rs
  19. 2
      acmed/src/config.rs
  20. 2
      acmed/src/hooks.rs
  21. 2
      acmed/src/logs.rs
  22. 2
      acmed/src/main.rs
  23. 2
      acmed/src/main_event_loop.rs
  24. 4
      acmed/src/storage.rs

25
acme_common/Cargo.toml

@ -0,0 +1,25 @@
[package]
name = "acme_common"
version = "0.1.0"
authors = ["Rodolphe Breard <rodolphe@what.tf>"]
edition = "2018"
repository = "https://github.com/breard-r/libreauth"
readme = "../README.md"
license = "MIT OR Apache-2.0"
include = ["src/**/*", "Cargo.toml", "Licence_*.txt"]
[lib]
name = "acme_common"
[dependencies]
base64 = "0.10"
handlebars = "2.0.0-beta.1"
http_req = "0.4"
openssl = "0.10"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
syslog = "4.0"
toml = "0.5"
[target.'cfg(unix)'.dependencies]
nix = "0.13"

87
acme_common/src/error.rs

@ -0,0 +1,87 @@
use std::fmt;
#[derive(Debug)]
pub struct Error {
pub message: String,
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.message)
}
}
impl From<&str> for Error {
fn from(error: &str) -> Self {
Error {
message: error.to_string(),
}
}
}
impl From<String> for Error {
fn from(error: String) -> Self {
error.as_str().into()
}
}
impl From<&String> for Error {
fn from(error: &String) -> Self {
error.as_str().into()
}
}
impl From<std::io::Error> for Error {
fn from(error: std::io::Error) -> Self {
format!("IO error: {}", error).into()
}
}
impl From<std::string::FromUtf8Error> for Error {
fn from(error: std::string::FromUtf8Error) -> Self {
format!("UTF-8 error: {}", error).into()
}
}
impl From<syslog::Error> for Error {
fn from(error: syslog::Error) -> Self {
format!("syslog error: {}", error).into()
}
}
impl From<toml::de::Error> for Error {
fn from(error: toml::de::Error) -> Self {
format!("IO error: {}", error).into()
}
}
impl From<serde_json::error::Error> for Error {
fn from(error: serde_json::error::Error) -> Self {
format!("IO error: {}", error).into()
}
}
impl From<handlebars::TemplateRenderError> for Error {
fn from(error: handlebars::TemplateRenderError) -> Self {
format!("Template error: {}", error).into()
}
}
impl From<openssl::error::ErrorStack> for Error {
fn from(error: openssl::error::ErrorStack) -> Self {
format!("{}", error).into()
}
}
impl From<http_req::error::Error> for Error {
fn from(error: http_req::error::Error) -> Self {
format!("HTTP error: {}", error).into()
}
}
#[cfg(unix)]
impl From<nix::Error> for Error {
fn from(error: nix::Error) -> Self {
format!("{}", error).into()
}
}

0
acmed/src/keygen.rs → acme_common/src/gen.rs

6
acme_common/src/lib.rs

@ -0,0 +1,6 @@
pub mod error;
pub mod gen;
pub fn b64_encode<T: ?Sized + AsRef<[u8]>>(input: &T) -> String {
base64::encode_config(input, base64::URL_SAFE_NO_PAD)
}

2
acmed/Cargo.toml

@ -12,7 +12,7 @@ include = ["src/**/*", "Cargo.toml", "LICENSE-*.txt"]
build = "build.rs" build = "build.rs"
[dependencies] [dependencies]
base64 = "0.10"
acme_common = { path = "../acme_common" }
clap = "2.32" clap = "2.32"
daemonize = "0.4" daemonize = "0.4"
env_logger = "0.6" env_logger = "0.6"

6
acmed/src/acme_proto.rs

@ -4,8 +4,8 @@ use crate::acme_proto::structs::{
Authorization, AuthorizationStatus, NewOrder, Order, OrderStatus, Authorization, AuthorizationStatus, NewOrder, Order, OrderStatus,
}; };
use crate::certificate::Certificate; use crate::certificate::Certificate;
use crate::error::Error;
use crate::storage; use crate::storage;
use acme_common::error::Error;
use log::info; use log::info;
use std::fmt; use std::fmt;
@ -156,7 +156,3 @@ pub fn request_certificate(cert: &Certificate) -> Result<(), Error> {
info!("Certificate renewed for {}", cert.domains.join(", ")); info!("Certificate renewed for {}", cert.domains.join(", "));
Ok(()) Ok(())
} }
pub fn b64_encode<T: ?Sized + AsRef<[u8]>>(input: &T) -> String {
base64::encode_config(input, base64::URL_SAFE_NO_PAD)
}

2
acmed/src/acme_proto/account.rs

@ -3,8 +3,8 @@ use crate::acme_proto::jws::algorithms::SignatureAlgorithm;
use crate::acme_proto::jws::encode_jwk; use crate::acme_proto::jws::encode_jwk;
use crate::acme_proto::structs::{Account, AccountResponse, Directory}; use crate::acme_proto::structs::{Account, AccountResponse, Directory};
use crate::certificate::Certificate; use crate::certificate::Certificate;
use crate::error::Error;
use crate::storage; use crate::storage;
use acme_common::error::Error;
use openssl::pkey::{PKey, Private, Public}; use openssl::pkey::{PKey, Private, Public};
use std::str::FromStr; use std::str::FromStr;

15
acmed/src/acme_proto/certificate.rs

@ -1,6 +1,7 @@
use crate::certificate::{Algorithm, Certificate}; use crate::certificate::{Algorithm, Certificate};
use crate::error::Error;
use crate::{keygen, storage};
use crate::storage;
use acme_common::error::Error;
use acme_common::{b64_encode, gen};
use openssl::hash::MessageDigest; use openssl::hash::MessageDigest;
use openssl::pkey::{PKey, Private, Public}; use openssl::pkey::{PKey, Private, Public};
use openssl::stack::Stack; use openssl::stack::Stack;
@ -10,10 +11,10 @@ use serde_json::json;
fn gen_key_pair(cert: &Certificate) -> Result<(PKey<Private>, PKey<Public>), Error> { fn gen_key_pair(cert: &Certificate) -> Result<(PKey<Private>, PKey<Public>), Error> {
let (priv_key, pub_key) = match cert.algo { let (priv_key, pub_key) = match cert.algo {
Algorithm::Rsa2048 => keygen::rsa2048(),
Algorithm::Rsa4096 => keygen::rsa4096(),
Algorithm::EcdsaP256 => keygen::p256(),
Algorithm::EcdsaP384 => keygen::p384(),
Algorithm::Rsa2048 => gen::rsa2048(),
Algorithm::Rsa4096 => gen::rsa4096(),
Algorithm::EcdsaP256 => gen::p256(),
Algorithm::EcdsaP384 => gen::p384(),
}?; }?;
storage::set_priv_key(cert, &priv_key)?; storage::set_priv_key(cert, &priv_key)?;
Ok((priv_key, pub_key)) Ok((priv_key, pub_key))
@ -52,7 +53,7 @@ pub fn generate_csr(
builder.sign(priv_key, MessageDigest::sha256())?; builder.sign(priv_key, MessageDigest::sha256())?;
let csr = builder.build(); let csr = builder.build();
let csr = csr.to_der()?; let csr = csr.to_der()?;
let csr = super::b64_encode(&csr);
let csr = b64_encode(&csr);
let csr = json!({ "csr": csr }); let csr = json!({ "csr": csr });
Ok(csr.to_string()) Ok(csr.to_string())
} }

4
acmed/src/acme_proto/http.rs

@ -1,5 +1,5 @@
use crate::acme_proto::structs::Directory;
use crate::error::{AcmeError, Error, HttpApiError};
use crate::acme_proto::structs::{AcmeError, Directory, HttpApiError};
use acme_common::error::Error;
use http_req::request::{Method, Request}; use http_req::request::{Method, Request};
use http_req::response::Response; use http_req::response::Response;
use http_req::uri::Uri; use http_req::uri::Uri;

10
acmed/src/acme_proto/jws.rs

@ -1,6 +1,6 @@
use crate::acme_proto::b64_encode;
use crate::acme_proto::jws::algorithms::{EdDsaVariant, SignatureAlgorithm}; use crate::acme_proto::jws::algorithms::{EdDsaVariant, SignatureAlgorithm};
use crate::error::Error;
use acme_common::b64_encode;
use acme_common::error::Error;
use openssl::ecdsa::EcdsaSig; use openssl::ecdsa::EcdsaSig;
use openssl::pkey::{PKey, Private}; use openssl::pkey::{PKey, Private};
use openssl::sha::sha256; use openssl::sha::sha256;
@ -113,7 +113,7 @@ mod tests {
#[test] #[test]
fn test_default_jwk() { fn test_default_jwk() {
let (priv_key, _) = crate::keygen::p256().unwrap();
let (priv_key, _) = acme_common::gen::p256().unwrap();
let payload = "Dummy payload 1"; let payload = "Dummy payload 1";
let payload_b64 = "RHVtbXkgcGF5bG9hZCAx"; let payload_b64 = "RHVtbXkgcGF5bG9hZCAx";
let s = encode_jwk(&priv_key, payload.as_bytes(), "", ""); let s = encode_jwk(&priv_key, payload.as_bytes(), "", "");
@ -127,7 +127,7 @@ mod tests {
#[test] #[test]
fn test_default_nopad_jwk() { fn test_default_nopad_jwk() {
let (priv_key, _) = crate::keygen::p256().unwrap();
let (priv_key, _) = acme_common::gen::p256().unwrap();
let payload = "Dummy payload"; let payload = "Dummy payload";
let payload_b64 = "RHVtbXkgcGF5bG9hZA"; let payload_b64 = "RHVtbXkgcGF5bG9hZA";
let payload_b64_pad = "RHVtbXkgcGF5bG9hZA=="; let payload_b64_pad = "RHVtbXkgcGF5bG9hZA==";
@ -143,7 +143,7 @@ mod tests {
#[test] #[test]
fn test_default_kid() { fn test_default_kid() {
let (priv_key, _) = crate::keygen::p256().unwrap();
let (priv_key, _) = acme_common::gen::p256().unwrap();
let payload = "Dummy payload 1"; let payload = "Dummy payload 1";
let payload_b64 = "RHVtbXkgcGF5bG9hZCAx"; let payload_b64 = "RHVtbXkgcGF5bG9hZCAx";
let key_id = "0x2a"; let key_id = "0x2a";

7
acmed/src/acme_proto/jws/algorithms.rs

@ -1,7 +1,6 @@
use super::jwk::{EdDsaEd25519Jwk, Es256Jwk, Jwk}; use super::jwk::{EdDsaEd25519Jwk, Es256Jwk, Jwk};
use crate::acme_proto::b64_encode;
use crate::error::Error;
use crate::keygen;
use acme_common::error::Error;
use acme_common::{b64_encode, gen};
use openssl::bn::{BigNum, BigNumContext}; use openssl::bn::{BigNum, BigNumContext};
use openssl::ec::EcGroup; use openssl::ec::EcGroup;
use openssl::nid::Nid; use openssl::nid::Nid;
@ -117,7 +116,7 @@ impl SignatureAlgorithm {
pub fn gen_key_pair(&self) -> Result<(PKey<Private>, PKey<Public>), Error> { pub fn gen_key_pair(&self) -> Result<(PKey<Private>, PKey<Public>), Error> {
match self { match self {
SignatureAlgorithm::Es256 => keygen::p256(),
SignatureAlgorithm::Es256 => gen::p256(),
SignatureAlgorithm::EdDsa(EdDsaVariant::Ed25519) => Err("Not implemented".into()), SignatureAlgorithm::EdDsa(EdDsaVariant::Ed25519) => Err("Not implemented".into()),
} }
} }

2
acmed/src/acme_proto/structs.rs

@ -15,10 +15,12 @@ macro_rules! deserialize_from_str {
mod account; mod account;
mod authorization; mod authorization;
mod directory; mod directory;
mod error;
mod order; mod order;
pub use account::{Account, AccountDeactivation, AccountResponse, AccountUpdate}; pub use account::{Account, AccountDeactivation, AccountResponse, AccountUpdate};
pub use authorization::{Authorization, AuthorizationStatus, Challenge}; pub use authorization::{Authorization, AuthorizationStatus, Challenge};
pub use deserialize_from_str; pub use deserialize_from_str;
pub use directory::Directory; pub use directory::Directory;
pub use error::{AcmeError, HttpApiError};
pub use order::{Identifier, IdentifierType, NewOrder, Order, OrderStatus}; pub use order::{Identifier, IdentifierType, NewOrder, Order, OrderStatus};

2
acmed/src/acme_proto/structs/account.rs

@ -1,5 +1,5 @@
use crate::certificate::Certificate; use crate::certificate::Certificate;
use crate::error::Error;
use acme_common::error::Error;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::str::FromStr; use std::str::FromStr;

4
acmed/src/acme_proto/structs/authorization.rs

@ -1,7 +1,7 @@
use crate::acme_proto::b64_encode;
use crate::acme_proto::jws::algorithms::SignatureAlgorithm; use crate::acme_proto::jws::algorithms::SignatureAlgorithm;
use crate::acme_proto::structs::Identifier; use crate::acme_proto::structs::Identifier;
use crate::error::Error;
use acme_common::b64_encode;
use acme_common::error::Error;
use openssl::pkey::{PKey, Private}; use openssl::pkey::{PKey, Private};
use openssl::sha::sha256; use openssl::sha::sha256;
use serde::Deserialize; use serde::Deserialize;

2
acmed/src/acme_proto/structs/directory.rs

@ -1,4 +1,4 @@
use crate::error::Error;
use acme_common::error::Error;
use serde::Deserialize; use serde::Deserialize;
use std::str::FromStr; use std::str::FromStr;

99
acmed/src/error.rs → acmed/src/acme_proto/structs/error.rs

@ -1,99 +1,8 @@
use acme_common::error::Error;
use serde::Deserialize; use serde::Deserialize;
use std::fmt; use std::fmt;
use std::str::FromStr; use std::str::FromStr;
#[derive(Debug)]
pub struct Error {
pub message: String,
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.message)
}
}
impl From<&str> for Error {
fn from(error: &str) -> Self {
Error {
message: error.to_string(),
}
}
}
impl From<String> for Error {
fn from(error: String) -> Self {
error.as_str().into()
}
}
impl From<&String> for Error {
fn from(error: &String) -> Self {
error.as_str().into()
}
}
impl From<AcmeError> for Error {
fn from(error: AcmeError) -> Self {
error.to_string().into()
}
}
impl From<std::io::Error> for Error {
fn from(error: std::io::Error) -> Self {
format!("IO error: {}", error).into()
}
}
impl From<std::string::FromUtf8Error> for Error {
fn from(error: std::string::FromUtf8Error) -> Self {
format!("UTF-8 error: {}", error).into()
}
}
impl From<syslog::Error> for Error {
fn from(error: syslog::Error) -> Self {
format!("syslog error: {}", error).into()
}
}
impl From<toml::de::Error> for Error {
fn from(error: toml::de::Error) -> Self {
format!("IO error: {}", error).into()
}
}
impl From<serde_json::error::Error> for Error {
fn from(error: serde_json::error::Error) -> Self {
format!("IO error: {}", error).into()
}
}
impl From<handlebars::TemplateRenderError> for Error {
fn from(error: handlebars::TemplateRenderError) -> Self {
format!("Template error: {}", error).into()
}
}
impl From<openssl::error::ErrorStack> for Error {
fn from(error: openssl::error::ErrorStack) -> Self {
format!("{}", error).into()
}
}
impl From<http_req::error::Error> for Error {
fn from(error: http_req::error::Error) -> Self {
format!("HTTP error: {}", error).into()
}
}
#[cfg(unix)]
impl From<nix::Error> for Error {
fn from(error: nix::Error) -> Self {
format!("{}", error).into()
}
}
#[derive(PartialEq)] #[derive(PartialEq)]
pub enum AcmeError { pub enum AcmeError {
AccountDoesNotExist, AccountDoesNotExist,
@ -208,6 +117,12 @@ impl From<Error> for AcmeError {
} }
} }
impl From<AcmeError> for Error {
fn from(error: AcmeError) -> Self {
error.to_string().into()
}
}
#[derive(Deserialize)] #[derive(Deserialize)]
pub struct HttpApiError { pub struct HttpApiError {
#[serde(rename = "type")] #[serde(rename = "type")]

2
acmed/src/acme_proto/structs/order.rs

@ -1,4 +1,4 @@
use crate::error::Error;
use acme_common::error::Error;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::fmt; use std::fmt;
use std::str::FromStr; use std::str::FromStr;

2
acmed/src/certificate.rs

@ -1,8 +1,8 @@
use crate::acme_proto::Challenge; use crate::acme_proto::Challenge;
use crate::config::Account; use crate::config::Account;
use crate::error::Error;
use crate::hooks::{self, ChallengeHookData, Hook, PostOperationHookData}; use crate::hooks::{self, ChallengeHookData, Hook, PostOperationHookData};
use crate::storage::{certificate_files_exists, get_certificate}; use crate::storage::{certificate_files_exists, get_certificate};
use acme_common::error::Error;
use log::debug; use log::debug;
use std::fmt; use std::fmt;
use time::{strptime, Duration}; use time::{strptime, Duration};

2
acmed/src/config.rs

@ -1,7 +1,7 @@
use crate::acme_proto::Challenge; use crate::acme_proto::Challenge;
use crate::certificate::Algorithm; use crate::certificate::Algorithm;
use crate::error::Error;
use crate::hooks; use crate::hooks;
use acme_common::error::Error;
use log::info; use log::info;
use serde::Deserialize; use serde::Deserialize;
use std::fs::{self, File}; use std::fs::{self, File};

2
acmed/src/hooks.rs

@ -1,4 +1,4 @@
use crate::error::Error;
use acme_common::error::Error;
use handlebars::Handlebars; use handlebars::Handlebars;
use log::debug; use log::debug;
use serde::Serialize; use serde::Serialize;

2
acmed/src/logs.rs

@ -1,4 +1,4 @@
use crate::error::Error;
use acme_common::error::Error;
use env_logger::Builder; use env_logger::Builder;
use log::LevelFilter; use log::LevelFilter;
use syslog::Facility; use syslog::Facility;

2
acmed/src/main.rs

@ -6,9 +6,7 @@ use log::{error, LevelFilter};
mod acme_proto; mod acme_proto;
mod certificate; mod certificate;
mod config; mod config;
mod error;
mod hooks; mod hooks;
mod keygen;
mod logs; mod logs;
mod main_event_loop; mod main_event_loop;
mod storage; mod storage;

2
acmed/src/main_event_loop.rs

@ -1,7 +1,7 @@
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;
use crate::error::Error;
use acme_common::error::Error;
use log::{debug, warn}; use log::{debug, warn};
use std::thread; use std::thread;
use std::time::Duration; use std::time::Duration;

4
acmed/src/storage.rs

@ -1,7 +1,7 @@
use crate::acme_proto::b64_encode;
use crate::certificate::Certificate; use crate::certificate::Certificate;
use crate::error::Error;
use crate::hooks::{self, FileStorageHookData}; use crate::hooks::{self, FileStorageHookData};
use acme_common::b64_encode;
use acme_common::error::Error;
use log::trace; use log::trace;
use openssl::pkey::{PKey, Private, Public}; use openssl::pkey::{PKey, Private, Public};
use openssl::x509::X509; use openssl::x509::X509;

Loading…
Cancel
Save