Skip to content

Commit ca6efad

Browse files
authored
Merge branch 'main' into colmurph/update-wasi-test-nightly
2 parents 1abb8fb + 06155eb commit ca6efad

File tree

11 files changed

+128
-51
lines changed

11 files changed

+128
-51
lines changed

Cargo.lock

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

cli/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ wasi = "0.14"
5656
wstd = "0.5"
5757

5858
[dev-dependencies]
59-
mockall = "0.13.0"
59+
mockall = "0.14.0"
6060

6161
[target.'cfg(not(target_os = "wasi"))'.dev-dependencies]
6262
assert_cmd = "2.0.14"

sdk/Cargo.toml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -156,12 +156,12 @@ pkcs8 = "0.10.2"
156156
png_pong = "0.9.1"
157157
quick-xml = "0.38.3"
158158
rand = "0.8.5"
159-
rand_chacha = "0.3.1"
159+
rand_chacha = { version = "0.9.0", features = ["os_rng"] }
160160
range-set = "0.0.11"
161-
rasn = "0.26.0"
162-
rasn-cms = "0.26.0"
163-
rasn-ocsp = "0.26.0"
164-
rasn-pkix = "0.26.0"
161+
rasn = "0.28.2"
162+
rasn-cms = "0.28.2"
163+
rasn-ocsp = "0.28.2"
164+
rasn-pkix = "0.28.2"
165165
regex = "1.11"
166166
riff = "2.0.0"
167167
rsa = { version = "0.9.10", features = ["pem", "sha2", "std"], optional = true }
@@ -289,7 +289,7 @@ glob = "0.3.1"
289289
hex-literal = "1.0.0"
290290
jumbf = "0.4.0"
291291
c2pa_macros = { path = "../macros" }
292-
mockall = "0.13.1"
292+
mockall = "0.14.0"
293293

294294
[target.'cfg(all(target_arch = "wasm32", not(target_os = "wasi")))'.dev-dependencies]
295295
wasm-bindgen-test = "0.3.55"

sdk/src/builder.rs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1259,7 +1259,7 @@ impl Builder {
12591259
// are resolved to their hashed URIs.
12601260
self.add_actions_assertion_settings(&ingredient_map, &mut actions)?;
12611261

1262-
claim.add_assertion(&actions)
1262+
add_assertion(&mut claim, &actions, manifest_assertion.created())
12631263
}
12641264
#[allow(deprecated)]
12651265
CreativeWork::LABEL => {
@@ -4026,4 +4026,49 @@ mod tests {
40264026

40274027
Ok(())
40284028
}
4029+
4030+
#[test]
4031+
fn actions_created_assertion() {
4032+
let mut dest = Cursor::new(Vec::new());
4033+
Builder::new()
4034+
.with_definition(
4035+
json!({
4036+
"assertions": [
4037+
{
4038+
"label": "c2pa.actions",
4039+
"data": {
4040+
"actions": [
4041+
{
4042+
"action": "c2pa.created",
4043+
"digitalSourceType": "http://c2pa.org/digitalsourcetype/empty"
4044+
}
4045+
]
4046+
},
4047+
"created": true
4048+
}
4049+
]
4050+
})
4051+
.to_string(),
4052+
)
4053+
.unwrap()
4054+
.sign(
4055+
&Settings::signer().unwrap(),
4056+
"image/jpeg",
4057+
&mut Cursor::new(TEST_IMAGE),
4058+
&mut dest,
4059+
)
4060+
.unwrap();
4061+
4062+
dest.rewind().unwrap();
4063+
4064+
let reader = Reader::from_stream("image/jpeg", &mut dest).unwrap();
4065+
let active_manifest = reader.active_manifest().unwrap();
4066+
4067+
let actions_assertion = active_manifest
4068+
.assertions()
4069+
.iter()
4070+
.find(|assertion| assertion.label().starts_with(Actions::LABEL))
4071+
.unwrap();
4072+
assert!(actions_assertion.created());
4073+
}
40294074
}

sdk/src/claim.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use std::{
2020

2121
use async_generic::async_generic;
2222
use chrono::{DateTime, Utc};
23+
use coset::CoseSign1;
2324
use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer};
2425
use serde_json::{json, Map, Value};
2526
use uuid::Uuid;
@@ -1051,6 +1052,17 @@ impl Claim {
10511052
&self.signature_val
10521053
}
10531054

