Skip to content

Commit bacab4f

Browse files
refactor(crypto): support independent backends and backend-free CA import
Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com>
1 parent 11fdc1e commit bacab4f

63 files changed

Lines changed: 5285 additions & 525 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎Cargo.lock‎

Lines changed: 143 additions & 47 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Cargo.toml‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ license = "Apache-2.0"
1313
repository = "https://github.com/NVIDIA/OpenShell"
1414

1515
[workspace.dependencies]
16+
# Product backend selection. Consumer crates inherit this choice.
17+
openshell-crypto = { path = "crates/openshell-crypto", default-features = false, features = ["aws-lc"] }
1618
# Async runtime
1719
tokio = { version = "1.43", features = ["full"] }
1820

@@ -40,7 +42,7 @@ h2 = "0.4"
4042
tokio-rustls = { version = "0.26", default-features = false, features = ["logging", "tls12"] }
4143
rustls = { version = "0.23", default-features = false, features = ["std", "logging", "tls12"] }
4244
rustls-pemfile = "2"
43-
rcgen = { version = "0.13", default-features = false, features = ["crypto", "pem", "x509-parser"] }
45+
rcgen = { version = "0.14.10", default-features = false, features = ["pem"] }
4446
webpki-roots = "1"
4547
rustls-native-certs = "0.8"
4648

‎architecture/build.md‎

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,21 @@ development shells provide static AWS-LC libraries.
3535
First-party crypto selection lives in `openshell-crypto`: backend-neutral
3636
primitive traits and protocol adapters preserve existing TLS, PKI, JWT, and
3737
credential-storage behavior. Application crates enable integration features on
38-
that crate instead of naming a backend. Process-default initialization preserves
39-
existing embedder providers; context capability reporting does not attest those
40-
globals or dependency-owned crypto. OpenSSL and strict FIPS operation are separate
41-
follow-up work. The crate README defines extension and coverage boundaries.
38+
that crate instead of naming a backend. The workspace selects the default AWS-LC
39+
feature centrally. Backend-owned signing keys support fallible export and import;
40+
rcgen only adapts certificate encoding. Explicit context selection controls
41+
first-party TLS configuration even after Rustls global initialization. Without
42+
explicit selection, builders preserve embedder defaults. Capability reporting
43+
does not attest globals or dependency-owned crypto. This boundary prepares a
44+
system-OpenSSL backend; its proof of concept, dynamic-link packaging, and strict
45+
FIPS operation are separate follow-up work. The crate README defines extension and coverage boundaries.
4246
Digest operations propagate backend failures through JWT and credential key-ID
4347
generation rather than requiring infallible provider operations.
48+
Persisted CA metadata is parsed by `openshell-crypto` using `x509-parser`
49+
without verification features. rcgen's parser feature remains disabled because
50+
it couples parsing to built-in CSR verification backends. Backend keys implement
51+
rcgen's signing trait directly; the proxy checks certificate/key matching through
52+
the selected TLS backend and retains the original CA bytes in certificate chains.
4453

4554
SQLx uses AWS-LC with native certificate roots.
4655
The server enables

‎crates/openshell-binary-identity/Cargo.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ repository.workspace = true
1212

1313
[dependencies]
1414
openshell-isolation-interface = { path = "../openshell-isolation-interface" }
15-
sha2 = { workspace = true }
15+
openshell-crypto = { workspace = true }
1616

1717
[lints]
1818
workspace = true

