Browse Source

Prepare the code for an OpenSSL replacement

The part of code that are specific to OpenSSL are now included only if
the openssl feature is activated. The generic parts of code included in
OpenSSL specific files has been moved out.
pull/39/head
Rodolphe Breard 4 years ago
parent
commit
b75b8ba9f7
  1. 15
      acme_common/src/crypto.rs
  2. 24
      acme_common/src/crypto/openssl_certificate.rs
  3. 2
      acme_common/src/error.rs
  4. 5
      acmed/src/http.rs
  5. 2
      tacd/src/main.rs

15
acme_common/src/crypto.rs

@ -4,12 +4,22 @@ use std::str::FromStr;
mod jws_signature_algorithm; mod jws_signature_algorithm;
mod key_type; mod key_type;
#[cfg(feature = "openssl_dyn")]
mod openssl_certificate; mod openssl_certificate;
#[cfg(feature = "openssl_dyn")]
mod openssl_hash; mod openssl_hash;
#[cfg(feature = "openssl_dyn")]
mod openssl_keys; mod openssl_keys;
#[cfg(feature = "openssl_dyn")]
mod openssl_subject_attribute; mod openssl_subject_attribute;
#[cfg(feature = "openssl_dyn")]
mod openssl_version; mod openssl_version;
const APP_ORG: &str = "ACMEd";
const APP_NAME: &str = "ACMEd";
const X509_VERSION: i32 = 0x02;
const CRT_SERIAL_NB_BITS: i32 = 32;
const INVALID_EXT_MSG: &str = "invalid acmeIdentifier extension";
pub const CRT_NB_DAYS_VALIDITY: u32 = 7; pub const CRT_NB_DAYS_VALIDITY: u32 = 7;
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
@ -70,8 +80,13 @@ impl fmt::Display for BaseHashFunction {
pub use jws_signature_algorithm::JwsSignatureAlgorithm; pub use jws_signature_algorithm::JwsSignatureAlgorithm;
pub use key_type::KeyType; pub use key_type::KeyType;
#[cfg(feature = "openssl_dyn")]
pub use openssl_certificate::{Csr, X509Certificate}; pub use openssl_certificate::{Csr, X509Certificate};
#[cfg(feature = "openssl_dyn")]
pub use openssl_hash::HashFunction; pub use openssl_hash::HashFunction;
#[cfg(feature = "openssl_dyn")]
pub use openssl_keys::{gen_keypair, KeyPair}; pub use openssl_keys::{gen_keypair, KeyPair};
#[cfg(feature = "openssl_dyn")]
pub use openssl_subject_attribute::SubjectAttribute; pub use openssl_subject_attribute::SubjectAttribute;
#[cfg(feature = "openssl_dyn")]
pub use openssl_version::{get_lib_name, get_lib_version}; pub use openssl_version::{get_lib_name, get_lib_version};

24
acme_common/src/crypto/openssl_certificate.rs

@ -12,12 +12,6 @@ use std::collections::{HashMap, HashSet};
use std::net::IpAddr; use std::net::IpAddr;
use std::time::{Duration, SystemTime, UNIX_EPOCH}; use std::time::{Duration, SystemTime, UNIX_EPOCH};
const APP_ORG: &str = "ACMEd";
const APP_NAME: &str = "ACMEd";
const X509_VERSION: i32 = 0x02;
const CRT_SERIAL_NB_BITS: i32 = 32;
const INVALID_EXT_MSG: &str = "invalid acmeIdentifier extension";
fn get_digest(digest: HashFunction, key_pair: &KeyPair) -> MessageDigest { fn get_digest(digest: HashFunction, key_pair: &KeyPair) -> MessageDigest {
#[cfg(not(any(ed25519, ed448)))] #[cfg(not(any(ed25519, ed448)))]
let digest = digest.native_digest(); let digest = digest.native_digest();
@ -162,16 +156,16 @@ fn gen_certificate(
acme_ext: &str, acme_ext: &str,
) -> Result<X509, Error> { ) -> Result<X509, Error> {
let mut x509_name = X509NameBuilder::new()?; let mut x509_name = X509NameBuilder::new()?;
x509_name.append_entry_by_text("O", APP_ORG)?;
let ca_name = format!("{} TLS-ALPN-01 Authority", APP_NAME);
x509_name.append_entry_by_text("O", super::APP_ORG)?;
let ca_name = format!("{} TLS-ALPN-01 Authority", super::APP_NAME);
x509_name.append_entry_by_text("CN", &ca_name)?; x509_name.append_entry_by_text("CN", &ca_name)?;
let x509_name = x509_name.build(); let x509_name = x509_name.build();
let mut builder = X509Builder::new()?; let mut builder = X509Builder::new()?;
builder.set_version(X509_VERSION)?;
builder.set_version(super::X509_VERSION)?;
let serial_number = { let serial_number = {
let mut serial = BigNum::new()?; let mut serial = BigNum::new()?;
serial.rand(CRT_SERIAL_NB_BITS - 1, MsbOption::MAYBE_ZERO, false)?;
serial.rand(super::CRT_SERIAL_NB_BITS - 1, MsbOption::MAYBE_ZERO, false)?;
serial.to_asn1_integer()? serial.to_asn1_integer()?
}; };
builder.set_serial_number(&serial_number)?; builder.set_serial_number(&serial_number)?;
@ -191,16 +185,16 @@ fn gen_certificate(
if !acme_ext.is_empty() { if !acme_ext.is_empty() {
let ctx = builder.x509v3_context(None, None); let ctx = builder.x509v3_context(None, None);
let mut v: Vec<&str> = acme_ext.split('=').collect(); let mut v: Vec<&str> = acme_ext.split('=').collect();
let value = v.pop().ok_or_else(|| Error::from(INVALID_EXT_MSG))?;
let acme_ext_name = v.pop().ok_or_else(|| Error::from(INVALID_EXT_MSG))?;
let value = v.pop().ok_or_else(|| Error::from(super::INVALID_EXT_MSG))?;
let acme_ext_name = v.pop().ok_or_else(|| Error::from(super::INVALID_EXT_MSG))?;
if !v.is_empty() { if !v.is_empty() {
return Err(Error::from(INVALID_EXT_MSG));
return Err(Error::from(super::INVALID_EXT_MSG));
} }
let acme_ext = X509Extension::new(None, Some(&ctx), &acme_ext_name, &value) let acme_ext = X509Extension::new(None, Some(&ctx), &acme_ext_name, &value)
.map_err(|_| Error::from(INVALID_EXT_MSG))?;
.map_err(|_| Error::from(super::INVALID_EXT_MSG))?;
builder builder
.append_extension(acme_ext) .append_extension(acme_ext)
.map_err(|_| Error::from(INVALID_EXT_MSG))?;
.map_err(|_| Error::from(super::INVALID_EXT_MSG))?;
} }
builder.sign(&key_pair.inner_key, *digest)?; builder.sign(&key_pair.inner_key, *digest)?;

2
acme_common/src/error.rs

@ -111,12 +111,14 @@ impl From<handlebars::TemplateRenderError> for Error {
} }
} }
#[cfg(feature = "openssl_dyn")]
impl From<native_tls::Error> for Error { impl From<native_tls::Error> for Error {
fn from(error: native_tls::Error) -> Self { fn from(error: native_tls::Error) -> Self {
format!("{}", error).into() format!("{}", error).into()
} }
} }
#[cfg(feature = "openssl_dyn")]
impl From<openssl::error::ErrorStack> for Error { impl From<openssl::error::ErrorStack> for Error {
fn from(error: openssl::error::ErrorStack) -> Self { fn from(error: openssl::error::ErrorStack) -> Self {
format!("{}", error).into() format!("{}", error).into()

5
acmed/src/http.rs

@ -1,9 +1,11 @@
use crate::acme_proto::structs::{AcmeError, HttpApiError}; use crate::acme_proto::structs::{AcmeError, HttpApiError};
use crate::endpoint::Endpoint; use crate::endpoint::Endpoint;
#[cfg(feature = "openssl_dyn")]
use acme_common::crypto::X509Certificate; use acme_common::crypto::X509Certificate;
use acme_common::error::Error; use acme_common::error::Error;
use attohttpc::{charsets, header, Response, Session}; use attohttpc::{charsets, header, Response, Session};
use std::fs::File; use std::fs::File;
#[cfg(feature = "openssl_dyn")]
use std::io::prelude::*; use std::io::prelude::*;
use std::{thread, time}; use std::{thread, time};
@ -157,11 +159,14 @@ fn get_session(root_certs: &[String]) -> Result<Session, Error> {
session.try_header(header::ACCEPT_LANGUAGE, "en-US,en;q=0.5")?; session.try_header(header::ACCEPT_LANGUAGE, "en-US,en;q=0.5")?;
session.try_header(header::USER_AGENT, &useragent)?; session.try_header(header::USER_AGENT, &useragent)?;
for crt_file in root_certs.iter() { for crt_file in root_certs.iter() {
#[cfg(feature = "openssl_dyn")]
{
let mut buff = Vec::new(); let mut buff = Vec::new();
File::open(crt_file)?.read_to_end(&mut buff)?; File::open(crt_file)?.read_to_end(&mut buff)?;
let crt = X509Certificate::from_pem_native(&buff)?; let crt = X509Certificate::from_pem_native(&buff)?;
session.add_root_certificate(crt); session.add_root_certificate(crt);
} }
}
Ok(session) Ok(session)
} }

2
tacd/src/main.rs

@ -1,5 +1,7 @@
#[cfg(feature = "openssl_dyn")]
mod openssl_server; mod openssl_server;
#[cfg(feature = "openssl_dyn")]
use crate::openssl_server::start as server_start; use crate::openssl_server::start as server_start;
use acme_common::crypto::{get_lib_name, get_lib_version, HashFunction, KeyType, X509Certificate}; use acme_common::crypto::{get_lib_name, get_lib_version, HashFunction, KeyType, X509Certificate};
use acme_common::error::Error; use acme_common::error::Error;

Loading…
Cancel
Save