Skip to content

Commit

Permalink
feat: Add TLS certificate util crate (#736)
Browse files Browse the repository at this point in the history
* Initial commit

* Use certs crate

* Add first rough plans

* Add ED25519 signing key support

* Add RSA signing key

* Finish initial CA creation, slowly start to refine code

* Start to add K8s traits

* Add SecretReference

Copied from https://github.com/stackabletech/secret-operator/blob/main/rust/crd-utils/src/lib.rs

* Add more errors, add more helper traits

* Make certificate authority generic over the signing key

* Start to add leaf certificate generation

* Add more interop code, clean up trait impls and errors

* Slightly simplify wrapper types and trait impls

* Start to work through initial round of TODOs

* Remove unwraps, add error handling

* Move k8s code into own file

* Remove initial manager code

This code will be re-introduced in a follow-up PR.

* Add a few more (doc) comments

* Add more doc comments for constants

* Apply suggestions

Co-authored-by: Nick <[email protected]>

* Add fixups for code suggestions

* Change default RSA bit size

* Add RSA bit size guard

* Add doc comments, add leaf cert helper functions

* Add doc comments for CertificatePairExt trait

* Rename rustls feature to webhook

* Fix doc comment reference

* Add secret type guard

* Remove unused trait function

* Initial commit

* Add const for Kubernetes TLS secret type

* Turn the RSA bit size into an enum

* Use enum discriminants

* Remove hashset of serial numbers

* Remove customizable line endings

* Adjust root CA subject

* Remove TLS mount related code

* Add error handling for cert generation

* Adjust conditional imports

* Apply suggestion

Co-authored-by: Natalie Klestrup Röijezon <[email protected]>

* Revert "Apply suggestion"

This reverts commit a0182d7.

* Add from_secret and from_secret_ref functions to struct directly

* Remove unneeded newlines

* Add doc comment to SecretReference

* Rename to KeySize, add bits method

* Slightly adjust doc comment for SecretReference

* Rename Keypair trait to CertificateKeypair

* Remove KeySize enum

* Move key size into constant

* Use with_context to avoid unnecessary allocation when Ok

* Adjust error message to reflect underlying error

* Add doc comment to clarify paramter usage

---------

Co-authored-by: Nick <[email protected]>
Co-authored-by: Natalie Klestrup Röijezon <[email protected]>
  • Loading branch information
3 people authored Mar 15, 2024
1 parent 8092fd4 commit 8664a3d
Show file tree
Hide file tree
Showing 17 changed files with 971 additions and 217 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@ Cargo.lock
.idea/
*.iws
*.iml

# TLS certificates for testing
*.crt
*.key
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,4 @@ rstest = "0.18.1"
tempfile = "3.7.1"

[workspace]
members = ["stackable-operator-derive", "stackable-webhook"]
members = ["stackable-certs", "stackable-operator-derive", "stackable-webhook"]
1 change: 1 addition & 0 deletions src/commons/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ pub mod product_image_selection;
pub mod rbac;
pub mod resources;
pub mod s3;
pub mod secret;
pub mod secret_class;
45 changes: 45 additions & 0 deletions src/commons/secret.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use std::fmt::Display;

use k8s_openapi::api::core::v1::Secret;
use kube::runtime::reflector::ObjectRef;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

/// [`SecretReference`] represents a Kubernetes [`Secret`] reference.
///
/// In order to use this struct, the following two requirements must be met:
///
/// - Must only be used in cluster-scoped objects
/// - Namespaced objects must not be able to define cross-namespace secret
/// references
///
/// This struct is a redefinition of the one provided by k8s-openapi to make
/// name and namespace mandatory.
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "camelCase")]
pub struct SecretReference {
/// Namespace of the Secret being referred to.
pub namespace: String,

/// Name of the Secret being referred to.
pub name: String,
}

// Use ObjectRef for logging/errors
impl Display for SecretReference {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
ObjectRef::<Secret>::from(self).fmt(f)
}
}

impl From<SecretReference> for ObjectRef<Secret> {
fn from(val: SecretReference) -> Self {
ObjectRef::<Secret>::from(&val)
}
}

impl From<&SecretReference> for ObjectRef<Secret> {
fn from(val: &SecretReference) -> Self {
ObjectRef::<Secret>::new(&val.name).within(&val.namespace)
}
}
37 changes: 37 additions & 0 deletions stackable-certs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
[package]
name = "stackable-certs"
version.workspace = true
authors.workspace = true
license.workspace = true
edition.workspace = true
repository.workspace = true

[features]
default = []
rustls = ["dep:tokio-rustls", "dep:rustls-pemfile"]

[dependencies]
stackable-operator = { path = ".." }

const-oid = "0.9.6"
ecdsa = { version = "0.16.9", features = ["digest", "pem"] }
p256 = { version = "0.13.2", features = ["ecdsa"] }
k8s-openapi = { version = "0.21.0", default-features = false, features = [
"v1_28",
] }
kube = { version = "0.88.1", default-features = false, features = [
"client",
"rustls-tls",
] }
tracing = "0.1.40"
tokio = { version = "1.29.1", features = ["fs"] }
tokio-rustls = { version = "0.25.0", optional = true }
rand = "0.8.5"
rand_core = "0.6.4"
rsa = { version = "0.9.6", features = ["sha2"] }
rustls-pemfile = { version = "2.0.0", optional = true }
sha2 = { version = "0.10.8", features = ["oid"] }
signature = "2.2.0"
snafu = "0.8.0"
x509-cert = { version = "0.2.5", features = ["builder"] }
zeroize = "1.7.0"
5 changes: 5 additions & 0 deletions stackable-certs/src/ca/consts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/// The default CA validity time span of one hour (3600 seconds).
pub const DEFAULT_CA_VALIDITY_SECONDS: u64 = 3600;

/// The root CA subject name containing only the common name.
pub const ROOT_CA_SUBJECT: &str = "CN=Stackable Data Platform Internal CA";
Loading

0 comments on commit 8664a3d

Please sign in to comment.