‎crates/openshell-binary-identity/src/lib.rs‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -329,11 +329,11 @@ fn executable_path(pid: u32) -> Result<std::path::PathBuf, ResolveError> {
329329

330330
#[cfg(target_os = "linux")]
331331
fn hash_executable(pid: u32, executable: &mut std::fs::File) -> Result<Sha256Digest, ResolveError> {
332-
use sha2::{Digest as _, Sha256};
333332
use std::io::Read as _;
334333

335334
let path = format!("/proc/{pid}/exe");
336-
let mut digest = Sha256::new();
335+
let crypto_error = |error| ResolveError::Failed(format!("hash executable: {error}"));
336+
let mut digest = openshell_crypto::sha256_digest().map_err(crypto_error)?;
337337
let mut buffer = [0_u8; 8 * 1024];
338338
loop {
339339
let length = executable
@@ -342,9 +342,11 @@ fn hash_executable(pid: u32, executable: &mut std::fs::File) -> Result<Sha256Dig
342342
if length == 0 {
343343
break;
344344
}
345-
digest.update(&buffer[..length]);
345+
digest.update(&buffer[..length]).map_err(crypto_error)?;
346346
}
347-
format!("{:x}", digest.finalize()).parse()
347+
let bytes = digest.finish().map_err(crypto_error)?;
348+
let hex: String = bytes.iter().map(|byte| format!("{byte:02x}")).collect();
349+
hex.parse()
348350
}
349351

350352
#[cfg(target_os = "linux")]

‎crates/openshell-bootstrap/Cargo.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ repository.workspace = true
1010
rust-version.workspace = true
1111

1212
[dependencies]
13-
openshell-crypto = { path = "../openshell-crypto" }
13+
openshell-crypto = { workspace = true }
1414
openshell-core = { path = "../openshell-core", default-features = false }
1515
bytes = { workspace = true }
1616
miette = { workspace = true }

‎crates/openshell-bootstrap/src/jwt.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ pub fn generate_jwt_key() -> Result<JwtKeyMaterial> {
4040
let keypair = openshell_crypto::pki::generate_jwt_keypair()
4141
.into_diagnostic()
4242
.wrap_err("failed to generate Ed25519 JWT signing key")?;
43-
let signing_key_pem = keypair.serialize_pem();
43+
let signing_key_pem = keypair.serialize_pem().into_diagnostic()?;
4444
let public_key_pem = keypair.public_key_pem();
4545
let kid = kid_from_public_key_der(&keypair.public_key_der())?;
4646
Ok(JwtKeyMaterial {

‎crates/openshell-bootstrap/src/pki.rs‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use crate::jwt::{JwtKeyMaterial, generate_jwt_key};
55
use miette::{IntoDiagnostic, Result, WrapErr};
66
use rcgen::{
7-
BasicConstraints, CertificateParams, DnType, Ia5String, IsCa, KeyUsagePurpose, SanType,
7+
BasicConstraints, CertificateParams, DnType, IsCa, KeyUsagePurpose, SanType, string::Ia5String,
88
};
99
use std::net::IpAddr;
1010

@@ -121,11 +121,11 @@ pub fn generate_pki(extra_sans: &[String]) -> Result<PkiBundle> {
121121

122122
Ok(PkiBundle {
123123
ca_cert_pem: ca_cert.pem(),
124-
ca_key_pem: ca_key.serialize_pem(),
124+
ca_key_pem: ca_key.serialize_pem().into_diagnostic()?,
125125
server_cert_pem: server_cert.pem(),
126-
server_key_pem: server_key.serialize_pem(),
126+
server_key_pem: server_key.serialize_pem().into_diagnostic()?,
127127
client_cert_pem: client_cert.pem(),
128-
client_key_pem: client_key.serialize_pem(),
128+
client_key_pem: client_key.serialize_pem().into_diagnostic()?,
129129
jwt_signing_key_pem,
130130
jwt_public_key_pem,
131131
jwt_key_id,

‎crates/openshell-cli/Cargo.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ name = "openshell"
1515
path = "src/main.rs"
1616

1717
[dependencies]
18-
openshell-crypto = { path = "../openshell-crypto", features = ["tls-hyper"] }
18+
openshell-crypto = { workspace = true, features = ["tls-hyper"] }
1919
openshell-bootstrap = { path = "../openshell-bootstrap" }
2020
openshell-core = { path = "../openshell-core", default-features = false }
2121
openshell-policy = { path = "../openshell-policy" }

‎crates/openshell-cli/src/tls.rs‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ pub fn build_rustls_config(materials: &TlsMaterials) -> Result<rustls::ClientCon
215215
.into_diagnostic()?;
216216
let key = load_private_key(&materials.key)?;
217217

218-
rustls::ClientConfig::builder()
218+
openshell_crypto::tls::client_builder()
219219
.with_root_certificates(roots)
220220
.with_client_auth_cert(cert_chain, key)
221221
.into_diagnostic()
@@ -284,7 +284,7 @@ impl ServerCertVerifier for InsecureServerCertVerifier {
284284
}
285285

286286
fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
287-
openshell_crypto::tls::provider()
287+
openshell_crypto::tls::configuration_provider()
288288
.signature_verification_algorithms
289289
.supported_schemes()
290290
}
@@ -324,7 +324,7 @@ impl tower::Service<hyper::Uri> for InsecureTlsConnector {
324324
}
325325

326326
pub fn build_insecure_rustls_config() -> Result<rustls::ClientConfig> {
327-
let config = rustls::ClientConfig::builder()
327+
let config = openshell_crypto::tls::client_builder()
328328
.dangerous()
329329
.with_custom_certificate_verifier(std::sync::Arc::new(InsecureServerCertVerifier))
330330
.with_no_client_auth();

0 commit comments

Comments
 (0)