Browse Source

Don't handle ACME root certs

They are volatile, and issued certs are already bundled nowadays.
master
Adrian Heine 4 months ago
parent
commit
4392e65f3f
  1. 32
      src/builder.rs
  2. 16
      src/locator.rs
  3. 7
      src/resources/mod.rs
  4. 11
      src/symbols/acme/cert.rs
  5. 30
      static_files/lets_encrypt_r3.pem

32
src/builder.rs

@ -1,12 +1,11 @@
use crate::command_runner::{SetuidCommandRunner, StdCommandRunner}; use crate::command_runner::{SetuidCommandRunner, StdCommandRunner};
use crate::resources::{ use crate::resources::{
AcmeAccountKey, AcmeChallengesDir, AcmeChallengesNginxSnippet, AcmeRootCert, AcmeUser, Cert,
AcmeAccountKey, AcmeChallengesDir, AcmeChallengesNginxSnippet, AcmeUser, Cert,
CertChain, Cron, Csr, DefaultServer, Dir, File, GitCheckout, Key, KeyAndCertBundle, CertChain, Cron, Csr, DefaultServer, Dir, File, GitCheckout, Key, KeyAndCertBundle,
LoadedDirectory, MariaDbDatabase, MariaDbUser, NpmInstall, Owner, PhpFpmPool, PostgresqlDatabase, LoadedDirectory, MariaDbDatabase, MariaDbUser, NpmInstall, Owner, PhpFpmPool, PostgresqlDatabase,
Resource, ServeCustom, ServePhp, ServeRedir, ServeService, ServeStatic, StoredDirectory, Resource, ServeCustom, ServePhp, ServeRedir, ServeService, ServeStatic, StoredDirectory,
SystemdSocketService, User, UserForDomain, WordpressPlugin, WordpressTranslation, SystemdSocketService, User, UserForDomain, WordpressPlugin, WordpressTranslation,
}; };
use crate::static_files::LETS_ENCRYPT_R3;
use crate::storage::SimpleStorage; use crate::storage::SimpleStorage;
use crate::storage::Storage; use crate::storage::Storage;
use crate::symbols::acme::Cert as CertSymbol; use crate::symbols::acme::Cert as CertSymbol;
@ -99,7 +98,6 @@ impl<D: Clone> ImplementationBuilder<Csr<D>> for DefaultBuilder {
impl<D: Clone> ImplementationBuilder<Cert<D>> for DefaultBuilder { impl<D: Clone> ImplementationBuilder<Cert<D>> for DefaultBuilder {
type Prerequisites = ( type Prerequisites = (
Csr<D>, Csr<D>,
AcmeRootCert,
AcmeAccountKey, AcmeAccountKey,
AcmeChallengesDir, AcmeChallengesDir,
AcmeUser, AcmeUser,
@ -108,7 +106,6 @@ impl<D: Clone> ImplementationBuilder<Cert<D>> for DefaultBuilder {
fn prerequisites(resource: &Cert<D>) -> Self::Prerequisites { fn prerequisites(resource: &Cert<D>) -> Self::Prerequisites {
( (
Csr(resource.0.clone()), Csr(resource.0.clone()),
AcmeRootCert,
AcmeAccountKey, AcmeAccountKey,
AcmeChallengesDir, AcmeChallengesDir,
AcmeUser, AcmeUser,
@ -121,12 +118,11 @@ impl<D: Clone> ImplementationBuilder<Cert<D>> for DefaultBuilder {
fn create( fn create(
resource: &Cert<D>, resource: &Cert<D>,
target: &<Cert<D> as Resource>::Artifact, target: &<Cert<D> as Resource>::Artifact,
(csr, root_cert, account_key, challenges_dir, (user_name, _), _): <Self::Prerequisites as ToArtifact>::Artifact,
(csr, account_key, challenges_dir, (user_name, _), _): <Self::Prerequisites as ToArtifact>::Artifact,
) -> Self::Implementation { ) -> Self::Implementation {
CertSymbol::new( CertSymbol::new(
resource.0.clone(), resource.0.clone(),
SetuidCommandRunner::new(user_name.0), SetuidCommandRunner::new(user_name.0),
root_cert.clone_rc(),
account_key.clone_rc(), account_key.clone_rc(),
challenges_dir.clone_rc(), challenges_dir.clone_rc(),
csr.clone_rc(), csr.clone_rc(),
@ -136,18 +132,18 @@ impl<D: Clone> ImplementationBuilder<Cert<D>> for DefaultBuilder {
} }
impl<D: Clone> ImplementationBuilder<CertChain<D>> for DefaultBuilder { impl<D: Clone> ImplementationBuilder<CertChain<D>> for DefaultBuilder {
type Prerequisites = (Cert<D>, AcmeRootCert);
type Prerequisites = Cert<D>;
fn prerequisites(resource: &CertChain<D>) -> Self::Prerequisites { fn prerequisites(resource: &CertChain<D>) -> Self::Prerequisites {
(Cert(resource.0.clone()), AcmeRootCert)
Cert(resource.0.clone())
} }
type Implementation = ConcatSymbol<[Rc<Path>; 2], Rc<Path>, Rc<Path>>;
type Implementation = ConcatSymbol<[Rc<Path>; 1], Rc<Path>, Rc<Path>>;
fn create( fn create(
_resource: &CertChain<D>, _resource: &CertChain<D>,
target: &<CertChain<D> as Resource>::Artifact, target: &<CertChain<D> as Resource>::Artifact,
(cert, root_cert): <Self::Prerequisites as ToArtifact>::Artifact,
cert: <Self::Prerequisites as ToArtifact>::Artifact,
) -> Self::Implementation { ) -> Self::Implementation {
ConcatSymbol::new([cert.clone_rc(), root_cert.clone_rc()], target.clone_rc())
ConcatSymbol::new([cert.clone_rc()], target.clone_rc())
} }
} }
@ -667,20 +663,6 @@ impl ImplementationBuilder<AcmeAccountKey> for DefaultBuilder {
} }
} }
impl ImplementationBuilder<AcmeRootCert> for DefaultBuilder {
type Prerequisites = ();
fn prerequisites(_resource: &AcmeRootCert) -> Self::Prerequisites {}
type Implementation = FileSymbol<Rc<Path>, &'static str>;
fn create(
_resource: &AcmeRootCert,
target: &<AcmeRootCert as Resource>::Artifact,
(): <Self::Prerequisites as ToArtifact>::Artifact,
) -> Self::Implementation {
FileSymbol::new(target.clone_rc(), LETS_ENCRYPT_R3)
}
}
impl<D> ImplementationBuilder<MariaDbUser<D>> for DefaultBuilder { impl<D> ImplementationBuilder<MariaDbUser<D>> for DefaultBuilder {
type Prerequisites = (); type Prerequisites = ();
fn prerequisites(_resource: &MariaDbUser<D>) -> Self::Prerequisites {} fn prerequisites(_resource: &MariaDbUser<D>) -> Self::Prerequisites {}

16
src/locator.rs

@ -3,7 +3,7 @@ use crate::artifacts::{
UserName as UserNameArtifact, UserName as UserNameArtifact,
}; };
use crate::resources::{ use crate::resources::{
AcmeAccountKey, AcmeChallengesDir, AcmeChallengesNginxSnippet, AcmeRootCert, AcmeUser, Cert,
AcmeAccountKey, AcmeChallengesDir, AcmeChallengesNginxSnippet, AcmeUser, Cert,
CertChain, Cron, Csr, DefaultServer, Dir, File, GitCheckout, Key, KeyAndCertBundle, CertChain, Cron, Csr, DefaultServer, Dir, File, GitCheckout, Key, KeyAndCertBundle,
LoadedDirectory, MariaDbDatabase, MariaDbUser, NpmInstall, Owner, PhpFpmPool, PostgresqlDatabase, LoadedDirectory, MariaDbDatabase, MariaDbUser, NpmInstall, Owner, PhpFpmPool, PostgresqlDatabase,
Resource, ServeCustom, ServePhp, ServeRedir, ServeService, ServeStatic, StoredDirectory, Resource, ServeCustom, ServePhp, ServeRedir, ServeService, ServeStatic, StoredDirectory,
@ -237,20 +237,6 @@ impl<P: Policy> ResourceLocator<AcmeChallengesNginxSnippet> for DefaultLocator<P
} }
} }
impl<P: Policy> ResourceLocator<AcmeRootCert> for DefaultLocator<P> {
type Prerequisites = Dir<Rc<Path>>;
fn locate(
_resource: &AcmeRootCert,
) -> (<AcmeRootCert as Resource>::Artifact, Self::Prerequisites) {
let acme_user = P::acme_user();
let home = P::user_home(acme_user);
(
PathArtifact::from(home.join("lets_encrypt_r3.pem")),
Dir(home),
)
}
}
impl<P: Policy, D: AsRef<str>> ResourceLocator<UserForDomain<D>> for DefaultLocator<P> { impl<P: Policy, D: AsRef<str>> ResourceLocator<UserForDomain<D>> for DefaultLocator<P> {
type Prerequisites = (); type Prerequisites = ();
fn locate( fn locate(

7
src/resources/mod.rs

@ -94,12 +94,6 @@ impl Resource for AcmeUser {
type Artifact = (UserNameArtifact, PathArtifact); type Artifact = (UserNameArtifact, PathArtifact);
} }
#[derive(Debug, Hash, PartialEq, Eq)]
pub struct AcmeRootCert;
impl Resource for AcmeRootCert {
type Artifact = PathArtifact;
}
#[derive(Debug, Hash, PartialEq, Eq)] #[derive(Debug, Hash, PartialEq, Eq)]
pub struct AcmeChallengesDir; pub struct AcmeChallengesDir;
impl Resource for AcmeChallengesDir { impl Resource for AcmeChallengesDir {
@ -348,7 +342,6 @@ default_resources!(
AcmeAccountKey: AcmeAccountKey, AcmeAccountKey: AcmeAccountKey,
AcmeChallengesDir: AcmeChallengesDir, AcmeChallengesDir: AcmeChallengesDir,
AcmeChallengesNginxSnippet: AcmeChallengesNginxSnippet, AcmeChallengesNginxSnippet: AcmeChallengesNginxSnippet,
AcmeRootCert: AcmeRootCert,
AcmeUser: AcmeUser, AcmeUser: AcmeUser,
Cert: Cert<D>, Cert: Cert<D>,
CertChain: CertChain<D>, CertChain: CertChain<D>,

11
src/symbols/acme/cert.rs

@ -12,7 +12,6 @@ use std::path::Path;
pub struct Cert<_C, C, D, P> { pub struct Cert<_C, C, D, P> {
domain: D, domain: D,
command_runner: C, command_runner: C,
root_cert_path: P,
account_key_path: P, account_key_path: P,
challenges_path: P, challenges_path: P,
csr_path: P, csr_path: P,
@ -24,7 +23,6 @@ impl<_C, C, D, P> Cert<_C, C, D, P> {
pub fn new( pub fn new(
domain: D, domain: D,
command_runner: C, command_runner: C,
root_cert_path: P,
account_key_path: P, account_key_path: P,
challenges_path: P, challenges_path: P,
csr_path: P, csr_path: P,
@ -33,7 +31,6 @@ impl<_C, C, D, P> Cert<_C, C, D, P> {
Self { Self {
domain, domain,
command_runner, command_runner,
root_cert_path,
account_key_path, account_key_path,
challenges_path, challenges_path,
csr_path, csr_path,
@ -84,8 +81,12 @@ impl<_C: CommandRunner, C: Borrow<_C>, D: AsRef<str>, P: AsRef<Path>> Symbol for
"openssl", "openssl",
args![ args![
"verify", "verify",
"--untrusted",
self.root_cert_path.as_ref(),
// Since the cert file includes the intermediate,
// this pulls the intermediate into the verification chain
// without trusting it
"-untrusted",
self.cert_path.as_ref(),
// Only the first cert in the cert file is verified
self.cert_path.as_ref(), self.cert_path.as_ref(),
], ],
) )

30
static_files/lets_encrypt_r3.pem

@ -1,30 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAw
WhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
RW5jcnlwdDELMAkGA1UEAxMCUjMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQC7AhUozPaglNMPEuyNVZLD+ILxmaZ6QoinXSaqtSu5xUyxr45r+XXIo9cP
R5QUVTVXjJ6oojkZ9YI8QqlObvU7wy7bjcCwXPNZOOftz2nwWgsbvsCUJCWH+jdx
sxPnHKzhm+/b5DtFUkWWqcFTzjTIUu61ru2P3mBw4qVUq7ZtDpelQDRrK9O8Zutm
NHz6a4uPVymZ+DAXXbpyb/uBxa3Shlg9F8fnCbvxK/eG3MHacV3URuPMrSXBiLxg
Z3Vms/EY96Jc5lP/Ooi2R6X/ExjqmAl3P51T+c8B5fWmcBcUr2Ok/5mzk53cU6cG
/kiFHaFpriV1uxPMUgP17VGhi9sVAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMC
AYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYB
Af8CAQAwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYfr52LFMLGMB8GA1UdIwQYMBaA
FHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw
AoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRw
Oi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQB
gt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCFyk5HPqP3hUSFvNVneLKYY611TR6W
PTNlclQtgaDqw+34IL9fzLdwALduO/ZelN7kIJ+m74uyA+eitRY8kc607TkC53wl
ikfmZW4/RvTZ8M6UK+5UzhK8jCdLuMGYL6KvzXGRSgi3yLgjewQtCPkIVz6D2QQz
CkcheAmCJ8MqyJu5zlzyZMjAvnnAT45tRAxekrsu94sQ4egdRCnbWSDtY7kh+BIm
lJNXoB1lBMEKIq4QDUOXoRgffuDghje1WrG9ML+Hbisq/yFOGwXD9RiX8F6sw6W4
avAuvDszue5L3sz85K+EC4Y/wFVDNvZo4TYXao6Z0f+lQKc0t8DQYzk1OXVu8rp2
yJMC6alLbBfODALZvYH7n7do1AZls4I9d1P4jnkDrQoxB3UqQ9hVl3LEKQ73xF1O
yK5GhDDX8oVfGKF5u+decIsH4YaTw7mP3GFxJSqv3+0lUFJoi5Lc5da149p90Ids
hCExroL1+7mryIkXPeFM5TgO9r0rvZaBFOvV2z0gp35Z0+L4WPlbuEjN/lxPFin+
HlUjr8gRsI3qfJOQFy/9rKIJR0Y/8Omwt/8oTWgy1mdeHmmjk7j1nYsvC9JSQ6Zv
MldlTTKB3zhThV1+XWYp6rjd5JW1zbVWEkLNxE7GJThEUG3szgBVGP7pSWTUTsqX
nLRbwHOoq7hHwg==
-----END CERTIFICATE-----
Loading…
Cancel
Save