1055+
/// Returns the `COSE_Sign1_Tagged` structure found in the claim signature box.
1056+
pub fn cose_sign1(&self) -> Result<CoseSign1> {
1057+
let sig = self.signature_val();
1058+
let data = self.data()?;
1059+
let mut validation_log =
1060+
StatusTracker::with_error_behavior(ErrorBehavior::StopOnFirstError);
1061+
1062+
let sign1 = parse_cose_sign1(sig, &data, &mut validation_log)?;
1063+
Ok(sign1)
1064+
}
1065+
10541066
/// get claim generator
10551067
pub fn claim_generator(&self) -> Option<&str> {
10561068
self.claim_generator.as_deref()

sdk/src/crypto/raw_signature/openssl/validators/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ pub fn validator_for_signing_alg(alg: SigningAlg) -> Option<Box<dyn RawSignature
4343
}
4444
}
4545

46-
pub(crate) fn validator_for_sig_and_hash_algs(
47-
sig_alg: &Oid,
48-
hash_alg: &Oid,
46+
pub(crate) fn validator_for_sig_and_hash_algs<T: AsRef<[u8]>, U: AsRef<[u8]>>(
47+
sig_alg: &Oid<T>,
48+
hash_alg: &Oid<U>,
4949
) -> Option<Box<dyn RawSignatureValidator>> {
5050
if sig_alg.as_ref() == RSA_OID.as_bytes() {
5151
if hash_alg.as_ref() == SHA1_OID.as_bytes() {

sdk/src/crypto/raw_signature/rust_native/validators/mod.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,9 @@ pub fn validator_for_signing_alg(alg: SigningAlg) -> Option<Box<dyn RawSignature
9191
}
9292

9393
/// Select validator based on signing algorithm and hash type or EC curve.
94-
pub(crate) fn validator_for_sig_and_hash_algs(
95-
sig_alg: &Oid,
96-
hash_alg: &Oid,
94+
pub(crate) fn validator_for_sig_and_hash_algs<T: AsRef<[u8]>, U: AsRef<[u8]>>(
95+
sig_alg: &Oid<T>,
96+
hash_alg: &Oid<U>,
9797
) -> Option<Box<dyn RawSignatureValidator>> {
9898
// Handle legacy RSA.
9999
if sig_alg.as_ref() == RSA_OID.as_bytes() {
@@ -394,17 +394,17 @@ mod tests {
394394

395395
// Argh. Different Oid types across different crates, so we have to construct
396396
// our own constants here.
397-
const RSA_OID: Oid = bcder::Oid(OctetString::from_static(&[
397+
const RSA_OID: Oid<OctetString> = bcder::Oid(OctetString::from_static(&[
398398
42, 134, 72, 134, 247, 13, 1, 1, 1,
399399
]));
400400

401-
const SHA256_OID: Oid =
401+
const SHA256_OID: Oid<OctetString> =
402402
bcder::Oid(OctetString::from_static(&[96, 134, 72, 1, 101, 3, 4, 2, 1]));
403403

404-
const SHA384_OID: Oid =
404+
const SHA384_OID: Oid<OctetString> =
405405
bcder::Oid(OctetString::from_static(&[96, 134, 72, 1, 101, 3, 4, 2, 2]));
406406

407-
const SHA512_OID: Oid =
407+
const SHA512_OID: Oid<OctetString> =
408408
bcder::Oid(OctetString::from_static(&[96, 134, 72, 1, 101, 3, 4, 2, 3]));
409409

410410
#[test]

sdk/src/crypto/raw_signature/tests/validators.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -231,21 +231,24 @@ fn ps512() {
231231

232232
// Argh. Different Oid types across different crates, so we have to construct
233233
// our own constants here.
234-
const RSA_OID: Oid = bcder::Oid(OctetString::from_static(&[
234+
const RSA_OID: Oid<OctetString> = bcder::Oid(OctetString::from_static(&[
235235
42, 134, 72, 134, 247, 13, 1, 1, 1,
236236
]));
237237

238-
const SHA256_OID: Oid = bcder::Oid(OctetString::from_static(&[96, 134, 72, 1, 101, 3, 4, 2, 1]));
238+
const SHA256_OID: Oid<OctetString> =
239+
bcder::Oid(OctetString::from_static(&[96, 134, 72, 1, 101, 3, 4, 2, 1]));
239240

240-
const SHA384_OID: Oid = bcder::Oid(OctetString::from_static(&[96, 134, 72, 1, 101, 3, 4, 2, 2]));
241+
const SHA384_OID: Oid<OctetString> =
242+
bcder::Oid(OctetString::from_static(&[96, 134, 72, 1, 101, 3, 4, 2, 2]));
241243

242-
const SHA512_OID: Oid = bcder::Oid(OctetString::from_static(&[96, 134, 72, 1, 101, 3, 4, 2, 3]));
244+
const SHA512_OID: Oid<OctetString> =
245+
bcder::Oid(OctetString::from_static(&[96, 134, 72, 1, 101, 3, 4, 2, 3]));
243246

244247
#[cfg_attr(
245248
any(feature = "rust_native_crypto", target_arch = "wasm32"),
246249
allow(unused)
247250
)]
248-
const SHA1_OID: Oid = bcder::Oid(OctetString::from_static(&[43, 14, 3, 2, 26]));
251+
const SHA1_OID: Oid<OctetString> = bcder::Oid(OctetString::from_static(&[43, 14, 3, 2, 26]));
249252

250253
#[test]
251254
#[cfg_attr(
@@ -359,8 +362,8 @@ fn sha1() {
359362
}
360363

361364
#[allow(dead_code)]
362-
fn ans1_oid_bcder_oid(asn1_oid: &asn1_rs::Oid) -> bcder::Oid {
363-
const TEST_FAIL: Oid = bcder::Oid(OctetString::from_static(&[0, 0, 0, 0]));
365+
fn ans1_oid_bcder_oid(asn1_oid: &asn1_rs::Oid) -> bcder::Oid<OctetString> {
366+
const TEST_FAIL: Oid<OctetString> = bcder::Oid(OctetString::from_static(&[0, 0, 0, 0]));
364367

365368
let asn1_oid_str = asn1_oid.to_id_string();
366369

@@ -398,6 +401,6 @@ fn test_get_by_sig_and_alg() {
398401
assert!(validator_for_sig_and_hash_algs(&ed25519_oid, &sha512).is_some());
399402

400403
// test negative case
401-
const TEST_FAIL: Oid = bcder::Oid(OctetString::from_static(&[0, 0, 0, 0]));
404+
const TEST_FAIL: Oid<OctetString> = bcder::Oid(OctetString::from_static(&[0, 0, 0, 0]));
402405
assert!(validator_for_sig_and_hash_algs(&TEST_FAIL, &sha512).is_none());
403406
}

sdk/src/crypto/raw_signature/validator.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,9 @@ pub fn validator_for_signing_alg(alg: SigningAlg) -> Option<Box<dyn RawSignature
9393
///
9494
/// Which validators are available may vary depending on the platform and
9595
/// which crate features were enabled.
96-
pub(crate) fn validator_for_sig_and_hash_algs(
97-
sig_alg: &Oid,
98-
hash_alg: &Oid,
96+
pub(crate) fn validator_for_sig_and_hash_algs<T: AsRef<[u8]>, U: AsRef<[u8]>>(
97+
sig_alg: &Oid<T>,
98+
hash_alg: &Oid<U>,
9999
) -> Option<Box<dyn RawSignatureValidator>> {
100100
// TO REVIEW: Do we need any of the RSA-PSS algorithms for this use case?
101101
#[cfg(any(feature = "rust_native_crypto", target_arch = "wasm32"))]

sdk/src/manifest.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,12 @@ pub struct Manifest {
118118
#[serde(skip_serializing_if = "Option::is_none")]
119119
label: Option<String>,
120120

121+
/// The [`CoseSign1::signature`] value.
122+
///
123+
/// [`CoseSign1::signature`]: coset::CoseSign1::signature
124+
#[serde(skip)]
125+
signature: Option<Vec<u8>>,
126+
121127
/// Indicates where a generated manifest goes
122128
#[serde(skip)]
123129
remote_manifest: Option<RemoteManifest>,
@@ -236,6 +242,12 @@ impl Manifest {
236242
self.signature_info.as_ref()
237243
}
238244

245+
/// Returns the signature field of the `COSE_Sign1_Tagged` structure found in the
246+
/// claim signature box.
247+
pub fn signature(&self) -> Option<&[u8]> {
248+
self.signature.as_deref()
249+
}
250+
239251
/// Returns the parent ingredient if it exists.
240252
pub fn parent(&self) -> Option<&Ingredient> {
241253
self.ingredients.iter().find(|i| i.is_parent())
@@ -368,6 +380,10 @@ impl Manifest {
368380
format: claim.format().map(|s| s.to_owned()),
369381
instance_id: claim.instance_id().to_owned(),
370382
label: Some(claim.label().to_owned()),
383+
signature: claim
384+
.cose_sign1()
385+
.ok()
386+
.map(|cose_sign1| cose_sign1.signature),
371387
..Default::default()
372388
};
373389

0 commit comments

Comments
 (0)