Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 43 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ console_error_panic_hook = "0.1.1"
console_log = { version = "1.0" }
criterion = { version = "0.5", features = ["html_reports"] }
generic_log_worker = { path = "crates/generic_log_worker", version = "0.2.0" }
der = "0.7.9"
der = "0.7.10"
ed25519-dalek = { version = "2.1.1", features = ["pem"] }
futures-executor = "0.3.31"
futures-util = "0.3.31"
Expand Down Expand Up @@ -69,6 +69,7 @@ tlog_tiles = { path = "crates/tlog_tiles", version = "0.2.0" }
tokio = { version = "1", features = ["sync"] }
url = "2.2"
worker = "0.5.0"
x509-cert = "0.2.5"
x509-verify = { version = "0.4.4", features = [
"md2",
"md5",
Expand All @@ -86,3 +87,6 @@ x509-verify = { version = "0.4.4", features = [
"pem",
] }
x509_util = { path = "crates/x509_util" }

[patch.crates-io]
der = { git = "https://github.com/lukevalenta/formats", branch = "relative-oid-tag-v0.7.10" }
4 changes: 2 additions & 2 deletions crates/ct_worker/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jsonschema.workspace = true
serde_json.workspace = true
serde.workspace = true
url.workspace = true
x509-verify.workspace = true
x509-cert.workspace = true

[dev-dependencies]
rand = { workspace = true, features = ["small_rng"] }
Expand All @@ -55,7 +55,7 @@ static_ct_api.workspace = true
signed_note.workspace = true
tlog_tiles.workspace = true
worker.workspace = true
x509-verify.workspace = true
x509-cert.workspace = true
x509_util.workspace = true
prometheus.workspace = true

Expand Down
2 changes: 1 addition & 1 deletion crates/ct_worker/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use serde_json::from_str;
use std::env;
use std::fs;
use url::Url;
use x509_verify::x509_cert::Certificate;
use x509_cert::Certificate;

fn main() {
let env = env::var("DEPLOY_ENV").unwrap_or_else(|_| "dev".to_string());
Expand Down
2 changes: 1 addition & 1 deletion crates/ct_worker/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ use std::sync::{LazyLock, OnceLock};
use tlog_tiles::{LookupKey, SequenceMetadata};
#[allow(clippy::wildcard_imports)]
use worker::*;
use x509_cert::Certificate;
use x509_util::CertPool;
use x509_verify::x509_cert::Certificate;

mod batcher_do;
mod frontend_worker;
Expand Down
2 changes: 1 addition & 1 deletion crates/mtc_api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@ sha2.workspace = true
signed_note.workspace = true
thiserror.workspace = true
tlog_tiles.workspace = true
x509-verify.workspace = true
x509-cert.workspace = true
x509_util.workspace = true
34 changes: 19 additions & 15 deletions crates/mtc_api/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
// Copyright (c) 2025 Cloudflare, Inc.
// Licensed under the BSD-3-Clause license found in the LICENSE file or at https://opensource.org/licenses/BSD-3-Clause

mod relative_oid;
mod subtree_cosignature;
use byteorder::{BigEndian, ReadBytesExt};
pub use relative_oid::*;
pub use subtree_cosignature::*;

use anyhow::{anyhow, bail, ensure};
use byteorder::{BigEndian, ReadBytesExt};
use der::{
asn1::BitString,
asn1::{BitString, OctetString},
oid::{db::rfc5280, ObjectIdentifier},
Decode, Encode, Sequence, ValueOrd,
};
Expand All @@ -18,26 +20,24 @@ use sha2::{Digest, Sha256};
use std::{
collections::{BTreeSet, HashMap},
io::Read,
num::ParseIntError,
};
use thiserror::Error;
use tlog_tiles::{
Hash, LeafIndex, LogEntry, PathElem, PendingLogEntry, SequenceMetadata, TlogError,
TlogTilesLogEntry, TlogTilesPendingLogEntry, UnixTimestamp,
};
use x509_util::CertPool;
use x509_verify::{
der::asn1::OctetString,
x509_cert::{
certificate::Version,
ext::{
pkix::{ExtendedKeyUsage, KeyUsage, KeyUsages},
Extension,
},
name::RdnSequence,
time::Validity,
Certificate, TbsCertificate,
use x509_cert::{
certificate::Version,
ext::{
pkix::{ExtendedKeyUsage, KeyUsage, KeyUsages},
Extension,
},
name::RdnSequence,
time::Validity,
Certificate, TbsCertificate,
};
use x509_util::CertPool;

// The OID to use for experimentaion. Eventually, we'll switch to "1.3.6.1.5.5.7.TBD1.TBD2"
// as described in <https://www.ietf.org/archive/id/draft-davidben-tls-merkle-tree-certs-05.html#name-log-ids>.
Expand Down Expand Up @@ -133,8 +133,12 @@ pub enum MtcError {
Der(#[from] der::Error),
#[error(transparent)]
IO(#[from] std::io::Error),
#[error(transparent)]
ParseInt(#[from] ParseIntError),
#[error("empty chain")]
EmptyChain,
#[error("invalid relative OID")]
InvalidRelativeOID,
#[error("unknown entry type")]
UnknownEntryType,
}
Expand Down Expand Up @@ -488,7 +492,7 @@ pub fn validate_chain(
mod tests {
use der::asn1::UtcTime;
use std::time::Duration;
use x509_verify::x509_cert::{time::Time, Certificate};
use x509_cert::{time::Time, Certificate};

use super::*;

Expand Down
68 changes: 68 additions & 0 deletions crates/mtc_api/src/relative_oid.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use crate::MtcError;
use std::str::FromStr;

/// ASN.1 `RELATIVE OID`.
///
/// TODO upstream this to the `der` crate.
pub struct RelativeOid {
ber: Vec<u8>,
}

impl RelativeOid {
fn from_arcs(arcs: &[u32]) -> Result<Self, MtcError> {
let mut ber = Vec::new();
for arc in arcs {
for j in (0..=4).rev() {
#[allow(clippy::cast_possible_truncation)]
let cur = (arc >> (j * 7)) as u8;

if cur != 0 || j == 0 {
let mut to_write = cur & 0x7f; // lower 7 bits

if j != 0 {
to_write |= 0x80;
}
ber.push(to_write);
}
}
}
if ber.len() > 255 {
return Err(MtcError::InvalidRelativeOID);
}
Ok(Self { ber })
}

/// Returns the DER-encoded content bytes.
pub fn as_bytes(&self) -> &[u8] {
&self.ber
}
}

impl FromStr for RelativeOid {
type Err = MtcError;
/// Parse the [`RelativeOid`] from a decimal-dotted string.
fn from_str(s: &str) -> Result<Self, Self::Err> {
let parts = s.split('.');
let mut arcs = Vec::new();
for part in parts {
let i = part.parse::<u32>()?;
arcs.push(i);
}
Self::from_arcs(&arcs)
}
}

#[cfg(test)]
mod tests {

use der::{Any, Encode, Tag};

use super::*;

#[test]
fn encode_decode() {
let relative_oid = RelativeOid::from_str("13335.2").unwrap();
let any = Any::new(Tag::RelativeOid, relative_oid.as_bytes()).unwrap();
assert_eq!(any.to_der().unwrap(), b"\x0d\x03\xe8\x17\x02");
}
}
6 changes: 4 additions & 2 deletions crates/mtc_worker/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ mtc_api.workspace = true
serde_json.workspace = true
serde.workspace = true
url.workspace = true
x509-verify.workspace = true
x509-cert.workspace = true
der.workspace = true

[dev-dependencies]
rand = { workspace = true, features = ["small_rng"] }
Expand All @@ -41,6 +42,7 @@ futures-executor.workspace = true
[dependencies]
base64.workspace = true
config = { path = "./config", package = "mtc_worker_config" }
der.workspace = true
generic_log_worker.workspace = true
ed25519-dalek.workspace = true
futures-util.workspace = true
Expand All @@ -55,7 +57,7 @@ sha2.workspace = true
signed_note.workspace = true
tlog_tiles.workspace = true
worker.workspace = true
x509-verify.workspace = true
x509-cert.workspace = true
x509_util.workspace = true
prometheus.workspace = true
mtc_api.workspace = true
Expand Down
Loading