Skip to content

Commit 1c861b9

Browse files
feat: Add new function c2pa_crypto::cose::signing_time_from_sign1 (#812)
(Will allow me to make some other things private.)
1 parent 79e6014 commit 1c861b9

File tree

3 files changed

+39
-36
lines changed

3 files changed

+39
-36
lines changed

internal/crypto/src/cose/mod.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,17 @@ mod sign;
3333
pub use sign::{sign, sign_async};
3434

3535
mod sign1;
36-
pub use sign1::{cert_chain_from_sign1, parse_cose_sign1, signing_alg_from_sign1};
36+
pub use sign1::{
37+
cert_chain_from_sign1, parse_cose_sign1, signing_alg_from_sign1, signing_time_from_sign1,
38+
signing_time_from_sign1_async,
39+
};
3740

3841
mod sigtst;
3942
pub use sigtst::{
4043
add_sigtst_header, add_sigtst_header_async, cose_countersign_data, parse_and_validate_sigtst,
41-
parse_and_validate_sigtst_async, validate_cose_tst_info, validate_cose_tst_info_async,
42-
TstToken,
44+
parse_and_validate_sigtst_async, TstToken,
4345
};
46+
pub(crate) use sigtst::{validate_cose_tst_info, validate_cose_tst_info_async};
4447

4548
mod time_stamp_storage;
4649
pub use time_stamp_storage::TimeStampStorage;

internal/crypto/src/cose/sign1.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,18 @@
1111
// specific language governing permissions and limitations under
1212
// each license.
1313

14+
use async_generic::async_generic;
1415
use c2pa_status_tracker::{log_item, validation_codes::CLAIM_SIGNATURE_MISMATCH, StatusTracker};
1516
use ciborium::value::Value;
1617
use coset::{
1718
iana::{self, Algorithm, EnumI64},
1819
CoseSign1, Label, RegisteredLabelWithPrivate, TaggedCborSerializable,
1920
};
2021

21-
use crate::{cose::CoseError, SigningAlg};
22+
use crate::{
23+
cose::{validate_cose_tst_info, validate_cose_tst_info_async, CoseError},
24+
SigningAlg,
25+
};
2226

2327
/// Parse a byte slice as a COSE Sign1 data structure.
2428
///
@@ -159,3 +163,26 @@ fn cert_chain_from_cbor_value(value: Value) -> Result<Vec<Vec<u8>>, CoseError> {
159163
_ => Err(CoseError::MissingSigningCertificateChain),
160164
}
161165
}
166+
167+
/// Return the time of signing for this signature.
168+
///
169+
/// Should not be used for certificate validation.
170+
#[async_generic]
171+
pub fn signing_time_from_sign1(
172+
sign1: &coset::CoseSign1,
173+
data: &[u8],
174+
) -> Option<chrono::DateTime<chrono::Utc>> {
175+
// get timestamp info if available
176+
177+
let time_stamp_info = if _sync {
178+
validate_cose_tst_info(sign1, data)
179+
} else {
180+
validate_cose_tst_info_async(sign1, data).await
181+
};
182+
183+
if let Ok(tst_info) = time_stamp_info {
184+
Some(tst_info.gen_time.into())
185+
} else {
186+
None
187+
}
188+
}

sdk/src/cose_validator.rs

Lines changed: 5 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ use std::io::Cursor;
1616
use async_generic::async_generic;
1717
use c2pa_crypto::{
1818
cose::{
19-
cert_chain_from_sign1, parse_cose_sign1, signing_alg_from_sign1, validate_cose_tst_info,
20-
validate_cose_tst_info_async, CertificateTrustPolicy, Verifier,
19+
cert_chain_from_sign1, parse_cose_sign1, signing_alg_from_sign1, signing_time_from_sign1,
20+
signing_time_from_sign1_async, CertificateTrustPolicy, Verifier,
2121
},
2222
SigningAlg, ValidationInfo,
2323
};
@@ -75,27 +75,6 @@ fn dump_cert_chain(certs: &[Vec<u8>]) -> Result<Vec<u8>> {
7575
Ok(out_buf)
7676
}
7777

78-
// Note: this function is only used to get the display string and not for cert validation.
79-
#[async_generic]
80-
fn get_signing_time(
81-
sign1: &coset::CoseSign1,
82-
data: &[u8],
83-
) -> Option<chrono::DateTime<chrono::Utc>> {
84-
// get timestamp info if available
85-
86-
let time_stamp_info = if _sync {
87-
validate_cose_tst_info(sign1, data)
88-
} else {
89-
validate_cose_tst_info_async(sign1, data).await
90-
};
91-
92-
if let Ok(tst_info) = time_stamp_info {
93-
Some(gt_to_datetime(tst_info.gen_time))
94-
} else {
95-
None
96-
}
97-
}
98-
9978
fn extract_subject_from_cert(cert: &X509Certificate) -> Result<String> {
10079
cert.subject()
10180
.iter_organization()
@@ -130,9 +109,9 @@ pub(crate) fn get_signing_info(
130109
Ok(der_bytes) => {
131110
if let Ok((_rem, signcert)) = X509Certificate::from_der(&der_bytes) {
132111
date = if _sync {
133-
get_signing_time(&sign1, data)
112+
signing_time_from_sign1(&sign1, data)
134113
} else {
135-
get_signing_time_async(&sign1, data).await
114+
signing_time_from_sign1_async(&sign1, data).await
136115
};
137116
issuer_org = extract_subject_from_cert(&signcert).ok();
138117
cert_serial_number = Some(extract_serial_from_cert(&signcert));
@@ -168,12 +147,6 @@ pub(crate) fn get_signing_info(
168147
}
169148
}
170149

171-
fn gt_to_datetime(
172-
gt: x509_certificate::asn1time::GeneralizedTime,
173-
) -> chrono::DateTime<chrono::Utc> {
174-
gt.into()
175-
}
176-
177150
#[allow(unused_imports)]
178151
#[allow(clippy::unwrap_used)]
179152
#[cfg(feature = "openssl_sign")]
@@ -207,7 +180,7 @@ pub mod tests {
207180

208181
let cose_sign1 = parse_cose_sign1(&cose_bytes, &claim_bytes, &mut validation_log).unwrap();
209182

210-
let signing_time = get_signing_time(&cose_sign1, &claim_bytes);
183+
let signing_time = signing_time_from_sign1(&cose_sign1, &claim_bytes);
211184

212185
assert_eq!(signing_time, None);
213186
}

0 commit comments

Comments
 (0)