Skip to content

Commit 80d2727

Browse files
committed
Detect duplicates by hash, not serial
1 parent 57f10a7 commit 80d2727

5 files changed

Lines changed: 50 additions & 11 deletions

File tree

Cargo.lock

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

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ clap = "4.5"
2222
const_format = "0.2.34"
2323
futures = { version = "0.3", features = ["compat"] }
2424
h2 = "0.4"
25+
hex = "0.4"
2526
kube-runtime = { version = "1.0", features = ["unstable-runtime-stream-control"] }
2627
ldap3 = { version = "0.11", default-features = false, features = ["gssapi", "tls"] }
2728
libc = "0.2"

rust/truststore-merger/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ stackable-secret-operator-utils = { path = "../utils" }
1313

1414
anyhow.workspace = true
1515
clap = { workspace = true, features = ["derive"] }
16+
hex.workspace = true
1617
openssl.workspace = true
1718
tracing.workspace = true
1819
tracing-subscriber = { workspace = true, features = ["env-filter"] }
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
use anyhow::Context;
2+
use openssl::{
3+
hash::{DigestBytes, MessageDigest},
4+
string::OpensslString,
5+
x509::X509,
6+
};
7+
8+
pub trait CertExt {
9+
fn serial_as_hex(&self) -> anyhow::Result<OpensslString>;
10+
fn sha256_digest(&self) -> anyhow::Result<DigestBytes>;
11+
}
12+
13+
impl CertExt for X509 {
14+
fn serial_as_hex(&self) -> anyhow::Result<OpensslString> {
15+
self.serial_number()
16+
.to_bn()
17+
.context("failed to get certificate serial number as BigNumber")?
18+
.to_hex_str()
19+
.context("failed to convert certificate serial number to hex string")
20+
}
21+
22+
fn sha256_digest(&self) -> anyhow::Result<DigestBytes> {
23+
self.digest(MessageDigest::sha256())
24+
.context("failed to get certificate digest")
25+
}
26+
}

rust/truststore-merger/src/main.rs

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
use std::{collections::HashMap, fs};
22

33
use anyhow::{Context, ensure};
4+
use cert_ext::CertExt;
45
use clap::Parser;
56
use cli_args::Cli;
67
use openssl::x509::X509;
78
use stackable_secret_operator_utils::pkcs12::pkcs12_truststore;
89
use tracing::{info, level_filters::LevelFilter, warn};
910

11+
mod cert_ext;
1012
mod cli_args;
1113
mod parsers;
1214

@@ -44,30 +46,32 @@ pub fn main() -> anyhow::Result<()> {
4446
let mut certificates = HashMap::<Vec<u8>, X509>::new();
4547
for (source, certificates_list) in certificate_sources.into_iter() {
4648
for certificate in certificates_list {
47-
let serial_bn = certificate
48-
.serial_number()
49-
.to_bn()
50-
.context("failed to get certificate serial number as BigNumber")?;
51-
let serial = serial_bn.to_vec();
52-
if let Some(existing) = certificates.get(&serial) {
49+
let sha256 = certificate.sha256_digest()?;
50+
51+
if let Some(existing) = certificates.get(&*sha256) {
5352
warn!(
54-
serial = ?serial_bn.to_hex_str(),
5553
?source,
54+
sha25 = hex::encode(sha256),
55+
existing.not_before = ?existing.not_before(),
5656
existing.not_after = ?existing.not_after(),
5757
existing.subject = ?existing.subject_name(),
58+
existing.serial = ?existing.serial_as_hex()?,
59+
new.not_before = ?certificate.not_before(),
5860
new.not_after = ?certificate.not_after(),
5961
new.subject = ?certificate.subject_name(),
60-
"Skipped certificate as it was already added",
62+
new.serial = ?existing.serial_as_hex()?,
63+
"Skipped certificate as a cert with the same SHA256 hash was already added",
6164
);
6265
} else {
6366
info!(
64-
serial = ?serial_bn.to_hex_str(),
65-
not_after = ?certificate.not_after(),
6667
subject = ?certificate.subject_name(),
68+
not_before = ?certificate.not_before(),
69+
not_after = ?certificate.not_after(),
70+
serial = ?certificate.serial_as_hex()?,
6771
?source,
6872
"Added certificate"
6973
);
70-
certificates.insert(serial, certificate);
74+
certificates.insert(sha256.to_vec(), certificate);
7175
}
7276
}
7377
}

0 commit comments

Comments
 (0)